词法分析器实验报告
实验名称:语法分析器
实验内容:利用LL(1)或LR(1)分析语句语法,判断其是否符合可识别语法。学会根据状态变化、first、follow或归约转移思想构造状态分析表,利用堆栈对当前内容进行有效判断
实验设计:
1. 实现功能
可对一段包含加减乘除括号的赋值语句进行语法分析,其必须以$为终结符,语句间以;隔离,判断其是否符合语法规则,依次输出判断过程中所用到的产生式,并输出最终结论,若有错误可以报错并提示错误所在行数及原因
2. 实验步骤
3. 算法与数据结构
a) LLtable:left记录产生式左端字符;right记录产生式右端字符;ln记录产生式右端字符长度
Status:记录token分析情况
Token:category,类型;value,具体内容
b) 根据LL(1)算法,手工构造分析表,并将内容用数组存储,便于查找
c) 先将当前语句的各token按序存储,当前处理语句最后一个token以#标记,作为输入流与产生式比较,堆栈中初始放入#,x,a为处理输入流中当前读头内容
? 若top=a=‘#‘表示识别成功,退出分析程序
? 若top=a!=‘#‘表示匹配,弹出栈顶符号,读头前进一个
? 若top为i或n,但top!=a,出错,输出当前语句所在行,出错具体字符
? 若top不为i或n,查预测分析表,若其中存放关于top产生式,则弹出top,将产生式右部自右向左压入栈内,输出该产生式,若其中没有产生式,出错,输出当前语句所在行,出错具体字符
d) 以;作为语句终结,每次遇到分号则处理之前语句并清空后预备下语句处理,当遇到$表示该段程序结束,停止继续处理
4. 分析表构造过程
a) x->i=e
e->e+t|e-t|t
t->t*f|t/f|f
f->(e)|i|n
note: i表示变量,n表示数字,!表示空串
b) 提取左公因子
x->i=e
e->ea|t
a->+t|-t
t->tb|f
b->*f|/f
f->(e)|i|n
c) 消除左递归
x->i=e
e->tc
c->ac|!
a->+t|-t
t->fd
d->bd|!
b->*e|/f
f->(e)|i|n
d) FIRST & FOLLOW
FIRST(x)={i}
FOLLOW(x)={#}
FIRST(e)={(,i,n}
FOLLOW(e)={#, ) }
FIRST(t)={(,i,n}
FOLLOW(t)={#,+,-, )}
FIRST(c)={+,-,!}
FOLLOW(c)={#, ) }
FIRST(a)={+,-}
FOLLOW(a)={#,+,-, ) }
FIRST(f)= {(,i,n}
FOLLOW(f)={#,+,-,/,*}
FIRST(d)={*,/,!}
FOLLOW(d)={#,+,- ,) }
FIRST(b)={*,/}
FOLLOW(b)={#,+,-,/,*}
e) 分析表
0
1
2
3
4
5
6
7
8
+
-
*
/
(
)
i
n
#
0
x
x->i=e
1
e
e->tc
e->tc
e->tc
2
c
c->ac
c->ac
c->!
c->!
3
a
a->+t
a->-t
4
t
t->fd
t->fd
t->fd
5
d
d->!
d->!
d->bd
d->bd
d->!
d->!
6
b
b->*f
b->/f
7
f
f->(e)
f->n
5. 类
class parser
{
public:
LLtable table[100][100]; //LL(1)表
void scanner(); //扫描输入流中内容并分析
parser(istream& in); //初始化,得到输入文件地址
int getLine() const; //得到当前行数
private:
int match(); //分析语法
stack
proStack; //分析堆栈
void constructTable(); //建立LL(1)表
int getRow(char ch); //取字符所在表中行
int getCol(char ch); //取字符所在表中列
istream* pstream; //输入流
void insertToken(token& t); //插入当前token
status getToken(token& t); //找到token
int getChar(); //得到当前字符
int peekChar(); //下一个字符
void putBackChar(char ch); //将字符放回
void skipChar(); //跳过当前字符
void initialization(); //初始化堆栈等
int line; //当前行数
token tokens[1000]; //字符表
int counter; //记录当前字符表使用范围
}
6. 主要代码
void parser::constructTable() //建立LL(1)表
{
for (int i=0;i<8;i++)
{
for (int j=0;j<9;j++)
{
table[i][j].left=' ';
for (int k=0;k<3;k++)
table[i][j].right[k]=' ';
}
}
table[0][6].left='x';
table[0][6].ln=3;
table[0][6].right[0]='i';
table[0][6].right[1]='=';
table[0][6].right[2]='e';
table[1][4].left='e';
table[1][4].ln=2;
table[1][4].right[0]='t';
table[1][4].right[1]='c';
table[1][6].left='e';
table[1][6].ln=2;
table[1][6].right[0]='t';
table[1][6].right[1]='c';
table[1][7].left='e';
table[1][7].ln=2;
table[1][7].right[0]='t';
table[1][7].right[1]='c';
table[2][0].left='c';
table[2][0].ln=2;
table[2][0].right[0]='a';
table[2][0].right[1]='c';
table[2][1].left='c';
table[2][1].ln=2;
table[2][1].right[0]='a';
table[2][1].right[1]='c';
table[2][5].left='c';
table[2][5].ln=0;
table[2][5].right[0]='!';
table[2][8].left='c';
table[2][8].ln=0;
table[2][8].right[0]='!';
table[3][0].left='a';
table[3][0].ln=2;
table[3][0].right[0]='+';
table[3][0].right[1]='t';
table[3][1].left='a';
table[3][1].ln=2;
table[3][1].right[0]='-';
table[3][1].right[1]='t';
table[4][4].left='t';
table[4][4].ln=2;
table[4][4].right[0]='f';
table[4][4].right[1]='d';
table[4][6].left='t';
table[4][6].ln=2;
table[4][6].right[0]='f';
table[4][6].right[1]='d';
table[4][7].left='t';
table[4][7].ln=2;
table[4][7].right[0]='f';
table[4][7].right[1]='d';
table[5][0].left='d';
table[5][0].ln=0;
table[5][0].right[0]='!';
table[5][1].left='d';
table[5][1].ln=0;
table[5][1].right[0]='!';
table[5][2].left='d';
table[5][2].ln=2;
table[5][2].right[0]='b';
table[5][2].right[1]='d';
table[5][3].left='d';
table[5][3].ln=2;
table[5][3].right[0]='b';
table[5][3].right[1]='d';
table[5][5].left='d';
table[5][5].ln=0;
table[5][5].right[0]='!';
table[5][8].left='d';
table[5][8].ln=0;
table[5][8].right[0]='!';
table[6][2].left='b';
table[6][2].ln=2;
table[6][2].right[0]='*';
table[6][2].right[1]='f';
table[6][3].left='b';
table[6][3].ln=2;
table[6][3].right[0]='/';
table[6][3].right[1]='f';
table[7][4].left='f';
table[7][4].ln=3;
table[7][4].right[0]='(';
table[7][4].right[1]='e';
table[7][4].right[2]=')';
table[7][6].left='f';
table[7][6].ln=1;
table[7][6].right[0]='i';
table[7][7].left='f';
table[7][7].ln=1;
table[7][7].right[0]='n';
}
int parser::match() //分析语法
{
ofstream ofs("out.txt",ios::app);
char a;
int i=0;
for (int p=0;p"<0)
{
//cout<
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
。另外,在分别求first、follow时容易出错,在程序运行中没有得到期望结果时才发现,因此手工构造分析表较容易出错。最简单的四则运算赋值也牵涉到如此多的细节、转换,相信更为复杂的语句判断、循环等更不简单,如今计算机各种处理都远比四则运算赋值复杂得多,牵涉到诸多关系,而机器则能根据规则无差错完成,这也是人类依靠机器的重要原因,机器只是根据产生式一步步判断得出结论。而关于树形输出,在操作过程中发现较为困难,没有成功实现。
本文档为【语法分析器实验报告】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
格式:doc
大小:65KB
软件:Word
页数:20
分类:互联网
上传时间:2019-05-17
浏览量:15