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

合集下载

算符优先文法实验报告

算符优先文法实验报告

《编译原理》课程实验报告实验名称:算符优先文法姓名学号:地点:教师院系:计算机与通信工程学院专业:计算机科学与技术09-2一.实验目的设计、编制并调试一个算符优先法分析程序,加深对算符优先法分析原理的理解。

二.实验内容算术表达式的文法:(1).E → E +T | E -T | T(2).T → T * F | T / F | F(3).F → i |(E)转化后的文法:(1).E → E +T(2).E → E -T(3).E → T(4).T → T * F(5).T →T / F(6).T →F(7).F → i(8).F →(E)根据表达式的文法,首先计算每个非终结符的FIRSTVT和LASTVT:执行算法逐条扫描文法规则,从而构造出文法的算符优先关系表如图所示用算符优先分析法法对该文法进行分析,在每次归约成功后则输出四元式。

四元式形式如下:(op,arg1,arg2,result)其中op是运算符,arg1,arg2分别是第一和第二个运算对象,当op是一目运算时,常常将运算对象定义为arg1.例如,表达式-C和赋值语句X=a的四元式可分别表示为(i)(@,C,-,T)(j)(=,a,-,X)三.源代码:#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXSIZE 64 //栈的大小#define N -10typedef char datatype; //以char作为栈中元素typedef struct //定义一个栈结构{datatype data[MAXSIZE];int top;}seqstack;seqstack OPR; //操作数栈OPRseqstack OPT; //申明操作符栈char *p; //全局变量指针,用来指向待分析字符串int matrix[7][7]={{N,-1,-1,-1,-1,N,1}, //算符优先矩阵{N,1,-1,-1,-1,1,1},{N,1,1,-1,-1,1,1},{1,1,1,N,N,1,1},{N,-1,-1,-1,-1,0,N},{N,1,1,N,N,1,1},{-1,N,N,-1,N,N,0}};int row,line; //全局变量,分别来表示算符优先矩阵的行和列int count=1;int compare(char m,char n){ //算符的优先级switch(m){case '=':row=0;break;case '+':row=1;break;case '*':row=2;break;case 'i':row=3;break;case '(':row=4;break;case ')':row=5;break;case '$':row=6;break;default: return -100;break;}switch(n){case '=':line=0;break;case '+':line=1;break;case '*':line=2;break;case 'i':line=3;break;case '(':line=4;break;case ')':line=5;break;case '$':line=6;break;default: return -100;break;}return matrix[row][line];}//定义对操作数栈的基本操作void OPRsetnull() //设置操作数栈空{OPR.top=-1;}bool OPRempty() //判断操作数栈是否为空{if(OPR.top>=0)return false;elsereturn true;}void OPRpush(char x) //往操作数栈push一个操作数i{printf("上溢!");else {OPR.top++;OPR.data[OPR.top]=x;}}datatype OPRpop() //从操作数栈中pop出一个操作数{if(OPRempty()){printf("下溢!");return NULL;}else{OPR.top--;return(OPR.data[OPR.top+1]);}}//定义对操作数栈的基本操作结束datatype OPRtop() //获取操作数栈的栈顶的操作数{if(OPRempty()){return NULL;}elsereturn(OPR.data[OPR.top]);}void OPTsetnull() //设置操作符栈空{OPT.top=-1;}bool OPTempty() //判断操作符栈是否为空{if(OPT.top>=0)return false;elsereturn true;}void OPTpush(char x) //往操作符栈push一个操作数{printf("上溢!");else{OPT.top++;OPT.data[OPT.top]=x;}}datatype OPTpop() //从操作数符中pop出一个操作数{if(OPTempty()){printf("下溢!");return NULL;}else{OPT.top--;return(OPT.data[OPT.top+1]);}}datatype OPTtop() //获取操作符栈的栈顶的操作数{if(OPTempty()){return NULL;}else return(OPT.data[OPT.top]);}//定义对操作符栈的基本操作结束void output(char opt,char op1,char op2,int num) //输出四元式{if(op1=='i'&&op2=='i') printf("(%c,%c,%c,t%d)\n",opt,op1,op2,num);if(op1!='i'&&op2=='i') printf("(%c,t%d,%c,t%d)\n",opt,op1,op2,num);if(op2!='i'&&op1=='i') printf("(%c,%c,t%d,t%d)\n",opt,op1,op2,num);if(op1!='i'&&op2!='i') printf("(%c,t%d,t%d,t%d)\n",opt,op1,op2,num); }void scan()//扫描语法分析程序{char opt;char op1,op2;if(*p=='$') OPTpush(*p);//将待分析的字符串的首字符$压栈p++;while(*p!='$')//循环直到待分析字符串尾{if(*p=='i') OPRpush(*p);//如果当前字符是操作数则入栈,只有i一种操作数else {opt=OPTtop();//否则是操作符与操作符栈顶的字符比较优先级P: switch(compare(opt,*p)){case -1: OPTpush(*p); break;//如果栈顶操作符优先级下,则将当前字符压栈case N: break;//若无优先级则说明待分析字符有误,不合语法规范//出现语法错误case 0: OPTpop(); break;//若操作符优先级相等则说明栈顶//符合当前操作符分别是左右括号//将栈顶的左括号出栈即可case 1: op1=OPRpop();//若栈顶操作符优先级高,则将操作符栈最上两个操作数出栈op2=OPRpop();output(opt,op1,op2,count);//输出四元式OPRpush(count); //并将生成的t的序数压栈(t1,t2等);count++;opt=OPTpop();//将已规约的输出的操作符出栈opt=OPTtop();//取栈顶操作符跳转到继续下一步。

算符优先语法分析设计原理与实现技术实验报告

算符优先语法分析设计原理与实现技术实验报告

算符优先语法分析设计原理与实现技术实验报告变更说明一、实验目的:本实验的目的在于在教师的引导下以问题回朔与思维启发的方式,使学生在不断的探究过程中掌握编译程序设计和构造的基本原理和实现技术,启迪学生的抽象思维、激发学生的学习兴趣、培养学生的探究精神和专业素养,从而提高学生发现问题、分析问题和解决问题的能力。

二、实验内容:[实验项目]实现算符优先分析算法,完成以下描述算术表达式的算符优先文法的算符优先分析过程。

G[E]:E→E+T∣E-T∣TT→T*F∣T/F∣FF→(E)∣i[实验说明]终结符号i 为用户定义的简单变量,即标识符的定义。

[设计要求](1)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。

输出为输入串是否为该文法定义的算术表达式的判断结果;(2)算符优先分析过程应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

