1 输入任意文法,改写文法使其成为LL(1)文法。
1.1 由于老师给的应该是最适合我们联系的LL(1)文法,所以说我也是用以下文法进行分析。
E→E+T | T
T→T*F | F
F→( E ) | i
注意e在此表示‘’,也就是空,表示没有任何字符输入。
1.2 消除左递归
E--------TE’
E’----------+TE’|e
T ------------FT’
T’---------------*FT’|e
F------------------(E)|i
1.3 消除回溯
1.3.1 FIRST和FALLOW集合
1.3.2 判断
FIRST(E’)∩FOLLOW(E’)= 空集
FIRST(T’)∩FOLLOW(T’)=空集
所以上述文法式LL(1)文法
2 构造文法的预测分析表;
3 设计堆栈和预测分析表的机内表示
我将会使用MAP作为机内表示的数据结构
///E’,T’分别表示为e,t
//~表示空,也就是 无输入
map,string> forecast;
void fore_init()
{
forecast[pair(“E”,“i”)]=“Te”;
forecast[pair(“T”,“i”)]=“Ft”;
forecast[pair(“F”,“i”)]=“i”;
forecast[pair(“e”,"+")]="+Te";
forecast[pair(“t”,"+")]="~";
forecast[pair(“t”,"*")]="*Ft";
forecast[pair(“E”,"(")]=“Te”;
forecast[pair(“T”,"(")]=“Ft”;
forecast[pair(“F”,"(")]="(E)";
forecast[pair(“e”,")")]="~";
forecast[pair(“t”,")")]="~";
forecast[pair(“e”,"#")]="~";
forecast[pair(“t”,"#")]="~";
}
4 设计并书写语法分析程序;
```cpp
#include
#include
5 调试并运行语法分析程序
5.1 测试数据:
5.1.1 正确数据i+i*i#
5.1.2 正确数据i*i+i#
5.1.3 正确数据 无限个i+ 最后添加一个i#
5.1.4 错误数据iiiiii
5.1.5 非法数据i+i8i
5.2 实验结果分析
分析程序中文法存储所采用的数据结构
pair和map数据结构
采用的数据结构是三维坐标,map,string> forecast;通过前两个string来唯一确定出第三个tring,也就是产生式的值。
将产生时存储到map里
forecast[pair(“E”,“i”)]=“Te”;
forecast[pair(“T”,“i”)]=“Ft”;
forecast[pair(“F”,“i”)]=“i”;
forecast[pair(“e”,"+")]="+Te";
forecast[pair(“t”,"+")]="~";
forecast[pair(“t”,"*")]="*Ft";
forecast[pair(“E”,"(")]=“Te”;
forecast[pair(“T”,"(")]=“Ft”;
forecast[pair(“F”,"(")]="(E)";
forecast[pair(“e”,")")]="~";
forecast[pair(“t”,")")]="~";
forecast[pair(“e”,"#")]="~";
forecast[pair(“t”,"#")]="~";
接下来通过
pair k;//这个是预测分析表的坐标
string term,nonterm;///终结符,非终结符
string prod;//这个用来接收产生式
term=analysis.top();
nonterm=in[i];
k.first=term;
k.second=nonterm;
prod=forecast[k];///找到产生式
到最后一步位置,便可以唯一确定一个字符串
Stack数据结构
栈主要用来当做分析栈
stack analysis;
void analysis_init()
{
analysis.push(’#’);
analysis.push(‘E’);
}
初始状态两个字符,按照ll1(1),文法进行操作,栈空表示接受字符串