算符优先文法分析

算符优先文法分析
算符优先文法分析

算符优先文法分析

1.问题描述

基于算符优先分析法的语法分析程序

要求:

(1)输入已知文法,生成文法矩阵,判断该文法是否是算符优先文法。

(2)用程序自动生成该文法的算符优先关系矩阵。

(3)对人工输入的句型或句子,分析该句型或句子是否合法,能否用已知文法推出。

(4)具有通用性。所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为算符优先文法。

(5)有运行实例。对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。

2.算符优先分析法

2.1算符优先文法

定义:设有不含空串的一文法G,如果G中没有形如G>……BC……的产生式,其中B和C为非终结符,且对任意两个终结符a,b之间之多只有<,>,=,三种关系的一种成立,则称G是一个算符优先文法。

非终结符的FIRSTVT集合和LASTVT集合

FIRSTVT(B)={b|B→b…或B→Cb…}

LASTVT(B)={b|B→…a或B→…aC}

2.2算符优先矩阵

算符优先关系矩阵,判断输入是否满足已知文法的依据。根据非终结符的FIRSTVT集合和LASTVT集合产生。

1.“=”关系

若A→…ab…或A→…aBb…,则a=b;

2.“??”关系

若A→…aB…,对每一个b属于FIRSTVT(B),有a??b;

3.“??”关系

若A→…Bb…,对每一个a属于LASTVT(B),有a?? b。

2.3如何规约

在分析过程中,利用分析栈存放已识别的那部分句型,而句型的其余部分由剩余输入串组成,通过比较栈顶符号和下一个输入符号之间的关系,可以判别栈顶符号是否为句柄尾符号。如果是句柄尾,则沿栈顶向下,在栈内寻找句柄头(利用关系)。由关系和关系之间包括的符号串就是句柄,然后把它们弹出栈,并代之以归约后的非终结符。这样就完成了一次归约过程。

2.4算符优先分析方法的局限性

由于算符优先分析法去掉了单非终结符之间的归约,尽管在分析过程中,当决定是否为句柄时采取一些检查措施,但仍难完全避免把错误的句子得到正确的归约。

此外,通常一个适用语言的文法也很难满足算符优先文法的条件,因而致使算符优先分析法仅适用于表达式的语法分析。

3概要设计,即算法或流程图

本程序有java面向对象的程序设计方法设计。主要类有Suanfu(界面类),Grammar,FirstLast,Table,Guiyue。

其中Suanfu完成所有与界面相关的操作;Grammar完成文法的提取,和终结符,非终结符的识别,和初步判断输入文法的正确性;FirstLast完成非终结符FIRSTVT集合和LASTVT集合的构造;Table完成算符优先关系矩阵的构造,并检查文法的二义性。除界面类外,其他类均由构造函数完成其数据处理功能。

3.1 算符优先分析流程图

算符优先文法的执行过程为:输入已知文法,分析其正确性,提取非终结符和终结符,构造非终结符的FIRSTVT集和LASTVT 集,再次基础上构造算符优先关系矩阵,并用来判断表达式是否符合该文法。

算符优先文法程序总的流程图为:

开始

读入文法

提取文法并存储

识别终结符和非终结符,并存储

是否为算符优先文法?生成FIRSTVT和LASTVT 生成优先关系矩阵

文法是否有二义性?

报错报错

读入待分析字符串规约过程

规约成功?结束不符合文法

符合文法

程序总的程序流程图

3.2文法分析

Grammar类提取文法,识别终结符和非终结符,并简单判断文法是不是算符优先文法。

主要数据:

g:String[] 用于存储所有产生式;

T:char[] 用于存储非终结符;

t:char[] 用于存储终结符。

大写字母作为非终结符,其余字符均作为终结符。文法分析主要解决的问题有:(存在这些问题的文法,都不是算符优先文法)

1.产生式左边含有终结符

2.产生式右边有相邻非终结符

3.存在非终结符只在产生式右侧不在产生式左侧的

4.不可终结的产生式,即文法没有右侧全为终结符的产生式,此种文法不可产生终结的字符串。

5.不可到达的产生式,即产生式右侧的非终结符补出现在其他产生式中,开始字符除外。

3.3文法每个非终结符的FIRSTVT集和LASTVT集

FirstLast类用于FIRSTVT集合和LASTVT集合构造。

主要数据:

first:char[][] 用于存储非终结符的FIRSTVT集合;

last: char[][] 用于存储非终结符的LASTVT集合。

对FIRSTVT集的构造我们可以给出一个算法,这个算法基于下面两条规则:

(1)若有产生式A→a…或A→Ba…,则a属于FIRSTVT(A),其中A,B为非终结符,a为终结符