三、实验环境:操作系统:Windows 7软件:VC++6.0四、程序功能描述:●提供了文件输入方式,且输入的内容为二元式序列;●能够对输入的字符串做出正确的算符优先分析判断,并给出判断结果,判断结果输出到文件,并显示在屏幕;●能发现输入串中的错误,包含非法字符,输入不匹配等;●能够处理一些可预见性的错误,如文件不存在,输入非法等。

五、数据结构设计:六、程序结构描述:●设计方法:本程序采用从文件读取的输入方式,输入的内容需为二元式序列,然后按照算符优先分析的方法对输入的字符串进行分析判断,分析完成后输出判断结果到文件,并在屏幕显示。

程序通过对输入串的检查能够发现输入串中的错误。

程序规定的单词符号及其种别码见下表:算符优先矩阵+ - * / ( ) i #+ > > < < < > < >- > > < < < > < >* > > > > < > < >/ > > > > < > < >( < < < < < = < >) > > > > > >i > > > > > ># < < < < < < < =●算符优先分析法简介基本思路是根据既定的规则构建算符优先矩阵,然后根据算符之间的优先关系寻找输入串中的最左素短语,若找到,则寻找与最左素短语匹配的产生式进行规约;否则进行移进操作,及输入的算符进分析栈。

算符优先实验报告

算符优先实验报告

算符优先实验报告《算符优先实验报告》引言算符优先是一种用于解决算术表达式中运算符优先级的算法,它可以帮助我们在计算表达式时确定运算符的优先级,从而得到正确的计算结果。

本实验旨在通过编写算符优先算法的程序,来深入理解算符优先的原理和应用。

实验目的1. 了解算符优先算法的原理和应用。

2. 掌握算符优先算法的程序设计方法。

3. 实现一个能够正确解析算术表达式并计算结果的程序。

实验内容1. 算符优先算法的原理和应用算符优先算法是一种基于文法的算法,它通过分析运算符之间的优先级和结合性来确定表达式的计算顺序。

在算符优先算法中,每个运算符都有一个优先级,高优先级的运算符先进行计算,低优先级的运算符后进行计算。

此外,算符优先算法还要考虑到运算符的结合性,即左结合或右结合。

2. 算符优先算法的程序设计方法为了实现算符优先算法,我们需要首先定义运算符的优先级和结合性,然后编写程序来解析表达式并按照算符优先规则进行计算。

在程序设计中,我们可以使用栈来辅助进行运算符的优先级判断和计算顺序的确定。

3. 实现一个能够正确解析算术表达式并计算结果的程序在本实验中,我们将编写一个简单的算符优先算法程序,该程序能够正确解析算术表达式并按照算符优先规则进行计算,最终得到正确的计算结果。

实验结果通过本次实验,我们成功实现了一个能够正确解析算术表达式并计算结果的程序。

该程序能够正确地处理不同优先级和结合性的运算符,并得到正确的计算结果。

这表明算符优先算法是一种有效的算法,能够帮助我们正确地处理算术表达式中的运算符优先级问题。

结论通过本次实验,我们深入理解了算符优先算法的原理和应用,并掌握了算符优先算法的程序设计方法。

算符优先算法是一种重要的算法,它在计算表达式时能够帮助我们确定运算符的优先级,从而得到正确的计算结果。

在今后的学习和工作中,我们将继续深入研究算符优先算法,并将其应用到更多的实际问题中。

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

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

