语法分析器实验报告

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

语法分析器的设计实验报告

一、实验内容

语法分析程序用LL(1)语法分析方法。首先输入定义好的文法书写文件(所用的文 法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空, 再分 别计算非终结符号的FIRST 集合,每个非终结符号的FOLLOW 集合,以及每个 规则的SELECT 集合,并判断任意一个非终结符号的任意两个规则的 SELECT 集的交集是不是都为空,如果是,则输入文法符合 LL(1)文法,可以进行分析。 对于文法: G[E]: E->E+T|T T->T*F|F F->i|(E)

分析句子i+i*i 是否符合文法。

二、基本思想

1、语法分析器实现

语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词 法分析输出的源程序符号串中识别出各类语法成分, 同时进行词法检查,为语义 分析和代码生成作准备。这里采用自顶向下的 LL(1)分析方法。 语法分析程序的流程图如图5-4所示。

该程序可分为如下几步:

读入文法 判断正误

若无误,判断是否为LL(1)文法 若是,构造分析表; 由句型判别算法判断输

入符号串是为该文法的句型。

三、核心思想

该分析程序有15部分组成:

(1) 首先定义各种需要用到的常量和变量; (2) 判断一个字符是否在指定字符串中;

(1) (2) (3) (4)

(5)

(3) (4) (5)

(6)

(7)

(8)

(9)

(10) (11) (12) (13) (14)

(15) 下面是其中几部分程序段的算法思想: 1、求能推出空的非终结符集

I 、实例中求直接推出空的 empty 集的算法描述如下: void emp (char c ){ 参数 c 为空符号 char

temp[10]; 定义临时数组 int i;

for (i=0;i<=count-1;i++) 从文法的第一个产生式开始查找 {

if 产生式右部第一个符号是空符号并且右部长度为 then 将该条产生式左部符号保存在临时

数组 将临时数组中的元素合并到记录可推出

}

n 、求某一符号能否推出&

int _emp (char c ) {

//若能推出 &,返回 1 ;否则,返回 0

int i,j,k,result=1,mark=0; char temp[20]; temp[0]=c; temp[1]='\0';

存放到一个临时数组 empt 里,标识此字符已查找其是否可推出空字 如果 c 在可直接推出空字的

empty[] 中,返回 1 for (i=0;;i++)

{

if (i==count )

return (0);

找一个左部为 c 的产生式 j=strlen (right[i]);

if 右部长度为 if 右部长度为 else

{

读入一个文法; 将单个符号或符号串并入另一符号串; 求所有能直接推出 & 的符号;

求某一符号能否推出‘ & '; 判断读入的文法是否正确; 求单个符号的 FIRST ; 求各产生式右部的 FIRST ; 求各产生式左部的 FOLLOW ; 判断读入文法是否为一个 LL (1) 文法; 构造分析表 M ; 句型判别算法; 一个用户调用函数; 主函数;

1, temp 中 & 符号的数组 empty 中。

//j 为 c 所在产生式右部的长度

1且右部第一个字符在 empty[]中.then 返回1(A->B,B 可推出空) 1 但第一个字符为终结符 ,then 返回 0(A->a,a 为终结符 )

for(k=0;k<=j-1;k++)

{

查找临时数组 empt[]. 并标记 mark-=1(A->AB)

if 找到的字符与当前字符相同 (A->AB) 结束本次循环 else(mark 等于 0)

查找右部符号是否可推出空字 ,把返回值赋给 result 把当前符号加入到临时数组

empt[] 里.

当前字符不能推出空字且还没搜索完全部的产生式 then 跳出本次循环继续搜索下一条产生式 else if // 当前字符可推出空字 ,返回

}

2、计算每个符号的 first 集: 实例中求单个符号的 FIRST 集的算法描述如下: void first2

(int i) { 参数 i 为符号在所有输入符号中的序号 c 等于指示器 i 所指向的符号 在保存终结符元

素的 termin[] 数组查找 c

if c 为终结符(c € V T ), then FIRST(c)={c} 在保存终结符元素的 non_ter[] 数组查

找 c if c 是非终结符(c € V N )

在所有产生式中查找 c 所在的产生式 if 产生式右部第一个字符为终结符或空 把 a 或 & 加进 FIRST(c) if 产生式右部第一个字符为非终结符

if 产生式右部的第一个符号等于当

前字符 then 跳到下一条产生式进行查找 求当

前非终结符在所有字符集中的位置 if 当前非终结符还没求其 FIRST 集 then 查找它的

FIRST 集并标识此符号已求其 FIRST 集 求得结果并入到 c 的 FIRST 集 .

if 当前产生式右部符号可推出空字且当前字符不是右部的最后一个字符 获取右部符号下一个字符在所有字符集中的位置 if 此字符的 FIRST 集还未查找 then 找其

FIRST 集 ,并标其查找状态为 1 把求得的 FIRST 集并入到 c 的 FIRST 集 . if 当前右部符号串可推出空且是右部符号串的最后一个字符

(即产生式为 c7

丫1丫2…Y k ,若对一切 1<=i<=k ,均有 & € FIRST(Y i ),则将 & €符号加进 FIRST(c)) then

把空字加入到当前字符 c 的FIRST 集.

else

不能推出空字则结束循环

标识当前字符c 已查找其FIRST 集.}

3. 计算 FOLLOW

FOLLOW 集的构造可用如下方法来求:

对于文法中的符号 X V N ,其FOLLOW(A)集合可反复应用下列规则计算,直到

FOLLOW(A)集合不再增大为止。

(1) 对于文法开始符号 S ,因为S S ,故# FOLLOW(S); (2) 若 A7 B ,其中 B V N ,

(V T V N )*、 (V T V N )+

,贝U

FIRST( )-{ } FOLLOW(B); (3) 若 A 7 B 或 A 7 B (禺),贝y

FOLLOW(A) FOLLOW(B)。 FOLLOW 集的算法描述如下: void FOLLOW(i nt i)

}

if

(即 C7 a (a € V T )或 &) then

then

then

相关文档
最新文档