(2)若a属于FIRSTVT(B)且有产生式A→B…则有a属于FIRSTVT(A)。

为了计算方便,我们建立一个布尔数组F[m,n](m为非终结符个数,n为终结符个数)和一个后进先出栈STACK。我们将所有的非终结符排序,用的序号,再将所有的终结符排序,用表示

终结符a 的序号。算法的目的是要合数组每一个元素最终取什满足:F[ , ]的值为真,当且仅当a 属于FIRSTVT (A )。至此,显然所有非终结符的FIRSTVT 集己完全确定。

步骤如下:

首先按规则(1)对每个数组元素赋初值。观察这些初值,若F [A i ,a j ]的值为真,则将(A ,a )推入栈中,直至对所有数组元素的初值都按此处处理完。然后对栈做以下运算。

将栈顶项弹出,设为(B ,a ),再用规则(2)检查所有产生式,若有形为A →B …的产生式,而F [A i ,a j ]的值是假,则令其变为真,且将(A ,a )推进栈,如此重复直到栈弹空为止。具体的算法可用程序描述为:

PROCEDURE INSERT (A ,a );

IF NOT F [A i ,a j ] THEN

BEGIN

F[A i ,a j ]:=TRUE

PUSH(A,a) ONTO STACK

END

此过程用于当a 属于FIRSTVT (A )时置F[A i ,a j ]为真,并将符号对(A,a )下推到栈中,其主程序为:

BEGIN (MAIN )

FOR I 从1到m,j 从1到n

DO F[A i ,a j ] :=FALSE ;

FOR 每个形如A →a …或A →Ba …的产生式

DO INSERT (A ,a )

WHILE STACK 非空 DO

BEGIN

把STACK 的顶项记为(B ,a )弹出去

FOR 每个形如A →B …的产生式

DO INSERT (A ,a )

END

END (MAIN )

利用类似的方法可求得每个非终结符的LASTVT (A )

3.4由LASTVT 和FIRSTVT 集建立优先矩阵

Table 类利用之前构造的LASTVT 和FIRSTVT 生成。

主要数据:

table: int[][] 用于存储算符优先关系矩阵。

有了文法中的每个非终结符的FIRSTVT 集和LASTVT 集,我们就可以用如下算法最后构造文法的优先关系表

FOR 每个产生式A →1X 2X …n X DO

FOR i:=1 TO n-1 DO

BEGIN

IF i X 和1+i X 均为终结符

THEN 置i X =1+i X

IF i X 和2+i X 都为终结符,但1+i X 为非终结符 THEN 置i X =2+i X ;

IF i X 为终结符而1+i X 为非中介符 THEN FOR FIRSTFVT(1+i X )中的每个b DO 置 i X

IF i X 为非终结符而1+i X 为终结符 THEN FOR LASTVT(i X )中的每个a DO 置 a>1+i X

END

以上算法对任何算符文法G 可自动构造其算符优先关系表,并可判断G 是否为算符优先关系

3.5算符文法的分析归约过程算法

自底向上的算符优先分析法,也为自左右向右归约,我们已经知道它不是规范归约。规范归约的关键问题是如何寻找当前句型的句柄,句柄为某一产生式的右面部,归约结果为用与句柄相同的产生式右面部之左部非终结符代替句柄,而算符优先分析归约的关键,是如何找最左素短语,而最左右素短语i N i a 1+i N 1+i a ……j a 1+j N 应满足:

1-i a ?? i a

i a = 1+i a =……j a

j a ?? 1+j a

在文法的产生式中存在右面部符号串的符号个数与该素短语的符号个数相等,非终结符号对应k N ,(k=i,…,j+1)不管其符号名是什么。终结符对应i a ,…, j a ,其符号表示要与实际的终结符相一致才有可能形成素短语。由此,我们在分析过程中可以设置一个符号栈S ,用以寄存归约或待形成最左素短语的符号串,用一个工作单元a 存放当前读入的终结符号,归约成功的标志是当读到句子结束符#时,S 本中只剩#N ,即只剩句子最左括号“#”和一非终结符N 。下面给出分析过程的示意图

在归约时要检查是否有对应产生式的右部与S[j+1]…S[k]形式相符,(忽略非终结符名的不同)若有才可归约,否则出错。在这个分析过程中把“#”也放在终结符串中。

3.6算符优先分析的移进规约流程图:

算符优先文法的分析归约过程流程图。

置初值k:=1,S[k]:=’#’

当前输入符读入a

检查是否

正常结束 S[k]属于

j:=k J:=k-1

S[j]>a? Q:=S[j]

S[j-1]属于J:=j-2

j:=j-1 S[j]

为N

k:=j+1 S[k0:=N] S[j]=’#’

