4编译原理_算符优先算法分析程序

合集下载

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

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

编译原理课程设计报告_算符优先分析法编译原理课程设计报告选题名称: 算符优先分析法系(院): 计算机工程学院专业: 计算机科学与技术班级:姓名: 学号:指导教师:学年学期: 7>2012 ~ 2013 学年第 1 学期2012年 12 月 04 日设计任务书课题名称算符优先分析法设计目的通过一周的课程设计,对算符优先分析法有深刻的理解,达到巩固理论知识、锻炼实践能力、构建合理知识结构的目的。

实验环境Windows2000以上操作系统,Visual C++6.0编译环境任务要求1.判断文法是否为算符优先文法,对相应文法字符串进行算符优先分析;2.编写代码,实现算符优先文法判断和相应文法字符串的算符优先分析;3.撰写课程设计报告;4提交报告。

工作进度计划序号起止日期工作内容1 理论辅导,搜集资料2 ~编写代码,上机调试3 撰写课程设计报告4 提交报告指导教师(签章):年月日摘要:编译原理是计算机专业重要的一门专业基础课程,内容庞大,涉及面广,知识点多。

本次课程设计的目的正是基于此,力求为学生提供一个理论联系实际的机会,通过布置一定难度的课题,要求学生独立完成。

我们这次课程设计的主要任务是编程实现对输入合法的算符优先文法的相应的字符串进行算符优先分析,并输出算符优先分析的过程。

算符优先分析法特别有利于表达式的处理,宜于手工实现。

算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的规范归约。

而在整个归约过程中,起决定作用的是相继连个终结符之间的优先关系。

因此,所谓算符优先分析法就是定义算符之间的某种优先关系,并借助这种关系寻找句型的最左素短语进行归约。

通过实践,建立系统设计的整体思想,锻炼编写程序、调试程序的能力,学习文档编写规范,培养独立学习、吸取他人经验、探索前言知识的习惯,树立团队协作精神。

同时,课程设计可以充分弥补课堂教学及普通实验中知识深度与广度有限的缺陷。

关键字:编译原理;归约;算符优先分析;最左素短语;目录1 课题综述 11.1 课题来源 11.2课题意义 11.3 预期目标 11.4 面对的问题 12 系统分析 22.1 基础知识 22.2 解决问题的基本思路 52.3 总体方案 53 系统设计 63.1 算法实现 63.2 流程图74 代码编写85 程序调试116 运行与测试12总结13致谢14参考文献151 课题综述1.1 课题来源算符文法:即它的任一产生式的右部都不含两个相继的非终结符的文法。

编译原理实验4算符优先算法

编译原理实验4算符优先算法

一、实验目的与任务算术表达式和赋值语句的文法可以是(你可以根据需要适当改变):S→i=EE→E+E|E-E|E*E|E/E|(E)|i根据算符优先分析法,将赋值语句进行语法分析,翻译成等价的一组基本操作,每一基本操作用四元式表示。

二、实验涉及的相关知识点算符的优先顺序。

三、实验内容与过程如参考C语言的运算符。