算符优先语法分析设计原理与实现技术XXX 1028XXX 计科1XXX 班功能描述能够有效识别以下算符优先文法E T E+T | E-TT T T*F | T/F | FF T (E) | i所描述算术表达式.主要数据结构描述程序结构描述设计方法2. 根据算符优先矩阵算数表达式的词法分析结果进行语法分析,分析算法为:数据结构:符号栈S ---存放所有读进的符号(计数i)K ---符号栈使用深度a ---工作单元R, Q ---变量分析算法:先找最左素短语的尾部(>)再找最左素短语的头部(<)以分析表达式i+i*i为例,详细过程如下:■算符优先关系矩阵例:舖入串i+i*i 的界苻优先分析过程(査界替优先关系矩体)1#N + N**<i■11# N + N*'■ 1#1#N + N J* N+<*># 接受# N + N#<+>## N结论:汁详iJt 文法的命法句子函数原型功能描述void in it()各种初始化操作,主要是建立符号与整 数、整数与行列号、整数与符号之间的映 射,也包括各全局变量的初始化void isVt(i nt )判断某整数所代表的符号是否是终结符##<i# i#<i>-l- #N#<+# N + +<i# N + i +<i>* # N+ N+<*分析栈优先关系号或’#'void comp(i nt a, int b) r比较两整数所代表的字符的优先关系—void adva nce() 从输入文件中读入一个词bool parser() 算符优先分析函数,根据算符优先矩阵进行语法分析int main (i nt argc, char *argv[]) 主函数,参数argv[1]代表输入文件函数调用关系程序执行图S(l)=#;i=l;k=Q;k~k+1: R=siiLrQ=SG); j=j-ij=j-i l| t=i 11i=讦丄;S(i)=R程序测试测试用例一:(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')在以此分析结果作为本程序实验结果的输入,得到如下分析结果:taw Cf'v/indov^5\system32\cmd.exe该结果显示了详细的分析过程,且表明该表达式是一个符合该文法的表达式测试用例二:(a+b*c)+d*-a*c+(a+b同样调用实验--的词法分析程序,得到如下结果:(19, '(')(12, 'a')(14, '+')(12, 'b')(16, '*')(12, 'c')(20, ')')(14, '+') (12, 'd') (16, '*') (15, '-') (12, 'a') (16, '*') (12, 'c') (14, '+') (19, '(') (12, 'a') (14, '+') (12, 'b')以此分析结果作为本实验程序的输入,得到如下语法分析结果:实验结果表明,在分析过程中出现了错误,分析过程未完成,该样例是一个非法的表达式.学习总结按算符优先关系所确定的应被规约的子串恰好是当前举行的最左素短语.尽管算符优先分析也属于自底向上语法分析的范畴,但却不是严格的从左至右的规范分析,每步所得的句型自然也不是一个规范句型.采用上述策略进行算符优先分析时,尽管我们也指出了每一最左素短语应规约到的非终结符号,然而每次在查找最左素短语时,起主导作用的是终结符号间的优先关系,两终结符号之间究竟是哪个非终结符号无关宏旨.// operator_prior.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <ctype.h>#include <map>#include <vector>#include <string>#define ID 12#define ADD 14#define SUB 15#define MUL 16#define DIV 17#define LP 19#define RP 20#define EOI 31#define SHARP 32#define EQ 0#define BT 1#define LT 2#define UD 3#define N_Base 1000 using namespace std;FILE *fp;int lookahead, yylineno;bool success;map<int, int> intToint; map<char, int> charToint; map<int, char> intTochar; string grammer[8] = {"E+T", "E-T", "T","T*F", "T/F", "F","(E)", n:n};int prior_matrix[9][9] = {{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{LT, LT, LT, LT, LT, EQ, LT, UD},{BT, BT, BT, BT, UD, BT, UD, BT},{BT, BT, BT, BT, UD, BT, UD, BT},{LT, LT, LT, LT, LT, UD, LT, EQ}};void init() {success = true;yylineno = 0;intToint[ADD] = 0; intToint[SUB] = 1;intToint[MUL] = 2; intToint[DIV] = 3;intToint[LP] = 4; intToint[RP] = 5;intToint[ID] = 6; intToint[SHARP] = 7;charToint['+'] = ADD; charToint['-'] = SUB;charToint['*'] = MUL; charToint['/'] = DIV;charToint['('] = LP; charToint[')'] = RP;charToint['i'] = ID;intTochar[ADD] = '+'; intTochar[SUB] = '-';intTochar[MUL] = '*'; intTochar[DIV] = '/';intTochar[LP] = '('; intTochar[RP] = ')';intTochar[ID] = 'i'; intTochar[SHARP] = '#';intTochar[N_Base] = 'N';}bool isVt(int a) {if (a >= N_Base) return false;else return true;}int comp(int a, int b) { int x = intToint[a];int y = intToint[b]; return prior_matrix[x][y]; }void advance() {if (fscanf(fp, "(%d", &lookahead) == EOF) { lookahead = SHARP;} else {char ch;do {ch = fgetc(fp);if (ch == '\n' || ch == EOF) break; } while (true);} yylineno++;}void parser() {int stack[100], top = 0;int i, j, k, ii, jj;stack[top++] = SHARP;advance();do {for (i = 0; i < top; i++) {printf("%c", intTochar[stack[i]]);}printf("\t%c\n", intTochar[lookahead]);for (i = top - 1; i >= 0; i--) { if (isVt(stack[i])) break;}int res = comp(stack[i], lookahead);if (res == LT || res == EQ) { stack[top++] = lookahead; advance();} else if (res == BT) {int temp = stack[i]; for (j = i - 1; j >= 0; j--) {if (isVt(stack[j])) {if (comp(stack[j], temp) == LT) {break;} else {temp = stack[j];}}}for (k = 0; k < 8; k++) {if ((int)grammer[k].length() == top - 1 - j) {ii = j + 1;jj = 0;do {if (grammer[k].at(jj) >= 'A' && grammer[k].at(jj) <= 'Z'){ if (isVt(stack[ii])) break;} else {if (charToint[grammer[k].at(jj)] != stack[ii]) break;}ii++;jj++;} while (ii < top && jj < (int)grammer[k].length());if (ii >= top) break;}}if (k >= 8) {success = false;return ;}top = j + 1;stack[top++] = N_Base;} else {success = false;return ;}if (stack[0] == SHARP && stack[1] == N_Base&& stack[2] == SHARP) { printf("#N#\n"); break;}} while (true);success = true;}int main(int argc, char *argv[]) {if (argc == 2) {fp = fopen(argv[1], "r");init();parser();if (success) printf("This is a legal expression."); else printf("Thisis a illegal expression.");} else {printf(" 参数错误!\n");}return 0;。

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

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

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

⑶实习时间为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文件中五、实验总结经过此次试验对算符优先分析的原理有了深入的理解,熟悉了算符分析的过程,掌握了算符优先分析的有关处理,能够使用一种高级语言构造算符优先的语法分析器。

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

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

实验三 算符优先分析算法的设计与实现(8学时)一、 实验目的根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。

通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。

二、 实验要求1、输入文法。

可以是如下算术表达式的文法(你可以根据需要适当改变):E→E+T|E-T|TT→T*F|T/F|FF→(E)|i2、对给定表达式进行分析,输出表达式正确与否的判断。

程序输入/输出示例:输入: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] thenbeginF[P,a] = true; //(P,a)进栈end;Procedure FirstVT;Beginfor 对每个非终结符 P和终结符 a doF[P,a] = falsefor 对每个形如 P a…或 P→Qa…的产生式 doInsert(P,a)while stack 非空begin栈顶项出栈,记为(Q,a)for 对每条形如 P→Q…的产生式 doinsert(P,a)end;end.同理,可构造计算LASTVT的算法。

实验二语法分析(算符优先)(1)

实验二语法分析(算符优先)(1)

实验二语法分析实验报告一、实验题目算符优先分析程序二、实验内容及要求(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][0]='>';priority[0][1]='<';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][1]='<';priority[5][2]='<';priority[5][3]='<';priority[5][4]='$';priority[5][5]='=';}void analyse()//对所输入的句子进行算符优先分析过程的函数{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'||Analys eStack[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;}p=priority[z][n];if(p=='$'){printf("错误!该句子不是该文法的合法句子!\n");return;}if(p=='>'){ for( ; ; ){Q=AnalyseStack[j];if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'||Ana lyseStack[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);k=j+1;i--;AnalyseStack[k]='N';int r,r1;r=strlen(AnalyseStack);for(r1=k+1;r1<r;r1++)AnalyseStack[r1]='\0';break;}elsecontinue;}}else{if(p=='<') //表示移进{count++;printf("(%d) %s\t%10c\t%5c%17s\t 移进\n",count,AnalyseStack,p,a,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);printf("该句子是该文法的合法句子。

编译原算符优先分析实验报告 (2)

编译原算符优先分析实验报告 (2)

编译原理实验报告——算符优先文法分析指导教师:***学号:**********姓名:***【实验名称】算符优先文法分析【实验目的】掌握算符优先分析法的原理,利用算符优先分析法将赋值语句进行语法分析,翻译成等价的四元式表示。

【实验内容】1.算术表达式的文法可以是:(1)S->#E# (2)E->E+T (3)E->T (4)T->T*F (5)T->F (6)F->P^F (7)F->P (8)P->(E) (9)P->i2.根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。

【设计思想】(1)定义部分:定义常量、变量、数据结构。

(2)初始化:设立算符优先关系表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用算符优先文法分析算法进行表达式处理:根据优先关系表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

