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

合集下载

编译原理-第4章 语法分析--习题答案

编译原理-第4章 语法分析--习题答案

第4章语法分析习题答案1.判断(1)由于递归下降分析法比较简单,因此它要求文法不必是LL(1)文法。

(× )LL(1)文法。

(× )(3)任何LL(1)文法都是无二义性的。

(√)(4)存在一种算法,能判定任何上下文无关文法是否是LL(1) 文法。

(√)(× )(6)每一个SLR(1)文法都是LR(1)文法。

(√)(7)任何一个LR(1)文法,反之亦然。

(× )(8)由于LALR是在LR(1)基础上的改进方法,所以LALR(× )(9)所有LR分析器的总控程序都是一样的,只是分析表各有不同。

(√)(10)算符优先分析法很难完全避免将错误的句子得到正确的归约。

(√)2.文法G[E]:E→E+T|TT→T*F|FF→(E)|i试给出句型(E+F)*i的短语、简单短语、句柄和最左素短语。

答案:画出语法树,得到:短语: (E+F)*i ,(E+F) ,E+F ,F ,i简单短语: F ,i句柄: F最左素短语: E+F3.文法G[S]:S→SdT | TT→T<G | GG→(S) | a试给出句型(SdG)<a的短语、简单短语、句柄和最左素短语。

答案:画出语法树,得到:短语:(SdG)<a 、(SdG) 、SdG 、G 、a简单(直接)短语:G 、a句柄:G最左素短语:SdG4.对文法G[S]提取公共左因子进行改写,判断改写后的文法是否为LL(1)文法。

