语法分析器含完整源码.docx
《语法分析器含完整源码.docx》由会员分享,可在线阅读,更多相关《语法分析器含完整源码.docx(32页珍藏版)》请在冰豆网上搜索。
语法分析器含完整源码
语法分析实验报告
一、实验目的:
1.了解单词(内部编码)符号串中的短语句型结构形成规律。
2.理解和掌握语法分析过程中语法分析思想(LL,LR)的智能算法化方法。
二、实验内容:
构造自己设计的小语言的语法分析器:
1.小语言的语法描述(语法规则)的设计即文法的设计;
2.把文法形式符号中所隐含的信息内容挖掘出来并用LL或LR的资料形式(分析表)表示出来;
3.语法分析的数据输入形式和输出形式的确定;
4.语法分析程序各个模块的设计与调试。
主要设备和材料:
电脑、winxp操作系统、VC语言系统
三、实验分工:
学号
姓名
实验分工
08
实验代码设计及编写
08150
检查校对代码
0815
写电子版实验报告
08150
查找、分析、整理资料
08150
查找、分析、整理资料
08050
0815
081
四、实验步骤:
1、语法规则
<程序>:
:
={<变量定义语句>|<赋值语句>|<条件语句>|<循环语句>}
<变量定义语句>:
:
=var变量{,变量};
<赋值语句>:
:
=变量:
=<表达式>;
<表达式>:
:
=标识符{运算符标识符};
<标识符>:
:
=变量|常量
<运算符>:
:
=+|-|*|/|>=|<=
<条件语句>:
:
=[]
:
:
=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
#include
#include
#include
#include
#include
usingnamespacestd;
#defineMax655//最大代码长度
#defineWordMaxNum256//变量最大个数
#defineDigitNum256//常量最大个数
#defineMaxKeyWord32//关键字数量
#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<<"第"<\n";
break;
case2:
cout<<"第"<\n";
break;
case3:
cout<<"第"<\n";
break;
}//switch
}//error
voidScanner(charch[],intchLen,intnLine)
{
intchIndex=0;
while(chIndex{
/****************处理空格和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//是关键字,写入table表中
if(strcmp(str,KeyWord[i])==0)
{
strcpy(table[TableNum].symbol,str);
table[TableNum].type=1;//关键字
table[TableNum].line=nLine;
table[TableNum].Index=i;
TableNum++;
break;
}
if(i>=MaxKeyWord)//不是关键字
{
table[TableNum].Index=WordNum;
strcpy(Word[WordNum++],str);
table[TableNum].type=2;//变量标识符
strcpy(table[TableNum].symbol,str);
table[TableNum].line=nLine;
TableNum++;
}
}
}
/**************************常数**************************/
elseif(isdigit(ch[chIndex]))//遇到数字
{
intflag=0;
charstr[256];
intstrLen=0;
//数字和小数点
while(isdigit(ch[chIndex])||ch[chIndex]=='.'){
//flag表记小数点的个数,0时为整数,1时为小数,2时出错
if(ch[chIndex]=='.')
flag++;
str[strLen++]=ch[chIndex];
chIndex++;
}
str[strLen]=0;
if(strlen(str)>20)//常量标识符超过规定长度20,报错处理
{
error(str,nLine,3);
}
if(flag==0)
{
table[TableNum].type=3;//整数
}
if(flag==1)
{
table[TableNum].type=4;//小数
}
if(flag>1)
{
error(str,nLine,2);
}
table[TableNum].Index=DigNum;
strcpy(Digit[DigNum++],str);
strcpy(table[TableNum].symbol,str);
table[TableNum].line=nLine;
TableNum++;
}
/*************************运算符************************/
else
{
//用来区分是不是无法识别的标识符,0为运算符,1为界符
interrorFlag;
charstr[3];
str[0]=ch[chIndex];
str[1]=ch[chIndex+1];
str[2]='\0';
inti;
for(i=0;iif(strcmp(str,OptB[i])==0)
{
errorFlag=0;
table[TableNum].type=6;
strcpy(table[TableNum].symbol,str);
table[TableNum].line=nLine;
table[TableNum].Index=i;
TableNum++;
chIndex=chIndex+2;
break;
}
if(i>=MaxOptBNum)
{
for(intk=0;kif(OptA[k]==ch[chIndex])
{
errorFlag=0;
table[TableNum].type=5;
table[TableNum].symbol[0]=ch[chIndex];
table[TableNum].symbol[1]=0;
table[TableNum].line=nLine;
table[TableNum].Index=k;
TableNum++;
chIndex++;
break;
}
/*************************界符************************/
for(intj=0;jif(End[j]==ch[chIndex])
{
errorFlag=1;
table[TableNum].line=nLine;
table[TableNum].symbol[0]=ch[chIndex];
table[TableNum].symbol[1]=0;
table[TableNum].Index=j;
table[TableNum].type=7;
TableNum++;
chIndex++;
}
/********************其他无法识别字符*****************/
//开头的不是字母、数字、运算符、界符
if(errorFlag!
=0&&errorFlag!
=1){
charstr[256];
intstrLen=-1;
str[strLen++]=ch[chIndex];
chIndex++;
while(*ch!
=''||*ch!
=9||ch[chIndex]!
=10)
{
str[strLen++]=ch[chIndex];
chIndex++;
}
str[strLen]=0;
table[TableNum].type=8;
strcpy(table[TableNum].symbol,str);
table[TableNum].line=nLine;
table[TableNum].Index=-2;
TableNum++;
}
}
}
}
}
/**************把十进制小数转为16进制******************/
voidTrans(doublex,intp)//把十进制小数转为16进制
{
inti=0;//控制保留的有效位数
while(i
{
if(x==0)//如果小数部分是0
break;//则退出循环
else
{
intk=int(x*16);//取整数部分
x=x*16-int(k);//得到小数部分
if(k<=9)
cout<else
cout<};
i++;
};
};
/***********************语法错误*************************/
voidGerror(interrorType,intnIndex)
{
errorFlag=1;
switch(errorType)
{
case1:
cout<<"第"<
"<
=\n";
break;
case2:
cout<<"第"<
"<
break;
case3:
cout<<"第"<
"<
break;
case4:
cout<<"第"<
"<
break;
case5:
cout<<"第"<
"<
break;
case6:
cout<<"第"<
"<
break;
case7:
cout<<"第"<
<
<
<<"之间缺少运算符\n";
break;
case8:
cout<<"第"<
"<
break;
case9:
cout<<"第"<
<
break;
case10:
cout<<"第"<
<<"行:
缺少'then'"<break;
case11:
cout<<"第"<
"
<
break;
case12:
cout<<"第"<
end后不能接"<
break;
case13:
cout<<"第"<
"
<
<
break;
case14:
cout<<"第"<
<
break;
case15:
cout<<"第"<
"
<
break;
case16:
cout<<"第"<
<<"行,begin后不能接"
<
break;
}
}
/************************表达式判断********************/
boolexpress
展开阅读全文
相关搜索