S[j]=a S[j]

出错

结束

k:=k+1 S[k]:=a 出错

4.详细设计(源代码)

见附件。

5.调试结果及实验总结

在算符优先文法的程序设计过程中,程序比较复杂,光数据结构设计阶段就占据了很长的时间,几种数据结构很难确定那种能满足程序要求。一旦确定了数据结构,程序编写还是比较顺利。很快程序就可以对正确的输入做出正确的处理,不过没有查错纠错的能力,之后加入查错纠错的功能花费了很大的力气。对整个编程的过程把握的不是很好,以致调试很艰难。

本程序虽然还不能尽如人意,但本人也已经尽力把所有已知的错误作出修正,这次编程其实收获还是很大的。

首先,再一次锻炼了自己独立编程的能力。从整个要求分析,到数据据够设计和一些算法的实现都使我对程序设计有了新的设计体会。

其次,通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现方法。把学过的计算机编译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解,通过实际动手做实验,从实践上认识了操作系统是如何处理命令的,对计算机编译原理的认识更加深刻。

最后,感谢老师们的辛勤指导,和同学们的关爱,谢谢你们。

6.参考文献

《编译原理》张素琴,吕映芝著清华大学出版社

算符优先分析器设计实验报告--宁剑

编译原理实验报告 题目: 算符优先分析法分析器 学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 xxxx 2015年xx 月xx 日 算符优先分析法分析器 装 订 线

一、实验目的 1.理解自底向上优先分析,比较和自顶向下优先分析的不同。 2.理解算符优先分析的特点,体会其和简单优先分析方法的不同。 3.加深对编译器语法分析的理解。 二、实验原理 1.自底向上优先分析方法,也称移进-归约分析,粗略地说它的思想是对输入符号串自左向右进行扫描,并将输入符号逐个移入一个后进先出栈,边移入边分析,一旦栈顶符号串形成某个句型的句柄或可归约串时,就将该产生式的左部非终极符代替相应的右边文法符号串。 2.算符优先分析法的基本思想 首先确定算符(确切地说是终结符)之间的优先关系和结合性质,然后借助这种关系,比较相邻算符之间的优先级来确定句型的可归约串,并进行归约。 注意:算符优先分析过程是自下而上的归约过程,但它的可归约串未必是句柄,也就是说,算符优先分析过程不是一种规归约。 3.终结符号间优先关系的确定,用FIRSTVT和LASTVT计算。 4.最左素短语 所谓素短语是指这样一个短语,它至少含有一个终结符,并且除它自身之外不再含有其它素短语。最左素短语是指处于句型最左边的那个素短语。最左素短语是算符优先分析算法的可归约串。 5.计算得到所给文法的算符优先矩阵

6.算符优先分析的基本过程 三、实验要求 使用算符优先分析算法分析下面的文法: E’→#E# E→E+T|T T→T*F|F F→P^F|P

编译原理课程设计报告_算符优先分析法

编译原理课程设计报告_算符优先分析法 编译原理课程设计报告 选题名称: 算符优先分析法 系(院): 计算机工程学院 专业: 计算机科学与技术 班级: 姓名: 学号: 指导教师: 学年学期: 7>2012 ~ 2013 学年第 1 学期 2012年 12 月 04 日 设计任务书 课题名称算符优先分析法 设计 目的 通过一周的课程设计,对算符优先分析法有深刻的理解,达到巩固理论知识、锻炼实践能力、构建合理知识结构的目的。实验环境Windows2000以上操作系统,Visual C++6.0编译环境 任务要求 1.判断文法是否为算符优先文法,对相应文法字符串进行算符优先分析; 2.编写代码,实现算符优先文法判断和相应文法字符串的算符优先分析; 3.撰写课程设计报告; 4提交报告。工作进度计划序号起止日期工作内容 1 理论辅导,搜集资料 2 ~编写代码,上机调试

3 撰写课程设计报告 4 提交报告 指导教师(签章): 年月日 摘要: 编译原理是计算机专业重要的一门专业基础课程,内容庞大,涉及面广,知识点多。本次课程设计的目的正是基于此,力求为学生提供一个理论联系实际的机会,通过布置一定难度的课题,要求学生独立完成。我们这次课程设计的主要任务是编程实现对输入合法的算符优先文法的相应的字符串进行算符优先分析,并输出算符优先分析的过程。算符优先分析法特别有利于表达式的处理,宜于手工实现。算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的规范归约。而在整个归约过程中,起决定作用的是相继连个终结符之间的优先关系。因此,所谓算符优先分析法就是定义算符之间的某种优先关系,并借助这种关系寻找句型的最左素短语进行归约。通过实践,建立系统设计的整体思想,锻炼编写程序、调试程序的能力,学习文档编写规范,培养独立学习、吸取他人经验、探索前言知识的习惯,树立团队协作精神。同时,课程设计可以充分弥补课堂教学及普通实验中知识深度与广度有限的缺陷。 关键字:编译原理;归约;算符优先分析;最左素短语; 目录 1 课题综述 1 1.1 课题来源 1 1.2课题意义 1 1.3 预期目标 1 1.4 面对的问题 1 2 系统分析 2