输入如下表达式(以分号为结束):(1)a = 10;(2)b = a + 20;注:此例可以进行优化后输出(不作要求):(+,b,a,20)(3)c=(1+2)/3+4-(5+6/7);四、实验结果及分析(1)输出:(=, a,10,-)(2)输出:(=,r1,20,-)(+,r2,a,r1)(=,b,r2,-)(3)输出:(+,r1,1,2) (/,r2,r1,3) (/,r3,6,7) (+,r4,5,r3,) (+,r5,r2,4) (-,r6,r5,r4) (=,c,r6,-)五、实验有关附件(如程序、附图、参考资料,等)......h == '#') o][Peek(n0).No];if(r == '<') h == 'E'&& Peek(1).ch == '#' && Token[ipToken].ch == '#')return TRUE;elsereturn FALSE;}h){k = TRUE; h == 'E'){n ++;}return n;}词结束(遇到“#”号),无法移进,需要规约,返回:1词没有结束,需判断是否可以移进栈单词<=单词:移进后返回:2栈单词>单词:不能移进,需要规约,返回:1单词没有优先关系:出错,返回:-1int MoveIn(){SToken s,t; h = '#';Token[TokenNumber].No = O_NUL;return TRUE; h = '+';Token[TokenNumber].No = O_PLUS;GetChar();break;case '-':Token[TokenNumber].ch = '-';Token[TokenNumber].No = O_MINUS;GetChar();break;case '*':Token[TokenNumber].ch = '*';Token[TokenNumber].No = O_TIMES;GetChar();break;case '/':Token[TokenNumber].ch = '/';Token[TokenNumber].No = O_SLASH;GetChar();break;case '(':Token[TokenNumber].ch = '(';Token[TokenNumber].No = O_L_PAREN;GetChar();break;case ')':Token[TokenNumber].ch = ')';Token[TokenNumber].No = O_R_PAREN;GetChar();break;default:if(ch >= '0' && ch <= '9') h = 'i';Token[TokenNumber].No = O_IDENT;}else{return ! MakeErr("表达式中含有非法字符。

算符优先分析编译原理演示文稿

算符优先分析编译原理演示文稿
算符优先分析编译原理演示文 稿
(优选)算符优先分析编译原 理
6.3 算符优先分析法
算符优先文法的定义 算符优先关系表的构造 算符优先分析算法 算符优先分析法的局限性
6.3.1 算符优先分析
• 自下而上分析算法模型----移进归约 • 算符优先分析不是规范归约
算符优先分析的可归约 串是句型的最左素短语 定义: cfg(上下文无关文法) G 的句型的素短
2)’<‘关系
– 求出每个非终结符B的FIRSTVT(B)
– 若A→…aB…,则b∈FIRSTVT(B),则a<b
3)’>’关系
– 求出每个非终结符B的LASTVT(B)
– 若A→…Bb…,则a∈LASTVT(B),则a>b
计算算符优先关系
例文法G’[E’]: (0) E’→#E# (1) E→E+T (2) E→T (3) T→T*F (4) T→F (5) F→PF|P (6) P→(E) (7) P→i
例 G’[E]:
算符优先关表
E→E+T|T
T→T*F|F F→P↑F|P
P→(E)|i
+ * ( ) i#
+>< << >< >
*> > < < > < >
> > < < > < >
( < < < <=<
)>>>
>
>
i >>>
>
>
#< < < <
<=

实验二 编译原理语法分析(算符优先)

实验二  编译原理语法分析(算符优先)

实验二语法分析算符优先分析程序一.实验要求⑴选择最有代表性的语法分析方法算符优先法;⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

⑶实习时间为6学时。