【流程图】【源码】#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <stack>using namespace std;struct Node1{char vn;char vt;char s[10];}MAP[20];//存储分析预测表每个位置对应的终结符,非终结符,产生式int k;//用R代表E',W代表T',e代表空char G[10][10]={"E->TR","R->+TR","R->e","T->FW","W->*FW","W->e","F->(E)","F->i"};//存储文法中的产生式char VN[6]={'E','R','T','W','F'};//存储非终结符char VT[6]={'i','+','*','(',')','#'};//存储终结符char SELECT[10][10]={"(,i","+","),#","(,i","*","+,),#","(","i"};//存储文法中每个产生式对应的SELECT集char Right[10][8]={"->TR","->+TR","->e","->FW","->*FW","->e","->(E)","->i"};stack <char> stak,stak1,stak2;bool compare(char *a,char *b){int i,la=strlen(a),j,lb=strlen(b);for(i=0;i<la;i++)for(j=0;j<lb;j++){if(a[i]==b[j])return 1;}return 0;}char *Find(char vn,char vt){int i;for(i=0;i<k;i++){if(MAP[i].vn==vn && MAP[i].vt==vt)return MAP[i].s;}return "error";}char * Analyse(char * word){char p,action[10],output[10];int i=1,j,l=strlen(word),k=0,l_act,m;while(!stak.empty())stak.pop();stak.push('#');stak.push('E');printf("_________________________________________________________________________ _______\n");printf("\n 对符号串%s的分析过程\n",word);printf(" 步骤栈顶元素剩余输入串推到所用产生式或匹配\n");p=stak.top();while(p!='#'){printf("%7d ",i++);p=stak.top();stak.pop();printf("%6c ",p);for(j=k,m=0;j<l;j++)output[m++]=word[j];output[m]='\0';printf("%10s",output);if(p==word[k]){if(p=='#'){printf(" 接受\n");return "SUCCESS";}printf(" “%c”匹配\n",p);k++;}else{strcpy(action,Find(p,word[k]));if(strcmp(action,"error")==0){printf(" 没有可用的产生式\n");return "ERROR";}printf(" %c%s\n",p,action);int l_act=strlen(action);if(action[l_act-1]=='e')continue;for(j=l_act-1;j>1;j--)stak.push(action[j]);}}if(strcmp(output,"#")!=0)return "ERROR";}int main (){freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);char source[100];int i,j,flag,l,m;printf("\n为了方便编写程序,用R代表E',W代表T',e代表空\n\n");printf("该文法的产生式如下:\n");for(i=0;i<8;i++)printf(" %s\n",G[i]);printf("\n该文法的SELECT集如下:\n");for(i=0;i<8;i++){printf(" SELECT(%s) = { %s }\n",G[i],SELECT[i]);}//判断是否是LL(1)文法flag=1;for(i=0;i<8;i++){for(j=i+1;j<8;j++){if(G[i][0]==G[j][0]){if(compare(SELECT[i],SELECT[j])){flag=0;break;}}}if(j!=8)break;}if(flag)printf("\n有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。

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

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

年级专业_学号 _姓名成绩__________________数学与计算机学院编译原理实验报告实验题目算符优先分析法分析器的设计实验日期一、实验目的:设计一个算符优先分析器,理解优先分析方法的原理。

二、实验要求:设计一个算符优先分析器三、实验内容:使用算符优先分析算法分析下面的文法:E' T #E#E T E+T | TT T T*F | FF T P AF | PP T (E) | i其中i可以看作是一个终结符,无需作词法分析。

具体要求如下:1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况;2、如果输入符号串不是正确句子,则指示出错位置。

