}
int ProcedureC(ifstream& from_file) { Indent();
cout<<\< indentation += 4;//子程序开始 Token* token; ProcedureE(from_file); token = TokenScan(from_file); Indent(); if (token->type == MORE) { cout< } else if (token->type == LESS) { cout< indentation -= 4;//子程序结束 return 0; } int ProcedureE(ifstream& from_file) { Indent(); cout<<\< indentation += 4;//子程序开始 Token* token; ProcedureT(from_file); while (true) { token = TokenScan(from_file); if (token->type == ADD) { Indent(); cout< } else if (token->type == MINUS) { Indent(); cout< for (int i = 0; i < (int)token->name.length(); i++) { from_file.unget();//回退 } indentation -= 4;//子程序结束 return 0; } } indentation -= 4;//子程序结束 return 0; } int ProcedureT(ifstream& from_file) { Indent(); cout<<\< indentation += 4;//子程序开始 Token* token; ProcedureF(from_file); while (true) { token = TokenScan(from_file); if (token->type == MUL) { Indent(); cout< } else if (token->type == DIC) { Indent(); cout< for (int i = 0; i < (int)token->name.length(); i++) { from_file.unget();//回退 } indentation -= 4;//子程序结束 return 0; } } indentation -= 4;//子程序结束 return 0; }int ProcedureF(ifstream& from_file) { Indent(); cout<<\< indentation += 4;//子程序开始 Token* token; token = TokenScan(from_file); if (token->type == LBRAC) { cout< token = TokenScan(from_file); cout< Indent(); if (token->type == IDN) { cout<<\< if (token->type == INT8) { cout<<\< if (token->type == INT10) { cout<<\< if (token->type == INT16) { cout<<\< indentation -= 4;//子程序结束 return 0; } 实验结果: 实验中遇到的问题及其解决: 1、消除左递归,提取左因子之后的E、 T对应的子程序的编写问题: 经过多次测试,我发现在一个expression超过两个运算符的时候我的E、T子程序就只能成功的分析出第一段的式子,后来发现E->T(+T)*类似的产生式没有写循环调用控制,后来在(+T)*的最外层加了一个while(true)循环,然后在while(true)的首行加入了不是‘+’就return的判定,成功解决了问题。 2、缩进的控制: 这个实验中碰到的第二个问题就是语法树缩进的控制问题,最终通过一个全局变量indentation来控制缩进的字符数量,一个Indent()函数来输出缩进(其实就是空格),控制缩进数量的关键点有两个:一为进入子程序的时候indentation+=4, 二为结束子程序的时候indentation-=4。剩下的就是根据调试来选择在哪里输出缩进空格的问题了。 实验三 语法制导的三地址代码生成程序 语法制导定义: 产生式 S –> id = E ; S –> if C then S C.true = newlabel; C.false = S.next; S1.next = S.next; S.code = C.code || gen(C.true ‘:’) || S1.code S –> while C do S S.begin = newlabel; C.true = newlabel; C.false = S.next; S1.next = S.begin; S.code = gen(S.begin ‘:’) || C.code || gen(C.true ‘:’) || S1.code || gen(‘goto’ S.begin); C –> E1 > E2 C.code = E1.code || E2.code || gen(‘if’E1.place ‘>’ E2.place ‘goto’ C.true) || gen(‘goto’C.false) C –> E1 < E2 C.code = E1.code || E2.code || gen(‘if’ E1.place ‘<’ E2.place ‘goto’ C.true) || gen(‘goto’ C.false) E –> T1 (+ T2)* E.place = newtemp; (E.code = T1.code||T2.code|| gen(E.place ‘:=’ T1.place ‘+’ T2.place); T1.place = E.place; T1.code = E.code;)+ 语义规则 S.code = E.code || gen(id.place ‘:=’ E.place) E –> T1 (- T2)* E.place = newtemp; (E.code = T1.code||T2.code|| gen(E.place ‘:=’ T1.place ‘-’ T2.place); T1.place = E.place; T1.code = E.code;)+ E.place = T.place; E.code = T.code T.place = F.place; T.code = F.code E –> T T –> F