二.实验内容及要求(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E’): E’→#E#E→E+T | TT→T*F |FF→(E)|i(4)分析的句子为:(i+i)*i和i+i)*i三.实验代码#include "stdafx.h"#include "stdio.h"#include "stdlib.h"#include "iostream.h"int k;char a;int j;char q;int r;int r1;char st[10][30];char data[20][20];char s[100];char lable[20];char input[100];char string[20][10];char first[10][10];char last[10][10];int fflag[10]={0};int lflag[10]={0};int deal();int zhongjie(char c);int xiabiao(char c);void out(int j,int k,char *s);void firstvt(char c);void lastvt(char c);void table();void main(){int i,j,k=0;printf("请输入文法规则数:");scanf("%d",&r);printf("请输入文法规则:\n");for(i=0;i<r;i++){scanf("%s",st[i]);first[i][0]=0;last[i][0]=0;}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if(st[i][0]<'A'||st[i][0]>'Z'){printf("不是算符文法!\n");exit(-1);}if(st[i][j]>='A'&&st[i][j]<='Z'){if(st[i][j+1]>='A'&&st[i][j+1]<='Z'){printf("不是算符文法!\n");exit(-1);}}}}for(i=0;i<r;i++){for(j=0;st[i][j]!='\0';j++){if((st[i][j]<'A'||st[i][j]>'Z')&&st[i][j]!='-'&&st[i][j]!='>'&&st[i][j]!='|') lable[k++]=st[i][j];}}lable[k]='#';lable[k+1]='\0';table();//输出每个非终结符的FIRSTVT集printf("每个非终结符的FIRSTVT集为:\n"); for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<first[i][0];j++){printf("%c ",first[i][j+1]);}printf("\n");}//输出每个非终结符的LASTVT集printf("每个非终结符的LASTVT集为:\n"); for(i=0;i<r;i++){printf("%c: ",st[i][0]);for(j=0;j<last[i][0];j++){printf("%c ",last[i][j+1]);}printf("\n");}printf("算符优先分析表如下:\n");for(i=0;lable[i]!='\0';i++)printf("\t%c",lable[i]);printf("\n");for(i=0;i<k+1;i++){printf("%c\t",lable[i]);for(j=0;j<k+1;j++){printf("%c\t",data[i][j]);}printf("\n");}printf("请输入文法输入符号串以#结束:");scanf("%s",input);deal();}void table(){char text[20][10];int i,j,k,t,l,x=0,y=0;int m,n;x=0;for(i=0;i<r;i++){firstvt(st[i][0]);lastvt(st[i][0]);}for(i=0;i<r;i++){text[x][y]=st[i][0];y++;for(j=1;st[i][j]!='\0';j++){if(st[i][j]=='|'){text[x][y]='\0';x++;y=0;text[x][y]=st[i][0];y++;text[x][y++]='-';text[x][y++]='>';}else{text[x][y]=st[i][j];y++;}}text[x][y]='\0';x++;y=0;}r1=x;//输出转化后的文法规则串printf("转化后的文法为:\n");for(i=0;i<x;i++) {printf("%s\n",text[i]);}for(i=0;i<x;i++){string[i][0]=text[i][0];for(j=3,l=1;text[i][j]!='\0';j++,l++)string[i][l]=text[i][j];string[i][l]='\0';}for(i=0;i<x;i++){for(j=1;text[i][j+1]!='\0';j++){if(zhongjie(text[i][j])&&zhongjie(text[i][j+1])){m=xiabiao(text[i][j]);n=xiabiao(text[i][j+1]);data[m][n]='=';}if(text[i][j+2]!='\0'&&zhongjie(text[i][j])&&zhongjie(text[i][j+2])&&!zhongjie(text[i][j+1])) {m=xiabiao(text[i][j]);n=xiabiao(text[i][j+2]);data[m][n]='=';}if(zhongjie(text[i][j])&&!zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j+1])break;}m=xiabiao(text[i][j]);for(t=0;t<first[k][0];t++){n=xiabiao(first[k][t+1]);data[m][n]='<';}}if(!zhongjie(text[i][j])&&zhongjie(text[i][j+1])){for(k=0;k<r;k++){if(st[k][0]==text[i][j])break;}n=xiabiao(text[i][j+1]);for(t=0;t<last[k][0];t++){m=xiabiao(last[k][t+1]);data[m][n]='>';}}}}m=xiabiao('#');for(t=0;t<first[0][0];t++){n=xiabiao(first[0][t+1]);data[m][n]='<';}n=xiabiao('#');for(t=0;t<last[0][0];t++){m=xiabiao(last[0][t+1]);data[m][n]='>';}data[n][n]='=';}//求FIRSTVT集void firstvt(char c) { int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(fflag[i]==0){n=first[i][0]+1;m=0;do{if(m==2||st[i][m]=='|'){if(zhongjie(st[i][m+1])){first[i][n]=st[i][m+1];n++;}else{if(zhongjie(st[i][m+2])){first[i][n]=st[i][m+2];n++;}if(st[i][m+1]!=c){firstvt(st[i][m+1]);for(j=0;j<r;j++){if(st[j][0]==st[i][m+1])break;}for(k=0;k<first[j][0];k++){int t;for(t=0;t<n;t++){if(first[i][t]==first[j][k+1])break;}if(t==n){first[i][n]=first[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');first[i][n]='\0';first[i][0]=--n;fflag[i]=1;}}//求LASTVT集{void lastvt(char c)int i,j,k,m,n;for(i=0;i<r;i++){if(st[i][0]==c)break;}if(lflag[i]==0){n=last[i][0]+1;m=0;do{if(st[i][m+1]=='\0'||st[i][m+1]=='|'){if(zhongjie(st[i][m])){last[i][n]=st[i][m];n++;}else{if(zhongjie(st[i][m-1])){last[i][n]=st[i][m-1];n++;}if(st[i][m]!=c){lastvt(st[i][m]);for(j=0;j<r;j++){if(st[j][0]==st[i][m])break;}for(k=0;k<last[j][0];k++){int t;for(t=0;t<n;t++){if(last[i][t]==last[j][k+1])break;}if(t==n){last[i][n]=last[j][k+1];n++;}}}}}m++;}while(st[i][m]!='\0');last[i][n]='\0';last[i][0]=--n;lflag[i]=1;}}int deal(){int i,j;int x,y;int z;k=1;s[k]='#';for(i=0;input[i]!='\0';i++);z=i--;i=0;while((a=input[i])!='\0'){if(zhongjie(s[k]))j=k;elsej=k-1;x=xiabiao(s[j]);y=xiabiao(a);if(data[x][y]=='>'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("规约\n");do{q=s[j];if(zhongjie(s[j-1]))j=j-1;else j=j-2;x=xiabiao(s[j]);y=xiabiao(q);}while(data[x][y]!='<');int m,n,N;for(m=j+1;m<=k;m++){for(N=0;N<r1;N++)for(n=1;string[N][n]!='\0';n++){if(!zhongjie(s[m])&&!zhongjie(string[N][n])) {if(zhongjie(s[m+1])&&zhongjie(string[N][n+1])&&s[m+1]==string[N][n+1]){s[j+1]=string[N][0];break;}}elseif(zhongjie(s[m]))if(s[m]==string[N][n]){s[j+1]=string[N][0];break;}}}k=j+1;if(k==2&&a=='#'){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("结束\n");printf("输入串符合文法的定义!\n");return 1; } }elseif(data[x][y]=='<'||data[x][y]=='='){out(1,k,s);printf("%c",a);out(i+1,z,input);printf("移进\n");k++;s[k]=a;i++;}else{printf("\nflase");return 0;}}printf("\nflase");return 0;}void out(int j,int k,char *s){int n=0;int i;for(i=j;i<=k;i++){printf("%c",s[i]);n++;}for(;n<15;n++){printf(" ");}}//判断字符c是否是终极符int zhongjie(char c){int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return 1;}return 0;}//求字符c在算符优先关系表中的下标{int xiabiao(char c)int i;for(i=0;lable[i]!='\0';i++){if(c==lable[i])return i;}return -1;}四、实验结果输入串为#(i+i)/i#存放于Read.txt文件中五、实验总结经过此次试验对算符优先分析的原理有了深入的理解,熟悉了算符分析的过程,掌握了算符优先分析的有关处理,能够使用一种高级语言构造算符优先的语法分析器。