实验4 算符优先分析法.

实验名称: 实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 实验容: 有上下无关文法如下: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明:优先关系矩阵的构造过程: (1) = 关系由产生式 F->(E) 知‘(’=‘)’ FIRSTVT集及LASTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F)

/F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E) (3) > 关系 E+ 则有: LASTVT(E) > + E- 则有: LASTVT(E) > - T* 则有: LASTVT(T) > * T/ 则有: LASTVT(T) > / E) 则有: LASTVT(E) > ) (4)请大家画出优先关系矩阵 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。程序的功能描述:程序由文件读入字符串(以#结束),然后进行算符优先分析,分析过程中如有错误,则终止程序并报告错误位置,最终向屏幕输出移近——规约过程。

(5)依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。算法描述如下: for 每个形如 P->X1X2…Xn的产生式 do for i =1 to n-1 do begin if Xi和Xi+1都是终结符 then Xi = Xi+1 if i<= n-2, Xi和Xi+2 是终结符, 但Xi+1 为非终结符 then Xi = Xi+2 if Xi为终结符, Xi+1为非终结符 then for FirstVT 中的每个元素 a do Xi < a if Xi为非终结符, Xi+1为终结符 then for LastVT 中的每个元素 a do a > Xi+1 end (6)构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度

编译原理 实验3 算符优先分析

编译原理实验3 算符优先分析 一、实验目的 通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法,对给定的符号串进行分析的方法。 二、实验内容 1. 给定一文法G,输出G的每个非终结符的FIRSTVT集和LASTVT集。 2. 构造算符优先表。 3. 对给定的符号串进行分析,包含符号栈,符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。 三、程序思路 在文法框内输入待判断文法产生式,格式E->a|S,注意左部和右部之间是“->”,每个产生式一行,ENTER键换行。文法结束再输入一行G->#E# 1. 先做文法判断,即可判断文法情况。 2. 若是算符优先文法,则在优先表栏显示优先表。 3. 写入要分析的句子,按回车即可。 4. 在分析过程栏,可以看到整个归约过程情况 四、实验结果 FunctorFirst.h #include #include #include #include usingnamespace std;

#define rightlength 20 #define product_num 20 // 产生式最多个数 #define num_noterminal 26 // 非终结符最多个数 #define num_terminal 26 // 终结符最多个数 struct Production { char Left; char Right[rightlength]; int num; }; struct VT { bool vt[num_noterminal][num_terminal]; }; struct Stack { char P; char a; }; class CMyDlg { public:CMyDlg(); void InputRule(); CString showLastVT(); CString showFirstVT(); CString shownoTerminal(char G[]); CString showTerminal(char g[]); CString showLeftS(char S[], int j, int k); void InitAll(); CString showSentence(CString sen, int start); CString showStack(char S[], int n); void Initarry(char arry[], int n); CString ProdtoCStr(Production prod); int selectProd(int i, int j, char S[]); void preFunctor(CString sen); void insertFirstVT(Stack S[], int&sp, char P, char a); void insertLastVT(Stack S[], int&sp, char P, char a); void ShowPreTable(); void createPreTable();

算符优先分析程序

南华大学 实验名称:算符优先分析程序 学院:计算机学院 专业班级:本2010 电气信息类03班 学号:20104030342 姓名:谢志兴 指导教师:吴取劲 日期:2012 年 6 月12 日

实验二算符优先分析程序 一、实验目的 调试并完成一个算符优先分析程序,加深对算符优先分析原理的理解。 二、实验要求 算符优先分析程序的功能: 输入:所给文法的源程序字符串、待匹配字符串。 输出:转化后的文法、每个非终结符的FIRSTVT集和LASTVT集、算符优先分析表、规约过程。 三、源程序代码: #include "stdio.h" #include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出

int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出 int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i'Z') { printf("不是算符文法!\n"); exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') {

算符优先报告及代码

实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明: 优先关系矩阵的构造过程: (1)= 关系 由产生式F->(E) 知‘(’=‘)’ FIRSTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F) /F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E)