四、实验结果及主要代码:1•主要代码 void operatorp()char s[100];char a,Q;int k,j,i,l;string input,temp;cin>>input;"<<'\t'<<" 剩cout<<" 步骤 "<<'\t'<<" 栈 "<<'\t'<<" 优先关系 "<<'\t'<<" 当前符号余输入串 "<<'\t'<<" 移进或归约 "<<endl;k=1;s[k]='#';i=1;do{a=input[0];temp="";for(l=1;l<input.length();l++)temp+=input[l];input=temp;if(svt(s[k])) j=k;else j=k-1;while (search(s[j],a)=='>'){// 步骤cout<<'('<<i<<')'<<'\t';temp="";// 优先关系 // 当前符号 // 剩余输入串for(l=1;l<k+1;l++)temp+=s[l];cout<<temp<<'\t'; // 栈cout<<'>'<<'\t'<<setw(10);cout<<a<<'\t'<<setw(15);cout<<input<<'\t'<<setw(15);i++;for(;;){Q=s[ j];if(svt(s[j-1])) j=j-1;else j=j-2;if(search(s[j],Q)=='<'){cout<<" 归约 "<<endl;// 归约break;}}temp="";for(l=j+1;l<k+1;l++)temp+=s[l]; for(l=0;l<6;l++)// 优先关系// 当前符号// 剩余输入串if(temp==key[l]){k=j+1; s[k]=v[l]; break;}}cout<<'('<<i<<')'<<'\t'; // 步骤 temp="";for(l=1;l<k+1;l++)temp+=s[l];cout<<temp<<'\t'; // 栈if(search(s[j],a)=='<'){cout<<'<'<<'\t'<<setw(10);;cout<<a<<'\t'<<setw(15);cout<<input<<'\t'<<setw(15);cout<<" 移进 "<<endl;i++;k=k+1;s[k]=a;} // 移进else if(search(s[j],a)=='Y')cout<<'='<<'\t'<<setw(10);; //优先关系cout<<a<<'\t'<<setw(15); //当前符号cout<<i nput<<'\t'<<setw(15); //剩余输入串cout<<"接受"<<e ndl;i++;}else{cout<<?<<'\t'<<setw(10);; //优先关系cout<<a<<'\t'<<setw(15); //当前符号cout<<i nput<<'\t'<<setw(15); //剩余输入串cout<<"出错"<<e ndl;exit(O);}//出错}while(a!='#');2•实验结果优九关系 ■fri 利余输入串 当前符号 i*n few ■ *F ::\2O12\^i§J '^:S\^:SJFt?^=£-\0perator_preredAnce_rpdL4r+ion\cipFr i a J or^preced?nre,red 1! 話讲<2> <3> <4> <5> <6> <7> Pi*es £栈 t 11 tF IF* »F*i tF*F tF any key to continue H inn imtmt欢迎下载,谢谢观看!资料仅供参考学习。

实验2 语法分析(算符优先分析)

实验2 语法分析(算符优先分析)

实验2 语法分析(算符优先分析)一、实验任务:算术表达式的文法:E→ E+T | E-T | TT→ T*F | T/F | FF→(E)| i根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。

二、实验时间:上机2次。

三、实验过程和指导:(一)准备:1.确定算术表达式的文法,设计出算符优先关系表;2.考虑好设计方案,设计出模块结构、测试数据;3.初步编制好程序。

(二)上机实验:上机调试,发现错误,分析错误,逐渐修改完善。

(三)程序要求:程序输入/输出示例:如参考C语言的运算符。

输入如下表达式(以分号为结束)和输出结果:(1)10输出:正确(2)1+2*(15-6)输出:正确(3)(1+2)/3+4- (11+6/7)输出:正确(4)((1-2)/3+4输出:错误,出错位置是(5)1+2-3+(*4/5)输出:错误,出错位置是注意:1.为降低难度,表达式中不含变量(只含无符号整数);2.可以直接调用此法分析程序,取得单词;3.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好,最好有详细的出错位置和出错性质说明);4.测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;5.对学有余力的同学,可增加功能:当判断一个表达式正确时,输出计算结果,计算过程用浮点表示,但要注意不要被0除。

(四)练习该实验的目的和思路:程序比较复杂,需要利用到大量的编译原理,也用到了大量编程技巧和数据结构,通过这个练习可极大提高编程能力。

程序规模大概为300行。

通过练习,掌握对表达式进行处理的一种方法。

(五)为了能设计好程序,注意以下事情:1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。

3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用、变量合理命名等。

算符优先_实验报告

算符优先_实验报告

一、实验目的1. 理解算符优先分析法的原理和过程。

2. 掌握算符优先分析法的实现方法。

3. 通过实验加深对自底向上语法分析方法的理解。

二、实验内容1. 算符优先分析法原理介绍算符优先分析法是一种自底向上的语法分析方法,它通过比较相邻算符的优先次序来识别句型中的句柄,进而执行归约。

该方法的核心是确立文法的终结符之间的优先关系。

2. 实验步骤(1)判断文法是否为OG文法:OG文法要求所有产生式右部至少有一个终结符。

(2)判断文法是否为OPG文法:计算FIRSTVT集、LASTVT集,并构建算符优先矩阵。

(3)对句子进行分析:根据分析表判断句子是否为文法的句子。

(4)实现程序:从文件和键盘读取输入,将结果输出到指定文件和屏幕,并具有一致性。

3. 实验数据(1)文法:g[e]:e->e+t|t(2)测试句子:12+t, t+12, 12+13t, 12+t13三、实验过程1. 判断文法是否为OG文法根据给定的文法,我们可以看到所有产生式右部至少有一个终结符,因此该文法为OG文法。

2. 判断文法是否为OPG文法,并构建算符优先矩阵(1)计算FIRSTVT集FIRSTVT(e) = {t}FIRSTVT(t) = {t}(2)计算LASTVT集LASTVT(e) = {t}LASTVT(t) = {t}(3)构建算符优先矩阵| + - ( ) t e $+ > - - - > > -- > - - - > > -> > > > > > >( > > > > > > >) - - - - - - -t - - - - - - -e - - - - - - -$ - - - - - - -3. 对句子进行分析(1)分析句子“12+t”根据分析表,我们可以得到以下分析过程:12+t -> 12+t -> 12+t -> t -> t(2)分析句子“t+12”根据分析表,我们可以得到以下分析过程:t+12 -> t+12 -> t+12 -> t+12 -> t+12 -> t -> t (3)分析句子“12+13t”根据分析表,我们可以得到以下分析过程:12+13t -> 12+13t -> 12+13t -> 12+13t -> 12+13t -> t -> t(4)分析句子“12+t13”根据分析表,我们可以得到以下分析过程:12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> 12+t13 -> t13 -> t13 -> t13 -> t -> t四、实验结果1. 测试句子“12+t”分析结果:正确2. 测试句子“t+12”分析结果:正确3. 测试句子“12+13t”分析结果:正确4. 测试句子“12+t13”分析结果:正确五、实验总结通过本次实验,我们深入了解了算符优先分析法的原理和实现方法。

LL(1)语法分析设计原理与实现技术实验 实验报告及源代码 北京交通大学

LL(1)语法分析设计原理与实现技术实验 实验报告及源代码 北京交通大学

LL(1)语法分析设计原理与实现技术实验计科100X班 10284XXX程序设计功能实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的LL(1)文法的LL(1)分析程序。

G[E]: E→TE′E′→ATE′|εT→FT′T′→MFT′|εF→(E)|iA→+|-M→*|/说明:终结符号i 为用户定义的简单变量,即标识符的定义。

主要数据结构描述由文法可得:对于E:FIRST( E )= {(, i }对于E’: FIRST( E’ ) ={+,−,ε}对于T: FIRST( T )= ={(, i }对于T’: FIRST( T’)= ={*,∕,ε}对于F: FIRST( F )= ={(, i }对于A: FIRST( A )= ={+, - }对于M: FIRST(M)= ={*, / }由此我们容易得出各非终结符的FOLLOW集合如下:FOLLOW( E )= { ),#}FOLLOW(E’) ={ ),#}FOLLOW( T ) ={+,−,),#}FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}FOLLOW( F )=FIRST(T’)\ε∪FOLLOW(T’)={*,∕,+,−,),#}FOLLOW( A )= { (, i }FOLLOW( M )= { (, i}文法LL(1)的预测分析表(表1):表1. LL(1)预测分析表注:为编程方便,在程序中,将E’、T’改为G、S程序结构描述1.设计方法:程序通过从文本文档读入数据,将所读数据以空格、回车或者退格为标示符,分为字符串,对字符串进行词法分析,最后将所有字符串按序输出到结果文档中,并在结果文档中标明每个字符串的类别序号。

2、程序中主要函数定义和调用关系如下:函数:void print()作用:输出分析栈void print1();作用:输出剩余串int main();作用:主要逻辑功能程序执行图如下:实验结果测试用例1:i+i*i#测试用例2:i-i++#实验总结相对于递归下降分析法,LL(1)分析法更为有效.采用此种方法的分析器由一张预测分析表(LL(1)分析表)、一个控制程序(表驱动程序)和一个分析栈组成,预测分析表中个元素的含义是:或者指出当前推到所应使用过的产生式,或者指出输入符号串中存在语法错误.LL(1)分析法的局限在于:只能分析LL(1)文法或者某些非LL(1)文法,但需先将其改造成LL(1)文法。

C.4-算符优先分析法-实验报告

C.4-算符优先分析法-实验报告
姓名
学号
成绩
实 验 报 告
实验题目:算符优先分析法
课程名称:编译原理
主讲教师:
班 级:
实验日期:
提交日期:
1、
实验目的:
采用算符优先分析法对表达式(不包含括号运算)进行分析,并给出四元式。
二、实验内容
在实验1、2的基础上,用算符优先分析法编制语法分析程序。
分析过程:先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。分析过程从头开始,并重复进行;若读来的是运算符θ2 则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。
结果
四、我的感想
这次试验可以说是前两个试验的综合了,程序中也很多用到了前两次的代码。对于我自己来说,最难的部分在于将这些思想转换成代码实现出来,很大一部分在于自己平时没有多打代码以及就是对算符优先分析的思想理解得还不够透彻。在写main函数时,因为要调用很多函数,刚开始写的时候陷入了死循环,以及栈函数的各种调用发生错误,说明自己思路还不够清晰。因为这次实验是在考完试后做的,之前对算符优先分析以及四元式的理解不够明白,在这个实验实现成功后,自己能够透彻地了解,知道了算符文法的形式,对给定的算符文法能构造算符优先关系分析表,并判别所给出的文法是否为算符优先文法。同时我也算符优先文法的优缺点以及实际应用中的局限性。
三、程序的改写:
因为这次的实验与前面两次的实验有很大的重合,所以会用到很多之前两次的代码。首先,定义函数:
其中本次需要写的函数有:入栈优先函数f,比较优先函数g,compare,middle,栈函数以及主函数。
1.入栈优先函数f
书上已经给出了入栈优先函数的表,根据输入的符号赋予数值,以便后面方便比较。

语义分析及中间代码生成程序设计原理与实现技术--实验报告及源代码-北京交通大学

语义分析及中间代码生成程序设计原理与实现技术--实验报告及源代码-北京交通大学

语义分析及中间代码生成程序设计原理与实现技术XXX 1028XXX2 计科1XXX班1.程序功能描述完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过程。

G[A]:A→V:=EE→E+T∣E-T∣T→T*F∣T/F∣FF→(E)∣iV→i说明:终结符号i 为用户定义的简单变量,即标识符的定义。

2. 设计要求(1)给出每一产生式对应的语义动作;(2)设计中间代码四元式的结构(暂不与符号表有关)。

(3)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。

输出为输入串的四元式序列中间文件。

(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。

3.主要数据结构描述:本程序采用的是算符优先文法,文法以及算符优先矩阵是根据第四次实验来修改的,所以主要的数据结构也跟第四次差不多,主要为文法的表示,FirstVT集和LastVT集以及算符优先矩阵:算符优先矩阵采用二维字符数组表示的:char mtr[9][9]; //算符优先矩阵4.程序结构描述:本程序一共有8功能函数:void get(); //获取文法void print(); //打印文法void fun(); //求FirstVT 和 LastVTvoid matrix(); //求算符优先矩阵void test(); //测试文法int cmp(char a,char b); 比较两个运算符的优先级 1 0 -1void out(char now,int avg1,int avg2); //打印四元式int ope(char op,int a,int b); //定义四元式计算方法5.实验代码详见附件6.程序测试6.1 功能测试程序运行显示如下功能菜单:选择打印文法:选择构造FirstVt集和LastVT集:选择构造算符优先矩阵:6.2 文法测试测试1:1+2*3测试2:2+3+4*5+(6/2)7.学习总结本次实验完成了语义及中间代码生成的设计原理与实现,所采用的方法为算符优先分析方法,首先根据文法求出此文法的FirstVT集和LastVT集,然后根据他们求出此文法的算符优先矩阵。

算符优先实验报告

算符优先实验报告

算符优先实验报告算符优先实验报告引言算符优先是一种用于描述和分析算术表达式的语法分析方法。

在本次实验中,我们将通过编写一个算符优先分析器来深入理解算符优先算法的原理和应用。

实验目的1. 了解算符优先算法的基本原理和概念;2. 掌握算符优先算法的具体实现方法;3. 实现一个简单的算符优先分析器,用于分析和判断输入的算术表达式是否符合文法规则。

实验过程1. 算符优先的基本原理算符优先算法是一种自底向上的语法分析方法,用于判断算术表达式中运算符的优先级关系。

它通过构建一个算符优先关系表来实现对表达式的分析和判断。

2. 算符优先的概念和定义算符优先表是一个二维表格,行和列分别表示算术表达式中的运算符。

表格中的每个元素表示两个运算符之间的优先关系,可以是大于、小于或等于。

根据这个表格,我们可以判断两个相邻的运算符之间的优先级关系。

3. 算符优先分析器的实现为了实现一个算符优先分析器,我们首先需要构建算符优先表。

算符优先表的构建需要根据文法规则和运算符的优先级来确定。

在本次实验中,我们假设算术表达式中只包含加法和乘法运算符,并且加法运算符的优先级高于乘法运算符。

4. 算符优先分析的过程算符优先分析的过程可以分为两个步骤:扫描和规约。

在扫描过程中,我们从左到右扫描输入的算术表达式,并将扫描到的运算符和操作数依次入栈。

在规约过程中,我们根据算符优先表中的优先关系,将栈中的符号进行规约,直到最终得到一个唯一的非终结符号。

实验结果与分析通过实验,我们成功实现了一个简单的算符优先分析器,并对不同的算术表达式进行了分析和判断。

实验结果表明,算符优先分析器能够准确地判断算术表达式的语法正确性,并且能够正确地处理运算符的优先级关系。

结论算符优先算法是一种常用的语法分析方法,能够有效地判断算术表达式的语法正确性。

通过本次实验,我们深入理解了算符优先算法的原理和应用,并成功实现了一个简单的算符优先分析器。

这对我们进一步学习和应用语法分析方法具有重要的意义。

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

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

专题4_算符优先语法分析李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;算符优先文法、最左素短语、算符优先矩阵、优先函数的基本概念;算符优先文法句型最左素短语的确定;算符优先分析算法的实现。

二、目标任务实验项目实现算符优先分析算法,完成以下描述算术表达式的算符优先文法的算符优先分析过程。

G[E]:E→E+T|E-T|TT→T*F|T/F|FF→(E)|i设计说明终结符号i为用户定义的简单变量,即标识符的定义。

加减乘除即运算符。

设计要求(1)构造该算符优先文法的优先关系矩阵或优先函数;(2)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(3)算符优先分析程序应能发现输入串出错;(4)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

任务分析重点解决算符优先矩阵的构造和算符优先算法的实现。

能力培养深入理解理论对实践的指导作用;基本原理、实现技术和方法的正确运用。

三、实现过程OPG优先关系设G是一OG(简单优先)文法,a,b∈Vt,U,V,W ∈Vn(1)a = b 当且仅当OG有形如U→….ab….或U→….aVb….的规则(2)a < b 当且仅当OG有形如U→….aW….的规则,而且W=+>b….或W=+>Vb…..(3)a > b 当且仅当OG有形如U→….Wb….的规则,而且W=+> …. a或W=+>….aV 若a,b之间至多存在上述三种优先关系之一,OG为OPG(算符优先)文法。

FIRSTVT集和LASTVT集a)FIRSTVT集▪两条原则1.若有规则U→b…或U→Vb…,则b ∈ FIRSTVT(U)2.若有规则U→V…且b ∈ FIRSTVT(V),则b ∈ FIRSTVT(U)▪过程描述数据结构:STACK栈布尔数组F(U,b) U∈Vn,b∈VtF(U,b) 真 b∈FIRSTVT(U)假 b FIRSTVT(U)▪算法分析初始:F(U,b)初值(根据原则①)F(U,b)为真的(U,b)对进STACK栈循环:直至STACK空(根据原则②)弹出栈顶元素,记(V,b)对每一个形如U→V…的规则若F(U,b) 为假,变为真,进STACK栈若F(U,b) 为真,再循环结果:FIRSTVT(U)={b∣F(U,b)=TRUE}FIRSTVT(E)={ +, -, *, /, (, i }FIRSTVT(T)={ *, /, (, i }b)LASTVT集▪两条原则①若有规则U→…a或U→…aV,则a ∈ LASTVT (U)②若有规则U→…V且a ∈ LASTVT (V),则a ∈ LASTVT (U) ▪过程描述数据结构:STACK栈布尔数组F(U,a) U∈Vn,a∈VtF(U,a) 真 a∈LASTVT (U)假 a LASTVT (U)▪算法分析初始:F(U,a)初值(根据原则①)F(U,a)为真的(U,a)对进STACK栈循环:直至STACK空(根据原则②)弹出栈顶元素,记(V,a)对每一个形如U→V…的规则若F(U,a) 为假,变为真,进STACK栈若F(U,a)为真,再循环结果: LASTVT (U)={a∣F(U,a)=TRUE}LASTVT(E)={ +, -, *, /, ), i }LASTVT(T)={ *, /, ), i }最左素短语算符优先文法句型的一般形式:#N1a1N2a2…… N n a n N n+1# a i∈V t N i∈V n(可有可无)最左素短语的确定:一个OPG句型的最左素短语是满足以下条件的最左子串:N j a j…..N i a i N i+1其中:a j-1 < a ja j = a j+1 = … = a i-1 = a ia i > a i+1a j-1 < a j = a j+1= … = a i-1 = a i> a i+1 所以,构造OPG优先矩阵算法根据构造OPG优先矩阵算法,可得如下优先关系:+ FIRSTVT(T) LASTVT(E) +- FIRSTVT(T) LASTVT(E) -* FIRSTVT(F) LASTVT(T) */ FIRSTVT(F) LASTVT(T) /( FIRSTVT(E) LASTVT(E) ) ( )# FIRSTVT(E) LASTVT(E) #所以,构造OPG优先矩阵如表3.3所示:+ - * / ( ) i #acc算法框架主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。

LR 分析方法程序设计原理与实现技术实验报告及源代码 北京交通大学

LR 分析方法程序设计原理与实现技术实验报告及源代码 北京交通大学
lr分析方法程序设计原理与实现技术实验报告及源代码北京交通大学lr分析方法程序设计原理与实现技术xxx1028xxx计科1xxx通过设计编写和构造lr0项目集规范簇和lr分析表对给定的符号串进行lr析的程序了解构造lr0分析表的步骤对文法的要求能够从文法出发生成lr0分析表并对给定的符号串进行分析
LR 分析方法程序设计原理与实现技术
分析失败:aAcAd
分析成功:acd
7. 实验总结:
本次实验按照书上的相应步骤,一步一步按照要求来完成实现,最终文成了给定文 法的分析程序。首先是获取文法,文法的获取是采用直接输入的方法,保存成预先设定 的结构体,然后根据文法,对文法编号,求出项目集规范族,然后再构造 LR(0)分析 表,最后根据分析表来判断输入符号串是否为此文法产生的语言。
sign = 0;
for(int i = 0;i < pro[0].data.size();i ++){
for(int j = 0;j < pro[0].data[i].right.size();j ++){
char ch = pro[0].data[i].right[j][1];
if(ch <= 'Z' && ch >= 'A' && pro[0].data[i].sign == 0){ //
cout << " 文法获取完成"
<< endl;
cout << "****************************************" << endl;
cout << endl;

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

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

编译原理算符优先算法语法分析实验报告实验报告:算符优先算法的语法分析一、实验目的本次实验旨在通过算符优先算法对给定的文法进行语法分析,实现对给定输入串的分析过程。

通过本次实验,我们能够了解算符优先算法的原理和实现方式,提升对编译原理的理解和应用能力。

二、实验内容1.完成对给定文法的定义和构造2.构造算符优先表3.实现算符优先分析程序三、实验原理算符优先算法是一种自底向上的语法分析方法,通过构造算符优先表来辅助分析过程。

算符优先表主要由终结符、非终结符和算符优先关系组成,其中算符优先关系用1表示优先关系,用2表示不优先关系,用0表示无关系。

算符优先分析程序的基本思路是:根据算符优先关系,依次将输入串的符号压栈,同时根据优先关系对栈内符号进行规约操作,最终判断输入串是否属于给定文法。

四、实验步骤1.定义和构造文法在本次实验中,我们假设给定文法如下:1)E->E+T,T2)T->T*F,F3)F->(E),i2.构造算符优先表根据给定文法,构造算符优先表如下:+*()i#+212112*222112(111012222122i222222#1112203.实现算符优先分析程序我们可以用C语言编写算符优先分析程序,以下是程序的基本框架:```c#include <stdio.h>//判断是否为终结符int isTerminal(char c)//判断条件//匹配符号int match(char stack, char input)//根据算符优先关系表进行匹配//算符优先分析程序void operatorPrecedence(char inputString[]) //定义栈char stack[MAX_SIZE];//初始化栈//将#和起始符号入栈//读入输入串//初始化索引指针//循环分析输入串while (index <= inputLength)//判断栈顶和输入符号的优先关系if (match(stack[top], inputString[index])) //栈顶符号规约} else//符号入栈}//计算新的栈顶}//判断是否成功分析if (stack[top] == '#' && inputString[index] == '#')printf("输入串符合给定文法!\n");} elseprintf("输入串不符合给定文法!\n");}```五、实验结果经过实验,我们成功实现了算符优先算法的语法分析。

实验三(算符优先分析)

实验三(算符优先分析)

实验三算符优先分析
一.实验目的
1、掌握算符优先分析法——一种自底向上的语法分析方法的思想。

2、领会算符优先关系表转换成优先函数的方法。

二.实验内容
在TINY计算机语言的编译程序的词法分析部分实现的基础上,根据课堂讲授的形式化算法,编制程序实现一个算符优先分析器
语法分析的输入是记号串,按照从左到右扫描,按照文法规则的要求,判断表达式是否符合文法要求,如果符合要求则形成语法树,求出表达式的值,不符合则指出原因。

为了简化程序的编写,对表达式语法有具体如下的要求:
(1)E->E+E | E-E | E*E | E/E | (E) | id
(2)表达式的数只是整数
(3)表达式中没有变量
(4)要分析的表达式满足下面的算符优先矩阵
三.实验要求
要求实现语法分析程序的以下功能:
(1)把表达式首先经过词法分析形成二元式记号提供给语法分析程序
(2)如果符合语法要求,形成一个语法树
(3)如果出现错误,指出错误的位置和类型
(4)把语法树按照树的前序遍历的形式把所有的结点打印输出
(5)按照某种规则计算出表达式的值。

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

算符优先语法分析设计原理与实现技术XXX 1028XXX 计科1XXX班功能描述能够有效识别以下算符优先文法E → E+T | E-TT → T*F | T/F | FF → (E) | i所描述算术表达式.主要数据结构描述程序结构描述设计方法1.由文法构造算符优先矩阵( < < < < < = <) > > > > > >i > > > > > ># < < < < < < =2.根据算符优先矩阵算数表达式的词法分析结果进行语法分析,分析算法为:数据结构:符号栈S --- 存放所有读进的符号(计数i)K --- 符号栈使用深度a --- 工作单元R, Q --- 变量分析算法:先找最左素短语的尾部(>)再找最左素短语的头部(<)以分析表达式i+i*i为例,详细过程如下:函数定义函数原型功能描述void init() 各种初始化操作,主要是建立符号与整数、整数与行列号、整数与符号之间的映射,也包括各全局变量的初始化void isVt(int ) 判断某整数所代表的符号是否是终结符号或’#’void comp(int a, int b) 比较两整数所代表的字符的优先关系void advance() 从输入文件中读入一个词bool parser() 算符优先分析函数,根据算符优先矩阵进行语法分析int main(int argc, char *argv[]) 主函数,参数argv[1]代表输入文件⏹函数调用关系⏹程序执行图maininitisVt advanceparsercomp程序测试测试用例一:(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, ')')(14, '+')(12, 'd')(16, '*')(15, '-')(12, 'a')(16, '*')(12, 'c')(14, '+')(19, '(')(12, 'a')(14, '+')(12, 'b')以此分析结果作为本实验程序的输入,得到如下语法分析结果:实验结果表明,在分析过程中出现了错误,分析过程未完成,该样例是一个非法的表达式.学习总结➢按算符优先关系所确定的应被规约的子串恰好是当前举行的最左素短语.➢尽管算符优先分析也属于自底向上语法分析的范畴,但却不是严格的从左至右的规范分析,每步所得的句型自然也不是一个规范句型.➢采用上述策略进行算符优先分析时,尽管我们也指出了每一最左素短语应规约到的非终结符号,然而每次在查找最左素短语时,起主导作用的是终结符号间的优先关系,两终结符号之间究竟是哪个非终结符号无关宏旨.// operator_prior.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <ctype.h>#include <map>#include <vector>#include <string>#define ID 12#define ADD 14#define SUB 15#define MUL 16#define DIV 17#define LP 19#define RP 20#define EOI 31#define SHARP 32#define EQ 0#define BT 1#define LT 2#define UD 3#define N_Base 1000using namespace std;FILE *fp;int lookahead, yylineno;bool success;map<int, int> intToint;map<char, int> charToint;map<int, char> intTochar;string grammer[8] = {"E+T", "E-T", "T","T*F", "T/F", "F","(E)", "i"};int prior_matrix[9][9] = {{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{LT, LT, LT, LT, LT, EQ, LT, UD},{BT, BT, BT, BT, UD, BT, UD, BT},{BT, BT, BT, BT, UD, BT, UD, BT},{LT, LT, LT, LT, LT, UD, LT, EQ}};void init() {success = true;yylineno = 0;intToint[ADD] = 0; intToint[SUB] = 1;intToint[MUL] = 2; intToint[DIV] = 3;intToint[LP] = 4; intToint[RP] = 5;intToint[ID] = 6; intToint[SHARP] = 7;charToint['+'] = ADD; charToint['-'] = SUB;charToint['*'] = MUL; charToint['/'] = DIV;charToint['('] = LP; charToint[')'] = RP;charToint['i'] = ID;intTochar[ADD] = '+'; intTochar[SUB] = '-';intTochar[MUL] = '*'; intTochar[DIV] = '/';intTochar[LP] = '('; intTochar[RP] = ')';intTochar[ID] = 'i'; intTochar[SHARP] = '#';intTochar[N_Base] = 'N';}bool isVt(int a) {if (a >= N_Base) return false;else return true;}int comp(int a, int b) {int x = intToint[a];int y = intToint[b];return prior_matrix[x][y];}void advance() {if (fscanf(fp, "(%d", &lookahead) == EOF) { lookahead = SHARP;} else {char ch;do {ch = fgetc(fp);if (ch == '\n' || ch == EOF) break;} while (true);}yylineno++;}void parser() {int stack[100], top = 0;int i, j, k, ii, jj;stack[top++] = SHARP;advance();do {for (i = 0; i < top; i++) {printf("%c", intTochar[stack[i]]);}printf("\t%c\n", intTochar[lookahead]);for (i = top - 1; i >= 0; i--) {if (isVt(stack[i])) break;}int res = comp(stack[i], lookahead);if (res == LT || res == EQ) {stack[top++] = lookahead;advance();} else if (res == BT) {int temp = stack[i];for (j = i - 1; j >= 0; j--) {if (isVt(stack[j])) {if (comp(stack[j], temp) == LT) {break;} else {temp = stack[j];}}}for (k = 0; k < 8; k++) {if ((int)grammer[k].length() == top - 1 - j) {ii = j + 1;jj = 0;do {if (grammer[k].at(jj) >= 'A' && grammer[k].at(jj) <= 'Z') {if (isVt(stack[ii])) break;} else {if (charToint[grammer[k].at(jj)] != stack[ii]) break;}ii++;jj++;} while (ii < top && jj < (int)grammer[k].length());if (ii >= top) break;}}if (k >= 8) {success = false;return ;}top = j + 1;stack[top++] = N_Base;} else {success = false;return ;}if (stack[0] == SHARP && stack[1] == N_Base&& stack[2] == SHARP) {printf("#N#\n");break;}} while (true);success = true;}int main(int argc, char *argv[]) {if (argc == 2) {fp = fopen(argv[1], "r");init();parser();if (success) printf("This is a legal expression.");else printf("This is a illegal expression.");} else {printf("参数错误!\n");}return 0;}。

相关文档
最新文档