河北工业大学语法分析实验报告.docx
- 文档编号:24890764
- 上传时间:2023-06-02
- 格式:DOCX
- 页数:13
- 大小:136.23KB
河北工业大学语法分析实验报告.docx
《河北工业大学语法分析实验报告.docx》由会员分享,可在线阅读,更多相关《河北工业大学语法分析实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
河北工业大学语法分析实验报告
实验二语法分析程序实现
一、实验设计
选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<算术表达式>],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。
G2[<算术表达式>]:
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<运算对象>|(<算术表达式>)
若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F和i代表,则G2可写成:
G2[E]:
E→T|E+T|E-TT→F|T*F|T/FF→i|(E)
输入:
由实验一输出的单词串,例如:
UCON,PL,UCON,MU,ID······
输出:
若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。
此程序决定采用SLR
(1)方法作为编制语法分析程序的依据,对实验一所得扫描器提供的单词序列进行语法检查和结构分析,进一步实现语法分析,为了在对源程序的一遍扫描过程中,同时完成词法和语法分析任务,修改实验一中的词法分析程序,将它编写为头文件的形式,供语法分析程序调用。
另外,应加强错误检查,对输入符号串中的词法、语法错误,给出必要的说明信息,尽可能多地、确切地指出错误的位置、原因和性质。
首先,对于分析对象,即算术表达式的文法G2[E],引入一个新的开始符号E’,得到G2[E]的拓广文法G2’[E’]:
0.E’→E1.E→E+T2.E→E-T3.E→T4.T→T*F5.T→T/F6.T→F7.F→(E)8.F→i
求出文法中各个非终结符号的FOLLOW集如下:
Follow(E)={#,),+,-}Follow(T)={#,),+,-,*,/}Follow(F)={#,),+,-,*,/}
然后,根据文法G2’[E’]构造识别其全部活前缀的DFA,以便据此构造SLR
(1)分析表,参见表III。
表IIIG2’[E’]的SLR
(1)分析表
状态
ACTION
GOTO
(
)
+
-
*
/
i
#
E
T
F
0
S4
S5
1
2
3
1
S6
S7
Acc
2
R3
R3
R3
S8
S9
R3
3
R6
R6
R6
R6
R6
R6
4
S4
S5
10
2
3
5
R8
R8
R8
R8
R8
R8
6
S4
S5
11
3
7
S4
S5
12
3
8
S4
S5
13
9
S4
S5
14
10
S15
S6
S7
11
R1
R1
R1
S8
S9
R1
12
R2
R2
R2
S8
S9
R2
13
R4
R4
R4
R4
R4
R4
14
R5
R5
R5
R5
R5
R5
15
R7
R7
R7
R7
R7
R7
最后,编程实现SLR
(1)分析表的驱动程序,即开发LR分析器的总控程序,完成对算术表达式的识别。
二、程序代码
将词法分析程序作为头文件”cifa.h”,在VC++6.0中运行
#include
#include
#include
#include
#include
#include"cifa.h"
#defineLB0//左括号
#defineRB1//右括号
#definePL2
#defineMI3
#defineMU4
#defineDI5
#defineUCON6
#defineOVER7
#defineLT8
#defineLE9
#defineEQ10
#defineNE11
#defineGT12
#defineGE13
#defineIS19//14至18被五个关键字占用
#defineID20
intPush(intState);
intPop(intcount);
intSLRControl(FILE*fp);
///////语法分析部分
#defineMax256
//goto表的列项
#defineE0
#defineT1
#defineF2
intStateStack[Max];//状态栈
intStackPoint;//状态栈指针
intTopState;//作为状态栈栈顶指针
charAction[16][8][4]={"s4","","","","","","s5","",
"","","s6","s7","","","","A",
"","r3","r3","r3","s8","s9","","r3",
"","r6","r6","r6","r6","r6","","r6",
"s4","","","","","","s5","",
"","r8","r8","r8","r8","r8","","r8",
"s4","","","","","","s5","",
"s4","","","","","","s5","",
"s4","","","","","","s5","",
"s4","","","","","","s5","",
"","s15","s6","s7","","","","",
"","r1","r1","r1","s8","s9","","r1",
"","r2","r2","r2","s8","s9","","r2",
"","r4","r4","r4","r4","r4","","r4",
"","r5","r5","r5","r5","r5","","r5",
"","r7","r7","r7","r7","r7","","r7",};//action表
intGoto[16][3]={{1,2,3},
{-1,-1,-1},
{-1,-1,-1},
{-1,-1,-1},
{10,2,3},
{-1,-1,-1},
{-1,11,3},
{-1,12,3},
{-1,-1,13},
{-1,-1,14},
{-1,-1,-1},
{-1,-1,-1},
{-1,-1,-1},
{-1,-1,-1},
{-1,-1,-1},
{-1,-1,-1}};//goto表
/////////////////////////////////////语法分析程序
intSLRControl(FILE*fp)
{
while(Action[TopState][InputWordType][0]!
='A')
{
//printf("栈顶状态:
%i\n",TopState);
printf("扫描的单词类型:
%i\n",InputWordType);
if(-1==TopState)
{
printf("状态栈栈顶指针错误!
\n");
return0;
}
if(''==Action[TopState][InputWordType][0])
{
printf("语法分析出错!
\n");
return0;
}
elseif('s'==Action[TopState][InputWordType][0])
{
Push(atoi(&Action[TopState][InputWordType][1]));
printf("执行压栈操作\n");
if(EOF!
=fgetc(fp))
{
scanner(fp);
}
else
{
return0;
}
}
elseif('r'==Action[TopState][InputWordType][0])
{
intProductionNum=atoi(&Action[TopState][InputWordType][1]);
intProdutionLeft=0;
if(1==ProductionNum)
{
ProdutionLeft=E;//为下面差goto表提供列坐标
Pop(3);
printf("用产生式1归约\n");
}
elseif(2==ProductionNum)
{
ProdutionLeft=E;
Pop(3);
printf("用产生式2归约\n");
}
elseif(3==ProductionNum)
{
ProdutionLeft=E;
Pop
(1);
printf("用产生式3归约\n");
}
elseif(4==ProductionNum)
{
ProdutionLeft=T;
Pop(3);
printf("用产生式4归约\n");
}
elseif(5==ProductionNum)
{
ProdutionLeft=T;
Pop(3);
printf("用产生式5归约\n");
}
elseif(6==ProductionNum)
{
ProdutionLeft=T;
Pop
(1);
printf("用产生式6归约\n");
}
elseif(7==ProductionNum)
{
ProdutionLeft=F;
Pop(3);
printf("用产生式7归约\n");
}
elseif(8==ProductionNum)
{
ProdutionLeft=F;
Pop
(1);
printf("用产生式8归约\n");
}
else
{
printf("产生式编号超出范围!
\n");
return0;
}
Push(Goto[TopState][ProdutionLeft]);
}
}
printf("栈顶状态:
%i\n",TopState);
printf("扫描的单词类型:
%i\n",InputWordType);
printf("语句正确!
\n");
return1;
}
/////////////////////////////////状态栈的压栈和出栈程序
intPush(intState)
{
if(Max==StackPoint)
{
printf("状态栈已满!
");
return0;
}
StateStack[StackPoint]=State;
StackPoint++;
TopState=State;//用topstate存储当前栈顶状态
return1;
}
intPop(intcount)//内部要把处理完的数组的顶部的值赋给topstate
{
StackPoint=StackPoint-count;
if(StackPoint<0)
{
printf("状态栈指针不能为负值!
");
return0;
}
TopState=StateStack[StackPoint-1];
return1;
}
/////////////////////////////////主程序
intmain(intargc,char*argv[])
{
FILE*p=fopen("file.txt","r");
if(ch=fgetc(p)==EOF)//不管小括号内的判断是否成功,p指针都会向后移一个位置,判断不成功,ch中存的字符不变
{
printf("Thefileisnull.\n");
return0;
}
TopState=0;
StackPoint=0;
memset(StateStack,-1,sizeof(StateStack));
scanner(p);
SLRControl(p);
fclose(p);
return0;
}
三、实验结果分析
语法分析错误,不是完整的句子
语法分析正确
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 河北 工业大学 语法分析 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)