算符优先分析法-思路方法在这里

为了方便,记录一下,因为本人也正在学编译原理,以便后续的学习复习,以下是自己整理的。

编写一个算符优先分析程序,能实现以下功能:

1.输入文法,判断是否为算符文法;
2.构造并输出该文法的每个非终结符的 FIRSTVT 集和 LASTVT 集;
3.构造并输出算符优先分析表,判断是否为算符优先文法,若不是提示无法进行分析;
4.任意输入一个输入串,可得到成功的分析或错误的提示,输出其分析过程或打印语法 分析树。

实验运行结果在这里插入图片描述
算符优先文法的特点:
我们构造了算符优先语法分析器,就可以忽略原来的文法,栈中的非终结符仅仅作为与这些非终结符相关的属性的占位符
难以处理像减号这样有不同优先级的符号
由于分析的语言的文法和算符优先语法分析器本身的关系不是很紧密,所以不能肯定语法分析器接受的就是所期望的语言

什么是算符文法?应满足什么条件
算符文法
设有一个文法G,若G中有形如U->Vw的产生式,即它的任意产生式的右部都不含两个相继的非终结符,则称G为算数文法,或称为OG文法。

算符优先文法
(1)是底向上分析法中的一种,虽然他不是规范规约,但具有分析速度快的特点,是和表达式分析。
(2)算符优先分析法就是仿照算数四则运算的运算过程。定义任意两个相继出现的终结符号a和b之间的优先关系,一点确定了这种优先关系,就可以用他确定“句柄”进行规约。
概述
   算符优先分析法(Operator Precedence Parse)是仿效四则运算的计算过程而构造的一种语法分析方法。算符优先分析法的关键是比较两个相继出现的终结符的优先级而决定应采取的动作。

   优点:简单,有效,适合表达式的分析。

   缺点:只适合于算符优先文法,是一个不大的文法类。
求FIRSTVT集和LASTVT集
FIRSTVT集

定义:FIRSTVT§={a|P=>a…,或P=>Qa…,a属于VT,Q 属于VN}

求法:

若P→a…或P→Qa…, 则a属于FIRSTVT(P);

若P→Q…, 则FIRSTVT(Q)含于FIRSTVT(P);

直至FIRSTVT(P)不再增大。
LASTVT集

定义:LASTVT§={a|P=>…a,或P=>…aQ,a含于VT,Q 含于VN}

求法:

若P→...a或P→…aQ, 则a属于LASTVT(P);

若P→...Q, 则LASTVT(Q)含于LASTVT(P);

直至LASTVT(P)不再增大。
构造算符优先关系表

以以下文法为例:

    E→E+T|T

    T→T*F|F 
    
    F→(E)|i
终结符之间的优先关系

对算符文法G, a,b属于VT 定义

(1)a=b: G中有P→. . .ab. . .或P→. . .aQb. . .

(2)a<b: G中有P→. . .aQ. . .且Q=>b…或Q=>Rb…

(3)a>b: G中有P→. . .Qb. . . 且Q=>. …a或Q=>…aR

算符优先关系表的构造

(1) 在文法中添加E→#E#。

(2) 求出FIRSTVT和LASTVT集

在这里插入图片描述

(3) 找出所有终结符,并画出关系表的结构

在这里插入图片描述

(4) 从文法中找出形为aQb(终结符+非终结符+终结符)和ab(终结符+终结符)的部分,本例中为(E)和#E#,然后在(和)与#和#相应的表格填=。

在这里插入图片描述

(5) 从文法中找出形为aQ(终结符+非终结符)的部分,a与Q的FIRSTVT集合中每一个元素在表格中的交叉点填小于号。

i.找出形为aQ的部分

在这里插入图片描述

ii.填小于号(终结符为竖排,非终结符中的元素为横排,以横排为基准填符号)

在这里插入图片描述

(6) 从文法中找出形为Qa(非终结符+终结符)的部分, Q的LASTVT集合中每一个元素与a在表格中的交叉点填大于号。
i.找出形如Qa的部分

在这里插入图片描述
ii.填大于号(非终结符中的元素为横排,终结符中的元素为竖排,以竖排为基准填符号)
在这里插入图片描述

(7) 合并后的结果为

在这里插入图片描述

从上表可知:

(1)相同终结符之间的优先关系未必是=

(2)有a<b,未必有b>a

(3)a、b之间未必一定有优先关系
分析过程

在这里插入图片描述

算符优先分析法最左规约串的确定
  1. 最左素短语的定义是什么?