S→if E then S else SS→if E then SS→otherE→b答案:提取公共左因子;文法改写为:S→if E then S S'|otherS'→else S|E→bLL(1)文法判定:① 文法无左递归② First(S)={if,other}, First(S')={else, }First(E)={b}Follow(S)= Follow(S')={else,#}Follow(E)={then}First(if E then S S')∩First(other)=First(else S)∩First( )=③First(S')∩Follow(S')={else}不为空集故此文法不是LL(1)文法。

西安交通大学18年9月课程考试《编译原理》作业考核试题

西安交通大学18年9月课程考试《编译原理》作业考核试题

(单选题) 1: 编译过程中,语法分析器的任务就是( )A: 分析单词是怎样构成的B: 分析单词串是如何构成语句和说明的C: 分析语句和说明是如何构成程序的D: 分析程序的结构正确答案:(单选题) 2: 算符优先分析法每次都是对________进行归约:A: 句柄B: 最左素短语C: 素短语D: 简单短语正确答案:(单选题) 3: 文法开始符号的所有________作为属性计算前的初始值。

A: 综合属性B: 继承属性C: 继承属性和综合属性D: 都不是正确答案:(单选题) 4: 乔姆斯基(Chomsky)把文法分为四种类型,即0型.1型.2型.3型。

其中3型文法是( ) A: 非限制文法B: 正则文法C: 上下文有关文法D: 上下文无关文法正确答案:(单选题) 5: Pascal中过程说明的局部变量地址分配在()。

A: 调用者的数据区中B: 被调用者的数据区中C: 主程序的数据区中D: 公共数据区中正确答案:(单选题) 6: 不是编译程序的组成部分。

A: 词法分析程序B: 代码生成程序C: 设备管理程序D: 语法分析程序正确答案:(单选题) 7: 教材介绍了三种符号表的构造和处理方法,其中________中常把符号表组织成二叉树形式。

A: 线性组织;B: 排序组织和二分法;C: 杂凑(散列)组织;D: 非线性组织正确答案:(单选题) 8: 数组的内情向量中肯定不含数组的()信息A: 维数B: 类型C: 各维的上下界D: 各维的界差正确答案:(单选题) 9: 在LR(0)的ACTION子表中,如果某一行中存在标记“rj”的栏,则( )。

A: 该行必定填满rjB: 该行未填满rjC: 其他行也有rj正确答案:(单选题) 10: 如果一个编译程序能产生不同于其宿主机的机器代码,则称它为( )A: 诊断编译程序B: 优化编译程序C: 交叉编译程序D: 可变目标编译程序正确答案:(单选题) 11: 在使用高级语言编程时,首先可通过编译程序发现源程序的全部和部分( )错误。

编译原理选择填空

编译原理选择填空

一.填空题1..已知文法G[E]:E →E+T|TT →T*F|FF →(E)|a该文法终结符集合V T = {+,*,(,),a} ,文法非终结符集合V N = {E,T,F} ,该 文法在乔姆斯基文法分类中属于 2型 文法。

2.给出下列文法的适合自上而下翻译的语义动作,使得当输入是aabb 时其输出串是12020。

(1)A →aB {printf('0');}(2)A →c {printf('1');}(3)B →Ab {printf('2');}二.选择题1..为了使编译程序能对程序设计语言进行正确的翻译,必须采用 C 方法定义程序设计语言。

A.非形式化B.自然语言猫鼠问题C.形式化D.自然语言和符号体系相结合2.设X 是符号串,符号串的幂运算x0= CA.1B.xC.εD.∅3.若有源程序是高级语言编写的程序,目标程序是 C ,则称它为编译程序。

A.汇编语言程序或高级语B. 高级语言程序或机器语言程序C.汇编语言程序或机器语言程序D.连接程序或运行程序4.编译程序对 A 程序进行翻译。

A.高级语言B.机器语言C.自然语言D.汇编语言5.编译过程中,语法分析阶段的任务是 B .A.语言识别B.识别语言单词C.识别语句D.识别程序6.字母表示的元素可以是 DA.字母B. 字母和数字C. 数字D.字母 数字和其他符号7.在规则(产生式)中,符号“→”(“::=”)表示 DA.恒等式B.等于C.取决于D.自定义8.在规则(产生式)中,符号“|”表示 BA.与B. 或C. 非D.引导开关参数9.设有文法G [S]=({S,B},{b},{S →bB|b,B →bS},S),改文法所描述的语言是 CA. L(G[S]) ={b n |n >=n 2|n >= C. L(G[S]) ={b 12+n |n >=12+n |n >=10.一个句型最左边的 C 称为该句型的句柄。

编译原理基础

编译原理基础

第一章引论主要内容:编译原理的基本概念、定义、编译原理的应用发展和现状。

重点:编译程序工作的基本构成及各阶段的基本任务,具体要求:理解什么是编译程序,了解各编译程序的基本构成及各阶段的基本任务,编译程序总框,了解编译程序生成过程和构造工具。

一、名词解释1、编译程序:能够把用各种高级语言书写的源程序翻译成某种等价的目标程序的翻译程序。

2、遍:指编译程序对源程序或中间代码程序从头到尾扫描一次。

3、静态分配:在编译时就能够安排好目标程序运行时的全部数据空间。

二、问答题1、简述编译程序的结构?答:编译程序包括词法分析、语法分析、中间代码生成、优化,目标代码产生五个阶段,上述各阶段中还要进行表格处理和出错处理的工作。

2、编译程序可分成哪几个阶段?它们之间的关系如何?答:编译程序可分为五个阶段:词法分析、语法分析、中间代码生成、优化、目标代码生成。

上述五个阶段之间每个阶段输出为作下一阶段的输入,第一阶段的输入是源程序,最后阶段的输出是目标代码程序。

注意:编译过程中,阶段的划分和遍的划分不一定相同第二章高级程序语言概述主要内容:程序语言定义、初等数据类型、数据结构、表达式、语句、高级语言的一般特征及程序语言的语法描述。

重点:程序语言定义具体要求:理解程序语言的词法、语法和语义等概念;熟悉高级程序语言的一般结构和主要共同特征。

一、填空题1、程序语言是由(语法)和(语义)两方面定义的。

2、一个名字的属性包括(类型)和(作用域)3、目标代码一般有三种形式:能够立即执行的机器语言代码,(待装配的机器语言模块)和(汇编语言代码)4、语义:定义一个程序的意义的(一组规则)5、2型文法又称为(上下文无关文法),3型文法又为(正规文法)二、是非题1、虽然名字都是用标识符表示的,但名字和标识符有着本质的区别(对)2、各种名字都是用标识符表示的,所以名字和标识没有本质的区别(错)3、数组元素的地址计算与数组的存储方式没有关系(错)4、语法是指程序的含义(错)5、因名字都是用标识符表示的,故名字与标识符没有区别(错)第三章词法分析主要内容:词法分析器的任务、词法分析器的设计、正规表达式与有限自动机、词法分析器的自动生成。

编译原理实验 词法分析&语法分析程序

编译原理实验 词法分析&语法分析程序

编译原理实验词法分析程序实验一:词法分析程序1、实验目的从左至右逐个字符的对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号形式的中间程序。

2、实验内容表C语言子集的单词符号及内码值单词符号种别编码助记符内码值while 1 while --if 2 if --else 3 else --switch 4 switch --case 5 case --标识符 6 id id在符号表中的位置常数7 num num在常数表中的位置+ 8 + --- 9 - --* 10 * --<= 11 relop LE< 11 relop LT== 11 relop LQ= 12 = --; 13 ; --输入源程序如下if a==1 a=a+1;else a=a+2;输出对应的单词符号形式的中间程序3、实验过程实验上机程序如下:#include "stdio.h"#include "string.h"int i,j,k;char s ,a[20],token[20];int letter(){if((s>=97)&&(s<=122))return 1;else return 0;}int Digit(){if((s>=48)&&(s<=57))return 1;else return 0;}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(){if(strcmp(token, "while")==0)return 1;else if(strcmp(token, "if")==0)return 2;else if(strcmp(token,"else")==0)return 3;else if(strcmp(token,"switch")==0)return 4;else if(strcmp(token,"case")==0)return 5;else return 0;}void main(){printf("please input you source program,end('#'):\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;memset(token,0,sizeof(char)*10);j=0;get();while(s!='#'){if(s==' '||s==10||s==13)get();else{switch(s){case'a':case'b':case'c':case'd':case'e':case'f':case'g':case'h':case'i':case'j':case'k':case'l':case'm':case'n':case'o':case'p':case'q':case'r':case's':case't':case'u':case'v':case'w':case'x':case'y':case'z':while(Digit()||letter()){token[j]=s;j=j+1;get();}retract();k=lookup();if(k==0)printf("(6,%s)\n",token); elseprintf("(%d,null)\n",k); break;case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':while(Digit()){token[j]=s;j=j+1;get();}retract();printf("(%d,%s)\n",7,token); break;case'+':printf("(+,null)\n"); break;case'-':printf("(-,null)\n"); break;case'*':printf("(*,null)\n"); break;case'<':get();if(s=='=')printf("(relop,LE)\n"); else{retract();printf("(relop,LT)\n");}break;case'=':get();if(s=='=')printf("(relop,EQ)\n"); else{retract();printf("(=,null)\n");}break;case';':printf("(;,null)\n"); break;default:printf("(%c,error)\n",s);break;}memset(token,0,sizeof(char)*10);j=0;get();}}}4、实验结果实验结果分析:if是关键字,对应种别编码为2,输出(2,null)a是标识符,对应种别编码为6,值为a,输出(6,a)==的助记符是relop,内码值为LE,输出(relop,LE)1是常数,对应种别编码为7,值为1,输出(7,1)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)1是常数,对应种别编码为7,值为1,输出(7,1);是语句结束符号,直接输出(;,null)else是关键字,对应种别编码为3,输出(3,null)a是标识符,对应种别编码为6,值为a,输出(6,a)=是赋值符号,直接输出,(=,null)a是标识符,对应种别编码为6,值为a,输出(6,a)+是运算符,直接输出(=,null)2是常数,对应种别编码为7,值为2,输出(7,2);是语句结束符号,直接输出(;,null)#是输入结束标志编译原理实验语法分析程序实验二:语法分析程序1、实验目的:将单词组成各类语法单位,讨论给类语法的形成规则,判断源程序是否符合语法规则3、实验内容:给定文法:G[E]:E→E+E|E-E|E*E|E/E|(E)E→0|1|2|3|4|5|6|7|8|9首先把G[E]构造为算符优先文法,即:G’[E]:E→E+T|TT→T-F|FF→F*G|GG→G/H|HH→(E)|i得到优先关系表如下:+ - * / i ( ) # + ·><·<·<·<·<··>·> - ·>·><·<·<·<··>·> * ·>·>·><·<·<··>·> / ·>·>·>·><·<··>·>i ·>·>·>·>·>·>( <·<·<·<·<·<·=) ·>·>·>·>·>·> # <·<·<·<·<·<·=构造出优先函数+ - * / i ( ) #f 6 8 10 12 12 2 12 2g 5 7 9 11 13 13 2 2要求输入算术表达式:(1+2)*3+2*(1+2)-4/2输出其对应的语法分析结果4、实验过程:上机程序如下:#include "stdio.h"#include "string.h"char a[20],optr[10],s,op;int i,j,k,opnd[10],x1,x2,x3;int operand(char s){if((s>=48)&&(s<=57))return 1;else return 0;}int f(char s){switch(s){case'+':return 6;case'-':return 8;case'*':return 10;case'/':return 12;case'(':return 2;case')':return 12;case'#':return 2;default:printf("error");}}int g(char s){switch(s){case'+':return 5;case'-':return 7;case'*':return 9;case'/':return 11;case'(':return 13;case')':return 2;case'#':return 2;default:printf("error");}}void get(){s=a[i];i=i+1;}void main(){printf("请输入算数表达式,并以‘#’结束:\n");i=0;do{scanf("%c",&a[i]);i++;}while(a[i-1]!='#');i=0;j=0;k=0;optr[j]='#';get();while((optr[j]!='#')||(s!='#')){if(operand(s)){opnd[k]=s-48;k=k+1;get();}else if(f(optr[j])<g(s)){j=j+1;optr[j]=s;get();}else if(f(optr[j])==g(s)){if(optr[j]=='('&&s==')'){j=j-1;get();}else if(optr[j]=='('&&s=='#'){printf("error\n");break;}else if(optr[j]=='#'&&s==')'){printf("error\n");break;}}else if(f(optr[j])>g(s)){op=optr[j];j=j-1;x2=opnd[k-1];x1=opnd[k-2];k=k-2;switch(op){case'+':x3=x1+x2;break;case'-':x3=x1-x2;break;case'*':x3=x1*x2;break;case'/':x3=x1/x2;break;}opnd[k]=x3;k=k+1;printf("(%c,%d,%d,%d)\n",op,x1,x2,x3);}else{printf("error\n");break;}}if(j!=0||k!=1)printf("error\n");}5、实验结果:实验结果分析:(1+2)*3+2*(1+2)-4/2#因为‘)’优先级大于‘*’,先计算1+2=3,并输出(+,1,2,3)原式变为:3*3+2*(1+2)-4/2#因为‘*’优先级大于‘+’,先计算3*3=9,并输出(*,3,3,9)原式变为:9+2*(1+2)-4/2#因为‘)’优先级大于‘-’,先计算1+2=3,并输出(+,1,2,3)原式变为:9+2*3-4/2#因为‘*’优先级大于‘-’,先计算2*3=6,并输出(*,2,3,6)原式变为:9+6-4/2#因为‘/’优先级大于‘#’,先计算4/2=2,并输出(/,4,2,2)原式变为:9+6-2#因为‘-’优先级大于‘#’,先计算6-2=4,并输出(-,6,2,4)原式变为:9+4#因为‘+’优先级大于‘#’,计算9+4=13,并输出(+,9,4,13)原式变为13#优先级等于#,跳出while循环,运算结束!。

编译原理实验报告1

编译原理实验报告1

编译原理实验报告某某:班级:学号:自评:中实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。

例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。

输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。

输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。

例如,所输出的每一单词均按形如(CLASS,V ALUE)的二元式编码。

对于变量和常数,CLASS字段为相应的类别码;V ALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。

对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,V ALUE字段则为“空”。

另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。

三、实现方法与环境词法分析是编译程序的第一个处理阶段,本次试验用手工的方式(C语言)构造词法分析程序。

根据文法和状态转换图直接编写词法分析程序。

四、基本实验题目1)题目1:试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。

语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。

参考实现方法简述如下。

单词的分类:构造上述语言中的各类单词符号及其分类码表。

表I 语言中的各类单词符号及其分类码表+ 15 PL- 16 MI* 17 MU/ 18 DI处理过程:在一个程序设计语言中,一般都含有若干类单词符号,为此首先为每类单词建立一X状态转换图,然后将这些状态转换图合并成一X统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

编译原理算符优先分析程序设计

编译原理算符优先分析程序设计

编译原理算符优先分析程序设计算符优先分析(Operator Precedence Parsing)是一种基于文法的自下而上的语法分析方法,用于构造一个将输入串转化为语法分析树的分析器。

它通过根据每一个终结符号和非终结符号之间的优先级关系,来判断是否可以进行规约操作。

算符优先分析的基本思想是,为每一个终结符和非终结符分配一个优先级,然后根据这些优先级来决定如何进行规约操作。

一般来说,基本的终结符都有一个固定的优先级,而非终结符的优先级则由其所对应的产生式右部中的终结符优先级来决定。

算符优先分析的核心在于构造一个优先级关系表,用于指导规约过程。

这个表一般由产生式构造得到,每个终结符和非终结符对应一行和一列,表中的每个元素表示两个符号之间的优先级关系。

算符优先分析的步骤如下:1.根据给定的文法,确定每个终结符号和非终结符号的优先级。

2.构造优先关系表,填入每两个符号之间的优先关系。

3.初始化分析栈和输入栈,将栈底符号设为文法开始符号,并将输入串入栈。

4.重复以下步骤,直到分析完成:a.查找栈顶和当前输入符号之间的优先关系。

b.如果栈顶符号的优先级较低或相等,则进行规约操作,将栈顶的符号替换为相应的非终结符号。

c.如果栈顶符号的优先级较高,则进行移进操作,将当前输入符号移入栈中。

d.如果找不到优先关系,则出现错误,分析失败。

算符优先分析的优点是简单明了,且规约过程中不需要回溯,效率较高。

然而,由于它只适用于算符优先文法,而不是所有的上下文无关文法,因此适用范围有限。

在实际编程中,我们可以通过编写算符优先分析程序来对给定的文法进行分析。

程序可以根据文法自动生成优先关系表,然后根据输入串和优先关系表进行分析。

下面是一个简单的算符优先分析程序设计:```python#定义终结符和非终结符的优先级priority = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0, ')': 0}#构造优先关系表def build_table(:table = {}for symbol1 in priority.keys(:row = {}for symbol2 in priority.keys(:if symbol1 == '(' and symbol2 == ')':row[symbol2] = 'r'elif symbol1 == ')' and symbol2 == '(':row[symbol2] = 'e'elif priority[symbol1] > priority[symbol2]:row[symbol2] = '>'elif priority[symbol1] < priority[symbol2]:row[symbol2] = '<'else:row[symbol2] = 'e'table[symbol1] = rowreturn table#算符优先分析程序def operator_precedence_parsing(table, input_str): input_stack = list(input_str)input_stack.append('#')analysis_stack = ['#']while len(analysis_stack) > 0:top = analysis_stack[-1]if top in priority.keys( and input_stack[0] in priority.keys(:relation = table[top][input_stack[0]]if relation == '>':analysis_stack.popprint('Reduce by', top)elif relation == '<':analysis_stack.append(input_stack.pop(0)) print('Shift', analysis_stack[-1])elif relation == 'e':analysis_stack.popinput_stack.pop(0)print('Error')returnelse:print('Error')returnelse:print('Error')return#测试代码table = build_tableinput_str = input('Please enter a valid expression: ')operator_precedence_parsing(table, input_str)```以上是一个简单的算符优先分析程序设计,实现了根据输入串和优先关系表进行分析的过程。

《编译原理》考试试题及答案

《编译原理》考试试题及答案

《编译原理》考试试题及答案(附录)一、判断题:1.一个上下文无关文法的开始符,可以是终结符或非终结符。

( X )2.一个句型的直接短语是唯一的。

( X )3.已经证明文法的二义性是可判定的。

( X )4.每个基本块可用一个DAG表示。

(√)5.每个过程的活动记录的体积在编译时可静态确定。

(√)6.2型文法一定是3型文法。

( x )7.一个句型一定句子。

( X )8.算符优先分析法每次都是对句柄进行归约。

(应是最左素短语) ( X )9.采用三元式实现三地址代码时,不利于对中间代码进行优化。

(√)10.编译过程中,语法分析器的任务是分析单词是怎样构成的。

( x )11.一个优先表一定存在相应的优先函数。

( x )12.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。

( )13.递归下降分析法是一种自下而上分析法。

( )14.并不是每个文法都能改写成LL(1)文法。

( )15.每个基本块只有一个入口和一个出口。

( )16.一个LL(1)文法一定是无二义的。

( )17.逆波兰法表示的表达试亦称前缀式。

( )18.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。

( )19.正规文法产生的语言都可以用上下文无关文法来描述。

( )20.一个优先表一定存在相应的优先函数。

( )21.3型文法一定是2型文法。

( )22.如果一个文法存在某个句子对应两棵不同的语法树,则文法是二义性的。

( )二、填空题:1.( 最右推导 )称为规范推导。

2.编译过程可分为(词法分析),(语法分析),(语义分析和中间代码生成),(代码优化)和(目标代码生成)五个阶段。

3.如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是()。

4.从功能上说,程序语言的语句大体可分为()语句和()语句两大类。

5.语法分析器的输入是(),其输出是()。

6.扫描器的任务是从()中识别出一个个()。

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

实验二语法分析程序(算符优先分析法)一、实验目的通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。

二、实验要求(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)实验要求独立完成,不允许有抄袭现象。

(4)实验完成后,要求提交源程序和上交实验报告(包括源程序清单)。

(附:实验报告格式)三、实验内容(1)给定表达式文法为:G(E’): E’→#E#E→E+T | TT→T*F |FF→(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集构造算符优先表(2)程序参考源码#include <iostream>#include <string>using namespace std;#define max 100char b[max]; //存放终结符char precedence[max][max];//存放优先关系struct opg{int step;string stack;char privior;char presentsignal;string leftstr;string explain;}temp;//存放一步int search(char ch){int i=0;while(ch!=b[i])i++;return i;}void anolyze(){//struct opg temp;temp.step=0;char s[max],c,a;string sentence;int m=0,q=0,flag=0,i=0; //flag标记着当前读到那个字符cout<<"输入要分析的句子:";cin>>sentence;int k=0;//s[k]='#';s[k]=sentence[flag++];s[k+1]='\0';int j=k;a=sentence[flag++]; //读入一个给a;temp.leftstr=sentence;while(temp.leftstr[i]!=a){ //while循环获得第一次的剩余字符串temp.leftstr[i]=' ';i++;}temp.leftstr[i]=' ';//把已经读过的字符赋空则就找到了剩余的串cout<<"步骤 "<<" 栈 "<<" 优先关系 "<<"当前符号"<<" 剩余字符串 "<<"移进或归约"<<endl;while(!(s[j]=='#'&&a=='#')){//栈顶和当前字符都是#if(!isupper(s[k]))j=k;//s[k]是终结符else j=k-1;m=search(s[j]);//获取要比较终结符所在行号q=search(a);//获取要比较终结符所在列号temp.step=temp.step+1;temp.stack=s;temp.privior=precedence[m][q];temp.presentsignal=a;cout<<temp.step<<'\t'<<temp.stack<<'\t'<<temp.privior<<'\t'<<temp.presentsignal <<temp.leftstr<<'\t';if(precedence[m][q]=='<'||precedence[m][q]=='=')//优先关系为<或={temp.explain="移进";cout<<temp.explain<<endl;k=k+1;s[k]=a;s[k+1]='\0';//赋上字符串的终结标准,相当于一个栈a=sentence[flag++];//读入一个给a;temp.leftstr[++i]=' ';//每读入一个句子中一个字符把此位置赋空,作为剩余串}else if(precedence[m][q]=='>')//优先关系为>{temp.explain="归约";cout<<temp.explain<<endl;//cout<<s[j]<<s[k]<<a;do{c=s[j];if (!isupper(s[j-1]))//s[j-1]是终结符(即不是大写字母)j=j-1;elsej=j-2;m=search(s[j]);q=search(c);}while(precedence[m][q]=='=');k=j+1;s[k]='N';s[k+1]='\0';}//出错else {cout<<"不是该文法可以识别的句子";break;}//出错}cout<<++temp.step<<'\t'<<"#N"<<'\t'<<"="<<'\t'<<"#"<<' '<<'\t'<<"接受";}void main(){int n,i,j; //终结符的个数cout<<"输入终结符的个数:";cin>>n;cout<<endl;cout<<n<<'\n';cout<<"输入终结符";for(i=0;i<n;i++)cin>>b[i];b[n]='#';for(i=0;i<n+1;i++)for(j=0;j<n+1;j++){cout<<b[i]<<"与"<<b[j]<<"的优先关系:";cin>>precedence[i][j];while(!(precedence[i][j]=='>'||precedence[i][j]=='<'||precedence[i][j]=='=' ||precedence[i][j]=='/')){ cout<<"没有此优先关系,请重新输入";cin>>precedence[i][j];}}cout<<"算术优先关系表\n"<<"===============================================\n";for(i=0;i<n+2;i++)for(j=0;j<n+2;j++){if(i==0){if(j==0)cout<<' ';else cout<<b[j-1]<<' ';}else {if(j==0)cout<<b[i-1];else cout<<precedence[i-1][j-1]<<' ';}if(j==n+1)cout<<endl;}cout<<"===============================================\n";anolyze();}。

相关文档
最新文档