编译原理--算符优先分析法研究--源程序

编译原理--算符优先分析法研究--源程序

编译原理算符优先分析法研究源程序目录1 课程设计的目的和要求 (2)1.1 课程设计的目的 (2)1.2 课程设计的要求 (2)2 系统描述 (2)2.1 自底向上分析方法的描述: (2)2.2 算符优先文法的描述: (2)3)输入符号串,进行移进-规约分析。

(3)3 概要设计 (3)3.1 设计思路 (3)3.2 系统功能结构 (4)3.3 技术路线或实现方法 (5)3.4 开发环境 (5)4 详细设计 (5)4.1 模块划分 (5)4.2 主要算法的流程图 (7)4.3 数据分析与定义 (8)4.4 系统界面设计 (8)5 测试方法和测试结果 (9)5.1 测试用例1 (9)5.2 测试用例2 (10)5.3 测试用例3 (11)5.4 测试用例4 (12)6 结论和展望 (13)结论 (13)展望 (13)学习编译技术课程的体会和对本门课程的评价 (13)7 参考文献 (13)8 源代码 (14)1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。

设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术。

1.2 课程设计的要求1、文法使用产生式来定义;2、用大写字母和小写字母分别表示非终结符和终结符;产生式使用->;3、文法中的空字符串统一使用@表示;4、分别给出每一个非终结符的FIRSTVT集和LASTVT集;5、画出算符优先关系表6、判定给定的文法是否是算符优先文法;7、给定符号串判定是否是文法中的句子,分析过程用分析表格的方式打印出来。

2 系统描述本次实验使用windows vista操作系统下visual C++6.0平台,使用C语言,利用读文件方式将待分析的文法读入到程序中,通过定义数组和结构体作为具有一定意义或关系的表或栈,存放FIRSTVT、LASTVT、算符优先关系表的元素。

编译原理 算符优先分析法 ppt课件

编译原理 算符优先分析法 ppt课件

