编译原理语法分析程序设计.docx
《编译原理语法分析程序设计.docx》由会员分享,可在线阅读,更多相关《编译原理语法分析程序设计.docx(18页珍藏版)》请在冰豆网上搜索。
![编译原理语法分析程序设计.docx](https://file1.bdocx.com/fileroot1/2023-1/30/68849647-fed0-4f46-b1b4-74c0a5bb7828/68849647-fed0-4f46-b1b4-74c0a5bb78281.gif)
编译原理语法分析程序设计
一、实验内容和目的
1.已知待分析的C语言子集的语法,用EBNF表示如下:
(1)<程序>fmain()<语句块>
(2)<语句块>f“”<语句串>“”
(3)<语句串>f<语句>{;<语句>};
(4)<语句>f<赋值语句>|<条件语句>|<循环语句>
(5)<赋值语句>fID=<表达式>
(6)<条件语句>fif(条件)<语句块>
(7)<循环语句>fwhile(<条件>)<语句块>
(8)<条件>f<表达式><关系运算符><表达式>
(9)<表达式>f<项>{+<项>}|<项>{-<项>}
(10)<项>f<因子>{*<因子>}|<因子>{/<因子>}
(11)<因子>fID|NUM|(<表达式>)
(12)<关系运算符>f<|<=|>|>=|==|!
=
2.实验目的、要求实现的功能
实验目的:
编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。
实验要求:
在上机
(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。
要求编译后能检查出语法错误。
3.将实验方法改写为适合预测分析法的文法如下:
(1)<程序>fmain()<语句块>
(2)<语句块>f{<语句串>}
(3)<语句串>f<语句>;<语句串>
(3_1)<语句串>f£
(4)<语句>f<赋值语句>
(5)<语句>f<条件语句>
(6)<语句>f<循环语句>
(7)<赋值语句>fID=<表达式>
(8)<条件语句>fif(<条件>)<语句块>
(9)<循环语句>fwhile(<条件>)<语句块>
(10)<条件>f<表达式><关系运算符><表达式>
(11)<表达式>f<项><表达式'>
(11_1)<表达式、>f+<项><表达式'>
(11_2)<表达式'>f-<项><表达式'>
(11_3)<表达式、>f£
(12)<项>f<因子><项'>
(12_1)<项、>f*v因子><项'>
(12_2)<项、>f/<因子><项'>
(12_3)<项、>f£
(13)<因子>fID
(14)<因子>fNUM
(15)<因子>f(v表达式>)
(16)<关系运算符>f<
(17)<关系运算符>f<=
(18)<关系运算符>->
(19)<关系运算符>—>=
(20)<关系运算符>—==
(21)<关系运算符>—!
=
4.求改写后文法的非终结符号的FIRST集和FOLLOW集:
非终结符号
FIRST
FOLLOW
<程序>:
main
#
<语句块>
{
#;
<语句串>
IDifwhile£
}
<语句>
IDifwhile
J
<赋值语句>
ID
J
<条件语句>
if
J
<循环语句>
while
J
<条件>
IDNUM(
)
<表达式>
IDNUM(
<<=>>===!
=);
<表达式>:
+-£
<<=>>===!
=);
<项>
IDNUM(
+-<<=>>===!
=);
<项'>
*/£
+-<<=>>===!
=);
<因子>:
IDNUM(
*/
<关系运算符>
<<=>>===!
=
IDNUM(
5.根据求得的FIRST集和FOLLOW集构造LL
(1)分析表如下:
表格内空白的部分表示“出错”,非空白部分表示要压入分析栈中的文法符号,是按照对
应产生式的逆序存放的,即当查找分析表时,表格内的内容从左至右依次入栈
第3步中改写文法的LL
(1)分析表
main
if
while
ID
NUM
(
)
{
}
+
-
*
/
<
<=
>
>=
==
!
=
=
;
#
<程序>
<语句块>
)(main
<语句块>
}
<语句串>
{
<语句串>
<语句串>;<语句>
£
<语句>
<条件语句>
<循环语句>
<赋值语句>
<赋值语
句>
<表达式>
=ID
<条件语
句>
<语句块>)
<条件>(if
<循环语
句>
<语句块>)<条件>(while
<条件>
<表达式><关系运算符><表达式>
<表达式>
<表达式'><项>
<表达式'>
£
<表达式'>
<项>+
<表达式'>
<项>-
£
£
£
£
£
£
£
<项>
<项'><因子>
<项'>
£
£
£
<项'>
<因子>*
<项'>
<因子>/
£
£
£
£
£
£
£
<因子>
ID
NUM
)<表达式>(
<关系运算
符>
<
<=
>
>=
==
!
=
二、所用仪器、材料(设备名称、型号、规格等)
操作系统:
MicrosoftWindows7
开发平台:
MicrosoftVisualStudio2010
三、实验方法、步骤
登录MicrosoftWindows7操作系统
打开VisualStudio2010开发平台
新建“项目”
“Win32控制台应用程序”
输入项目名称
“应用程序设置”
勾选“空项目”复选框
右击左侧“解决方案资源管理器”下的“源文件”
“添加”
“新建项…”
新建一个“C++文件(.cpp)”
在新建的.cpp文件中输入语法分析代码
调试
运行
记录结果
完成实验报告。
四、实验过程原始记录(数据、图表、计算等)
源代码见实验报告所在目录下的yangdongdong_2.cpp以下是部分程序代码的截图:
31nt
^37{
838]
539
315+intlaoJcupTable(intnonTenninaJ-,classNo,FILE^oFiie)
66?
|"语法分析程序样
+|inrgait瞪丄~~
ir^inG
匚二己rrir亡二;Y调用语三分产握言:
・
return0;
五、实验结果
测试一:
输入文本1(inputl.cpp):
1
bofilD()
204
3
a=a41;
4
if(a<3)
sE
3{
G
surt=suit]-Fi;
7
一Is.■
f・
a
3E
Q{
10
3knr-Bun-l;
1L
-、■
亠**
12
3uir=aj'5UJT-a/3'Ujr;
13
■-
调用语法分析程序后的运行情况:
输出output1.txt文件:
tD:
)卜
工具⑴帶陆(H)
共品<制录新建文件夹
燈改日期
,CLltputl.tKt
2010/12/1215:
24
立年文档
吋input2,cpp
2010/12/1215:
21
C++Source
inputl^cpp
2010/12/1215:
08
C*+Source
output1.txt文件中的内容如下:
Ioutputltxt-远事本
文嚨(0鞭旧艳式回壹看巴壽期ttD
nain()</
?
ID=
-
ID
+iFKE:
$$inN1>
-
HUH
;
1F(){EXPRESSI0NXRELA_OPTXEKPRESSIOH>
ID
(>:
1D-
ID
+
NUM
:
while7)
文悴(0濡施1艳式d童看也
|LIHE[8]:
—>
tfhile()—H
4
LINEL8J:
--〉
LIHE[8]:
—>
LIHE[8]:
—y
LINE[町:
—>
ID
L1NE[8]:
<7ERM_1>—>
LINE[8]:
—>
坨MULL〉
LINE[8]:
—>
>=
LIHE[8]:
—>
LINE⑹:
—>
LINE[8]:
—>
NUM
LINE[8]:
—>
LINE[8]:
—>
L1NE[9]:
—>
<y
LINE[10]
:
—
>
LIHE[10]
:
—
>
F
LINE[1B]
:
—
>ID-
LINETIBl
:
—>
LINE[-10]
:
—
>
LINE[1O]
:
—>ID
LIHE[10]
:
—
>
LIHET101
:
—
>-
LIHEflB]
:
—
>
LIHE[18]
z—
>HUH
LIHE[10]
:
—
>
J
cutputltxt-记事本
r
|outputltxt-记事本
文样is礎⑹植式gj童看M務旬砂
语法扫描咸功完咸•…
丿④
注:
语法分析程序本身只要求输出分析结果,此处暂时将每一步推导所用的产生式输出,方便对照检查,LINE[N]表示第N行,以下测试类似,不再说明。
测试二:
输入文本2(input2.cpp):
1[iAin(3)
20{
:
if(a<3)3(
3iirt=3Uir41^
11
while:
3Lanr>=9J(
5Wi=5':
5^iiir-G'
131-}
调用语法分析程序后的运行情况:
输出output2.txt文件
(D:
)卜
丄貝CD
*刻录新童丈件夹
燈改日期
outputs.tirt
2010/12/1216:
35
,OUtpUtl.tKt
2010/12/1216:
24
也input2xpp
2010/12/1215;21
dSource
Output2.txt文件中的内容如下:
]output2.tvt”远事本
IZZ3
文祥(E)漏辑近宿式◎壹看塑帮助(H)
LIHE[1J:
LINE[1]:
LINE[2J:
LINE[3]:
LIHE[3J:
LINE[3]:
LINE[3]:
LIKE[3J:
LINE[3]=
LINE[3|:
LIHE[3]:
LIHE[3]:
LIHE[9J:
LIHE[9|:
LIHE[3];LIHE[3]:
LIHE[41:
LlHE[>il:
LIME[4J;LIME[4]:
LIHE[4J:
LlNE[iiJ:
LINE[2|J:
naln()
<};id=
+—
HUM—
;
jf()
■K
output2.t文禅旧輻辑®宿式g】壹看⑼帮朋砂
LINE[4):
LINE[H]:
LINE[HJ:
LIME[4]:
LIHE[4J:
LlHE[i|]:
LINE[t|J:
LIME[U]:
LINE[4]:
L1HE[4J:
LIME[5J:
LINE[6]:
LINE[6J:
L1HE[6J:
LINE[6J:
LINE[6]:
LINE[6]:
LINE[6]:
LINE[6):
LINE[6]:
LIHE[6):
LIHE[6]=LIHE[6):
LIHE[7]:
—>ID
-一>—>
—><—>KTERMXEaiPRESS10N_1>-一>—>NUM~
—>—>
「印丽肌可能缺少*
—><<5TI1J_STRfRI1>><£TNT_STREnn>—>;—>—>1D=
CEXFRESSIOhl>—>—>—>ID—>—>+一—>NUM
—>--〉—>
K~
□utput2.1rt-远事衣
文件旧輻瑁®梧式◎查春璽帮助(H)
L1HE[7):
LINE]町:
LINE[0]:
LINE[8]:
LIHE[8]:
LINE[SJ:
LINE[8]:
LIHE[6]:
LIHE[Q]=LlHE[ej:
LIHE[8]:
LIbE[O]:
LIHE[8]:
LIHE[8]:
LINE[8J;LINE[8]:
LIHE[9J:
-
(FACTORS
;
-wriile()-
ID_
gCTORXTERM」〉
HUM
SULL〉
<}
LINE[10]:
LINE[16]:
LIME[10]:
LIHE[19]:
L1HE[10]:
LINE[1O]:
一一>;
-—>KfiSSI1_STIfT>-—>I»=—>―〉—>w—
|output2.1rt-记事本
I~I
文件(E)锚Q格式◎查看型}帮勛旧)
LIHE[10]:
L1HE[10]:
LINE[10]:
LINE[10J:
LINE[1O]:
LINE[1O):
LIHE[1O]:
LIHE[11):
LIHE[12]:
LIHE[12):
LINE[12]:
--〉ID
--〉—>-—>—>NUM~
〉
—>
LIHE[12];ERR0R
LIHE[12]
LIHE[12]
LIHE[12]
LINE[12]
LINE[12]
LINE[13]
ERROR*
ERRORERROR
ERRORERRORERROR
ERRORERROR
词[仙]
[21][H][2*][10]
[23][1«]
【25]
—>
唔法扫描成功完成….
六、分析和结论
1.本程序先用预先分析法进行语法分析,基本思路是:
(1)首先初始化分析栈和输入单词指示器(即读取当前输入串中的第一个单词);
(2)然后查看当前分析栈的栈顶符号:
①如果是终结符号,则查看是否与当前输入单词匹配,若匹配则将之出栈,输入指示器指向下一个单词,进行下一轮扫描,若不匹配则报错,②如果是非终结符号,则根据当前输入单词查找分析表,若查到,则将当前栈顶符号出栈,并将查到的产生式逆序入栈,进入下一轮扫描,若没有查到,则报错;(3)最后,若分析栈和输入单词同时为结束符(#)时,表示语法分析成功,程序结束。
2.本程序对语法分析中的错误处理和识别有很多问题,如某些错误可能导致程序进入死循环,因此在语法错误处理方面仍有待改进
3.程序中对文件的操作仍一些不足之处,如:
若关闭输入文件时失败,则会导致输出文件也无法关闭,占用系统资源。
另外,此程序只是对语法分析过程的一个演示,当真正进编译程序的编制时,需要配合专门的语法错误处理程序和中间代码转换程序等进行编译。