实验三自下而上语法分析及语义分析
编译原理中语法分析探讨及其应用

(一)语法分析概述语法分析是对高级语言的句子结构进行分析,在编译过程中处于核心地位,它的主要任务是在词法分析识别出正确单词符号串的基础上,根据语言定义的语法规则,从单词符号串中识别出各种语法成分,并进行语法检查和错误处理,生成相应的语法树。
生成语法树的方法有两种,一种是自上而下另一种是自下而上。
[1]自上而下的语法分析方法是对由单词种别构成的源程序,尝试用所有可能的途径,从语法树的根结点出发,从上至下为输入符号串建立一棵语法树。
也可以说成是为输入符号串构造一个最左推导。
整个分析过程就是一种试探的过程,通过不断使用不同产生式谋求匹配输入符号串的过程。
自上而下的语法分析方法分为确定的和不确定的两种。
只有LL(1)文法才能进行确定的自上而下语法分析,在这种分析方法中面临两个问题,回溯和死循环。
通过对文法的产生式进行改造来解决这两个问题,在回溯中改造的方法是提取公共左因子,比如:A→αβ1|αβ2,改造后为A→αA’,A’→β1|β2。
死循环的改造方法是消除左递归,比如:A→Aα|β改造后为A→βA’,A’→αA’|ε。
而不确定的有递归下降分析和预测分析,前者适合手工实现,后者适合自动生成。
递归下降分析是用子程序来实现的,为每个非终结符创造一个子程序,每个子程序里面都有一个函数体,这个函数体是根据非终结符的产生式而定义展开的,当分析过程中遇到终结符时就直接匹配,如果遇到非终结符就调用相应的非终结符对应的子程序。
预测分析方法需要借助一个状态栈和一个二维分析表来实现,两者必须联合控制才能更好的实现预测分析方法。
自下而上的语法分析方法和自上而下的语法分析方法是完全不同的两种方法,但是它们产生的结果是相同的,都是构造一棵语法树,只是构造的过程不同罢了。
语法树创建的过程是把分析符号串的各个符号作为叶子结点,按照文法定义的规则,把产生式左部的非终结符作为父结点,自下而上构造此树的过程。
它的基本思想是“移进—归约”。
语法分析程序的设计与实现

◆词法分析 用户必须提供一个词法分析器来读取输入流并把记号(带有值, 如果需要的话)传达到解析器。词法分析器使叫做 yylex 的整数值的 函数。这个函数返回一个整数的记号编号,它表示读取的记号的种类。 如果这个记号关联着一个值,应当把它赋予外部变量 yylval。 为使通信得以发生,解析器和词法分析器必须在记号编号上达成 一致。编号可以由 Yacc 或用户来选择。在这两种情况下,使用 C 语 言的“# define”机制允许词法分析器使用符号来返回这些编号。例如, 假定在 Yacc 规定文件的声明段中已经定义记号名字 DIGIT。 它的意图是返回一个 DIGIT 记号编号,和等于这个数字的数值 的一个值。倘若词法分析器代码位于规定文件的程序段,标识符 DIGIT 将被定义为与记号 DIGIT 关联的记号编号。 这种机制导致清晰的、易于修改的词法分析器;唯一的缺点是在 文法中需要避免使用任何在 C 语言或解析器中保留的或有意义的记 号名字;例如,使用记号名字 if 或 while 就一定会导致编译词法分 析器时出现严峻的困难。记号名字 error 保留给错误处理,不应该随 便使用。 同上所述,记号编号可以由 Yacc 或用户来选择。在缺省的条件 下,编号由 Yacc 选择。文字字符的缺省记号编号是它在本地字符集 中的字符数值。其他名字赋予从 257 开始的记号编号。 要把一个记号编号赋予一个记号(包括文字),可以在声明段中记 号或文字的第一次出现时直接跟随着一个非负整数。这个整数被接受
第四:YACC 内部名称: ................................................................................................ 7 第五:运行结果(源代码见附录).............................................................................. 8 第六:实验总结 ............................................................................................................... 8 第七:附录 ..................................................................................................................... 10
语法和语义分析