13
4.4.2 算符优先文法的定义 • 3 算符优先文法的定义
设有一个不含 规则的OG文法G,
如果任意两个终结符间至多有一种算符 关系存在, 则称G是算符优先文法,也称OPG文法。
结论:算符优先文法是无二义的。
编译原理 算符优先分析法
14
4.4.3 算符优先关系表的构造
• 1 FIRSTVT集、 LASTVT集
规范归约:
自上而下最右推导的逆过程。
编译原理 算符优先分析法
18
例4.12文法G[E]:
E E+T|T
E
T T*F|F
E +T
F (E)|id
句子id*id+id的
T
F
自下向上的语法分析过程。
T * F id
规范归约是最右推导的 逆过程。
*优先于+:
+优先于*:
(1)id+id*id
(1)id+id*id
(2)E+id*id
(2)E+id*id
(3)E+E*id
(3)E+E*id
(4)E+E*E
(4)E*id
(5)E+E
(5)E*E
(6)E
(6)E
编译原理 算符优先分析法
7
4.4.1 方法概述
• 3 优先关系种类
任何两个相邻的终结符a和b可能的优先关系有3 种: a b: a的优先级低于b
FIRSTVT
LASTVT
E
{+,*,(,id}
{+,*,),id}
T
{*,(,id}
{*,),id}
F
{(,id}

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

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

华北水利水电学院编译原理实验报告一、实验题目:语法分析(算符优先分析程序)(1)选择最有代表性的语法分析方法算符优先法;(2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。

二、实验内容(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E’): E’→#E#E→E+T | TT→T*F |FF→(E)|i(4) 分析的句子为:(i+i)*i和i+i)*i三、程序源代#include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream.h>#define SIZE 128char 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()//构造算符优先关系表,并将其存入数组中{priority[0][2]='<';priority[0][3]='<';priority[0][4]='>';priority[0][5]='>';priority[1][0]='>';priority[1][1]='>';priority[1][2]='<';priority[1][3]='<';priority[1][4]='>';priority[1][5]='>';priority[2][0]='>';priority[2][1]='>';priority[2][2]='$';//无优先关系的用$表示priority[2][3]='$';priority[2][4]='>';priority[2][5]='>';priority[3][0]='<';priority[3][1]='<';priority[3][2]='<';priority[3][3]='<';priority[3][4]='=';priority[3][5]='$';priority[4][0]='>';priority[4][1]='>';priority[4][2]='$';priority[4][3]='$';priority[4][4]='>';priority[4][5]='>';priority[5][0]='<';priority[5][3]='<';priority[5][4]='$';priority[5][5]='=';}void analyse()//对所输入的句子进行算符优先分析过程的函数{FILE *fp;fp=fopen("li","a");int i,j,f,z,z1,n,n1,z2,n2;int count=0;//操作的步骤数char a; //用于存放正在分析的字符char p,Q,p1,p2;f=strlen(input); //测出数组的长度for(i=0;i<=f;i++){a=input[i];if(i==0)remainString();if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i'||Analy seStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#')j=k;elsej=k-1;z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#')n=testchar(a);else //如果句子含有不是终结符集合里的其它字符,不合法{printf("错误!该句子不是该文法的合法句子!\n");break;}if(p=='$'){printf("错误!该句子不是该文法的合法句子!\n");return;}if(p=='>'){ for( ; ; ){Q=AnalyseStack[j];if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#')j=j-1;elsej=j-2;z1=testchar(AnalyseStack[j]);n1=testchar(Q);p1=priority[z1][n1];if(p1=='<') //把AnalyseStack[j+1]~AnalyseStack[k]归约为N{count++;printf("(%d) %s\t%10c\t%5c%17s\t 归约\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"归约");k=j+1;i--;AnalyseStack[k]='N';int r,r1;r=strlen(AnalyseStack);for(r1=k+1;r1<r;r1++)AnalyseStack[r1]='\0';break;}else}}else{if(p=='<') //表示移进{count++;printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"移进");k=k+1;AnalyseStack[k]=a;remainString();}else{if(p=='='){z2=testchar(AnalyseStack[j]);n2=testchar('#');p2=priority[z2][n2];if(p2=='='){count++;printf("(%d) %s\t%10c\t%5c%17s\t 接受\n",count,AnalyseStack,p,a,remain);fprintf(fp,"(%d) %s\t%17s\t %s\n",count,AnalyseStack,remain,"接受");printf("该句子是该文法的合法句子。

实验四算符优先分析算法

实验四算符优先分析算法

实验四:算符优先分析算法1.实验目的:掌握算符优先分析析程序的分析、设计与实现的基本技术与一般方法。

2.实验题目:编写并上机调试完成识别由下列文法所定义的表达式的算符优先分析程序。

E→E+T | E-T | TT→T*F | T/F |FF→(E) | i3.实验步骤(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 }(3)程序参考源码/****************************************/ /* 程序名称:算符优先分析程序*/ /* 程序用途:编译原理实验(四) */ /* 编写日期:2005年11月15日*/ /* 实验题目:对下列文法*/ /* E->E+T|E-T|T */ /* T->T*F|T/F|F */ /* F->(E)|i */ /* 编写算符优先分析程序*/ /* 程序版本: 1.0 Final */ /* 程序作者:黄记瑶B0226047 */ /* 作者邮箱:****************/ /****************************************//****************************************//* 程序相关说明*//* 0=+ 1=- 2=* 3=/ 4=( 5=) 6=i 7=# *//* *//* 算符优先关系表*//* ------------------------------------------------------*//* + - * / ( ) i # *//* + > > < < < > < > *//* - > > < < < > < > *//* * > > > > < > < > *//* / > > > > < > < > *//* ( < < < < < = < ? *//* ) > > > > ? > ? > *//* i > > > > ? > ? > *//* # < < < < < ? < = *//* ------------------------------------------------- *//****************************************/#include "stdio.h"#include "malloc.h"struct Lchar{char char_ch;struct Lchar *next;}Lchar,*p,*h,*temp,*top,*base;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 curchar;char curcmp;int right;/*设置开关项,当出错时为0*/int i,j;int k;/*比较字符在栈的位置*/void push(char pchar)/*入栈函数*/{temp=malloc(sizeof(Lchar));temp->char_ch=pchar;temp->next=top;top=temp;}void pop(void)/*出栈函数*/{if(top->char_ch!='#')top=top->next;}int changchartoint(char ch)/*将字符转为数字,以得到算符优先值*/ {int t;switch(ch){case '+':t=0;break;case '-':t=1;break;case '*':t=2;break;case '/':t=3;break;case '(':t=4;break;case ')':t=5;break;case 'i':t=6;break;case '#':t=7;}return t;}void dosome(void){k=1;for(;;){curchar=h->char_ch;temp=top;for(;;){if(temp->char_ch=='N'){temp=temp->next;k++;}else{curcmp=temp->char_ch;break;}}printf("\n%d\t%d\t",table[i][j],k);temp=top;for(;;)/*打印栈*/{printf("%c",temp->char_ch);if(temp->char_ch=='#')break;elsetemp=temp->next;}printf("\t");temp=h;for(;;)/*打印待比较的字符*/{printf("%c",temp->char_ch);if(temp->char_ch=='#')break;elsetemp=temp->next;}i=changchartoint(curcmp);j=changchartoint(curchar);if(table[i][j]==0)/*算符优先值为空*/{printf("\n%d\t%d\t%c\t%c\terror1",table[i][j],k,curcmp,curchar);right=0;break;}else/*算符优先值不为空*/{if(table[i][j]<0)/*算符优先值为-1,移进*/{if(curchar=='#')/*待比较字符为空*/{if(k==2)/*当前比较字符在栈的位置为两个元素*/break;else{printf("\n%d\t%d\t%c\t%c\terror2",table[i][j],k,curcmp,curchar);right=0;break;}}push(curchar);h=h->next;}else/*算符优先值为1,归约*/{if(curcmp=='i')/*当前比较为i,出栈一次*/pop();else/*当前比较不为i,出栈三次*/{pop();pop();pop();}push('N');/*归约到N*/k=1;}}}}void main(void){char ch;right=1;base=malloc(sizeof(Lchar));base->next=NULL;base->char_ch='#';top=base;h=malloc(sizeof(Lchar));h->next=NULL;p=h;do{ /*输入待比较字符串,以'#'结束*/ch=getch();putch(ch);if(ch=='i'||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#'){temp=malloc(sizeof(Lchar));temp->next=NULL;temp->char_ch=ch;h->next=temp;h=h->next;}else{temp=p->next;printf("\nInput a wrong char!Input again:\n");for(;;){if (temp!=NULL)printf("%c",temp->char_ch);elsebreak;temp=temp->next;}}}while(ch!='#');/*输入待比较字符串,以'#'结束*/p=p->next;h=p;dosome();/*开始识别*/if(right)printf("\nOK!\n");elseprintf("\nError!\n");getch();}。

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

#include<iostream.h>#include<string.h>#include<stdio.h>typedef struct{ char R;char r;int flag;}array;typedef struct{ char E;char e;}charLode;typedef struct{ charLode *base;int top;}charstack;char str[80][80],arr[80][80],brr[80][80]; array F[20];int m,kk,p,ppp,FF=1;char r[10];int crr[20][20],FLAG=0;char ccrr1[1][20],ccrr2[20][1];void Initstack(charstack &s)//定义栈{ s.base=new charLode[20];s.top=-1;}void push(charstack &s,charLode w) //入栈{ s.top++;s.base[s.top].E=w.E;s.base[s.top].e=w.e;}void pop(charstack &s,charLode &w) //出栈{ w.E=s.base[s.top].E;w.e=s.base[s.top].e;s.top--;}int IsEmpty(charstack s) //判断是否到栈顶{ if(s.top==-1)return 1;elsereturn 0;}int IsLetter(char ch) //判断是不是大写字母(非终结符){ if(ch>='A'&&ch<='Z')return 1;elsereturn 0;}int judge1(int n){ int j=3,flag=0;for(int i=0;i<=n;i++)while(str[i][j]!='\0'){ char a=str[i][j];char b=str[i][j+1];if(IsLetter(a)&&IsLetter(b)) //两个非终结符相连,不是算符文法 { flag=1;break;}elsej++;}if(flag==1) //根据flag设定返回值return 0;elsereturn 1;}void judge2(int n){ for(int i=0;i<=n;i++)if(str[i][3]=='~'||FLAG==1)//'~'代表空{ cout<<"文法G不是算符优先文法!"<<endl;FF=0;break;}if(i>n)cout<<"文法G是算符优先文法!"<<endl; }int search1(char r[],int kk,char a){ for(int i=0;i<kk;i++)if(r[i]==a)break;if(i==kk)return 0;elsereturn 1;}void createF(int n){ int k=0,i=1;char g;char t[10];//t数组用来存放非终结符t[0]=str[0][0];while(i<=n){ if(t[k]!=str[i][0]){ k++;t[k]=str[i][0];g=t[k];i++; }else i++; }kk=0;char c;for(i=0;i<=n;i++){ int j=3;while(str[i][j]!='\0'){ c=str[i][j];if(IsLetter(c)==0){ if(!search1(r,kk,c))r[kk]=c;kk++;//r数组用来存放终结符 } j++; } }m=0;for(i=0;i<k;i++)for(int j=0;j<kk-1;j++){ F[m].R=t[i];F[m].r=r[j];F[m].flag=0;m++; }}void search(charLode w){ for(int i=0;i<m;i++)if(F[i].R==w.E&&F[i].r==w.e){ F[i].flag=1;break; }}void FirstVT(int n)//求FirstVT{ charstack sta;charLode w;int i=0;Initstack(sta);while(i<=n){ int k=3;w.E=str[i][0];char a=str[i][k];char b=str[i][k+1];if(!IsLetter(a)) //产生式的后选式的第一个字符就是终{ w.e=a;push(sta,w);search(w);i++;}else if(IsLetter(a)&&b!='\0'&&!IsLetter(b)) //产生式的后选式的第一个字符是非终结符的情况{ w.e=b;push(sta,w);search(w);i++; }else i++;}charLode ww;while(!IsEmpty(sta)){ pop(sta,ww);for(i=0;i<=n;i++){ w.E=str[i][0];if(str[i][3]==ww.E&&str[i][4]=='\0') { w.e=ww.e;push(sta,w);search(w);break; } } }p=0;int k=1;i=1;while(i<m){ if(F[i-1].flag==1){ arr[p][0]=F[i-1].R;arr[p][k]=F[i-1].r;}while(F[i].flag==0&&i<m)i++;if(F[i].flag==1){ if(F[i].R==arr[p][0])k++;else {arr[p][k+1]='\0';p++;k=1;} i++; } } }void LastVT(int n)//求LastVT{ charstack sta;charLode w;for(int i=0;i<m;i++)F[i].flag=0;i=0;Initstack(sta);while(i<=n){ int k=strlen(str[i]);w.E=str[i][0];char a=str[i][k-1];char b=str[i][k-2];if(!IsLetter(a)){ w.e=a;push(sta,w);search(w);i++; }else if(IsLetter(a)&&!IsLetter(b)){ w.e=b;push(sta,w);search(w);i++; }else i++; }charLode ee;while(!IsEmpty(sta)){ pop(sta,ee);for(i=0;i<=n;i++){ w.E=str[i][0];if(str[i][3]==ee.E&&str[i][4]=='\0'){ w.e=ee.e;push(sta,w);search(w); } } }int k=1;i=1;ppp=0;while(i<m){ if(F[i-1].flag==1){ brr[ppp][0]=F[i-1].R;brr[ppp][k]=F[i-1].r;}while(F[i].flag==0&&i<m)i++;if(F[i].flag==1){ if(F[i].R==arr[ppp][0])k++;else {brr[ppp][k+1]='\0';ppp++;k=1;} i++; } } }void createYXB(int n)//构造优先表{ int i,j;for(j=1;j<=kk;j++)ccrr1[0][j]=r[j-1];for( i=1;i<=kk;i++)ccrr2[i][0]=r[i-1];for(i=1;i<=kk;i++)for(j=1;j<=kk;j++)crr[i][j]=0;int I=0,J=3;while(I<=n){ if(str[I][J+1]=='\0') //扫描右部{ I++;J=3;}else{ while(str[I][J+1]!='\0'){ char aa=str[I][J];char bb=str[I][J+1];if(!IsLetter(aa)&&!IsLetter(bb))//优先及等于的情况,用1值表示等于 { for(i=1;i<=kk;i++){ if(ccrr2[i][0]==aa)break;}for(j=1;j<=kk;j++){ if(ccrr1[0][j]==bb)break;}if(crr[i][j]==0)crr[i][j]=1;else { FLAG=1;I=n+1;}J++;}if(!IsLetter(aa)&&IsLetter(bb)&&str[I][J+2]!='\0'&&!IsLetter(str[I][ J+2]))//优先及等于的情况{ for(i=1;i<=kk;i++{ if(ccrr2[i][0]==aa) break;}for(int j=1;j<=kk;j++){if(ccrr1[0][j]==str[I][J+2])break;}if(crr[i][j]==0)crr[i][j]=1;else{FLAG=1;I=n+1;}}if(!IsLetter(aa)&&IsLetter(bb))//优先及小于的情况,用2值表示小于 {for(i=1;i<=kk;i++){if(aa==ccrr2[i][0])break;}for(j=0;j<=p;j++){if(bb==arr[j][0])break;}for(int mm=1;arr[j][mm]!='\0';mm++){for(int pp=1;pp<=kk;pp++){if(ccrr1[0][pp]==arr[j][mm])break;}if(crr[i][pp]==0)crr[i][pp]=2;else {FLAG=1;I=n+1;}}J++;}if(IsLetter(aa)&&!IsLetter(bb))//优先及大于的情况,用3值表示大于 {for(i=1;i<=kk;i++){if(ccrr1[0][i]==bb)break;}for(j=0;j<=ppp;j++){ if(aa==brr[j][0]) break;}for(int mm=1;brr[j][mm]!='\0';mm++) {for(int pp=1;pp<=kk;pp++){if(ccrr2[pp][0]==brr[j][mm])break;}if(crr[pp][i]==0)crr[pp][i]=3;else {FLAG=1;I=n+1;}}J++; } } } }}int judge3(char s,char a){int i=1,j=1;while(ccrr2[i][0]!=s)i++;while(ccrr1[0][j]!=a)j++;if(crr[i][j]==3)return 3;elseif(crr[i][j]==2)return 2;elseif(crr[i][j]==1)return 1;elsereturn 0;}void print(char s[],char STR[][20],int q,int u,int ii,int k)//打印归约的过程{cout<<u<<" ";for(int i=0;i<=k;i++)cout<<s[i];cout<<" ";for(i=q;i<=ii;i++)cout<<STR[0][i];cout<<" ";}void process(char STR[][20],int ii)//对输入的字符串进行归约的过程{cout<<"步骤"<<" "<<"符号栈"<<" "<<"输入串"<<" "<<"动作"<<endl; int k=0,q=0,u=0,b,i,j;char s[40],a;s[k]='#';print(s,STR,q,u,ii,k);cout<<"预备"<<endl;k++;u++;s[k]=STR[0][q];q++;print(s,STR,q,u,ii,k);cout<<"移进"<<endl;while(q<=ii){a=STR[0][q];if(!IsLetter(s[k])) j=k;else j=k-1;b=judge3(s[j],a);if(b==3)//大于的情况进行归约{while(IsLetter(s[j-1]))j--;for(i=j;i<=k;i++)s[i]='\0';k=j;s[k]='N';u++;print(s,STR,q,u,ii,k);cout<<"归约"<<endl;}else if(b==2||b==1)//小于或等于的情况移进{k++;s[k]=a;u++;q++;print(s,STR,q,u,ii,k);if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')cout<<"接受"<<endl;else cout<<"移进"<<endl;}else{cout<<"出错"<<endl;break;}}if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')cout<<"归约成功"<<endl;else cout<<"归约失败"<<endl;}void main(){int n,i,j;cout<<"请输入你要定义的文法G的产生式的个数n:"; cin>>n;cout<<"请输入文法产生式:"<<endl;for(i=0;i<n;i++){gets(str[i]);j=strlen(str[i]);str[i][j]='\0';}str[i][0]='Q'; //最末行添加扩展str[i][1]='-';str[i][2]='>';str[i][3]='#';str[i][4]=str[0][0];str[i][5]='#';cout<<"你定义的产生式如下:"<<endl;str[i][6]='\0';for(i=0;i<=n;i++)cout<<str[i]<<endl;if(judge1(n)==0) //判断文法G是否为算符文法cout<<"文法G不是算符文法!"<<endl;if(judge1(n)==1){ cout<<"文法G是算符文法!"<<endl; }createF(n);FirstVT(n);LastVT(n);createYXB(n);for(i=0;i<=p;i++)//打印FirstVT{ cout<<"FirstVT("<<arr[i][0]<<")={"; for(int l=1;arr[i][l+1]!='\0';l++)cout<<arr[i][l]<<",";cout<<arr[i][l]<<"}"<<endl;}cout<<"FirstVT(Q)={#}"<<endl;for(i=0;i<=ppp;i++)//打印LastVT{cout<<"LastVT("<<arr[i][0]<<")={";for(int l=1;brr[i][l+1]!='\0';l++)cout<<brr[i][l]<<",";cout<<brr[i][l]<<"}"<<endl;}cout<<"LastVT(Q)={#}"<<endl;cout<<"优先表如下:"<<endl;for(i=1;i<kk;i++)//打印优先关系表{ cout<<" ";cout<<ccrr1[0][i]; }cout<<endl;for(i=1;i<kk;i++){ cout<<ccrr2[i][0]<<" ";for(j=1;j<kk;j++){ if(crr[i][j]==0)cout<<" ";else if(crr[i][j]==1)cout<<"=";else if(crr[i][j]==2)cout<<"<";else if(crr[i][j]==3)cout<<">";cout<<" ";}cout<<endl; }judge2(n);//判断文法G是否为算符优先文法 if(FF==1){ char STR[1][20];cout<<"请输入要规约的字符串:"<<endl; gets(STR[0]);int ii=strlen(STR[0]);STR[0][ii]='#';cout<<"下面是规约的过程:"<<endl;process(STR,ii); }}。

相关文档
最新文档