在已有的词法分析器基础上实现一个文法的语法分析器,C++代码
时间: 2023-12-10 22:37:17 浏览: 112
以下是一个简单的 LL(1) 语法分析器的 C++ 实现,它可以读取并分析类似于以下文法的输入:
```
E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id
```
其中,`id` 表示标识符,`+` 表示加法操作符,`*` 表示乘法操作符,`(` 和 `)` 表示括号。
```c++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Token 类型枚举
enum TokenType {
TOKEN_TYPE_PLUS, // "+"
TOKEN_TYPE_STAR, // "*"
TOKEN_TYPE_LPAREN, // "("
TOKEN_TYPE_RPAREN, // ")"
TOKEN_TYPE_ID, // 标识符
TOKEN_TYPE_END // 输入结束标记
};
// Token 类
class Token {
public:
Token(TokenType type, string value) : type(type), value(value) {}
TokenType getType() const { return type; }
string getValue() const { return value; }
private:
TokenType type;
string value;
};
// 词法分析器类
class Lexer {
public:
Lexer(string input) : input(input), position(0) {}
Token getNextToken() {
while (position < input.length()) {
char currentChar = input[position];
if (isdigit(currentChar)) {
return parseId();
}
switch (currentChar) {
case '+':
position++;
return Token(TOKEN_TYPE_PLUS, "+");
case '*':
position++;
return Token(TOKEN_TYPE_STAR, "*");
case '(':
position++;
return Token(TOKEN_TYPE_LPAREN, "(");
case ')':
position++;
return Token(TOKEN_TYPE_RPAREN, ")");
default:
cerr << "Invalid character: " << currentChar << endl;
exit(1);
}
}
return Token(TOKEN_TYPE_END, "");
}
private:
Token parseId() {
string value = "";
while (position < input.length() && isdigit(input[position])) {
value += input[position++];
}
return Token(TOKEN_TYPE_ID, value);
}
string input;
int position;
};
// 语法分析器类
class Parser {
public:
Parser(Lexer lexer) : lexer(lexer), currentToken(lexer.getNextToken()) {}
void parse() {
parseE();
if (currentToken.getType() != TOKEN_TYPE_END) {
cerr << "Unexpected token: " << currentToken.getValue() << endl;
exit(1);
}
}
private:
void parseE() {
parseT();
parseEPrime();
}
void parseEPrime() {
if (currentToken.getType() == TOKEN_TYPE_PLUS) {
match(TOKEN_TYPE_PLUS);
parseT();
parseEPrime();
}
}
void parseT() {
parseF();
parseTPrime();
}
void parseTPrime() {
if (currentToken.getType() == TOKEN_TYPE_STAR) {
match(TOKEN_TYPE_STAR);
parseF();
parseTPrime();
}
}
void parseF() {
if (currentToken.getType() == TOKEN_TYPE_LPAREN) {
match(TOKEN_TYPE_LPAREN);
parseE();
match(TOKEN_TYPE_RPAREN);
} else {
match(TOKEN_TYPE_ID);
}
}
void match(TokenType expectedType) {
if (currentToken.getType() == expectedType) {
currentToken = lexer.getNextToken();
} else {
cerr << "Syntax error: expected " << getTokenName(expectedType)
<< " but got " << currentToken.getValue() << endl;
exit(1);
}
}
string getTokenName(TokenType type) {
switch (type) {
case TOKEN_TYPE_PLUS:
return "+";
case TOKEN_TYPE_STAR:
return "*";
case TOKEN_TYPE_LPAREN:
return "(";
case TOKEN_TYPE_RPAREN:
return ")";
case TOKEN_TYPE_ID:
return "id";
case TOKEN_TYPE_END:
return "end of input";
default:
return "";
}
}
Lexer lexer;
Token currentToken;
};
int main() {
string input = "3+4*5";
Lexer lexer(input);
Parser parser(lexer);
parser.parse();
cout << "Parsing completed successfully!" << endl;
return 0;
}
```
阅读全文