(3) > 关系 E+ 则有:LASTVT(E) > + E- 则有:LASTVT(E) > - T* 则有:LASTVT(T) > * T/ 则有:LASTVT(T) > / E) 则有:LASTVT(E) > ) (4)优先关系矩阵 + - * / ( ) i # + > > < < < > < > - > > < < < > < > * > > > > < > < > / > > > > < > < > ( < < < < < = < ) > > > > > > i > > > > > > # < < < < < < = 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。 程序的功能描述: 程序由文件读入字符串(以#结束),然后进行算符优先分析,

算符优先文法

编译原理实验代码: 对于任意给定的文法,判断其是否是算符优先文法。 代码如下: #include #include #include #define row 50 #define col 50 #define SIZE 50 using namespace std; //两个重要结构体的定义 //FIRSTVT表或LASTVT表中一个表项(A,a)结构体的初始化typedef struct { char nonterm; //非终结符 char term; //终结符 }StackElement; //存放(A,a)的栈的初始化 typedef struct { StackElement *top; StackElement *bottom; int stacksize; }stack; //初始化(A,a)栈 void InitStack(stack &S) { S.bottom = new StackElement[SIZE]; if(!S.bottom) cout<<"存储空间分配失败!"<

//判断(A,a)栈是否为空 bool ifEmpty(stack S) { if(S.top==S.bottom) return true; //如果栈为空,则返回true else return false; //否则不为空,返回false } //插入栈顶(A,a)元素 void Insert(stack &S,StackElement e) { if(S.top-S.bottom>=S.stacksize) cout<<"栈已满,无法插入!"<nonterm=e.nonterm; S.top->term=e.term; S.top++; } } //弹出栈顶(A,a)元素 StackElement Pop(stack &S) { StackElement e; e.nonterm = '\0'; e.term = '\0'; if(S.top==S.bottom) { cout<<"栈为空,无法进行删除操作!"<nonterm; e.term=S.top->term; return e; } }

算符优先分析算法(c语言).(优选)

编译原理实验 一实验目的 设计、编制并调试一个算符优先分析算法,加深对此分析法的理解 二实验过程 先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。分析过程从头开始,并重复进行;若读来的是运算符θ2则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。 2.2 各种单词符号对应的种别码 2.3 算符优先程序的功能 完成一个交互式面向对象的算符优先分析程序,而一个交互式面向对象的算符优先分析程序基本功能是: (1)输入文法规则 (2)对文法进行转换 (3)生成每个非终结符的FirstVT和LastVT (4)生成算符优先分析表 (5)再输入文法符号 (6)生成移进规约步骤 三设计源码 算符优先分析器 #include "stdio.h"

#include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; int m,n,N; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标 void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i

编译原理-语法分析-算符优先文法分析器

编译原理实验报告 实验名称:编写语法分析分析器实验类型: 指导教师: 专业班级: 学号: 电子邮件: 实验地点: 实验成绩:

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。 2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验过程 编写算符优先分析器。要求: (a)根据算符优先分析算法,编写一个分析对象的语法分析程序。读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入: Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。 Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。 (c)有运行实例。对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。 三、实验结果 算符优先分析器: 测试数据:E->E+T|T T->T*F|F F->(E)|i 实验结果:(输入串为i+i*i+i)

四、讨论与分析 自下而上分析技术-算符优先分析法: 算符文法:一个上下无关文法G,如果没有且没有P→..QR...(P ,Q ,R属于非终结符),则G是一个算符文法。 FIRSTVT集构造 1、若有产生式P →a...或P →Qa...,则a∈FIRSTVT(P)。 2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。由优先性低于的定义和firstVT集合的定义可以得出:若存在某个产生式:…P…,则对所有:b∈firstVT(P)都有:a≦b。 构造优先关系表: 1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。 2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有

实验三算符优先分析算法设计与实现

