Pascal 编译器语法分析实现:基于算符优先分析的表达式解析
#include
using namespace std;
// 四元式记录类型 struct Quatuor { TokenType op, first_obj, second_obj, result_obj; };
// 语法分析类 class Syntax { private: SemRecord *p_ID; // 符号表指针 int *p_m; Quatuor *p_Quat; // 四元式区指针 int *p_num; TokenType Token; // 单词Token Scan sExam; // 扫描器对象
public: Syntax(); Syntax(SemRecord *p1, int *p2, double *p3, int *p4, Quatuor *p5, int *p6); void Parse();
private: void EVA_SENTENCE(); // 递归下降分析 int map(int code); TokenType newt(int i); // 申请一个临时变量ti,作为四元式的结果单元 TokenType E(); // 算符优先分析 };
// 语法分析类成员定义 Syntax::Syntax(SemRecord *p1, int *p2, double *p3, int *p4, Quatuor *p5, int *p6) : sExam(p1, p2, p3, p4) { p_ID = p1; // 符号表指针 p_m = p2; p_Quat = p5; p_num = p6; }
void Syntax::Parse() { char filename[15]; // 文件名区 cout << 'please input file name:'; // 输入文件名 cin >> filename; if (!sExam.openfile(filename)) // 打开文件 return; sExam.Read(&Token); // read(w) EVA_SENTENCE(); if (!Token.code) // '#' 的 Token 为 (0, -1) cout << 'OK!' << endl; else cout << 'err' << endl; }
int Syntax::map(int code) { int i; switch (code) { case 16: // '+' case 17: i = 0; break; // '-' case 14: // '*' case 15: i = 1; break; // '/' case 1: case 2: i = 2; break; // 标识符、常数 case 19: i = 3; break; // '(' case 20: i = 4; break; // ')' default: i = 5; break; // -1 符号 } return i; }
TokenType Syntax::newt(int i) { // 申请一个临时变量 TokenType token; char strToken[30] = 't'; // 临时变量以 t 开头,以 i 为下标 int i_str = 1; char str[10]; int j = 0; while (i / 10) { // 生成一个新的临时变量 str[j++] = i % 10 + 48; // 0 -> '0' i = i / 10; } str[j] = i + 48; for (; j >= 0; j--) strToken[i_str++] = str[j]; strToken[i_str] = '\0'; strcpy((p_ID + (*p_m))->name, strToken); // 临时变量插入符号表 token.code = 1; token.value = (*p_m); (*p_m)++; return token; }
TokenType Syntax::E() { int n = 7; // 产生式个数 static int temp_id = 1; // 临时变量下标 TokenType syn[15]; // 语法栈 TokenType sem[15]; // 语义栈 TokenType temp_token; int top; // 栈顶指针 int top_in; // 移进指针 int handle[10]; // < 栈 int top_h; // < 栈顶指针 int prio[6][6] = { 3, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 0, 0, 3, 3, 1, 1, 1, 1, 2, 0, 3, 3, 0, 0, 3, 3, 1, 1, 1, 1, 0, 4 }; // 优先分析表 int i, j; // 表行和列 int code; // 表项 struct { int syn_rule[5]; int sem_rule; } rules[7] = { { {-1, 16, -1}, 1 }, { {-1, 17, -1}, 1 }, { {-1, 14, -1}, 1 }, { {-1, 15, -1}, 1 }, { {1}, 2 }, { {2}, 2 }, { {19, -1, 20}, 3 } }; // 产生式,-1 表示空位 syn[0].code = 0; // 初始化 top = 0; top_in = 1; handle[0] = 0; top_h = 0; while (1) { // 查分析表 code = prio(i, j) i = map(syn[top].code); // 定位行和列 j = map(Token.code); code = prio[i][j]; // 查表 // 空或 OK if (code == 0 || code == 4) break; // 栈操作 // 输入操作 if (code < 3) { // < or = syn[top_in].code = Token.code; // 进栈 syn[top_in].value = Token.value; if (code == 1) // 记录句柄的左端位置 handle[++top_h] = top + 1; top = top_in++; sExam.Read(&Token); // read(w) } else { // > for (i = 0; i < n; i++) { // 比较产生式 j = 0; while (rules[i].syn_rule[j] && rules[i].syn_rule[j] == (syn + handle[top_h] + j)->code) j++; if (!rules[i].syn_rule[j] && handle[top_h] + j == top_in) // 匹配上了一个 break; } if (i == n) cout << 'err!'; else { // 归约 // 执行语义动作 switch (rules[i].sem_rule) { case 1: // +, -, *, / 运算,生成四元式 temp_token = newt(temp_id++); // 类型检查,填写 temp_token 的语义信息 // ... // 生成四元式 p_Quat[*p_num].op.code = rules[i].syn_rule[1]; p_Quat[*p_num].op.value = -1; p_Quat[*p_num].result_obj.code = temp_token.code; p_Quat[*p_num].result_obj.value = temp_token.value; p_Quat[*p_num].first_obj.code = (sem + handle[top_h])->code; p_Quat[*p_num].first_obj.value = (sem + handle[top_h])->value; p_Quat[*p_num].second_obj.code = (sem + handle[top_h] + 2)->code; p_Quat[*p_num].second_obj.value = (sem + handle[top_h] + 2)->value; (*p_num)++; // E.place = t.entry (sem + handle[top_h])->code = temp_token.code; (sem + handle[top_h])->value = temp_token.value; break; case 2: // i,F.place = i.entry,保留值 sem[handle[top_h]].code = syn[handle[top_h]].code; sem[handle[top_h]].value = syn[handle[top_h]].value; break; case 3: // (E), F.place = i.entry,保留值 sem[handle[top_h]].code = sem[handle[top_h] + 1].code; sem[handle[top_h]].value = sem[handle[top_h] + 1].value; break; } // 执行归约 syn[handle[top_h]].code = -1; top = handle[top_h] - 1; top_in = handle[top_h] + 1; top_h--; } }
}
if (!code)
cout << 'err!';
return temp_token;
}
void Syntax::EVA_SENTENCE() { TokenType id_entry, E_place; if (Token.code == 1) { // 语义动作,保留 id.entry id_entry.code = Token.code; id_entry.value = Token.value; // read(w) sExam.Read(&Token); if (Token.code == 13) { // := sExam.Read(&Token); E_place = E(); // 生成四元式 p_Quat[*p_num].op.code = 13; p_Quat[*p_num].op.value = -1; p_Quat[*p_num].result_obj.code = id_entry.code; p_Quat[*p_num].result_obj.value = id_entry.value; p_Quat[*p_num].first_obj.code = E_place.code; p_Quat[*p_num].first_obj.value = E_place.value; p_Quat[*p_num].second_obj.code = -1; p_Quat[*p_num].second_obj.value = -1; (*p_num)++; } else cout << 'err!'; } else cout << 'err!';
};
原文地址: https://www.cveoy.top/t/topic/fZGG 著作权归作者所有。请勿转载和采集!