- 近段时间学习编译原理,借鉴了部分前辈代码,实现了龙书的伪代码。
- 不足之处敬请指正。
下面展示一些 内联代码片
。
#include <iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
//使用X、Y、Z 代替 E'、T'、F'
//非终结符
char non_terminal[7] = { 'E','X','T','Y','F','Z','P' };
//终结符
char terminal[9] = { '(','i','+','-','*','/','^',')','#' };
//分析表
string analystate[7][9] = {
{"TX","TX","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//TX->TE' E
{"NULL","NULL","+TX","-TX","NULL","NULL","NULL","e","e"},//E'
{"FY","FY","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//FY->FT' T
{"NULL","NULL","e","e","*FY","/FY","NULL","e","e"}, //T'
{"PZ","PZ","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//PZ->PF' F
{"NULL","NULL","e","e","e","e","^F","e","e"}, //F'
{"(E)","i","NULL","NULL","NULL","NULL","NULL","NULL","NULL"} //P
};
//获取非终结符索引
int GetNonIndex(char p) {
for (int i = 0; i < 7; i++) {
if (p == non_terminal[i]) {
return i;
}
}
return -1;//错误
}
//获取终结符索引
int GetTermIndex(char p) {
for (int i = 0; i < 9; i++) {
if (p == terminal[i]) {
return i;
}
}
return -1;//错误
}
//自顶向下预测分析
bool GramSyntax(const string & stament) {
stack<char>AnalStack;//定义分析栈
char ip;
string expr;
int x, y,i=0;//y代表终结符,x代表非终结符
int len;
AnalStack.push('#');
AnalStack.push('E');
char Symbol = AnalStack.top();//X=栈顶
ip = stament[i];
while (Symbol != '#') {
y = GetTermIndex(Symbol);//判断是否是终结符
if (y != -1) {//X是终结符
if (Symbol == ip) {
AnalStack.pop();
i++;
ip = stament[i];
}
else {//语法报错
cout << "语法错误" << endl;
return false;
}
}
else {//X是非终结符
//分别获取x,y的位置
x = GetNonIndex(Symbol);//获取非中介
y = GetTermIndex(ip);
if (y == -1) {
cout << "输入终结符不匹配,错误输入为:" << ip<<endl;
return false;
}
expr = analystate[x][y];//获取预测分析表内容
if (expr == "NULL") {//M[X,a] error()
cout << "语法规则错误:" <<ip<< endl;
return false;
}
if (expr == "e") {//弹出栈
AnalStack.pop();
}
else {//否则将表达式逆序入栈
AnalStack.pop();
for (int k = expr.size() - 1; k >= 0; k--) {
AnalStack.push(expr[k]);
}
}
}
Symbol = AnalStack.top();//X=栈顶符号
}
cout << "分析完毕,语法正确" << endl;
return true;
}
int main() {
string pp = "(i++i)*i#";
bool isok = GramSyntax(pp);
return 0;