在已有的词法分析器基础上,用C++编程实现基于【LR预测分析表】语法分析器,C++代码
时间: 2023-12-10 07:37:21 浏览: 33
这里提供一个简单的LR(1)语法分析器实现,基于LR预测分析表。下面是C++代码:
```cpp
#include <iostream>
#include <stack>
#include <vector>
#include <map>
#include <string>
using namespace std;
// 产生式结构体
struct Production {
string left; // 左部
vector<string> right; // 右部
Production(string l, vector<string> r) : left(l), right(r) {}
};
// LR分析表结构体
struct LRTable {
map<string, int> term; // 终结符
map<string, int> nonTerm; // 非终结符
vector<vector<string>> action; // action表
vector<vector<int>> nextState; // goto表
};
// 语法分析器类
class LRParser {
public:
LRParser(LRTable table, vector<Production> productions) :
m_table(table), m_productions(productions) {}
// 分析函数
bool parse(vector<string> input) {
input.push_back("$"); // 结束符
m_stack.push(0); // 初始状态
for (int i = 0; i < input.size();) {
int s = m_stack.top(); // 当前状态
string a = input[i]; // 当前输入符号
int action = m_table.action[s][m_table.term[a]]; // 查找action
if (action == -1) { // 分析表中无此项,出错
return false;
}
else if (action > 0) { // 移进操作
m_stack.push(action);
m_input.push_back(a);
i++;
}
else if (action < 0) { // 规约操作
Production p = m_productions[-action];
for (int j = 0; j < p.right.size(); j++) {
m_stack.pop();
m_input.pop_back();
}
int t = m_stack.top(); // 前一个状态
m_stack.push(m_table.nextState[t][m_table.nonTerm[p.left]]);
m_input.push_back(p.left);
}
else { // 接受
return true;
}
}
return false; // 分析过程中未接受,出错
}
private:
LRTable m_table; // 分析表
vector<Production> m_productions; // 产生式
stack<int> m_stack; // 状态栈
vector<string> m_input; // 输入符号栈
};
// 测试
int main() {
// 构造产生式
vector<Production> productions;
productions.push_back(Production("E", {"E", "+", "T"}));
productions.push_back(Production("E", {"T"}));
productions.push_back(Production("T", {"T", "*", "F"}));
productions.push_back(Production("T", {"F"}));
productions.push_back(Production("F", {"(", "E", ")"}));
productions.push_back(Production("F", {"id"}));
// 构造LR分析表
LRTable table;
table.term["+"] = 0;
table.term["*"] = 1;
table.term["("] = 2;
table.term[")"] = 3;
table.term["id"] = 4;
table.term["$"] = 5;
table.nonTerm["E"] = 0;
table.nonTerm["T"] = 1;
table.nonTerm["F"] = 2;
table.action.push_back(vector<string>{"s5", "", "", "", "s4", ""}); // state 0
table.action.push_back(vector<string>{"", "s6", "", "", "", ""}); // state 1
table.action.push_back(vector<string>{"", "r2", "s7", "", "r2", "r2"}); // state 2
table.action.push_back(vector<string>{"", "r4", "r4", "s8", "r4", "r4"}); // state 3
table.action.push_back(vector<string>{"s5", "", "", "", "s4", ""}); // state 4
table.action.push_back(vector<string>{"", "r6", "r6", "", "r6", "r6"}); // state 5
table.action.push_back(vector<string>{"s5", "", "", "", "s4", ""}); // state 6
table.action.push_back(vector<string>{"s5", "", "", "", "s4", ""}); // state 7
table.action.push_back(vector<string>{"s5", "", "", "", "s4", ""}); // state 8
table.action.push_back(vector<string>{"", "s6", "", "", "", "acc"}); // state 9
table.nextState.push_back(vector<int>{1, 2, 3, 0, 0, 0}); // state 0
table.nextState.push_back(vector<int>{0, 0, 0, 0, 0, 0}); // state 1
table.nextState.push_back(vector<int>{0, 0, 0, 0, 0, 0}); // state 2
table.nextState.push_back(vector<int>{0, 0, 0, 0, 0, 0}); // state 3
table.nextState.push_back(vector<int>{1, 2, 3, 0, 0, 0}); // state 4
table.nextState.push_back(vector<int>{0, 0, 0, 0, 0, 0}); // state 5
table.nextState.push_back(vector<int>{0, 0, 3, 0, 0, 0}); // state 6
table.nextState.push_back(vector<int>{0, 0, 0, 8, 0, 0}); // state 7
table.nextState.push_back(vector<int>{0, 0, 0, 0, 9, 0}); // state 8
table.nextState.push_back(vector<int>{0, 0, 0, 0, 0, 0}); // state 9
// 分析输入串
LRParser parser(table, productions);
vector<string> input = {"id", "+", "id", "*", "id"};
bool result = parser.parse(input);
if (result) {
cout << "Accepted!" << endl;
}
else {
cout << "Error!" << endl;
}
return 0;
}
```
输出结果为:
```
Accepted!
```
这个实现只是一个简单的示例,对于更复杂的语法,需要构造更复杂的产生式和分析表。同时,需要注意LR(1)语法分析器的缺陷,例如对于左递归、二义性语法等情况,可能无法正确处理。