语法分析器含源码Word文件下载.doc
《语法分析器含源码Word文件下载.doc》由会员分享,可在线阅读,更多相关《语法分析器含源码Word文件下载.doc(37页珍藏版)》请在冰豆网上搜索。
变量定义语句>
|<
赋值语句>
|<
条件语句>
|<
循环语句>
}
②<
=var变量{,变量};
③<
=变量:
=<
表达式>
;
④<
:
=标识符{运算符标识符};
⑤<
标识符>
=变量|常量
⑥<
运算符>
=+|-|*|/|>
=|<
=
⑦<
if语句>
[<
else语句>
]
⑧<
=if(表达式)then[begin]{赋值语句|条件语句|循环语句}[end]
⑨<
=[begin]{赋值语句|条件语句|循环语句}[end]
⑩<
=while(表达式)[begin]{赋值语句|条件语句|循环语句}[end]
<
输出语句>
=prn表达式
--注1:
若if语句、else语句、循环语句中出现begin,后面的end必须出现,即begin与end同对出现
--注2:
if、while后的"
("
,"
)"
表示终结符,而不是定义成分优先的说明符号
2、分析表:
=
变量
常量
,
;
运算符
(
)
变量
定义
->
②
②
赋值
语句
③
->
条件语句
⑦
⑦
循环语句
⑩
输出语句
分析表(续):
while
var
begin
end
if
then
prn
变量定义
赋值语句
条件语句
循环语句
输出语句
3、调试和测试
五、源代码(见附录):
六、实验总结:
本实验在词法分析的基础上,对提取出的标识符进行语法判断。
对已有的语法规则运用LL
(1)文法判别并进行构造分析表时,遇到的最大困难是:
当发生规约冲突时,该如何处理。
如对于产生式s-->
aAb,当对a进行规约时,满足语法规则的β(用户输入串中当前要进行规约的标识符)只有有限种,而不满足的却有无限种情况。
当发生规约冲突时,如何在这无限种情况中,确定冲突的具体信息,以便用户查找。
在反复的尝试和验证中,我们发现发生冲突的用户输入串满足一定的规律,且按这种规律可以把这无限种情况化归为有限类,于是我们找出其中规律并进行划分,然后再对这些有限类冲突进行处理。
七、实验心得:
通过这次实验有以下几点收获:
1.LR
(1)的构造使得对理论的知识理解的更加透彻。
其中LR
(1)分析表构造了很多遍,一直无法得到正确结果,这是恒心的考验。
2.在写程序中用类数组来存放单词属性使得对单词各项值的调用更加方便,特别是对出错信息的检测有很大的作用。
3.本实验是在词法基础上的更进一步,在词法程序上添加语法程序,更加理解二者之间的关系。
词法分析为语法分析提供了词法单元,方便分析,使程序模块化,易于读懂。
附录:
#include<
iostream>
fstream>
string>
math.h>
ctype.h>
cstdlib>
usingnamespacestd;
#defineMax655 //最大代码长度
#defineWordMaxNum256 //变量最大个数
#defineDigitNum256 //常量最大个数
#defineMaxKeyWord 32 //关键字数量
#defineMaxOptANum8 //运算符最大个数
#defineMaxOptBNum4 //运算符最大个数
#defineMaxEndNum11 //界符最大个数
typedefstructDisplayTable
{
intIndex;
//标识符所在表的下标
inttype;
//标识符的类型
intline;
//标识符所在表的行数
charsymbol[20];
//标识符所在表的名称
}Table;
intTableNum=0;
//display表的表项总数
charWord[WordMaxNum][20];
//标识符表
charDigit[WordMaxNum][20];
//数字表
intWordNum=0;
//变量表的下标
intDigNum=0;
//常量表的下标
boolerrorFlag=0;
//错误标志
intTableIndex=-1;
//display表的下标索引
intbeginCount=0;
//遇到begin加1,遇到end减1
intifCount=0;
//遇到if加1
Table*table=newTable[Max];
//关键字
constchar*constKeyWord[MaxKeyWord]={"
and"
"
array"
"
begin"
case"
char"
constant"
do"
else"
end"
false"
for"
if"
input"
integer"
not"
of"
or"
output"
"
packed"
procedure"
program"
read"
real"
repeat"
set"
then"
to"
type"
until"
var"
while"
with"
prn"
};
//单目运算
constcharOptA[]={'
+'
'
-'
*'
/'
='
#'
<
'
>
//双目运算符
constchar*OptB[]={"
="
//界符
constcharEnd[]={'
('
'
)'
'
;
.'
['
]'
{'
}'
voiderror(charstr[20],intnLine,interrorType)
{
errorFlag=1;
cout<
\nError:
"
switch(errorType)
{
case1:
cout<
"
第"
nLine-1<
行"
str<
变量的长度超过限制!
\n"
break;
case2:
小数点错误!
break;
case3:
常量的长度超过限制!
break;
}//switch
}//error
voidScanner(charch[],intchLen,intnLine)
intchIndex=0;
while(chIndex<
chLen)//对输入的字符扫描
/****************处理空格和tab***************************/
//忽略空格和tab
while(ch[chIndex]=='
'
||ch[chIndex]==9) {chIndex++;
/*************************处理换行符*********************/
//遇到换行符,行数加1
while(ch[chIndex]==10)
{ nLine++;
chIndex++;
}
/***************************标识符**********************/
if(isalpha(ch[chIndex]))//以字母、下划线开头
charstr[256];
intstrLen=0;
//是字母、下划线
while(isalpha(ch[chIndex])||ch[chIndex]=='
_'
) {
str[strLen++]=ch[chIndex];
chIndex++;
while(isdigit(ch[chIndex]))//不是第一位,可以为数字
{
str[strLen++]=ch[chIndex];
chIndex++;
}
}
str[strLen]=0;
//字符串结束符
if(strlen(str)>
20)//标识符超过规定长度,报错处理
error(str,nLine,1);
}
else
{
inti;
for(i=0;
i<
MaxKeyWord;
i++)//与关键字匹配
//是关键字,写入table表中
if(strcmp(str,KeyWord[i])==0)
{
strcpy(table[TableNum].symbol,str);
table[TableNum].type=1;
//关键字
table[TableNum].line=nLine;
table[Tabl