素短语:某文法句型的短语它至少包含有一个终结符号,并且除它之外,不再包含任何更小的素短语。
最左素短语:任意句型最左边的素短语。
  1. 最左素短语的特征?如何根据其特征确定当前句型的最左可归约串?在这里插入图片描述
  2. 什么是“单非产生式”,算符优先分析法进行规约为什么速度快?
右部仅有一个非终结符的产生式
比用文法的优先关系矩阵节省内存,若有n个终结符号,优先关系矩阵占内存为(n+1)2,优先函数为2(n+1);
编程时便于比较运算,即用一般的关系运算即可;

由于时间原因,代码没来及上传。

  • 34
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
算符优先分析法 C++ 编译原理 运行环境:Visual Studio 2005 #include "SStack.h" #include <iostream> #include <string> using namespace std; class Functor { private : char ** table; string ** production; string prog;//待分析字符串 int p;//字符指针 int num;//终结符个数 int num1;//产生式个数 SStack <char> stack; public: Functor(int m,int n,char ** T,string **prod,string pr) { num=m; num1=n; table=T; production=prod; prog=pr; p=0; stack.push('$'); } void traversal() { while(p<(prog.length())) { stack.display(); cout<<prog.substr(p)<<" "; char ch; if(Getnum(stack.gettop())) { ch=stack.gettop(); } else { ch=stack.getsecond(); } switch(compare(ch,prog[p])) { case 1: case 2:stack.push(prog[p]);p++;cout<<"移入"<<endl;break; case 3:reduct();cout<<"归约"<<endl;break; } } cout<<"分析成功!"<<endl; } int Getnum(char ch) { for(int i=1;i<num;i++) { if(ch==table[i][0]) { return i; } } return 0; } int compare(char col,char row) { int c=Getnum(col); int r=Getnum(row); switch( table[c][r]) { case '>': return 3;break; case '<': return 2;break; case '=': return 1;break; default:cout<<endl<<"输入串有误,程序将终止!"<<endl;system("pause");exit(0);break; } } void reduct() { //待定 string token=""; int temp; string str=""; if(!Getnum(stack.gettop())) { token+=stack.gettop(); stack.pop(); } char ch=stack.gettop(); str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); bool Nover=true; while(Nover) { if(Getnum(stack.gettop())) { if(compare(stack.gettop(),ch)==2) { Nover=false; } else { ch=stack.gettop(); str=""; str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); } } else { token+=stack.gettop(); stack.pop(); } } string token2=""; //cout<<token<<" "; for(int i=token.length()-1;i>=0;i--) { token2+=token[i]; } //cout<<token2<<endl; if(Haven(token2)!= -1) { stack.push(production[Haven(token2)][0][0]); } else { cout<<"输入串有误!分析终止!"<<endl; system("pause"); exit(0); } } int Haven(string temp) { for(int i=0;i<num1;i++) { int j=1; while(production[i][j]!="") { if(temp==production[i][j]) { return i; } j++; } } return -1; } public: ~Functor(void) { } };
算符优先分析文法是一种工具,在编译的过程中,隶属于语法分析环节,却又与中间代码的生成息息相关,编译可以分为五个阶段:词法分析、语法分析、语义分析(中间代码的生成)、代码优化、目标代码生成。语法分析是指:在词法分析基础上,将单词符号串转化为语法单位(语法范畴)(短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。也就是说语法分析是检验输入串的语法是否正确,注意这里的语法正确,只是简单地符合自己定义的规范,而不能检测出运行时错误,比如"X/0",空指针错误,对象未初始化等错误。在这一个实验中,我将通过算符优先分析文法这一个工具,在语法分析的时候,顺便进行语义分析,也就是识别出语法单位,同时简要的将识别出的中间代码进行计算(目标代码的生成+运行),得到相应的结果,来检验自己设计的正确性。可以说题目虽然叫做算符优先分析文法,其实却是一个贯穿了“词法分析+语法分析+语义分析+中间代码优化+目标代码生成+运行”全过程的一个极具概括性的程序。如果能将这个程序得心应手的完成出来,我相信诸位对编译原理的掌握也算是炉火纯青了。时隔将近两年再来整理自己以前写过的实验报告,还是挺有感慨的,对一件东西感兴趣,原来影响还会如此深远,还记得自己当时连续六个小时全神贯注写出的实验报告,现在看看竟然写了五六十页,核心内容也有三四十页,不觉的感慨当年充满热情的时代慢慢的竟走出许久
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘客-追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值