用VC++语言实现对C语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;同时进行标识符登记符号表的管理。 以下是实现词法分析设计的主要工作: (1)从源程序文件中读入字符。 (2)统计行数和列数用于错误单词的定位。 (3)删除空格类字符,包括回车、制表符空格。 (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token的机内表示) (5)如果发现错误则报告出错 (6)根据需要是否填写标识符表供以后各阶段使用。 用C++实现以上任务
时间: 2024-02-28 20:57:52 浏览: 147
基于C++实现词法分析程序(编译原理实验)
5星 · 资源好评率100%
好的,下面是一个简单的用 C++ 实现词法分析器的示例代码,实现了对 C 语言子集的词法分析,并将标识符存入符号表中:
```cpp
#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>
using namespace std;
enum TokenType {
KEYWORD, // 关键字
IDENTIFIER, // 标识符
OPERATOR, // 运算符
DELIMITER, // 分隔符
LITERAL, // 字面量
ERROR // 错误
};
struct Token {
TokenType type; // token 类型
string value; // token 值
int line; // 行号
int column; // 列号
};
unordered_map<string, TokenType> keywords = {
{"if", KEYWORD},
{"else", KEYWORD},
{"while", KEYWORD},
{"int", KEYWORD},
{"float", KEYWORD}
};
unordered_map<string, TokenType> operators = {
{"+", OPERATOR},
{"-", OPERATOR},
{"*", OPERATOR},
{"/", OPERATOR},
{"=", OPERATOR}
};
unordered_map<string, TokenType> delimiters = {
{"(", DELIMITER},
{")", DELIMITER},
{";", DELIMITER},
{",", DELIMITER}
};
unordered_map<int, string> tokenTypes = {
{KEYWORD, "Keyword"},
{IDENTIFIER, "Identifier"},
{OPERATOR, "Operator"},
{DELIMITER, "Delimiter"},
{LITERAL, "Literal"},
{ERROR, "Error"}
};
int main() {
// 读取源程序文件
ifstream fin("source.c");
if (!fin) {
cerr << "Failed to open source file!" << endl;
return 1;
}
string source((istreambuf_iterator<char>(fin)), istreambuf_iterator<char>());
fin.close();
// 统计行数和列数
int line = 1;
int column = 1;
// 删除空格类字符
source.erase(remove_if(source.begin(), source.end(), [](char c) {
return isspace(c);
}), source.end());
// 进行词法分析
vector<Token> tokens;
for (auto it = source.begin(); it != source.end(); ) {
// 处理关键字和标识符
if (isalpha(*it)) {
auto start = it;
while (it != source.end() && (isalpha(*it) || isdigit(*it))) {
++it;
}
string word(start, it);
if (keywords.count(word)) {
tokens.push_back({keywords[word], word, line, column});
} else {
tokens.push_back({IDENTIFIER, word, line, column});
}
}
// 处理运算符和分隔符
else if (isgraph(*it)) {
auto start = it;
while (it != source.end() && isgraph(*it) && !isspace(*it)) {
++it;
}
string symbol(start, it);
if (operators.count(symbol)) {
tokens.push_back({operators[symbol], symbol, line, column});
} else if (delimiters.count(symbol)) {
tokens.push_back({delimiters[symbol], symbol, line, column});
} else {
tokens.push_back({ERROR, symbol, line, column});
}
}
// 处理换行符
else if (*it == '\n') {
++line;
column = 1;
++it;
continue;
}
// 处理其他字符
else {
++it;
continue;
}
// 更新列数
column += it - source.begin() - (tokens.empty() ? 0 : tokens.back().value.size());
}
// 输出词法分析结果并填写符号表
unordered_map<string, int> symbolTable;
for (auto& token : tokens) {
cout << "(" << tokenTypes[token.type] << ", " << token.value << ")";
if (token.type == IDENTIFIER) {
if (symbolTable.count(token.value)) {
cout << " (already defined)";
} else {
symbolTable[token.value] = symbolTable.size() + 1;
}
}
cout << endl;
}
// 输出符号表
cout << "Symbol table:" << endl;
for (auto& entry : symbolTable) {
cout << entry.first << " => " << entry.second << endl;
}
return 0;
}
```
这段代码使用了 STL 中的 unordered_map 来实现符号表,使用了 C++11 中的 lambda 表达式和 auto 关键字来简化代码。在具体实现时,需要根据实际情况进行调整。
阅读全文