编写语法分析程序.docx
- 文档编号:9335394
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:15
- 大小:62.35KB
编写语法分析程序.docx
《编写语法分析程序.docx》由会员分享,可在线阅读,更多相关《编写语法分析程序.docx(15页珍藏版)》请在冰点文库上搜索。
编写语法分析程序
实验报告
课程名称:
编译原理项目名称:
编写语法分析程序
姓名:
专业:
计算机科学与技术班级:
2011级学号:
2
同组成员
一、实验预习部分:
1、实验环境准备:
软件环境:
visualC++6.0
硬件环境:
计算机一台
2、实验所需知识点准备:
语法分析是编译过程的一个逻辑阶段。
语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语法分析程序可以用YACC,等工具自动生成。
程序的结构通常是由递归规则表示的,我们可以用下面的规则来定义表达式:
(1)任何标识符是表达式;
(2)任何常数是表达式‘
(3)若表达式1和表达式2都是表达式,那么
表达式1+表达式2
表达式1*表达式2
(表达式1)
都是表达式
类似,语句也可以递归地定义,如;
(1)标识符:
=表达式是语句;
(2)while(表达式)do语句和
If(表达式)then语句else语句都是语句。
二、实验过程记录:
1、实验目的:
(1)语法分析和语义分析合在一起实现。
(2)把语法分析器设计成一个独立的过程。
(3)给出PL/0文法规范,要求编写PL/0语言的语法分析程序。
2、实验原理:
通过语法分析来实现对程序的编译。
对PL/0语言作如下功能扩充:
(1)扩充条件语句的功能使其为:
if<条件>then<语
句>[else<语句>]
(2)增加repeat语句,格式为:
repeat<语句>{;<语
句>}until <条件>
3、实验步骤:
已给PL/0语言文法,利用递归子程序法,编制语法分析程序,要求将错误信息输出到语法错误文件中,输出语法树。
PL/0语法如下:
<程序><分程序>.
<分程序>[<常量说明>][<变量说明>][<过程说明>]<语句>
<常量说明>CONST<常量定义>{,<常量定义>};
<常量定义><标识符>=<无符号整数>
<无符号整数><数字>{<数字>}
<变量说明>VAR<标识符>{,<标识符>}
<标识符><字母>{<字母>|<数字>}
<过程说明><过程首部><分程序>{;<过程说明>}
<过程首部>PROCEDURE<标识符>;
<语句><赋值语句>|<条件语句>|<当循环语句>|<过程语句>
|<复合语句>|<读语句><写语句>
<赋值语句><标识符>:
=<表达式>
<复合语句>BEGIN<语句>{;<语句>}END
<条件语句><表达式><关系表达式><表达式>|ODD<表达式>
<表达式>[+|-]<项>{<加碱运算符><项>}
还有10条规则构成了PL/0语言,为此文法写一个语法分析器。
CONSTA=10;
VARB,C;
PROCEDUREQ;
VARX;
BEGIN
READ(X);
B:
=X;
WHILEX#0
X:
=X-1;
END;
BEGIN
WRITE(A);
CALLQ;
END.
(1)PL/0编译程序结构
语法图
1:
扩充条件的语法图为:
2:
扩充repeat语句的语法图为:
递归子程序法:
对于每个非终结符,编写一个子程序,由该子程序负责识别该语法单位是否正确。
表达式的文法
〈表达式〉∷=[+|-]〈项〉{(+|-)〈项〉}
〈项〉∷=〈因子〉{(*|/)〈因子〉}
〈因子〉∷=〈标识符〉|〈无符号整数〉|‘(’〈表达式〉‘)’
〈表达式〉的递归子程序实现
procedureexpr;
begin
ifsymin[plus,minus]then
begin
getsym;term;
end
elseterm;
whilesymin[plus,minus]do
begin
getsym;term;
end
end;
〈项〉∷=〈因子〉{(*|/)〈因子〉}
〈项〉的递归子程序实现
procedureterm;
begin
factor;
whilesymin[times,slash]do
begin
getsym;factor;
end
end;
〈因子〉∷=〈标识符〉|〈无符号整数〉|‘(’〈表达式〉‘)’
〈因子〉的递归子程序实现
procedurefactor;
begin
ifsym<>identthen
ifsym<>numberthen
ifsym=‘(‘then
begin
getsym;
expr;
ifsym=‘)’thengetsym
elseerror
end
elseerror
elsegetsym
elsegetsym
end;
程序核心代码和注释:
publicvoidanalyzer()
{
//读入文件,进行语法分析
stringstrReadFile;
strReadFile="input.txt";
myTextRead.myStreamReader=newStreamReader(strReadFile);
stringstrBufferText;
intwid=0;
Console.WriteLine("分析读入程序(记号ID):
\n");
do
{
strBufferText=myTextRead.myStreamReader.ReadLine();
if(strBufferText==null)
break;
foreach(StringsubStringinstrBufferText.Split())
{
if(subString!
="")
{
intll;
if(subString!
=null)
{
ll=subString.Length;//每一个长度
}
else
{
break;
}
inta=ll+1;
char[]b=newchar[a];
StringReadersr=newStringReader(subString);
sr.Read(b,0,ll);//把substring读到char[]数组里
intsort=(int)b[0];
//word[i]和wordNum[i]对应
//先识别出一整个串,再根据开头识别是数字还是字母
Word[wid]=subString;
if(subString.Equals("void"))
{wordNum[wid]=0;}
else
{
if(subString.Equals("main"))
{wordNum[wid]=1;}
else
{
if(subString.Equals("()"))
{wordNum[wid]=2;}
else
{
if(subString.Equals("{"))
{wordNum[wid]=3;}
else
{
if(subString.Equals("int"))
{wordNum[wid]=4;}
else
{
if(subString.Equals("="))
{wordNum[wid]=6;}
else
{
if(subString.Equals("}"))
{wordNum[wid]=22;}
else
{
if(subString.Equals(";"))
{wordNum[wid]=23;}
else//识别变量和数字
{
if(sort>47&sort<58)
{wordNum[wid]=7;}
else
{wordNum[wid]=5;}
}
}
}
}
}
}
}
}
Console.Write(subString+"("+wordNum[wid]+")"+"");
wid++;
}
}
Console.WriteLine("\n");
}while(strBufferText!
=null);
wordNum[wid]=24;
myTextRead.myStreamReader.Close();
//*********************************
//读入LR分析表
//
//***********************************
/*此处代码略*/
int[]state=newint[100];
string[]symbol=newstring[100];
state[0]=0;
symbol[0]="#";
intp1=0;
intp2=0;
Console.WriteLine("\n按文法规则归约顺序如下:
\n");
//***************
//归约算法如下所显示
//***************
while(true)
{
intj,k;
j=state[p2];
k=wordNum[p1];
t=LR[j,k];//当出现t为0的时候
if(t==0)
{
//错误类型
stringerror;
if(k==0)
error="void";
else
if(k==1)
error="main";
else
if(k==2)
error="()";
else
if(k==3)
error="{";
else
if(k==4)
error="int";
else
if(k==6)
error="=";
else
if(k==22)
error="}";
else
if(k==23)
error=";";
else
error="其他错误符号";
Console.WriteLine("\n检测结果:
");
Console.WriteLine("代码中存在语法错误");
Console.WriteLine("错误状况:
错误状态编号为"+j+"读头下符号为"+error);
break;
}
else
{
if(t==-100)//-100为达到接受状态
{
Console.WriteLine("\n");
Console.WriteLine("\n检测结果:
");
Console.WriteLine("代码通过语法检测");
break;
}
if(t<0&&t!
=-100)//归约
{
stringm=grammar[-t];
Console.Write(m+"");//输出开始符
intlength=lengh[-t];
p2=p2-(length-1);
SearchmySearch=newSearch();
intright=mySearch.search(m);
if(right==0)
{
Console.WriteLine("\n");
Console.WriteLine("代码中有语法错误");
break;
}
inta=state[p2-1];
intLRresult=LR[a,right];
state[p2]=LRresult;
symbol[p2]=m;
}
if(t>0)
{
p2=p2+1;
state[p2]=t;
symbol[p2]=Convert.ToString(wordNum[p1]);
p1=p1+1;
}
}
}
myTextRead.myStreamReader.Close();
Console.Read();
}
实验结果:
3、实验结果与讨论:
1、任务分配
成员
任务分配
运行和调试源程序,编写实验报告
代码的编写,编写实验报告
修改词法的语言,编写实验报告
修改中间代码、语法的语言
2、实验小结:
通过对语法分析的操作实验,从中学习到了许多的PL/0编译程序的的方法。
它采用的是自顶向下的递归子程序法来编译的就是说对应每个非终结符语法单元,编一个独立的处理过程。
在运行程序的过程中也有遇到了一些问题,如在编译环境时,由于头文件和源文件没有分开,导致程序出现了错误;分开后运行程序也有问题,原来是因为要设置适应头文件的;其中也有一些小的问题就是在代码中出现的新的变量没有定义。
经过同学们的讨论和老师的指导,一一解决了这些问题。
3、实验心得体会:
对本次的实验学习了语法分析,再经过实验,我对语法分析有了更深刻的认识和了解。
递归下降分析法,是一种确定的自顶向下分析技术,实现思想是对文法中分别代表一种语法成分的每个非终结符号编写一个子程序,完成非终结符号所对应的语法成分的分析任务。
分析过程中调用一系列过程或函数,对源程序进行语法词法分析直到整个程序处理结束。
让我们学会了很多的知识,在以后的运用中会有很大的帮助。
实验报告成绩(百分制)__________实验指导教师签字:
__________
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编写 语法分析 程序