2 向前看集 Follow
定义 设文法G[S],非终结符号U的向前看集为 Follow(U)={a︱S * …Ua…, a∈ Vt∪{#}}
即Follow(U)为所有含有U的句型中紧跟在U之 后的终结符号或#组成的集合。 (若紧跟在非终结符号U后面的符号串为空时 ,则视U后面的符号为特殊符号#)
从语法树建立的角度来看,它是根据文法从树根结
点开始,试着自上而下建立一棵语法树,其末端结点
按从左到右的顺序若是给定的句子,则句子得到识别,
表明其结构符合文法,否则不符合文法。
14
文法G[N]:N→D︱ND D→0︱1︱2︱…︱9
分析25是否符合该文法 N
ND D5 2
15
2 自顶向下分析的难点及解决办法
16
对于某个非终结符号有n个规则(n个候选式), 此时要分两种情况 I 首符号不相同
10
例: 文法G[E] E→TE’
E’→+E︱є T→FT’ T’→T︱є F→PF’ F’→*F’︱є P→(E)︱a︱b︱∧
First(E)= First(T)= First(F)= First(P)={(,a,b,∧}
First(E’)={+,є } First(F’)={*,є }
First(T’)={(,a,b,∧,є }
6
例: 文法G[E]:E→E+T︱T
T→T*F︱F F→(E)︱i
E * E
E * E+T Follow(E)={#,+,)}
E * (E)
E * T
E * T+T E * T*F E * (T)
Follow(T)={#,*,+,)}Follow(F)=来自#,*,+,)}7
编译原理第4章 语法分析——自上而下分析

17
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
18
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
19
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
一个文法消除左递归的条件
丌含以为右部的产生式
丌含回路
PP
30
例 文法G(S): S→Qc|c Q→Rb|b R→Sa|a
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
Q
Q
ⅹ
S
R
S→Qc|c Q→Rb|b R→Sa|a
35
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
消除S的直接左递归后: S→abcS | bcS | cS S→abcS | Q→Sab |ab | b R→Sa|a
关于Q和R的觃则已是多余的,化简为:
S→abcS | bcS | cS
S→abcS |
(4.4)
36
注意,由于对非终结符排序的丌同,最 后所得的文法在形式上可能丌一样。但 丌难证明,它们都是等价的。
分析输入串x*y(记为)。
x*y
S
IP
15
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
实验三 LR(1)分析表语法分析报告

学生实验报告(理工类)课程名称:编译原理专业班级:08计算机科学与技术(单)本所属院部:信息技术学院指导教师:洪蕾20 10 ——20 11 学年第二学期金陵科技学院教务处制实验报告书写要求实验报告原则上要求学生手写,要求书写工整。
若因课程特点需打印的,要遵照以下字体、字号、间距等的具体要求。
纸张一律采用A4的纸张。
实验报告书写说明实验报告中一至四项内容为必填项,包括实验目的和要求;实验仪器和设备;实验内容与过程;实验结果与分析。
各院部可根据学科特点和实验具体要求增加项目。
填写注意事项(1)细致观察,及时、准确、如实记录。
(2)准确说明,层次清晰。
(3)尽量采用专用术语来说明事物。
(4)外文、符号、公式要准确,应使用统一规定的名词和符号。
(5)应独立完成实验报告的书写,严禁抄袭、复印,一经发现,以零分论处。
实验报告批改说明实验报告的批改要及时、认真、仔细,一律用红色笔批改。
实验报告的批改成绩采用百分制,具体评分标准由各院部自行制定。
实验报告装订要求实验批改完毕后,任课老师将每门课程的每个实验项目的实验报告以自然班为单位、按学号升序排列,装订成册,并附上一份该门课程的实验大纲。
实验项目名称: LR(1)分析表语法分析实验学时: 6 同组学生姓名:无实验地点: B513 实验日期: 2011.4.7/4.21 实验成绩:批改教师:批改时间:一、实验目的和要求语法分析主要目的是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成作准备.语法分析程序在分析过程中检查符号串是否为该程序的句子.若是则输出该句子的分析树,否则就表示源程序存在语法错误,并报告错误的性质与位置.二、实验仪器和设备主机一台:有Visual Studio 2005工具三、实验过程说明:此程序共有两个类,Lexical进行词法分析,Syntax进行语法分析.对于语法分析,采用LR(1)分析法,判断程序是否满足规定的结构.1:LR-table.txt:存放分析表,其中正数表示移进,负数表示归约,100表示接受状态,0表示不操作。
编译原理课程设计之第三章上下文无关文法及分析

14
无关文法及分析
1. 上下文无关文法(即2型文法)的形式定义:
上下文无关文法是一个四元组(VT , VN , P , S):
① ②
终非结终符 结集 符合 集合VTVN(与VT产的不生左相式部交)
产生式 的右部
③ 产生式或文法规则A→α形成的集合P,
其中A∈VN,α∈(VT∪VN)* 4) 开始符号S,其中S∈VN
25
无关文法及分析
3.2 上下文无关文法的形式定义
1. 上下文无关文法(即2型文法)的形式定义 2. chomsky文法的分类 3. 推导和规约的定义 4. 句型和句子的定义 5. 最左和最右推导 6. 文法定义的语言 7. 递归产生式和递归文法 8. 文法和语言
mcy
编译原理课程设计之第三章上下文
mcy
编译原理课程设计之第三章上下文
1
无关文法及分析
第三章 上下文无关文法及分析
本章的目的是为语言的语法 描述寻求形式工具,要求该 工具对程序设计语言给出精 确无二义的语法描述。
mcy
编译原理课程设计之第三章上下文
2
无关文法及分析
第三章 上下文无关文法及分析
✓3.1 语法分析过程 ▪ 3.2 上下文无关文法的形式定义
下面的2型文法描述了包含加法、减法和乘法的简 单整型算术表达式的语法结构。
文法G[exp]:
exp → exp op exp exp →(exp) exp → number
34-3 是符合该 语法结构的简单 整型算术表达式 (句子)吗?
op → + | - | *
mcy
编译原理课程设计之第三章上下文
令G是一个如上所定义的文法,则G=(VT,VN,P,S)
理学自上而下的语法分析

b∈follow(A),把A→α加至M[A][b]。 ⑤把所有未定义的M[A][c]标上“出错标志”
(c∈VT)。
4.7 预测分析法
㈢预测分析控制程序实现 ①数据结构 M:二维数组,存放预测分析表。 stack:符号栈,初始时为“#S”(S为开
中ε∈afi∈rsVt(XT ,)。则 a∈first(X) ; 若 X→ε , 则 ③观察每个产生式,若有X→Y……,其
中为fYir∈st(VYN),/ε)则加将到fifrisrts(tY(X)中)中的。非ε元素(记
4.5 first集和follow集
考虑更一般情况, Y2、…Yi-1∈VN。
始符号)。 X:表示栈顶符号 t.code:当前处理单词种别
4.7 预测分析法
②算法描述 预测分析控制程序任何时刻的动作,都
按照栈顶符号X和当前输入符号t.code行 事,控制程序每次执行下述三种可能的 动作之一(暂不考虑出错情况)。 l 若X 和 t.code 均为 '#',则分析成功, 输入串为合法句子,终止分析过程。
4.1 带回溯的自上而下分析法概 述
从文法的开始符号出发进行推导,最终 推出确定的输入串(由单词种别构成的 源程序)。
4.1 带回溯的自上而下分析法概 述
从根结点出发,试图用一切可能的办法, 自上而下地为输入串建立一棵语法树。 或者说,为输入串寻找一个最左推导。
4.1 带回溯的自上而下分析法概 述
A→α1|α2|…|αn|ε 设当前输入符号为a,根据下述原则
if (a∈first(αi))
用A→αi推导(1≤i≤n)
else if (a∈follow(A))
第五章自上而下语法分析

第五章⾃上⽽下语法分析第五章⾃上⽽下语法分析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分析⼀、带回溯的⾃顶向下分析⽅法是⾃顶向下分析的⼀般⽅法,即对任⼀输⼊符号串,试图⽤⼀切可能的办法,从树根结点(识别符号)出发,根据⽂法⾃上⽽下地为输⼊串建⽴⼀棵语法树,或者说,从识别符号开始,根据⽂法为输⼊串建⽴⼀个推导序列,这种分析过程本质上是⼀种试探过程,是反复使⽤不同规则谋求匹配输⼊串的过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三自下而上语法分析及语义分析
一、实验目的:
通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。
二、实验学时:
4学时。
三、实验内容
根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。
对于正确的表达式,给出表达式的值。
对于错误的表达式,给出出错位置。
四、实验方法
采用LR分析法。
首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。
属性文法的定义可参照书137页表),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表)。
接下来给出LR分析表。
然后程序的具体实现:
LR分析表可用二维数组(或其他)实现。
添加一个val栈作为语义分析实现的工具。
编写总控程序,实现语法分析和语义分析的过程。
注:对于整数的识别可以借助实验1。
五、文法定义
简单的表达式文法如下:
E->E+T|E-T|T
T->T*F|T/F|F
F->(E)|i
上式中, i 为整数。
六、处理程序例
例1: 正确源程序例:
23+(45+4)* 40分析结果应为:正确的表达式。
其值为:1983
例2: 错误源程序例:
5+(56+)-24
分析结果应为:错误的表达式:出错位置为)
附录:源程序
#include <>
#include""
#include <iostream>
using namespace std;
#define R 30
#define C 20
typedef struct elem
{
char e[4];
}Elem; ;
for(i=0;i<row;i++)
{
printf("请输入%d号状态所对应的各列的元素,空白的地方用s代替\n",i);
for(j=0;j<colno;j++)
{
scanf("%s",mid);
if(strcmp(mid,"s")==0||strcmp(mid,"S")==0)
strcpy(LR[i+1][j].e," ");
else
strcpy(LR[i+1][j].e,mid);
}
}
}
void output_LR(int row,int colno)
{
int i,j;
printf("**********************************************************\n");
printf("* LR分析表如下: *\n");
printf("**********************************************************\n");
printf("\n");
printf(" ");
for(j=0;j<colno;j++)
printf("%s ",LR[0][j].e);
printf("\n");
for(i=1;i<=row;i++)
{
printf("%d ",i-1);
for(j=0;j<colno;j++)
printf("%s ",LR[i][j].e);
printf("\n");
}
printf("\n");
}
int SignNum(char ch)==0)
return i;
return -1;
}
int CharChangeNum(char* ch);
if(strcmp(mid," ")==0)
{ printf("不能规约\n"); return -2; }
if(strcmp(mid,"acc")==0||strcmp(mid,"ACC")==0)
{ printf("规约成功\n"); return -1; }
out[i+1].order=i+2;
if(mid[0]=='s'||mid[0]=='S')
{
s_num=CharChangeNum(mid+1);tate[j]=out[i].state[j];
out[i+1].state[stateTop]=s_num;
out[i+1].state[++stateTop]=-1; ign,out[i].sign);
out[i+1].sign[signTop]=out[i].input[0];
out[i+1].sign[++signTop]='\0'; rasen," "); nput,out[i].input+1); tate[j]=out[i].state[j];
j=SignNum(gra[0]);
out[i+1].state[stateTop]=CharChangeNum(LR[out[i+1].state[stateTop-1]+1][
j].e);
out[i+1].state[++stateTop]=-1; ign,out[i].sign);
out[i+1].sign[signTop]=gra[0];
out[i+1].sign[++signTop]='\0'; rasen,gra);
nput,out[i].input); rder);
while(out[i].state[j]!=-1)
printf("%d",out[i].state[j++]);
printf(" %s %s %s\n",out[i].sign,out[i].grasen,out[i].input)
;
}
}
int OutControl()rder=1; tate[0]=0;
stateTop=1; out[0].state[stateTop]=-1; ign,"#");
signTop=1; rasen," "); nput,Sentence); nput,"#");
strcpy(out[0].explen,"0和#进栈"); nput[0]);
tate[stateTop-1],s_num,i)!=1)
break;
i++;
}
return i;
}
main()
{
int r;
printf("**********************************************************\n");
printf("* 函数的输入: 文法的产生式,文法句型的一个句子,LR分析
表 *\n");
printf("* 函数的输出: LR分析器的工作过程与说明 *\n");
printf("**********************************************************\n");
printf("请输入LR分析表中终结符与非终结符的总个数\n");
scanf("%d",&colno);
printf("请输入LR分析表中状态的总个数\n");
scanf("%d",&row);
input_LR(row,colno);
output_LR(row,colno);
input_GramSent();
r=OutControl(); //r为输出结果的行数 OutputResult(r);
}
七、实验小结
这个程序是从网上下载下来的,根据这个实验要求做了些更改,但是总是出现溢出错误,只能运行到LR分析表的部分(如截图),没有找到解决问题的办法。