语法分析自顶向下的分析

语法分析自顶向下的分析
语法分析自顶向下的分析

语法分析——自顶向下的分析

重点与难点

重点:自顶向下分析的基本思想,预测分析器总体结构,预测分析表的构造,递归下降分析法基本思想,简单算术表达式的递归下降分析器。

难点:FIRST 和FOLLOW 集的求法,对它们的理解以及在构造LL(1)分析表时的使用。递归子程序法中如何体现分析的结果。

基本要求

掌握语法分析、2型文法的概念和自顶向下分析的基本思想,预测分析器总体结构,预测分析表的构造,递归下降分析法基本思想,简单算术表达式的递归下降分析器。

熟练掌握推导、FIRST集和FOLLOW集的求法、消除左递归、提取左因子、LL(1)文法、文法的改写、递归子程序法、预测分析法。

例题解析

例1 求表达式文法的语法符号的FIRST 集和FOLLOW 集

表达式文法:

E→TE'

E'→+TE’|ε

T→FT'

T'→*FT’|ε

F→(E)|id

FIRST(F)={(,id}

FIRST(T)=FIRST(F)={(,id}

FIRST(E)=FIRST(T)={(,id}

FIRST(E')={+,ε}

FIRST(T')={*,ε}

FIRST(+)={+}, FIRST(*)={*}

FIRST( ( )={(}

FIRST( ) )={)}

FIRST(id)={id}

FOLLOW(E) = { #, ) }

FOLLOW(E')= FOLLOW( E ) = { #, ) }

FOLLOW(T) = FIRST(E’)∪FOLLOW(E)∪FOLLOW(E’) = {+,),#} FOLLOW(T')= FOLLOW(T)= {+,},#}

FOLLOW(F) = FIRST(T’)∪FOLLOW(T)∪FOLLOW(T’) ={*,+,},#}

例2消除下述文法的左递归。

S→Ac|c A→Bb|b B→Sa|a

【解】先将间接左递归,变成直接左递归

将B的定义代入A产生式得:A→Sab|ab|b,

将A的定义代入S产生式得: S→Sabc|abc|bc|c

采用引进新的非终结符的方法消除直接左递归:

S→abcS’|bcS’|cS’

S’→abcS’|ε

删除“多余的”产生式:A→Sab|ab|b和B→Sa|a

得到文法G[S]:S→abcS’|bcS’|cS’S’→abcS’|ε

例3已知文法G:

S →( L | a

L →S , L | )

(1)构造文法G的预测分析表。

(2)若输入串为“(a,)”,请给出语法分析过程。

【解】(1)

1)求各非终结符的FISRT 集和FOLLOW 集:

FIRST(S) = { (, a )

FIRST(L) = { a } FIRST(S) = { (, ), a }

FOLLOW(S) = { ’,’, # }

FOLLOW(L) = FOLLOW(S) ={ ’,’, # }

2

(2)对输入串“(a,)”的分析处理过程如表1所示。

表1 对输入串“(a,)”的分析过程

例4给定文法

G=({i,d,'(',')'},{E,A},E,P)

其中P:E→iA

E→EA

A→i

A→d

A→( E)

(1)消除左递归;

(2)计算改写后文法中各非终结符的FIRST 集和FOLLOW 集;

(3)构造改写后文法的预测分析表;该文法是LL(1) 文法吗?。【解】

(1)消除左递归后的文法为:

E →iAE'

E'→ε | AE'

A →i

A →d

A →( E )

(2)各非终结符的FISRT集和FOLLOW集

FIRST( E ) ={i}

FIRST(E') = {i, d, (, ε)

FIRST( A ) ={i, d, ()

FOLLOW( E ) ={), # }

FOLLOW(E') ={}, # }

FOLLOW( A ) ={i, d, (, ), # }

(3)改写后文法的预测分析表:

例5 if语句的原始文法

S→if E then S |if E then S else S |other

存在左因子if E then S,改写此文法消除左因子。.

【解】引进非终结符S’ S'→ε|else S

提取左因子:S→if E then SS’|other

改写后的文法:

S→if E then SS’|other

S'→ε|else S

例6 构造简单算术表达式的分析器

【解】E的子程序(E→T(+T)*)

procedure E;

begin

T; T的过程调用

while lookhead='+' do

begin 当前符号等于+时

match(‘+’); 处理终结符+

T T的过程调用

end

end; lookhead:当前符号

T的子程序(T→F(*F)*)

procedure T;

begin

F; F的过程调用

while lookhead='*' then

begin 当前符号等于*时

match('*'); 处理终结符*

F F的递归调用

end

end;

F的子程序(F→(E)|id)

procedure F;

begin

if lookhead='(' then

begin 当前符号等于(

match('('); 处理终结符(

E; E的递归调用

match(')'); 处理终结符)

end

else if lookhead=id then

match(id) 处理终结符id else error 出错处理

end

主程序

begin

lookhead:=nexttoken; 调词法分析程序

E E的过程调用

end

服务子程序

procedure match(t:token);

begin

if lookhead=t then

lookhead:=nexttoken

else error 出错处理程序end;

编译原理(语法分析程序设计)

一、实验内容和目的 1. 已知待分析的C语言子集的语法,用EBNF表示如下: (1)<程序>→main()<语句块> (2)<语句块>→“{” <语句串>“}” (3)<语句串>→<语句>{;<语句>} ; (4)<语句>→<赋值语句>|<条件语句>|<循环语句> (5)<赋值语句>→ID=<表达式> (6)<条件语句>→if(条件)<语句块> (7)<循环语句>→while(<条件>)<语句块> (8)<条件>→<表达式><关系运算符><表达式> (9)<表达式>→<项>{+<项>}|<项>{-<项>} (10)<项>→<因子>{*<因子>}|<因子>{/<因子>} (11)<因子>→ID|NUM|(<表达式>) (12)<关系运算符>→<|<=|>|>=|==|!= 2. 实验目的、要求实现的功能 实验目的:编制一个语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析。 实验要求:在上机(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。要求编译后能检查出语法错误。 3. 将实验方法改写为适合预测分析法的文法如下: (1) <程序>→main()<语句块> (2)<语句块>→{ <语句串>} (3)<语句串>→<语句>; <语句串> (3_1) <语句串>→ε (4)<语句>→<赋值语句> (5)<语句>→<条件语句> (6) <语句>→<循环语句> (7)<赋值语句>→ID=<表达式> (8)<条件语句>→if(<条件>)<语句块> (9)<循环语句>→while(<条件>)<语句块> (10)<条件>→<表达式><关系运算符><表达式> (11)<表达式>→<项><表达式`> (11_1)<表达式`>→+<项><表达式`> (11_2)<表达式`>→-<项><表达式`> (11_3)<表达式`>→ε (12) <项>→<因子><项`> (12_1) <项`>→*<因子><项`> (12_2)<项`>→/<因子><项`> (12_3)<项`>→ε (13) <因子>→ID (14) <因子>→NUM (15) <因子>→(<表达式>) (16) <关系运算符>→< (17) <关系运算符>→<=

语法分析(自上而下分析)实验报告

实习二语法分析-自上而下分析 一、实验目的 使用预测分析方法对输入的表达式进行分析,掌握其具体的使用并且学会去分析一个文法。 二、实验内容 1.设计表达式的语法分析器算法(使用预测分析) 2.编写一段代码并上机调试查看其运行结果 三、实验要求 使用LL(1)分析算法设计表达式的语法分析器 LL(1)文法是一个自上而下的语法分析方法,它是从文法的开始符号出发,生成句子的最左推导,从左到右扫描源程序,每次向前查看一个字符,确定当前应该选择的产生式。 实现LL(1)分析的另一种有效方法是使用一张分析表和一个栈进行联合控制。 预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前a的输入符号行事的。对于任何(X,a),总控程序每次都执行三种可能的动作之一。 1.若X=a=“#”,则宣布分析成功,停止分析过程 2.若X=a≠“#”,则把X从STACK栈顶逐出,让a指向下一 个输入符号。 3.若X是一个非终结符,则查看分析表。 四、运行结果

(本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析) 五、源程序实现 /*LL(1)分析法源程序,只能在VC++中运行*/ #include #include #include #include char A[20]; char B[20]; char v1[20]={'i','+','*','(',')','#'};/*终结符*/ char v2[20]={'E','G','T','S','F'};/*非终结符*/ int j=0,b=0,top=0,l;/*L为输入串长度*/

自顶向下的语法分析(实验报告一)

武汉轻工大学 编译原理实验报告 姓名朱春桃 院(系)数学与计算机学院 班级软件工程1203 学号 1205110605 指导教师李禹生 2014 年11 月10 日

一、实验目的 完成自顶向下语法分析算法的程序设计。 二、实验内容 设计、调试并测试自顶向下语法分析算法程序。 三、设计思路 根据课堂讲授的自顶向下语法分析方法,可以根据递归下降子程序方法设计语法分析程序,也可以根据LL(1)算法设计语法分析程序,针对文法:G[E] E→E+T | T T→T*F | F F→( E ) | i (1)由于文法G[E]不满足LL(1)文法条件,需要进行必要的等价文法变换。变换后的等价文法为: H[E] E→TA A→+TA | ε T→FB B→*FB | ε F→( E ) | i (2)等价文法H[E]不含左递归,可以证明文法H[E]满足LL(1)文法条件(3)根据递归下降子程序方法设计语法分析程序 ①递归程序清单 ②调试过程说明 ③测试语句设计 ④测试结果列表 ⑤测试结论分析 (4)根据LL(1)算法设计语法分析程序 ①预测分析表 ②预测分析程序清单 ③调试过程说明 ④测试语句设计 ⑤测试结果列表

⑥测试结论分析 四、程序清单 /* E->TA, A->+TA|ε, T->FB, B->*FB|ε, F->i|(E). */ #include void E(char str[80],int &i,int &err or); void A(char str[80],int &i,int &error); void T(char str[80],int &i,int &error); void B(char str[80],int &i,int &error); void F(char str[80],int &i,int &error); void main() { int i=0,j=0,error=0; char str[80]; printf("请输入字符串('#'为结束字符):"); while ((str[j]=getchar())!='#') j++; str[j]='#'; E(str,i,error); if(error) printf("error\n"); else printf("right\n"); } void E(char str[80],int &i,int &error) { printf("E->TA\n"); T(str,i,error); A(str,i,error); } void A(char str[80],int &i,int &error) { if(str[i]=='+') { printf("A->+TA|ε\n"); i++; T(str,i,error); A(str,i,error);

语义分析程序的设计与实现

语义分析程序的设计与实现 班号:2008211316姓名:张荣学号:08211627序号:26 实验日期:2010-11-23 一:实验内容: (2) 二:实验要求: (2) 三:实验方法: (2) ◆由LEX建立YACC的词法分析程序 (2) ◆yacc原理介绍 (3) ◆词法分析 (4) ◆解析器如何工作 (5) ◆Yacc环境 (6) ◆常用代码 (7) 第四:YACC内部名称: (7) 第五:运行结果(源代码见附录) (8) 第六:实验总结 (9) 第七:附录 (10) 附录一:yacc程序,加注释 (10) 附录二:词法分析器的工作原理 (16)

一:实验内容: 编写语法分析程序,实现对算术表达式的语法分析,要求所分析的算术表达式由如下的文法产生。 ◆E->E+T|E-T|T ◆T->T*F|T/F|F ◆F->id|(E)|num 二:实验要求: 在对表达式进行分析的同时,输出所采用的产生式。 可以采用多种方法 ◆编写递归调用程序,实现自顶向下的分析。 ◆编写LL(1)语法分析程序,要求: ◇编程实现算法4.2,为给定的文法自动构造预测分析表 ◇编程实现算法4.1,构造LL(1)预测分析程序, ◆编写语法分析程序,实现自底向上的分析,要求: ◇构造识别所有活前缀的DFA ◇构造LR分析表 ◇编程实现算法4.3,构造LR分析程序 ◆利用yacc自动生成语法分析程序,调用LEX自动生成的词法分析器程序 三:实验方法: ◆由LEX建立YACC的词法分析程序 由LEX产生的词法分析程序可用于YACC,LEX编译程序根据LEX

源程序产生词法分析程序yylex(),这个名字就是YACC所需要的词法分析程序的名字。如果YACC要调用LEX产生的词法分析程序,则在YACC源程序的第三部分用语句#include“lex.yy.c”代替函数yylex()的定义,这一yylex()就可以访问YACC中记号的名字,因为LEX的输出时候YACC输出文件的一部分,所有,每个LEX的动作都返回YACC 知道的终结符。 在UNIX的环境下,如果LEX源程序在first.l中,YACC的源程序在second.y中,可以使用以下命令得到所需要的分析程序。 Lex first.l Yacc second.y cc-o yaccdemo y.tab.c lex.yy.c ◆yacc原理介绍 Yacc 是用可移植的C 语言写成的。接受的规定类别是非常一般性的: 带有去歧义规则的LALR(1) 文法。 Yacc 提供了一个通用工具来在计算机程序的输入上施加结构。Yacc 用户准备输入处理的规定;它包括描述输入结构的规则,在识别了这些规则的时候调用的代码,和做基本输入的一个低层例程。Yacc 接着生成一个函数来控制输入处理。这个函数叫做解析器(parser),它调用用户提供的低层输入例程(词法分析器(analyzer))来从输入流中选取基本项目(叫做记号(token))。依据叫做文法规则的输入结构规则来组织这些记号;在识别了这些规则中的某一个的时候,接着调用为这个规则提供的叫做动作的用户代码;动作有能力返回值并

实验5 LL(1)语法分析程序的设计与实现(C语言)

实验五LL(1)文法识别程序设计 一、实验目的 通过LL(1)文法识别程序的设计理解自顶向下的语法分析思想。 二、实验重难点 FIRST集合、FOLLOW集合、SELECT集合元素的求解,预测分析表的构造。 三、实验内容与要求 实验内容: 1.阅读并理解实验案例中LL(1)文法判别的程序实现; 2.参考实验案例,完成简单的LL(1)文法判别程序设计。 四、实验学时 4课时 五、实验设备与环境 C语言编译环境 六、实验案例 1.实验要求 参考教材93页预测分析方法,94页图5.11 预测分析程序框图,编写表达式文法的识别程序。要求对输入的LL(1)文法字符串,程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 表达式文法为: E→E+T|T T→T*F|F F→i|(E) 2.参考代码

为了更好的理解代码,建议将图5.11做如下标注:

/* 程序名称:LL(1)语法分析程序*/ /* E->E+T|T */ /* T->T*F|F */ /* F->(E)|i */ /*目的: 对输入LL(1)文法字符串,本程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 /********************************************/ /* 程序相关说明*/ /* A=E' B=T' */ /* 预测分析表中列号、行号*/ /* 0=E 1=E' 2=T 3=T' 4=F */ /* 0=i 1=+ 2=* 3=( 4=) 5=# */ /************************************/ #include"iostream" #include "stdio.h" #include "malloc.h" #include "conio.h" /*定义链表这种数据类型参见: https://www.360docs.net/doc/ff7216355.html,/link?url=_owQzf8PRZOt9H-5oXIReh4X0ClHo6zXtRdWrdSO5YBLpKl NvkCk0qWqvFFxjgO0KzueVwEQcv9aZtVKEEH8XWSQCeVTjXvy9lxLQ_mZXeS###*/ struct Lchar{ char char_ch; struct Lchar *next; }Lchar,*p,*h,*temp,*top,*base; /*p指向终结符线性链表的头结点,h指向动态建成的终结符线性链表节点,top和base分别指向非终结符堆栈的顶和底*/

第五章 自上而下语法分析

第五章自上而下语法分析 1、教学目的及要求: 本章介绍编译程序的第二个阶段语法分析的设计方法和实现原理,包括自上而下分析的无回朔的递归下降分析、 LL(1)分析法。要求理解递归下降分析、LL(1)文法的基本概念;掌握无回朔的递归下降分析的设计和实现、LL(1)分析表的构造与分析方法。 ◇能够对一个给定的文法判断是否是LL(1)文法; ◇能构造预测分析表; ◇能用预测分析方法判断给定的输入符号串是否是该文法的句子; ◇能对某些非LL(1)文法做等价变换: ①消除左递归 ②提取左公共因子 可能会变成LL(1)文法。这样可扩大自顶向下分析方法的应用。 2、教学内容: 语法分析器的功能,自上而下语法分析(递归下降分析法,预测分析程序),LL(1)分析法,递归下降分析程序构造,预测分析程序。 3、教学重点: 递归下降子程序,预测分析表构造,LL(1)文法。 4、教学难点: 对一个文法如何判断是否是LL(1)文法,由于在判断 LL(1)文法时用到文法符号串的开始符号集合(FIRST集)和非终结符后跟符号集合(FOLLOW集)的计算,而一般学生往往因概念不清或不够细心对这两个集合的计算常常出错,导致判断和分析结果的错误。 5、课前思考 为了了解自顶向下(自上而下)分析的一般过程和问题,请学生首先回顾本章之前介绍的有关基本概念: ◇句子、句型和语言的定义是什么? ◇什么叫最左推导? ◇什么叫最右推导和规范推导? ◇什么叫确定的自顶向下语法分析?

◇自顶向下语法分析是从文法的开始符号出发,反复使用各种产生式,寻找与输入符号匹配的推导。 ◇确定的自顶向下语法分析中用的是哪种推导? ◇在确定的自顶向下语法分析过程中,当以同一个非终结符为左部的产生式有多个不同右部时,如何选择用哪个产生式的右部替换当前的非终结符? ◇确定的自顶向下语法分析对文法有何限制? 6、章节内容 第一节概述 第二节 LL(1)分析方法 第三节递归下降分析法 5.1 概述 LL分析法 确定的自上而下分析 自上而下分析递归下降分析法 语法分析不确定的自上而下分析——即带回溯的分析方法 算符优先分析 自下而上分析 LR分析 一、带回溯的自顶向下分析方法 是自顶向下分析的一般方法,即对任一输入符号串,试图用一切可能的办法,从树根结点(识别符号)出发,根据文法自上而下地为输入串建立一棵语法树,或者说,从识别符号开始,根据文法为输入串建立一个推导序列,这种分析过程本质上是一种试探过程,是反复使用不同规则谋求匹配输入串的过程。 例有文法G[S]:S→cAd,A→ab|a,输入串w=cad。其分析过程为带回溯的。 二、存在问题及解决办法 1、左递归问题: 自顶向下分析方法只有把规则排列得合适时才能正确工作,该方法不能处理具有左递归性文法,可采取某些算法消除左递归。 2、回溯问题:

编译原理 第四章自顶向下语法分析法

第四章 自顶向下语法分析方法 语法分析是编译过程的核心部分。语法分析的任务是:按照文法,从源程序符号串中识别出各类语法成份,同时进行语法检查,为语义分析和代码生成作准备。执行语法分析任务的程序称为分析程序。也称为语法分析器,它是编译程序的主要子程序之一。 在第二章中我们已经介绍过。通过语法分析可建立起相应的语法树。按语法树的建立方法,我们将语法分析方法分成两大类,即自顶向下分析和自底向上分析。下面,我们先介绍自顶向下分析。 本章重点:自顶向下分析、LL (1)分析 第一节 自顶向下分析方法 一、带回溯的自顶向下分析算法 这是自顶向下分析的一般方法,即对任一输入符号串,试图用一切可能的方法,从识别符号出发,根据文法自上而下地为输入串建立一棵语法树。 下面用一个简单例子来说明这种过程: 假定有文法G[S]: S→c Ad A →ab|a 以及输入串w=cad 为了自上而下地构造w 的语法树,我们首先按文法的识别符号产生根结点S ,并让指示器IP 指 c S 的规则仅有一条)把这棵树发展为 ( a ) (b ) (c ) 图3-1-1 图3-1-1a 。我们希望用S 的子结从左至右匹配整个输入串w 。首先,此树的最左子结是终结符c 为标志的子结,它和输入串的第一个符号相匹配。于是,我们就把IP 调整为指向下一输入符号a ,并让第二个子结A 去进行匹配,非终结符A 有二个选择,我们试着用它的第一个选择去匹配输入串,于是把语法树发展为图3-1-1b 。子树A 的最左子结和IP 所指的符号相符,然后我们再把IP 调为指向下一符号d 并让A 的第二个子结进入工作。但A 的第二个子结为终结符号b ,与IP 当前指的符号d 不一致。因此,A 宣告失败。这意味着A 的第一个选择此刻不适用于构造w 的语法树。这时,我们应该回头(回溯)看A 是否还有别的选择。 为了实现回溯,我们一方面应把A 的第一个选择所生长的子树注销掉;另一方面,应把IP 恢复为进入A 时的原值,也就是让它重新指向第二输入符号a 。现在我们试探用A 的第二个选择,即考虑生成图3-1-1c 的语法树。 由于子树A 只有一个子结a ,而且,它和IP 所指的符号相一致,于是,A 完成了匹配任务。在A 获得匹配后,指示器指向下一个未被触及的符号d 。 在S 的第二子结A 完成匹配后,接着就轮到第三个子结d 进行工作。由于这个子结和最后一个输入符号相符,于是,我们完成了构造语法树的任务,证明了w 是文法G[ s]的一个句子。 上述自顶向下地为输入符号w 建立语法树的过程,实际上也是设法建立一个最左推导序列,以便通过一步步推导将输入串推导出来。很明显,对于输入串w 可以通过如下的推导过程将其推导出来:S ?CAd ?cad 所以用最左推导,是因为我们对输入串是自左向右扫描的,只有使用最左推导,才能保证按扫描顺序去匹配输入串。在上述推出符号串w 的过程中,由于出现在符号串中的非终结符号只有一个,因此,未明显地表现出最左推导的性质。 根据以上分析,不难编出程序来实现这种分析的算法。但是,上述这种自顶向下的分析算法存

习题第5章自顶向下语法分析方法

习题第5章自顶向下语法分析方法 一课本练习部分(第99-101页) 5.1 5.4 5.6(2)(3)(4) 5.7(1)(3)(5) 参考答案: 5.1 (1)S =>(T)=>(T,S) =>(S,S) =>(a,S) =>(a,(T)) =>(a,(T,S)) =>(a,(S,S)) => (a,(a,S)) => (a,(a,a)) S => (T) => (T,S) => (S,S) => ((T),S) => ((T,S),S) => ((T,S,S),S) =>((S,S,S),S) => (((T),S,S),S) => (((T,S),S,S),S) => (((S,S),S,S),S) => (((a,S),S,S),S) => (((a,a),S,S),S) =>(((a,a), ∧,S),S) =>(((a,a), ∧,(T)),S) =>(((a,a), ∧,(S)),S) => (((a,a), ∧,(a)),S) => (((a,a), ∧,(a)),a) (2)改写文法如下: S→a|∧|(T) T→ST’ T’→,ST’|ε 递归子程序为: S() { if(SYM==’a’)P(a); else if(SYM==’∧’)P(∧); else if(SYM==’( ’) { GetSym(); P(T); match(’) ’); } else Error(); } T() { P(S); P(T’); } T’() { if(SYM==",") { match(",");??? P(S); P(T'); } else if(SYM==(")")return;

语法分析-自上而下分析

第四章语法分析—自上而下分析 知识结构: 带回溯分析法 回溯 自上而下分析面临的问题 左递归 问题的解决 语法分析-求FIRST、FOLLOW集合的算法自上而下分析LL(1)分析法证明LL(1)文法 构造LL(1)分析表 递归子程序的构造思想 递归子程序法递归子程序的特点 递归子程序的设计 第一节语法分析综述 一、语法分析的任务 按照语言即定的语法规则,对字符串形式的源程序进行语法检查,并识别出相应的语法成分。即语法结构是否符合语法规则。 二、语法分析器在编译程序中的地位(一遍扫描)

三、语法分析方法 通常把语法分析方法分为两大类,既自上而下分析与自下而上分析。 1、自上而下分析方法 实际上是一种产生的方法,分析过程是一个推导过程。 ⑴自上而下分析过程 从文法G的开始符号S出发,通过反复使用产生式,逐步推导出与输入的符号串完全相匹配的句子。采用最左推导,以文法开始符号为根结点,逐步为输入串自上而下地构造一棵语法树。 面临的输入符号为a,A所有的产生式: A12n ①若a FISRT(i),则指派去执行匹配任务。 ②若a不属于任何一个候选首字符集,则: a、若属于某个FISRT(i)且a FOLLOW(A),则让A 与自动匹配; b、否则,a的出现是一种错误。 例:设有文法G和输入符号串W:a*a+a G:S aA a A BaA

B +-*/ 推导过程: S aA aBaA a*aA a*aBaA a*a+aA a*a+a=W 构造语法树: S a A B a A * B a A + ⑵自上而下分析法 自上而下分析法又可分为确定和不确定的两种。 ①不确定的分析法(带回溯) 是一种穷举的试探方法,效率低、代价高,极少使用。 ②确定的分析法(不带回溯) 实现方法简单、直观,便于手工构造或自动生成语法分析器,是目前常用的方法之一。但是对文法有一定的限制。 2、自下而上分析法 ⑴自下而上分析过程 分析过程是归约过程。从给定的输入串W开始,不断寻找与文法G中某个产生式P的侯选式(右部)进行匹配,并用P代替也称为归约。 ⑵自下而上分析法

实验二--语法分析程序的设计-

实验二语法分析程序的设计 姓名:学号:专业班级 一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中预测分析方法。 二、实验内容 设计一个文法的预测分析程序,判断特定表达式的正确性。 三、实验要求 1、给出文法如下: G[E] E->T|E+T; T->F|T*F; F->i|(E); 2、根据该文法构造相应的LL(1)文法及LL(1)分析表,并为该文法设计预测分析程序, 利用C语言或C++语言或Java语言实现; 3、利用预测分析程序完成下列功能: 1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束; 2)读入文本文件中的表达式; 3)调用实验一中的词法分析程序搜索单词; 4)把单词送入预测分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息; 5)完成上述功能,有余力的同学可以进一步完成通过程序实现对非LL(1)文法到LL(1)文法的自动转换(见实验二附加资料1)。 四、实验环境 PC微机 DOS操作系统或Windows 操作系统 Turbo C 程序集成环境或Visual C++ 程序集成环境 五、实验步骤 1、分析文法,将给出的文法转化为LL(1)文法; 2、学习预测分析程序的结构,设计合理的预测分析程序; 3、编写测试程序,包括表达式的读入和结果的输出; 4、测试程序运行效果,测试数据可以参考下列给出的数据。 六、测试数据

输入数据: 编辑一个文本文文件expression.txt ,在文件中输入如下内容: 正确结果: (1)10; 输出:正确 (2)1+2; 输出:正确 (3)(1+2)*3+(5+6*7); 输出:正确 (4)((1+2)*3+4 输出:错误 (5)1+2+3+(*4+5) 输出:错误 (6)(a+b)*(c+d) 输出:正确 (7)((ab3+de4)**5)+1 输出:错误 七、源代码 import java.util.*; import java.io.*; public class test2 { static String[] key_word = { "main", "if", "then", "while", "do", "int", "else" }; static String[] cal_word = { "+", "-", "*", "/", "<", ">", "{", "}", "(", ")", "[", "]", "==", "!=", "!", "=", ">=", "<=", "+=", "-=", "*=", "/=", ";" }; /* * 给定文法G[E]: E->T|E+T; T->F|T*F; F->i|(E); */ static String[] gram = { "E->TA", "A->+TA", "A->@", "T->FB", "B->*FB", "B->@", "F->P", "F->(E)" }; static String[] followE = { ")", "#" };

编译原理-四章自顶向下语法分析法

第四章自顶向下语法分析方法 语法分析是编译过程的核心部分。语法分析的任务是:按照文法,从源 程序符号串中识别出各类语法成份,同时进行语法检查,为语义分析和代码生成作准备。执行语法分析任务的程序称为分析程序。也称为语法分析器,它是编译程序的主要子程序之一。 在第二章中我们已经介绍过。通过语法分析可建立起相应的语法树。按语法树的建立方法,我们将语法分析方法分成两大类,即自顶向下分析和自底向上分析。下面,我们先介绍自顶向下分析。 本章重点:自顶向下分析、LL(1)分析 第一节自顶向下分析方法 一、带回溯的自顶向下分析算法 这是自顶向下分析的一般方法,即对任一输入符号串,试图用一切可能的方法,从识别符号出发,根据文法自上而下地为输入串建立一棵语法树。 下面用一个简单例子来说明这种过程: 假定有文法G[S] : S—c A d A — ab|a 以及输入串w=cad 为了自上而下地构造w的语法树,我们首先按文法的识别符号产生根结点S, 并让指示器IP 指

向输入串的第一符号c。然后,用S的规则(此处左部为S的规则仅有一条)把这棵树发展为| (a) (b)(c) 图3-1-1 图3-1-1a。我们希望用S的子结从左至右匹配整个输入串w。首先,此树的最左子结是终结符c为标志的子结,它和输入串的第一个符号相匹配。于是,我们就把IP调整为指向下一输入符号a,并让第二个子结A去进行匹配,非终结符A有二个选择,我们试着用它的第一个选择去匹配输入串,于是把语法树发展为图3-1-1b。子树A的最左子结和IP所指的符号相符,然后我们再把IP调为指向下一符号d并让A的第二个子结进入工作。但A 的第二个子结为终结符号b,与IP当前指的符号d不一致。因此,A宣告失败。这意味着A的第一个选择此刻不适用于构造w的语法树。这时,我们应该回头(回溯)看A是否还有别的选择。 为了实现回溯,我们一方面应把A的第一个选择所生长的子树注销掉;另一方面,应把IP恢复为进入A时的原值,也就是让它重新指向第二输入符号a。现在我们试探用A的第二个选择,即考虑生成图3-1-1C的语法树。 由于子树A只有一个子结a,而且,它和IP所指的符号相一致,于是,A

编译原理实验报告语法分析程序的设计

编译原理实验报告语法分 析程序的设计 Last updated on the afternoon of January 3, 2021

实验5语法分析程序的设计(2)一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。 二、实验内容 设计一个文法的算法优先分析程序,判断特定表达式的正确性。 三、实验要求 1、给出文法如下: G[E] E->T|E+T; T->F|T*F; F->i|(E); 可以构造算符优先表如下: + * ( ) i + * ( ) i 2 2)为优先关系建立优先函数,这里由学生自己选择一种方式; 1、给出算符优先分析算法如下: k:=1;S[k]:=‘#’; REPEAT 把下一个输入符号读进a中; IFS[k]∈V T THENj:=kELSEj:=k-1; WHILES[j]aDO BEGIN REPEAT Q:=S[j];

IFS[j-1]∈V T THENj:=j-1ELSEj:=j-2 UNTILS[j]Q 把S[j+1]…S[k]归约为某个N ; k:=j+1; S[k]:=N; ENDOFWHILE; IFS[j]aORS[j]aTHEN BEGIN k:=k+1;S[k]:=a END ELSEERROR UNTILa=‘#’ 1、 根据给出算法,利用适当的数据结构实现算符优先分析程序; 2、 利用算符优先分析程序完成下列功能: 1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结 束; 2)读入文本文件中的表达式; 3)调用实验2中的词法分析程序搜索单词; 4)把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的 语言),若错误,应给出错误信息; 5)完成上述功能,有余力的同学可以对正确的表达式计算出结果。 四、实验环境 PC 微机 DOS 操作系统或Windows 操作系统 TurboC 程序集成环境或VisualC++程序集成环境 五、实验步骤 1、 分析文法中终结符号的优先关系; 2、 存放优先关系或构造优先函数; 3、利用算符优先分析的算法编写分析程序; 4、写测试程序,包括表达式的读入和结果的输出; 5、程序运行效果,测试数据可以参考下列给出的数据。 六、测试数据 输入数据: 编辑一个文本文文件,在文件中输入如下内容: 正确 结果: 10; 1+2; (1+2)*3+(5+6*7); ((1+2)*3+4; 1+2+3+(*4+5); (a+b)*(c+d); ((ab3+de4)**5)+1;

编译原理词法分析器语法分析课程设计报告书

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 2011级 学号 20112723 姓名林苾湲 西南交通大学信息科学与技术学院 2013年 12月

目录 课程设计1 词法分析器 (2) 1.1 设计题目 (2) 1.2 设计容 (2) 1.3 设计目的 (2) 1.4 设计环境 (2) 1.5 需求分析 (2) 1.6 概要设计 (2) 1.7 详细设计 (4) 1.8 编程调试 (5) 1.9 测试 (11) 1.10 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 2.1 设计题目 (14) 2.2 设计容 (14) 2.3 设计目的 (14) 2.4 设计环境 (14) 2.5 需求分析 (15) 2.6 概要设计 (16) 2.7 详细设计 (16) 2.8 编程调试 (24) 2.9 测试 (24) 2.10 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(可以是c语言的子集)。 二、设计容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: 4.1.硬件 (1)Intel Core Duo CPU P8700 (2)存4G 4.2.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 4.3.编程语言 C#语言 五、需求分析 5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号可以划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 5.3.将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 5.4.可选择性地将结果保存到文件中。 六、概要设计 6.1.数据类型 6.1.1.单词的分类:本词法分析器演示的是C语言的一个子集,故字符集如下:

编译原理实验三-自下而上语法分析报告及语义分析报告.docx

上海电力学院 编译原理 课程实验报告 实验名称:实验三自下而上语法分析及语义分析院系:计算机科学与技术学院 专业年级: 学生姓名:学号: 指导老师: 实验日期:

实验三自上而下的语法分析 一、实验目的: 通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。 二、实验学时: 4学时。 三、实验内容 根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。 对于正确的表达式,给出表达式的值。 对于错误的表达式,给出出错位置。 四、实验方法 采用LR分析法。 首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。 接下来给出LR分析表。 然后程序的具体实现:

●LR分析表可用二维数组(或其他)实现。 ●添加一个val栈作为语义分析实现的工具。 ●编写总控程序,实现语法分析和语义分析的过程。 注:对于整数的识别可以借助实验1。 五、文法定义 简单的表达式文法如下: (1)E->E+T (2)E->E-T (3)E->T (4)T->T*F (5)T->T/F (6)T->F (7)F->(E) (8)F->i

五、处理程序例和处理结果例 示例1:20133191*(20133191+3191)+ 3191#

六、源代码【cifa.h】 //cifa.h #include using namespace std; //单词结构定义 struct WordType{ int code;

实验二自顶向下语法分析--递归下降法

实验二递归下降法判断算术表达式的正确性 学时数:2-4 一、实验目的和要求 1、用递归下降技术实现语法分析器; 2、理解自顶向下语法分析方法; 3、熟练掌握预测分析程序的构造方法。 二、实验内容 算术表达式的文法是G[E]: E→E+T| T T→T*F| F F→(E)| i 用递归下降分析法按文法G[E]对算术表达式(包括+、*、()的算术表达式)进行语法分析,判断该表达式是否正确。 三、实验步骤 1、准备:阅读课本有关章节,将上述算术表达式的文法改造成LL(1)文法(即消除左递 归和提取左公因子);按P87例4.12编写程序。 2、上机调试,发现错误,分析错误,再修改完善。 四、测试要求 1、为降低难度,表达式中不含变量(只含单个无符号整数或i); 2、如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 3、测试用的表达式建议事先放在文本文件中,一行存放一个表达式,以分号结束。而 语法分析程序的输出结果写在另一个文本文件中; 4、选作:对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果。 5、程序输入/输出示例: 如参考C语言的运算符。输入如下表达式(以分号为结束)和输出结果: (a)1; 或 i; 输出:正确 (b)1+2; 或 i+i; 输出:正确 (c)(1+2)*3+4-(5+6*7); 或 (i+i)*i+i-(i+i*i); 输出:正确 (d)((1+2)*3+4 或 ((i+i)*i+i; 输出:错误,缺少右括号 (e)1+2+3+(*4/5) 或 i+i+i+(*4/5); 输出:错误

五、实验报告要求 1、写出修改后LL(1)文法 2、通过对核心代码做注释或通过程序流程图的方式说明递归下降分析程序的实现思想。 3、写出调试程序出现的问题及解决的方法。 4、给出测试的结果。 六、思考(选作) 文法G[E]所构造算术表达式只包含+和*。请修改文法和程序,使得该语法程序可判断包含减号和除号的算术表达式的正确性。 [实验指导] 将文法G[E]改造为LL(1)文法如下: G’[E]: E → TE’ E’→ +TE’| ε T → FT’ T’→ *FT’|ε F → (E)| i [补充说明] 预测分析法分析程序可以从网上下载,但要求: (1)理解该程序,在实验报告中说明该程序所使用的文法及修改后的文法; (2)实验报告要求同上

编译原理词法分析器语法分析课程设计范本

《 编译原理词法分析器语法分析课程设 计 -

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级级 学号 2723 姓名林苾湲 西南交通大学信息科学与技术学院 12月 目录 课程设计1 词法分析器 (2) 设计题目 (2) 设计内容 (2) 设计目的 (2)

设计环境 (2) 需求分析 (2) 概要设计 (2) 详细设计 (4) 编程调试 (5) 测试 (11) 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 设计题目 (14) 设计内容 (14) 设计目的 (14) 设计环境 (14) 需求分析 (15) 概要设计 (16) 详细设计 (16) 编程调试 (24) 测试 (24) 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(能够是c语言的子集)。 二、设计内容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: .硬件 (1)Intel Core Duo CPU P8700 (2)内存4G

.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 .编程语言 C#语言 五、需求分析 .源程序的预处理:源程序中,存在许多编辑用的符号,她们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 .单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号能够划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float 等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 .将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 .可选择性地将结果保存到文件中。

第四章 语法分析——自上而下分析

第四章语法分析——自上而下分析 【关键问题】 ◇什么叫确定的自上而下语法分析? ◇自上而下语法分析是从文法的开始符号出发,反复使用各种产生式,寻找与输入符号匹配的推导。 ◇在确定的自上而下语法分析过程中,当以同一个非终结符为左部的产生式有多个不同右部时,如何选择用哪个产生式的右部替换当前的非终结符? ◇确定的自上而下语法分析对文法有何限制? 【学习目标】 确定的自上而下分析方法虽对文法有一定的限制,但由于实现方法简单、直观,便于手工构造或自动生成语法分析器,因而仍是目前常用的方法之一。 ◇能够对一个给定的文法判断是否是LL(1)文法; ◇能构造预测分析表; ◇能用预测分析方法判断给定的输入符号串是否是该文法的句子; ◇能对某些非LL(1)文法做等价变换: ①消除左递归; ②提取左公共因子 【学习指南】 确定的自上而下分析由于实现方法简单、直观、便于手工构造,因此,仍是目前常用的语法分析方法之一,尤其对小型编译器的实现较为适合。确定的自上而下分析要求文法是LL(1)的,所以,能否用确定的自上而下分析方法构造语法分析器,首先必须对所给文法进行判断。由此构造LL(1) 分析器的关键问题是对文法的LL(1)判别。判断LL(1)文法时用到文法符号串的开始符号集合(FIRST集)和非终结符的后跟符号集合(FOLLOW集)的计算。本章的学习要求大家对给定的文法能熟练、准确地计算出产生式右部符号串的开始符号集合和每个非终结符的后跟符号集合,只有这两个集合的元素计算准确无误,才能对LL(1)文法的判断得出正确结论,从而正确构造LL(1)分析表。对非LL(1)文法的等价变换特别要注意的是:消除了左递归、提取了左公共因子后不一定就能满足LL(1)文法的条件。 【难重点】 语法分析是编译程序的核心部分。语法分析的作用是识别由词法分析给出的单词符号序列是否是给定文法的正确句子(程序),目前语法分析常用的方法有自上而下分析和自下而上分析两大类。本章将主要介绍确定的自上而下分析思想和对文法的要求。确定的自上而下分析要求文法满足LL(1)文法。本章主要介绍内容为: ◇LL(1) 文法的定义和判别 ◇非LL(1)文法的等价变换 ◇确定的自上而下分析方法 ◇预测分析方法 重点: ①LL(1)文法的定义和判别 ②非LL(1)文法的等价变换 ③预测分析方法 难点: 对一个文法如何判断是否是LL(1)文法。在判断LL(1)文法时用到文法符号串的开始符号集合(FIRST 集)和非终结符后跟符号集合(FOLLOW集)的计算,由于概念不清或不够细心常常导致对这两个集合的计算出错。 【知识结构】

第五章 自顶向下语法分析方法

第五章自顶向下语法分析方法 教学要求 1.掌握:计算FIRST集、FOLLOW集、SELECT集,LL(1)文法的概念 2.理解:不确定/确定的自顶向下分析法 3.了解:该分析方法的基本思想 5.1 确定的自顶向下分析思想 确定的自顶向下分析方法,首先要解决从文法的开始符号出发,如何根据当前的输入符号唯一地确定选用哪个产生式替换相应非终结符往下推导,或构造一颗相应的语法树。 1:首符号集: 设G=(VN,VT,P,S)是上下文无关文法 :FIRST(α)={a|α=>aβ,a∈VT, α, β∈V*} 若α=>ε则规定ε∈FRIST(α) 2:后继符号集: FOLLOW(A)={a |S =>μAβ且 a∈FRIST(β),μ∈V*,β∈V+ } 若S =>μAβ ,且β=>ε,则#∈FOLLOW(A) 3:选择集合SELECT: 给定上下文无关文法的产生式A→α A ∈VN, α∈V* ,若α≠>ε,则: SELECT(A→α)=FIRST(α) 如果α=>ε,则:SELECT(A→α)=FIRST(α)-{ε}∪FOLLOW(A) 4:LL(1)文法: 一个上下文无关文法是LL(1)文法的充分必要条件是,对每个非终结符A的两个不同产生式,A→α或A→β满足SELECT(A→α)∩SELECT(A→β)= φ 其中,α、β不能同时=>ε 注意:第一个L表明自顶向下分析是从左到右扫描输入串,第二个L表明分析过程中将用最左推导,1表明只需向右看一个字符便可决定如何推导即选择哪个产生式。 5.2 LL(1)文法的判别 判别文法是否是LL(1)文法,对任何文法计算需计算FIRST、FOLLOW和SELECT集合,进而判别文法是否为LL(1)文法。举例说明判断LL(1)文法的步骤。 1.计算FIRST集 1).若X∈V T,则FIRST(X)={X} 2).若X∈VN,且有产生式X→a…,a是终结符,则把a加入到FIRST(X)中;若X→ε也是一条产生式,则把ε也加到FIRST(X)中. 3).若X→Y…是一个产生式且Y∈VN,则把FIRST(Y)中的所有非ε元素都加到FIRST(X)中;若X →Y1Y2…YK 是一个产生式,Y1,Y2,…,Y(i-1)都是非终结符,而且,对于任何j,1≤j ≤i-1, FIRST(Yj)都含有ε (即Y1..Y(i-1) =>* ε ),则把FIRST(Yj)中的所有非ε元素都加到FIRST(X)中;特别是,若所有的FIRST(Yj , j=1,2,…,K)均含有ε,则把ε加到FRIST(X)中. 4)反复使用1)~3)直到每个符号的FIRST集不再增大为止 FIRST集的求法有两种:一是根据定义,二是用关系图求得。推荐采用定义即可 若文法G[ E]为: (1) E –> TE’ (2) E’ –> +TE’ (3) E’ –> ε (4) T –> FT’ (5) T’ –> *FT’ (6) T’ –> ε (7) F –> (E)

相关文档
最新文档