实验三算符优先分析算法的设计与实现 (8学时) 一、实验目的 根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。 二、实验要求 1、输入文法。可以是如下算术表达式的文法(你可以根据需要适当改变): E→E+T|E-T|T T→T*F|T/F|F F→(E)|i 2、对给定表达式进行分析,输出表达式正确与否的判断。 程序输入/输出示例: 输入:1+2; 输出:正确 输入:(1+2)/3+4-(5+6/7); 输出:正确 输入:((1-2)/3+4 输出:错误 输入:1+2-3+(*4/5) 输出:错误 三、实验步骤 1、参考数据结构 char *VN=0,*VT=0;//非终结符和终结符数组 char firstvt[N][N],lastvt[N][N],table[N][N]; typedef struct //符号对(P,a) { char Vn; char Vt; } VN_VT; typedef struct //栈 { VN_VT *top; VN_VT *bollow; int size; }stack; 2、根据文法求FIRSTVT集和LASTVT集 给定一个上下文无关文法,根据算法设计一个程序,求文法中每个非终结符的FirstVT 集和LastVT 集。

算符描述如下: /*求 FirstVT 集的算法*/ PROCEDURE insert(P,a); IF not F[P,a] then begin F[P,a] = true; //(P,a)进栈 end; Procedure FirstVT; Begin for 对每个非终结符 P和终结符 a do F[P,a] = false for 对每个形如 P a…或 P→Qa…的产生式 do Insert(P,a) while stack 非空 begin 栈顶项出栈,记为(Q,a) for 对每条形如 P→Q…的产生式 do insert(P,a) end; end. 同理,可构造计算LASTVT的算法。 3、构造算符优先分析表 依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。 算法描述如下: for 每个形如 P->X1X2…X n的产生式 do for i =1 to n-1 do begin if X i和X i+1都是终结符 then X i = X i+1 if i<= n-2, X i和X i+2 是终结符, 但X i+1 为非终结符 then X i = X i+2 if X i为终结符, X i+1为非终结符 then for FirstVT 中的每个元素 a do X i < a ; if X i为非终结符, X i+1为终结符 then for LastVT 中的每个元素 a do a > X i+1 ; end 4、构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度 S[k] = ‘#’ REPEAT

编译原理_实验报告实验二__语法分析(算符优先) 2

华北水利水电学院编译原理实验报告 一、实验题目:语法分析(算符优先分析程序) (1)选择最有代表性的语法分析方法算符优先法; (2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验内容 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (4) 分析的句子为: (i+i)*i和i+i)*i 三、程序源代 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数组 char input[SIZE]; //存放输入的要进行分析的句子 char remain[SIZE]; //存放剩余串 char AnalyseStack[SIZE]; //分析栈 void analyse(); int testchar(char x); //判断字符X在算符优先关系表中的位置 void remainString(); //移进时处理剩余字符串,即去掉剩余字符串第一个字符 int k; void init()//构造算符优先关系表,并将其存入数组中 {

编译原理 六章 算符优先分析法

第六章算符优先分析法 课前索引 【课前思考】 ◇什么是自下而上语法分析的策略? ◇什么是移进-归约分析? ◇移进-归约过程和自顶向下最右推导有何关系? ◇自下而上语法分析成功的标志是什么? ◇什么是可归约串? ◇移进-归约过程的关键问题是什么? ◇如何确定可归约串? ◇如何决定什么时候移进,什么时候归约? ◇什么是算符文法?什么是算符优先文法? ◇算符优先分析是如何识别可归约串的? ◇算符优先分析法的优缺点和局限性有哪些? 【学习目标】 算符优先分析法是自下而上(自底向上)语法分析的一种,尤其适应于表达式的语法分析,由于它的算法简单直观易于理解,因此,也是学习其它自下而上语法分析的基础。通过本章学习学员应掌握: ◇对给定的文法能够判断该文法是否是算符文法 ◇对给定的算符文法能够判断该文法是否是算符优先文法 ◇对给定的算符文法能构造算符优先关系表,并能利用算符优先关系表判断该文法是否是算符优先文法。 ◇能应用算符优先分析算法对给定的输入串进行移进-归约分析,在分析的每一步能确定当前应移进还是归约,并能判断所给的输入串是否是该文法的句子。 ◇了解算符优先分析法的优缺点和实际应用中的局限性。 【学习指南】 算符优先分析法是自下而上语法分析的一种,它的算法简单、直观、易于理解,所以通常作为学习其它自下而上语法分析的基础。为学好本章内容,学员应复习有关语法分析的知识,如:什么是语言、文法、句子、句型、短语、简单短语、句柄、最右推导、规范归约基本概念。 【难重点】 ◇通过本章学习后,学员应该能知道算符文法的形式。 ◇对一个给定的算符文法能构造算符优先关系分析表,并能判别所给文法是否为算符优先文法。 ◇分清规范句型的句柄和最左素短语的区别,进而分清算符优先归约和规范归约的区别。 ◇算符优先分析的可归约串是句型的最左素短语,在分析过程中如何寻找可归约串是算符优先分析的关键问题。对一个给定的输入串能应用算符优先关系分析表给出分析(归约)步骤,并最终判断所给输入串是否为该文法的句子。 ◇深入理解算符优先分析法的优缺点和实际应用中的局限性。 【知识点】

c语言实现算符优先语法分析

#include char prog[100],zhongjian[100],shu[500]; char ch,zh; int syn,p,q,a,b,c,d; //p指向prog,q指向zhongjian int table[8][8]={ {1,1,-1,-1,-1,1,-1,1}, {1,1,-1,-1,-1,1,-1,1}, {1,1,1,1,-1,1,-1,1}, {1,1,1,1,-1,1,-1,1}, {-1,-1,-1,-1,-1,-1,-1,0}, {1,1,1,1,0,1,0,1}, {1,1,1,1,0,1,0,1}, {-1,-1,-1,-1,-1,0,-1,-1}}; //存储算符优先关系表,大于为1,小于或等于为-1,其它为0表示出错char zhan[100];//数组栈 int z,j;//z为栈顶指针,j为zhongjian数组指针 void push(char ch)//入栈 { zhan[z++]=ch; } void pop()//出栈 { z--; } void putzhan()//打印栈内字符 { for(int i=0;i

算符优先分析算法

数学与计算机学院编译原理实验报告 年级09软工学号姓名成绩 专业软件工程实验地点主楼指导教师湛燕 实验项目算符优先关系算法实验日期2012.6.6 一、实验目的和要求 设计一个算符优先分析器,理解优先分析方法的原理。 重点和难点:本实验的重点是理解优先分析方法的原理;难点是如何构造算符优先关系。 二、实验内容 使用算符优先分析算法分析下面的文法: E’→ #E# E → E+T | T T → T*F | F F → P^F | P P → (E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 三、程序设计 全局变量有一下几个: static string input;//记录输入串 char s[20];//栈 int top=-1;//栈顶指针 有三个函数: int analyze(string input);//分析输入的串是否符合标准 void process();//进行归约的函数 int main() input是一个全局变量,记录输入串,用analyze(input)分析输入的是不是符合标准的字符串,(例如“i+i*i^(i+i)”)如果不符合标准,提示用户重新输入。 进行归约的函数主要思想是:先构造优先关系矩阵,有“<”,“>”,“=”和空格四种关系。Char a 记录栈中最高位的终结符,如果栈中是#E+E,则 a 的赋

值是“+”,如果形如“#E+”或“#E+i”则a 赋值“+”或“i”。charnowchar 记录当前的字符。a 与 nowchar 按照算符优先关系矩阵找出优先关系。如果优先关系是“<”,则进行移进;如果优先关系是“>”,则进行归约;如果是“=”,则去掉括号或分析成功。 五、代码和截图 自己编写代码如下: #include #include using namespace std; static string input;//输入串 char s[20];//栈 int top=-1;//栈顶指针 char VT[7]={'+','*','^','i','(',')','#'};//终结符 static char matrix[7][7]={ '>','<','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','>',' ',' ','>','>', '<','<','<','<','<','=',' ', '>','>','>',' ',' ','>','>', '<','<','<','<','<',' ','='}; //优先关系矩阵,不存在优先关系时为空格 int analyze(string input);//分析输入的串是否符合标准 void process();//规约 int main() { //cout<<"输入一个符号串!"<>input; if(analyze(input)==0) flag=1; else flag=0; } cout<<"***********************************************************"<<

算符优先分析法课程设计报告

淮阴工学院 编译原理课程设计报告 选题名称:算符优先分析法 系(院):计算机工程学院 专业:计算机科学与技术 班级:计算机1075 姓名:学号: 指导教师: 学年学期:2009 ~ 2010 学年第 2 学期2010 年 5 月17 日

设计任务书 指导教师(签章): 年月日

摘要: 编译原理是计算机系统的基本组成部分之一,而且多数据计算机系统都配有不止一个高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序。从功能上看,一个编译程序就是一个语言翻译程序。算符优先分析法是一种简单直观、广为使用的自下而上分析法。这种方法特别有利于表达式分析,宜于手工实现。算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的最左归约。也就是说,算符优先分析法不是一种规范归约法。所谓算符优先分析就是定义算符之间(确切地说,终结符之间)的某种优先关系,借助于这种优先关系寻找“可归约串”和进行归约。 关键词:编译原理;归约;算法;算符优先;编译

目录 1需求分析 (1) 2 概要设计 (1) 2.1算符优先分析法的思想及其原理 (1) 2.2算符优先分析算法 (4) 2.3 构建算符优先关系表 (6) 2.4 出错处理 (7) 3 详细设计 (7) 3.1 程序流程图 (7) 3.2 构建算符优先关系表 (8) 3.3 进栈优先函数 (8) 3.4 算符优先规约函数 (10) 3.5 弹出窗体 (12) 4 程序运行、调试及操作说明 (12) 总结 (15) 致谢 (16) 参考文献 (17)

1需求分析 本次课程设计的题目是算符优先分析法。算符优先分析法是一种简单直观、特别方便于表达式分析,易于手式实现的方法。算符优先法只考虑算符(广义为终结符号)之间的优先关系,它是一种自底向上的归约过程,但这种归约未必严格按照句柄归约。它是一种不规范归约法。 根据已知文法: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i(E)|i|d(其中d表示0-9的数字,i表示字母,大小写均包括) 根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确 (1)可以使用任何语言来完成,例如:Java、C++。 (2)构造此文法的分析过程 (3)输入测试字符串,输出测试结果 给出关键类类图、整个应用程序的结构描述文档、关键模块流程图、较详细的接口文档、所有源代码。对应用程序进行测试,对测试结果进行分析研究,进而对应用程序进行改进,对关键算法进行尽可能的优化,最终得到一个在windows运行的可以根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确,输入测试字符串,输出测试结果的完整应用程序。 2 概要设计 2.1算符优先分析法的思想及其原理 算符优先分析算法算法原理: (1)初始化栈:k=1; S[k]=‘#’; (2)依次从输入串中读入符号a: ①当前单词若为标识符,则a值为i,若为常数则a值为d; 其它a直接取单词值。 ②若a大于等于栈顶第一个终结符的优先级,则a进栈; ③若a小于栈顶第一个终结符的优先级,则重复做:

编译原理算符优先算法语法分析实验报告

数学与计算机学院编译原理实验报告 年级专业学号姓名成绩 实验题目算符优先分析法分析器的设计实验日期 一、实验目的: 设计一个算符优先分析器,理解优先分析方法的原理。 二、实验要求: 设计一个算符优先分析器 三、实验内容: 使用算符优先分析算法分析下面的文法: E’→#E# E →E+T | T T →T*F | F F →P^F | P P →(E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 四、实验结果及主要代码: 1.主要代码 void operatorp()

{ char s[100]; char a,Q; int k,j,i,l; string input,temp; cin>>input; cout<<"步骤"<<'\t'<<"栈"<<'\t'<<"优先关系"<<'\t'<<"当前符号"<<'\t'<<"剩余输入串"<<'\t'<<"移进或归约"<') { cout<<'('<

for(l=1;l'<<'\t'<

二语法分析程序(算符优先分析法)

实验二语法分析程序(算符优先分析法) 一、实验目的 通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。 二、实验要求 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)实验要求独立完成,不允许有抄袭现象。 (4)实验完成后,要求提交源程序和上交实验报告(包括源程序清单)。 (附:实验报告格式) 三、实验内容 (1)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (2)分析的句子为: (i+i)*i和i+i)*i (1)分析 1,判断为算符优先文法: 文法没有A->…BC…且BC均为非终结符,因此它为OG文法 文法没有同时存在①A->…ab…或A->….aBb…. ②A->…aB…且B=>b….或B=>Cb…. ③A->…Bb….且B=>…a或B=>…aC 文法为算符优先文法 2,求FirstVT集和LastVT集 FirstVT(E)={+, * , ( , i } LastVT(E)= {+, - , * , / , ) , i } FirstVT(T)={* , ( , i } LastVT(T)= {* , / , ( , i } FirstVT(F)={ ( , i } LastVT(F)={ ) , i } FirstVT(E’)={ #} LastVT(E’)={ #} 3,根据FirstVT和LastVT集构造算符优先表

算符优先语法分析设计原理与实现技术 实验报告 及源代码 北京交通大学

算符优先语法分析设计原理与实现技术 XXX 1028XXX 计科1XXX班 功能描述 能够有效识别以下算符优先文法 E → E+T | E-T T → T*F | T/F | F F → (E) | i 所描述算术表达式. 主要数据结构描述 程序结构描述 设计方法 1.由文法构造算符优先矩阵

2.根据算符优先矩阵算数表达式的词法分析结果进行语法分析,分析算法为: 数据结构: 符号栈S --- 存放所有读进的符号(计数i) K --- 符号栈使用深度 a --- 工作单元 R, Q --- 变量 分析算法:先找最左素短语的尾部(>) 再找最左素短语的头部(<) 以分析表达式i+i*i为例,详细过程如下:

函数定义

?函数调用关系 ?程序执行图

程序测试 测试用例一: (a+b*c)+d+e+a*c/b 首先调用实验一的词法分析程序,得到如下分析结果: (19, '(') (12, 'a') (14, '+') (12, 'b') (16, '*') (12, 'c') (20, ')') (14, '+') (12, 'd') (14, '+') (12, 'e') (14, '+') (12, 'a') (16, '*') (12, 'c') (17, '/') (12, 'b') 在以此分析结果作为本程序实验结果的输入,得到如下分析结果:

该结果显示了详细的分析过程,且表明该表达式是一个符合该文法的表达式 测试用例二: (a+b*c)+d*-a*c+(a+b 同样调用实验一的词法分析程序,得到如下结果: (19, '(') (12, 'a') (14, '+') (12, 'b') (16, '*') (12, 'c') (20, ')')

相关文档
最新文档