c语言实现ll 1 语法分析,课内资源 - 基于C++实现的语法分析之LL(1)分析法实现

一、设计目的

根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

二、设计要求

程序输入/输出示例:

对下列文法,用LL(1)分析法对任意输入的符号串进行分析:

原文法

E->E+T|E-T|T

T->T*F|T/F|F

F->id|(E)|num

其中:id:a-f,A-F,num:0-9

消左递归

E->TA A->+TA A->-TA A->e

T->FB B->*FB B->/FB B->e

F->i F->(E)F->n

其中:i:id,n:num,e:epsilonE->TG

FIRST集和FOLLOW集

TA

+TA

-TA

e

FB

*FB

/FB

e

i

(E)

n

FIRST

i,(,n

+

-

e

i,(,n

*

/

e

i

(

n

E

A

T

B

F

FOLLOW

$,)

$,)

+,-,$,)

+,-,$,)

*,/,+,-,$,)

输出的格式如下

输入一以#结束的符号串(包括+—*/()i#):

输出过程如下:

输入

输出

$E

(a-1)*(3+4/2)+((8*2))$

E->TA

输入符号串为非法符号串(或者为合法符号串)

注意

表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#

如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)

测试用的表达式可以事先放在文本文件中,一行存放一个表达式,同时以分号分割。同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照

三、设计说明

3.1 需求分析

3.1.1 输入及其范围

输入为文法,表达式中允许使用运算符(+-*/)、分割符(括号)、字符a。

3.1.2 输出形式栈

输入

输出

$E

(a-1)*(3+4/2)+((8*2))$

E->TA

3.1.3 程序功能

根据输入的文法进行分析,利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程。

3.1.4 测试数据输入:文件“fin.txt”输入待分析串

输出:命令行界面输出预测分析表,LL(1)分析过程输出至“fout.txt”

3.2 概要设计

3.2.1 数据类型的定义// 预测分析表

vector>table(5,vector(9));

// 消除左递归后的文法产生式

vectorG;

// 文法符号到下标的转换字典

mapindex;

// 终结符

stringterminal("in+-*/()$");

// 非终结符

stringnonTerminal("EATBF");

// 产生式右部符号串的first集

vectorFirst;

// 非终结符的follow集

vectorFollow;

3.2.2 主程序流程

ea261e3fd36e0c3160c840c2481689da.png

3.3 详细设计intmain()

{

for(文法G每个产生式itG,itFirst为其右部符号串的first集)

{

x=itG左部非终结符号的下标;

for(itFirst中的每个终结符号first)

{

y=终结符号first的下标;

把itG加入分析表表G[x][y];

}

if(终结符号first==epsilon)

for(Follow集中的每个符号follow)

{

y=follow的下标;

把itG加入分析表G[x][y];

}

}

for(所有非终结符号的Follow集)

if(对应表项为空)

写入synch;

将分析表输出到命令行界面;

returnanalysis();

}

intanalysis(void)

{

从文件fin.txt读取待分析串到s;

s末尾加‘$’;

分析栈vectoranalyStack;

向栈压入‘$’、‘E’;

ip指向s的第一个字符;

do

{

top是栈顶符号;

cur是ip所指向的输入符号;

if(cur是字母)cur=‘i’;

if(cur是数字)cur=‘n’;

if(top是终结符号或‘$’)

{

if(top==cur)

{

从栈顶弹出cur;

ip前移一个位置;

}

else

error;

}

else

{

x=top对应下标;

y=cur对应下标;

产生式production=table[x][y];

if(production非空)

{

栈顶弹出cur;

把production右部逆序压栈;

输出production;

}

else

error;

}while(top!=‘$’);

}

四、运行结果及分析

4.1 测试数据

fin.txt文件入字符串:(a-1)*(3+4/2)+((8*2))

4.2 测试输出的结果

566408621af93b995909a7cd5478254d.png

4.3 输出文件

acea059b8478cc43127700c70368694b.png

c0c2cd5af6a53ab46817ba6381261570.png

8f3b8afb95cd31e4702b35acfed9b529.png

4.4 设计和思考

主要的难点在于对LL(1)的理解部分,消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法,然后开始整理思路进行编码阶段。开始要对错误的文法进行分析,并提示详细的错误信息。思考之后实现了表达式中允许使用运算符(+-*/)、分割符(括号)、字符a。

五、总结

本次课程设计是本周实验来难点最大的一次作业,首先需要温习LL(1)的知识,如何消除左递归,区别二义性文法,以及对文法的分析。在实验的过程中,最重要的还是要理顺思路,想好解决办法,这也是我经过不断实验总结出的自我思考的方法。然后就进入了编码阶段,此次编码也有一定的难度,在代码量以及代码的整体设计上都有了提升,也是最值得思考的地方。最后,通过实验报告的书写,以及参考资料的查找,对今后的学习和工作都有很大的帮助。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值