论文—简单优先文法
- 格式:doc
- 大小:247.50 KB
- 文档页数:7
通达学院专业课程设计II 题目:简单优先文法关系矩阵构造专业计算机通信学生姓名班级学号指导教师指导单位计算机学院计算机科学与技术系日期2012.11.12-2012.11.23教师评语同学出勤率(满勤、较高、一般,较低),学习态度(端正、较端正、一般、较差),程序设计基础(好、较好、一般、较差),演示程序(已经、没有)达到了基本要求,算法设计(好、较好、一般),界面友好程度(好、较好、一般),答辩过程中回答问题(准确、较准确、错误率较高),撰写报告格式(规范、一般)、内容(丰满、简单)、表述(清晰、一般、不清楚),(圆满、较好、基本)完成了课题任务。
教师签名:年月日成绩评定备注简单优先文法关系矩阵构造一、课题内容和要求基本功能:对任意输入的文法均可计算其文法符号的优先关系。
例如文法G[Z],一共有7个符号:Z、M、L、a、b、(、),文法之间的关系(规则)如下:Z ∷=bMb M ∷=(L|a L∷=Ma)二、概要设计1.字符串处理:此模块要求能够从输入的字符串中提取出字符集,包括终结符和非终结符,建立对应的字符表。
2.矩阵的乘方:此模块要求能够计算矩阵的乘方,细化后应包括有局真的乘法的子模块。
3.求解R,L,=关系模块。
1)R关系:由语法语句定义可知”A::=…|..”形式可知扫描每一句语句找出第四个字符,和“|”字符的下一个字符,同定义符构成R关系。
2)L关系:由语法语句定义可知”A::=…|..”形式可知扫描每一句语句找出最后一个字符,和“|”字符的前一个字符,同定义符构成L关系。
3)=关系:例如”A::=AS|Aa|b”可知只需从第四个字符开始依次查找,A=S,遇到“|”符号时扫描指针i向后移动两位。
4.矩阵的并(和)运算:根据编译原理中简单文法的规则,需要求出L+关系,R+关系,L*关系,而此求解根据warshll算法的需要进行大量的乘方运算。
L+=(L) U(L^2)U(L^3)……U(L^n)L*=(L^0) U (L^1)U(L^2)U(L^3)……U(L^n)R+=(R) U(R^2)U(R^3)……U(R^n)5.矩阵显示输出模块6.流程图Start输入语法语句搜索终结符及非终结符建立字符集V建立各种矩阵并初始化完成矩阵的初始化计算R关系计算L关系计算=关系计算出三种关系计算L+计算R+计算L*根据公式计算出>、<关系合成最后输出矩阵输出显示各矩阵三、详细设计#include <stdio.h>#include <stdlib.h>#include <string.h>int hasletter(char *v,char c) //判断字符表中是否含有某一字符{int mark=0;int length=strlen(v);for (int i=0;i<length;i++){if (c==v[i]){mark=1; //mark=1 字符表v中含有cbreak;}}return mark;}void searchstring(char *v,char **pMatrix,int n) //建立字符表{int i,k,p;char *Vletter =new char[257];Vletter[256]='\0';;for (i=0;i<256;i++){Vletter[i]='\0';}for (i=0,k=0,p=0;i<n;i++){for (int j=0;j<strlen(pMatrix[i]);j++){if (!hasletter(v,pMatrix[i][j])){if ((pMatrix[i][j]<='Z')&&(pMatrix[i][j]>='A')){v[k++]=pMatrix[i][j];}else if (!hasletter(Vletter,pMatrix[i][j])){if(((pMatrix[i][j]<'A')||(pMatrix[i][j]>'Z'))&&(pMatrix[i][j]!=':'&&pMatrix[i][j]!='='&&pMatrix[i][j]!='|')){}}}}}int vl=strlen(v);int Vletterl=strlen(Vletter);for (i=vl,k=0;k<Vletterl;i++,k++){v[i]=Vletter[k];}}/*******矩阵乘法******/void Matrix_mutiply(int **Matrix_1, int **Matrix_2,int **Matrix_Resutl, int n){int length=n;int temp=0;for (int row=0;row<length;row++){for(int column=0;column<length;column++){for(int m=0;m<length;m++){Matrix_Resutl[row][column]+=Matrix_1[row][m]*Matrix_2[m][column];if (Matrix_Resutl[row][column]!=0){Matrix_Resutl[row][column]=1;}}}}}/*******矩阵输出显示******/void matrixprint(int **ma,int length) //矩阵的输出显示{int mark=0;for (int i=0 ;i<length;i++){for(int j=0;j<length;j++){mark++;if (mark<length)printf(" %d ",ma[i][j]);}else{printf(" %d \n",ma[i][j]);mark=0;}}}printf("\n \n");}void matrixprintchar(char **ma,int length,char *v) //矩阵的输出为> = <号{int mark=0;printf(" ");for (int k=0;k<length;k++){printf(" %c ",v[k]);}printf("\n");for (int i=0 ;i<length;i++){printf(" %c ",v[i]);for(int j=0;j<length;j++){mark++;if (mark<length){printf(" %c ",ma[i][j]);}else{printf(" %c \n",ma[i][j]);mark=0;}}}printf("\n \n");}/*******矩阵的转置******/void matrixTravers(int **Matrix_1,int **matrixTravers,int n) //矩阵的转置int temp=0;for (int i=0;i<n;i++){for (int j=i+1;j<n;j++){temp=Matrix_1[i][j];Matrix_1[i][j]=Matrix_1[j][i];Matrix_1[j][i]=temp;}}for (int k=0;k<n;k++){for (int m=0;m<n;m++){matrixTravers[k][m]=Matrix_1[k][m];}}}/*******显示最后的优先关系矩阵******/void showresult(int **BE_Matrix,int **BL_Matix,int **BB_Matrix,char **result_Matrix,int n) //合成最后的矩阵{for (int i=0;i<n;i++){for (int j=0;j<n;j++){if (!((BE_Matrix[i][j]==0)&&(BL_Matix[i][j]==0)&&(BB_Matrix[i][j]==0))){if (BE_Matrix[i][j]==1){result_Matrix[i][j]='=';continue;}else if (BB_Matrix[i][j]==1){result_Matrix[i][j]='>';continue;}else if (BL_Matix[i][j]==1){result_Matrix[i][j]='<';}}}void calcBLT(int **BE, int **BLPlus,int **BLLessThan,int n) //计算<=矩阵{Matrix_mutiply(BE,BLPlus,BLLessThan,n);}void calcBBT(int **Matrix_1, int **Matrix_2,int **Matrix_Resutl,int **Matrix_BigT, int n) //计算>=关系{int **Matrix_temp=new int*[n];for (int i = 0; i < n; i++)Matrix_temp[i] = new int[n];for (i=0;i<n;i++){for (int j=0;j<n;j++){Matrix_temp[i][j]=0;}}/*for (i=0;i<nletterlengh){for (int j=0;j<n;j++){Matrix_BigT[j][i]=0;}}*//***********修正使所有的非终结符对应的列置零******************/Matrix_mutiply(Matrix_1,Matrix_2,Matrix_temp,n);Matrix_mutiply(Matrix_temp,Matrix_Resutl,Matrix_BigT,n);//matrixprint(Matrix_BigT,n);}void initialMatirx(int **Matrix,int n){for (int i=0;i<n;i++){for (int j=0;j<n;j++){Matrix[i][j]=0;}int findletterindex(char *a,char c){int i=0;for (;a[i]!=c;i++);return i;}void unionMatrix(int **Matrix,int **Matrix1,int **MatrixR,int n) //矩阵的的并集{for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(Matrix[i][j]+Matrix1[i][j]!=0){MatrixR[i][j]=1;}}}}void washall(int **unitMatrix,int **Matrix,int **MatrixTemp,int **MatrixR,int n,int mark) //mark=1表示求L+,R+,mark=表示求L*{initialMatirx(MatrixTemp,n);initialMatirx(MatrixR,n);unionMatrix(MatrixTemp,Matrix,MatrixR,n);unionMatrix(MatrixTemp,Matrix,MatrixTemp,n);for(int i=2;i<n;i++){Matrix_mutiply(MatrixTemp,Matrix,MatrixTemp,n); //计算矩阵的i次方unionMatrix(MatrixTemp,MatrixR,MatrixR,n);}if (!(mark==1)){unionMatrix(MatrixR,unitMatrix,MatrixR,n);}}/*************计算R关系********************/void calcR(char **a,char *v,int **matrixR,int stringcolum) //计算R关系{int markrow =findletterindex(v,a[k][0]); //找到每句文法最右边的非终极符for (int n=4;n<strlen(a[k]);n++){int markcol;if (a[k][n]=='|'){markcol=findletterindex(v,a[k][n-1]);matrixR[markrow][markcol]=1;}if (n+1==strlen(a[k])){markcol=findletterindex(v,a[k][n]);matrixR[markrow][markcol]=1;}}}}/*************计算L关系********************/void calcL(char **a,char *v,int **matrixR,int stringcolum) //计算L关系{for (int k=0;k<stringcolum;k++){int markrow =findletterindex(v,a[k][0]); //找到每句文法最左边的非终极符int markcol =findletterindex(v,a[k][4]);matrixR[markrow][markcol]=1;for (int n=4;n<strlen(a[k]);n++){int markcol;if (a[k][n]=='|'){markcol=findletterindex(v,a[k][n+1]);matrixR[markrow][markcol]=1;}}}}/*************计算=关系********************/void calcE(char **a,char *v,int **matrixR,int stringcolum) //计算=关系{for (int k=0;k<stringcolum;k++)//找到每句文法=关系的非终极符for (int p=4;p<strlen(a[k])-1;p++){if ((a[k][p]!='|')&&(a[k][p+1]!='|')){int markrow=findletterindex(v,a[k][p]);int markcol=findletterindex(v,a[k][p+1]);matrixR[markrow][markcol]=1;}}}}/*******主函数******/void main(){int n,k,p;int stringcolum;printf("请输入语句数目\n");scanf("%d",&n);stringcolum=n; //语句数目char **pMatrix = new char*[n];for (int i = 0; i < n; i++){pMatrix[i] = new char[n];scanf("%s",pMatrix[i]);}char *v=new char[257];v[256]='\0';for (i=0;i<256;i++){v[i]='\0';}searchstring(v,pMatrix,n);printf("vocabulary :%s \n",v);n=strlen(v);int **unitMatrix=new int*[n];int **BL=new int*[n];int **BR=new int*[n];int **BE=new int*[n];int **BLPlus=new int*[n];int **BRPlus=new int*[n];int **BLLessThan=new int*[n];int **BRPlusTrav=new int*[n];int **BLM=new int*[n];int **BBigT=new int*[n];int **matrixtemp=new int*[n];char **result_Matrix=new char*[n];for (i = 0; i < n; i++){unitMatrix[i] = new int[n];BL[i] = new int[n];BR[i] = new int[n];BE[i] = new int[n];BLPlus[i] = new int[n];BRPlus[i] = new int[n];BLLessThan[i] = new int[n];BRPlusTrav[i] = new int[n];BLM[i] = new int[n];BBigT[i] = new int[n];matrixtemp[i]=new int[n];result_Matrix[i] = new char[n];}for (i=0;i<n;i++){for (int j=0;j<n;j++){result_Matrix[i][j]=2;}}initialMatirx(BL,n);initialMatirx(BR,n);initialMatirx(BLPlus,n);initialMatirx(BE,n);initialMatirx(BLM,n);initialMatirx(BLLessThan,n);initialMatirx(BBigT,n);initialMatirx(BRPlusTrav,n);initialMatirx(unitMatrix,n);for (i=0;i<n;i++){unitMatrix[i][i]=1; //初始化单位矩阵}calcR(pMatrix,v,BR,stringcolum);printf("R关系如下:\n");matrixprint(BR,n);calcL(pMatrix,v,BL,stringcolum);printf("L关系如下:\n");matrixprint(BL,n);calcE(pMatrix,v,BE,stringcolum);printf("=关系如下:\n");matrixprint(BE,n);washall(unitMatrix,BR,matrixtemp,BRPlus,n,1);printf("R+关系如下:\n");matrixprint(BRPlus,n);matrixTravers(BRPlus,BRPlusTrav,n);printf("(R+)T关系如下:\n");matrixprint(BRPlusTrav,n);washall(unitMatrix,BL,matrixtemp,BLM,n,0);printf("L*关系如下:\n");matrixprint(BLM,n);washall(unitMatrix,BL,matrixtemp,BLPlus,n,1);printf("L+关系如下:\n");matrixprint(BLPlus,n);calcBLT(BE,BLPlus,BLLessThan,n);printf("<=关系如下:\n");matrixprint(BLLessThan,n);calcBBT(BRPlusTrav,BE,BLM,BBigT,n);printf(">=关系如下:\n");matrixprint(BBigT,n);int nletter=0; //记录V中的非终结符的数目for (i=0;i<n;i++){if (v[i]>='A'&&v[i]<='Z'){nletter++;}}for (i=0;i<nletter;i++) //修正>=关系{for (int j=0;j<n;j++){BBigT[j][i]=0;}}printf("修正后的>=关系\n"); //简单文法最终的>关系要求将非终结符对应的列全部置零matrixprint(BBigT,n);printf("单位矩阵\n");matrixprint(unitMatrix,n);showresult(BE,BLLessThan,BBigT,result_Matrix,n);matrixprintchar(result_Matrix,n,v);}四、测试数据及其结果分析五、课程设计总结这个课程设计题目设计编译原理知识,所以一开始拿到题目后,对编译原理又学习了一遍,弄懂了以后发现这个程序对矩阵的用法很多,而我对C语言不擅长,所以经过图书馆里查找资料,学习以后才解决,在调试过程中经常出现字符串错误,对字符串的运用不恰当,还有字符串的初始化也出现了很多问题,后来通过不断的学习,修改,调试终于成功了。
编译原理期末论文一、概述算符文法:即它的任一产生式的右部都不含两个相继的非终结符的文法。
如果G是一个不含空字符的算法文法,那么只要它的任一对终结符都只满足>,=,<的关系的一种,则称G是一个算符优先文法。
算符文法分类:对于一个算符优先文法,只要能构造出它的算符优先表,就可以利用算符优先分析方法,分析一个句子是否符合这个文法的定义。
那么定义FirstVT(P)={a|P(+=>)a···或P(+=>)Qa···,a属于终结字符集,而Q属于非终结字符集},其中···表示所有字符集LastVT(P)={a|P(+=>)···a或P(+=>)···aQ,a属于终结字符集,而Q 属于非终结字符集}由以下两条规则来构造FirstVT集:(1) 若有产生式P=>a···、或P=>Qa···,则a属于FirstVT(P);(2) 若有a属于FirstVT(Q),且有产生式P=>Q···,则a属于FirstVT(P);类似的有构造LastVT集的规则:(1) 若有产生式P=>···a或P=>···aQ,则a属于LastVT集。
(2) 若a属于LastVT(Q),且有产生式P=>···Q,则a属于LastVT集。
构造FirstVT集的算法:BeginFor 每个非终结符P和终结符a Do F[P,a]=FALSE;For 每个形如P=>a...或P=>Qa...的产生式 (1)DO insert(P,a)While Stack 非空 DoBegin把Stack 的顶项,记为(Q,a),上托出去;For每条形如P=>Q...的产生式DO . (2)Insert(P,a)End of while;END构造LastVT集的算法:将上述算法的对应的(1),(2)分别修改为For 每个形如P-〉…a或P-〉…aQ的产生式,For每条形如P-〉…Q的产生式便可得。
SLR(1)文法一、引言SLR(1)文法,全称为“简单优先文法”,是计算机科学中编译器设计和语言理论的一个重要概念。
它是一种上下文无关文法,使用一个栈来存储语法信息,并根据简单的优先级规则进行扩展。
本文将详细解释SLR(1)文法的定义、特性、应用和计算过程,并通过实例分析其工作原理。
二、SLR(1)文法定义SLR(1)文法是一种上下文无关文法,它使用一个栈来存储语法信息。
在每一步解析过程中,它选择具有最高优先级的产生式进行扩展。
如果存在多个具有相同优先级的产生式,则选择左边的那个。
如果栈为空或者无法选择合适的产生式进行扩展,则发生语法错误。
三、SLR(1)文法的特性SLR(1)文法具有以下特性:1.上下文无关性:SLR(1)文法是一种上下文无关文法,语法规则的适用不依赖于上下文环境。
2.简单优先级:在每一步解析过程中,SLR(1)文法选择具有最高优先级的产生式进行扩展。
优先级由产生式的左部符号决定。
3.栈的使用:SLR(1)文法使用一个栈来存储语法信息,以便在解析过程中进行产生式的扩展。
4.左角限制:如果存在多个具有相同优先级的产生式,SLR(1)文法只选择左角的产生式进行扩展。
5.语法错误处理:如果栈为空或者无法选择合适的产生式进行扩展,SLR(1)文法则认为存在语法错误。
四、SLR(1)文法的应用SLR(1)文法在编译器设计和语言理论中有广泛的应用。
它主要用于确定语言的语法结构,并生成相应的解析器。
通过将源代码转换为抽象语法树(Abstract Syntax Tree, AST),可以将源代码转换为可执行的机器代码或中间代码。
此外,SLR(1)文法还可以用于自然语言处理、文本挖掘等领域。
五、SLR(1)文法的计算过程SLR(1)文法的计算过程包括以下步骤:1.定义:为每个非终结符生成一个包含优先级和产生式的表格。
这个表格定义了每个非终结符的优先级和可能的产生式。
2.解析:根据输入的字符串,使用栈来存储语法信息,并根据优先级和产生式表格进行解析。
编译原理优先函数优先函数是编译原理中一种重要的算法,用于处理表达式的语法分析和计算顺序的确定。
它是一种上下文无关文法分析的方法,也被称为优先关系矩阵或优先算符关系矩阵。
优先函数的核心思想是基于优先关系规则,根据运算符的优先级和结合性,为每个运算符设置相应的优先级。
根据优先级,可以确定表达式中操作符之间的计算顺序,从而避免了二义性和歧义。
优先函数主要有两个作用:确定操作符的结合性和计算顺序。
首先,优先函数可以确定操作符的结合性,即一个运算符在表达式中的使用方式。
根据优先函数,如果一个运算符的优先级和结合性与其周围的运算符相同,那么就符合该运算符的结合性规则。
对于左结合的运算符,优先级较低的运算符在表达式中的位置越靠左;对于右结合的运算符,优先级较低的运算符在表达式中的位置越靠右。
通过确定结合性,可以避免表达式的二义性。
其次,优先函数还可以确定操作符之间的计算顺序。
对于优先级较高的运算符,应该优先计算;对于优先级较低的运算符,应该等待高优先级的运算符计算完成后再计算。
通过确定计算顺序,可以确保表达式的计算结果是按照运算符的优先级从高到低依次计算的,避免了歧义和计算结果的错误。
优先函数的实现可以通过使用优先关系表来完成。
优先关系表是一个矩阵,用于存储每个运算符之间的优先关系。
在表中,行和列分别表示运算符,表格中的元素表示了对应运算符之间的优先关系。
优先关系表中的元素可以是“<”、“=”或“>”三种值,分别表示左优先、等优先或右优先。
通过构建优先关系表,可以确定每个运算符之间的优先关系。
在语法分析时,遵循以下规则进行操作符的处理:1.如果运算符栈顶的运算符的优先级小于当前操作符,将当前操作符放入运算符栈中;2.如果运算符栈顶的运算符的优先级大于当前操作符,从操作数栈中弹出两个操作数,并根据运算符进行计算;3.如果运算符栈顶的运算符的优先级等于当前操作符,将运算符栈顶的运算符弹出,继续比较下一个运算符。
简单优先文法简单优先文法是在文法推导过程中用来解决移进-归约冲突的一种方法,它是一类优先文法。
在编译原理中,优先文法对于构建语法分析器起到了至关重要的作用。
在本文中,我们将介绍简单优先文法的基础知识以及如何使用它来解决移进归约冲突。
简单优先文法定义了一个基本的优先级规则,该规则帮助语法分析器判断哪些产生式可以被应用。
在简单优先文法中,每个终结符和非终结符都有一个关联的优先级。
如果两个符号之间存在不同的优先级,语法分析器将使用较高优先级的符号。
例如,在表达式语法中,乘法和除法的优先级通常比加法和减法更高。
如果两个符号具有相同的优先级,则语法分析器将根据文法中定义的结合性规则来解决冲突。
例如,在表达式语法中,加法和乘法都是左结合的,而减法和除法都是右结合的。
基于简单优先文法的语法分析器通常被称为“算符优先分析器”。
这种类型的语法分析器使用状态转移表来确定如何移进或归约输入令牌序列。
它能够有效地处理大量的语法结构,并且速度比其他分析器更快。
下面给出一个简单的例子,以便更好地理解简单优先文法的原理。
假设我们有一个文法:S -> aA | bBA -> c | AaB -> c | Bb我们将给终结符 a 、 b 和 c 分配优先级 1 、 2 和 3 。
由于 a 和 b 具有相同的优先级,而 c 的优先级更高,因此,在 A 和 B 的产生式中,应用与终结符 c 相关联的优先级。
也就是说,在文法中,乘法和除法的优先级较高,加法和减法的优先级较低。
使用这种优先级规则,我们可以消除移进-归约冲突。
例如,在状态 S3 中,如果输入令牌是 a ,它将通过规则 S -> aA 被移进栈中。
如果该输入令牌是 c ,则可以将规则 A -> c 归约为 A ,以便栈中的符号与产生式 S -> bB 匹配。
这可以通过优先级规则来确定。
在编写简单优先文法时,必须避免悬挂文法以及二义性书写,否则将导致矛盾。
判断题第一章1.源语言是编写被编译的程序使用的语言。
(√)2. 解释执行与编译执行的根本区别在于解释程序对源程序没有真正进行翻译。
(╳)3. “遍”是指对源程序从头到尾扫描一遍,并做相应的加工处理。
( ╳ )4. 编译程序是将源程序翻译成等价的目标程序的程序。
(√)5. 宿主语言是目标机的目标语言(╳)6. 编译程序是应用软件(╳)第二章1.NFA和DFA的区别之一是映射函数是否唯一。
(√)2.FA的初始状态可以是多个。
(√)3. 若一个文法是递归的,则它所产生语言的句子个数必定是无穷的。
(√)4. 存在这样的语言,它能被确定的有穷自动机识别,但不能用正规表达式表示。
(╳)5. 设有字母表V,则V T ∩V N=Φ。
( √ )6. 有文法G1=G2,则L(G1)=L(G2)。
( ╳ )7.文法等价是指所描述的语言是完全相同的。
(√)8.一个确定有限状态自动机中,有且仅有一个唯一的终态。
(╳)9.设R和S分别是字母表∑上的正规式,则有L(R|S)=L(R)∪L(S)。
(√)10.自动机M1和M2的状态数不同,则二者必不等价。
(╳)11.确定有限自动机以及非确定有限自动机都能正确地识别正规集。
(√)12.对任意一个右线性正规文法G,都存在一个NFA M,满足L(G)=L(M)。
(√)13.对任何正规式e,都存在一个NFA M,满足L(M)=L(e)。
(√)14.从一个句型到另一个句型的推导过程是唯一的。
(╳)15、最右推导是最右规约的逆过程,最左推导是最左规约的逆过程。
(× )16.一张转换图只包含有限个状态,其中有一个被认为是初态,最多只有一个终态。
(╳)17.二义文法不是上下文无关文法。
(╳)18、对能用有限自动机描述的一个语言,该语言的一子集所构成的语言也一定能用有限自动机来描述。
(×)19、对任意文法G,都存在相应的正规式与之等价。
(× )20、对文法G中的一个句子,如果能够找到两种以上的推导,则该句子是二义性的。
编译原理_文法范文编译原理是计算机科学与技术中的一门重要课程,它主要研究如何将高级语言编写的程序转换为机器语言,并最终执行在计算机上。
编译原理中的一个重要概念就是文法,本文将详细介绍什么是文法以及文法的相关概念和应用。
文法是一种形式化的描述语言结构的数学模型。
在编译原理中,文法被用来描述一种编程语言的语法结构,即编程语言的合法的、可被解析和执行的语句和表达式。
文法可以看作是一种对语言结构的抽象描述,它定义了语言的语法规则和语法结构。
一个文法通常由四个部分组成:终结符集、非终结符集、产生式和开始符号。
1.终结符集:终结符是文法中的最基本的符号,代表了语言中的实际元素,例如关键字、操作符等等。
终结符可以通过正则表达式进行描述。
2.非终结符集:非终结符是用来描述语句或表达式的结构的符号,它可以展开成一系列的终结符和/或非终结符。
非终结符通常用大写字母表示。
3.产生式:产生式是文法中的一个基本规则,用来定义非终结符如何展开成终结符和/或非终结符的组合。
产生式通常由两部分组成,左部是一个非终结符,右部是一个终结符和/或非终结符的序列。
产生式可以用形如“非终结符->终结符/非终结符”的格式表示。
4.开始符号:开始符号是文法中唯一一个用来开始生成语言中有效句子的非终结符。
文法可以用来描述一种编程语言的语法结构,通过对语法规则的定义,运用合适的算法可以将源程序转为一个语法树。
语法树是一个以文法产生式为边的有向树,它描述了源程序的语法结构。
语法分析是编译原理中的一个重要阶段,它用来分析源程序的语法结构,并生成语法树。
语法分析有两种主要的方法:自顶向下分析和自底向上分析。
自顶向下分析是从文法的开始符号开始,根据产生式的规则进行推导,直到推导出整个源程序。
自顶向下分析可以分为递归下降分析和预测分析两类。
递归下降分析是一种基于产生式的自顶向下分析方法,它通过递归调用分析子程序来实现。
预测分析是一种具有预测性质的自顶向下分析方法,它通过预测下一个输入符号来进行推导。
课程设计任务书题目: IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码三地址表示的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试及测试。
周5:撰写课程设计报告。
设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。
设计报告书收取时间:设计周的次周星期一上午10点。
指导教师签名: 2013年月日系主任(或责任教师)签名: 2013年月日IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)1 系统描述1.1题目IF-ELSE条件语句的翻译程序设计(简单优先法、输出三地址表示)1.2.目的通过设计、编制、调试一个条件语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
1.3.设计内容及步骤对条件语句: IF 〈布尔表达式〉 THEN 〈赋值语句〉 ELSE 〈赋值语句〉(1)按给定的题目写出符合语法分析方法要求的文法和属性文法描述。
自下而上语法分析1、规约:自下而上的语法分析过程:分为简单优先分析法,算符优先分析法,LR分析法。
2、自下而上的语法分析过程思想:自下而上的语法分析过程是一个最左规约的过程,从输入串开始,朝着文法的开始符号进行规约,直到文法的开始符号为止的过程。
输入串在这里是指词法分析器送来的单词符号组成的二元式的有限序列。
3、自下而上的PDA(下推自动机)工作方式:“移近-规约”方式注:初态时栈内仅有栈顶符“#”,读头指在最左边的单词符号上。
语法分析程序执行的动作:◆移进:读入一个单词并压入栈内,读头后移◆规约:检查栈顶若干符号能否进行规约,若能,就以产生式左部代替该符号串,同时输出产生式编号。
◆识别成功:移近-规约的结局是栈内只剩下栈底符号和文法的开始符号,读头也指向语句的结束符。
◆识别失败。
4、判读一语句是否是该文法的合法语句(可以用语法树)5、优先分析器:简单优先分析法(理论简单,实际比较麻烦)算符优先分析法6、LR分析器7、相邻文法符号之间的优先关系◆在句型中,句柄内各相邻符号之间具有相同的优先级。
◆由于句柄要先规约,所以规定句柄两端符号的优先级要比位于句柄之外的相邻符号的优先级高。
(#的优先级是最低的。
)9、简单优先文法:定义:一个文法G,如果它不含ε的产生式,也不含任何右部相同的不同产生式,并且它的任何符号(X,Y)-X,Y是非终结符或终结符—或者没有关系,或者存在优先级相同或低于、高于等关系之一,则这是一个简单优先文法。
10、简短优先分析的思想1)简单优先矩阵:根据优先关系的定义:将简单优先文法中各文法符号之间的这种关系用一个矩阵表示,称作简单优先矩阵。
2)PDA读入一个单词后,比较栈顶符号和该单词的优先级,若栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或者等于读入符号,则找句柄进行规约,找不到句柄继续读入11、简单优先法的优缺点:1、优点:算法比较好理解。
2、缺点:适用范围小,分析表尺寸太大。
简单优先文法分析设计一、摘要众所周知,翻译有两种方式:编译方式和解释方式,其中编译程序的主要功能是将源程序翻译成等价的目标程序,这个翻译过程一般可分为词法分析、语法分析、语义分析、中间代码生成、中间代码优化和目标代码生成等阶段来实现。
在众多阶段中,语法分析是相当重要的一部分,其任务是根据语言的语法规则把单词符号串分解成各类语法单位,如表达式、语句等。
通过语法分析,可以确定整个输入符号串是否够成一个语法正确的程序。
在本文中,我们将重点探讨语法分析部分的简单优先分析法。
简单优先分析法是一种典型的自下而上的分析方法。
自下而上分析法是从输入符号串出发,试图归约到文法的识别符号,或从下往上地为输入串构造一棵语法树。
对这个“可进行归约的符号串”,在不同的自下而上分析方法中有着不同的称呼,在简单优先分析法中称之为“句柄”,而在算符优先分析方法中称之为“素短语”。
关于简单优先文法分析器,主要分为三大部分:数据结构及界面的设置、优先关系矩阵的求解、符号串的分析。
文法分析器使用VS2008编译器编译,主要是使用其强大的界面设计功能。
由于水平有限,本文或许有不妥之处,敬请读者不吝指教。
二、基本概念简单优先分析法对使用它的文法是有限制的,只有简单优先文法才能使用简单优先分析法。
在介绍简单优先文法之前,我们先来看一下三种简单优先关系。
①L±R,当且仅当文法中有以下形式的产生式:U::=αLRβ。
其中,L,R∈(V N∪V T);α,β∈(V N∪V T)*。
②L<R,当且仅当文法中有以下形式的产生式:U::=αLPβ且P Rγ。
其中,L,R∈(V N∪V T);P∈V N;α,β,γ∈(V N∪V T)*。
③L>R,当且仅当文法中有以下形式的产生式:U::=αWPβ且WδL,P Rγ。
其中,L,R∈(V N∪V T);W∈V N;P∈(V N∪V T);α,β,δ,γ∈(V N∪V T)*。
有了上面三种优先关系的说明,我们再来看一下简单优先文法的定义。
课程设计题目简单优先分析程序的设计学院计算机科学与技术学院专业软件工程专业班级软件工程1002班姓名指导教师何九周2013 年 1 月12 日课程设计任务书学生姓名:专业班级:软件工程1002班指导教师:何九周工作单位:计算机科学与技术学院题目:简单优先分析程序的设计初始条件:程序设计语言:主要使用C语言的开发工具,或者采用LEX、YACC等工具,也可利用其他熟悉的开发工具。
算法:可以根据《编译原理》课程所讲授的算法进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,说明书撰写等具体要求)1.明确课程设计的目的和重要性,认真领会课程设计的题目,读懂课程设计指导书的要求,学会设计的基本方法与步骤,学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。
严格要求自己,要独立思考,按时、独立完成课程设计任务。
2. 主要功能包括:对教材P104中的上下文无关文法,实现它的简单优先分析程序,给出符号串b(aa)b的分析过程。
(参考教材P103~106)3.进行总体设计,详细设计:包括算法的设计和数据结构设计。
系统实施、调试,合理使用出错处理程序。
4. 设计报告:要求层次清楚、整洁规范、不得相互抄袭。
正文字数不少于0.3万字。
包含内容:①课程设计的题目。
②目录。
③正文:包括引言、需求分析、总体设计及开发工具的选择,设计原则(给出语法分析方法及中间代码形式的描述、文法和属性文法的设计),数据结构与模块说明(功能与流程图)、详细的算法设计、软件调试、软件的测试方法和结果、有关技术的讨论、收获与体会等。
④结束语。
⑤参考文献。
⑥附录:软件清单(或者附盘)。
时间安排:消化资料、系统调查、形式描述1天系统分析、总体设计、实施计划3天撰写课程设计报告书1天指导教师签名: 2013年 1月 12日系主任(或责任教师)签名:2013年1月12日目录1引言.............................................................................................................................- 3 -2需求分析.....................................................................................................................- 3 -3总体设计.....................................................................................................................- 3 -3.1简单优先关系的定义............................................................................................- 4 -3.2简单优先分析法的基本思想 .................................................................................- 4 -3.3简单优先关系矩阵流程图.....................................................................................- 5 -3.4简单优先分析法流程图 ........................................................................................- 6 -3.5分析器构造..........................................................................................................- 7 -4开发工具的选择.........................................................................................................- 7 -5详细的算法设计.........................................................................................................- 7 -5.1简单优先关系矩阵输出算法 .................................................................................- 7 -5.2字符串读入..........................................................................................................- 8 -5.3字符串分析算法...................................................................................................- 8 -5.4优先关系判断算法 ...............................................................................................- 9 -5.5移近-规约算法.....................................................................................................- 9 -5.6分析结果判断 .................................................................................................... - 11 -6软件调试................................................................................................................... - 11 -7软件的测试方法和结果...........................................................................................- 12 -8有关技术的讨论.......................................................................................................- 13 -9收获与体会...............................................................................................................- 14 -10结束语.......................................................................................................................- 14 -11 参考文献....................................................................................................................- 15 -12 附录............................................................................................................................- 15 -简单优先分析程序的设计1引言上下文无关文法是形式语言理论中一种重要的变换文法,用来描述上下文无关语言,在乔姆斯基分层中称为2型文法。
编译原理系列之五⾃底向上优先分析(1)-简单优先分析法简单优先分析法1.基本概念通过语法树来理解这三个概念更加简单:⽂法G1[S]:S→ABA→bBA→AaB→aB→Sb语法树1. 短语:若S=*=>αAδ且A=+=>β,则称β是相对于⾮终结符A的句型αβδ的短语。
即:语法树中以⾮终结符的作为根的⼦树的叶⼦所组成的字符串。
如:ba是相对于⾮终结符A的句型AB的短语。
句型baSb的短语有ba,a,Sb,baSb。
2. 直接短语:若S=*=>αAδ且A=>β,则称β是相对于⾮终结符A的句型αβδ的直接短语。
即:语法树中以⾮终结符的作为根的⼦树,它的孩⼦都是叶⼦,没有其他⼦树。
如:Sb是相对于⾮终结符B的句型AB的短语。
句型baSb的短语有a,Sb。
3. 句柄:位于句型最左边的直接短语称为该句型的句柄。
即:位于语法树中最左边的直接短语。
如:句型baSb的句柄是a。
2.优先关系定义1. X和Y优先级相等,表⽰为X=·Y,当且仅当G中存在产⽣式规则A=>···XY···。
解读:X、Y的优先级相同,当XY存在⼀个句柄之中,它们将同时被归约。
表现在语法树中S=·b。
优先级相等在语法树中1. X优先级⼩于Y,表⽰为X<·Y,当且仅当G中存在产⽣式规则A=>···XB···,B=+=>Y···。
解读:X优先级⼩于Y,当XY存在⼀个句型中时,它们将不可能出现在同⼀个句柄中,Y⼀定⽐X先被规约。
表现在语法树中b<·a。
优先级⼩于语法树中1. X优先级⼤于Y,表⽰为X>·Y,当且仅当G中存在产⽣式规则A=>··BD···,B=+=>···X,D=*=>Y···。
简单优先和算符优先分析方法简单优先分析(Simple Precedence Parsing)和算符优先分析(Operator Precedence Parsing)是两种常用的自底向上的语法分析方法。
它们是基于符号优先级的理念,通过比较符号之间的优先级关系,来进行语法分析。
1.简单优先分析简单优先分析是一种自底向上的语法分析方法,它利用一个优先级表来确定符号之间的优先关系。
简单优先分析的算法如下:(1)将输入串和符号栈初始化为空。
(2)从输入串中读入第一个输入符号a。
(3)将a与栈顶的符号进行比较:a.如果a的优先级大于栈顶符号的优先级,将a推入符号栈,并读入下一个输入符号。
b.如果a的优先级小于栈顶符号的优先级,将栈中的符号做规约操作,直到栈顶的符号优先级不小于a。
然后,将a推入符号栈。
c.如果a和栈顶符号优先级相等,栈顶的符号出栈,并将a推入符号栈。
(4)重复步骤(3)直到输入串为空。
(5)如果符号栈中只有一个符号且为文法的开始符号,则分析成功。
简单优先分析的优先级表一般由语法规则和符号之间的优先关系组成。
我们可以通过构造优先级关系表来实现简单优先分析。
2.算符优先分析算符优先分析是一种自底向上的语法分析方法,它也是基于符号优先级的理念,但是相对于简单优先分析,算符优先分析更加灵活,并且允许处理左递归的文法。
算符优先分析的算法如下:(1)将输入串和符号栈初始化为空。
(2)从输入串中读入第一个输入符号a。
(3)将a与栈顶的符号进行比较:a.如果a的优先级大于栈顶符号的优先级,将a推入符号栈,并读入下一个输入符号。
b.如果a的优先级小于栈顶符号的优先级,将栈中的符号做规约操作,直到栈顶的符号优先级不小于a。
然后,将a推入符号栈。
c.如果a和栈顶符号优先级相等,根据符号栈中符号的类型执行相应的操作(如归约、移进等)。
(4)重复步骤(3)直到输入串为空。
(5)如果符号栈中只有一个符号且为文法的开始符号,则分析成功。
专题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>来存储单个二元组。
简单优先文法分析设计一、摘要众所周知,翻译有两种方式:编译方式和解释方式,其中编译程序的主要功能是将源程序翻译成等价的目标程序,这个翻译过程一般可分为词法分析、语法分析、语义分析、中间代码生成、中间代码优化和目标代码生成等阶段来实现。
在众多阶段中,语法分析是相当重要的一部分,其任务是根据语言的语法规则把单词符号串分解成各类语法单位,如表达式、语句等。
通过语法分析,可以确定整个输入符号串是否够成一个语法正确的程序。
在本文中,我们将重点探讨语法分析部分的简单优先分析法。
简单优先分析法是一种典型的自下而上的分析方法。
自下而上分析法是从输入符号串出发,试图归约到文法的识别符号,或从下往上地为输入串构造一棵语法树。
对这个“可进行归约的符号串”,在不同的自下而上分析方法中有着不同的称呼,在简单优先分析法中称之为“句柄”,而在算符优先分析方法中称之为“素短语”。
关于简单优先文法分析器,主要分为三大部分:数据结构及界面的设置、优先关系矩阵的求解、符号串的分析。
文法分析器使用VS2008编译器编译,主要是使用其强大的界面设计功能。
由于水平有限,本文或许有不妥之处,敬请读者不吝指教。
二、基本概念简单优先分析法对使用它的文法是有限制的,只有简单优先文法才能使用简单优先分析法。
在介绍简单优先文法之前,我们先来看一下三种简单优先关系。
①L±R,当且仅当文法中有以下形式的产生式:U::=αLRβ。
其中,L,R∈(V N∪V T);α,β∈(V N∪V T)*。
②L<R,当且仅当文法中有以下形式的产生式:U::=αLPβ且P Rγ。
其中,L,R∈(V N∪V T);P∈V N;α,β,γ∈(V N∪V T)*。
③L>R,当且仅当文法中有以下形式的产生式:U::=αWPβ且WδL,P Rγ。
其中,L,R∈(V N∪V T);W∈V N;P∈(V N∪V T);α,β,δ,γ∈(V N∪V T)*。
有了上面三种优先关系的说明,我们再来看一下简单优先文法的定义。
满足以下条件的文法称为简单优先文法:①字母表中的任意两个符号之间之多存在一种简单优先关系;②文法的任意两条产生式都没有相同的右部。
如文法G[S]:S::=(R)|a,R::=T ,T::=S,T|S 是一种简单优先文法。
下面我们再来看一下移进及规约。
移进过程:将输入符号串从左到右逐个移进符号栈。
规约过程:栈顶符号串与某一产生式右部相匹配成为可规约符号串时,将此符号串规约为一个非终结符,这个非终结符是该产生式左部符号。
在简单优先分析法中,我们用三种优先关系来判断符号栈面临当前符号的操作时移进还是规约,若为前两种则为移进,第三种则为规约。
而在规约过程中,我们用句柄来搜索用来规约的文法。
一个句型中的最左直接短语,称为该句型的句柄。
一个句型的直接短语和句柄可以用其语法树的子树描述。
语法树的一棵简单子树(只有单层的子树)的叶子结点组成的符号串是这个句型关于简单子树根结点的一个直接短语。
语法树最左边的简单子树的叶子结点组成的符号串就是这个句型的句柄。
例如:对于上面提到的文法G[S],子串(R) 即为符号串((R),a)的句柄。
三、程序运行效果为了方便理解后文的编程思路,我们先来看一下程序要达到的效果,如图1。
图1 合法语句运行结果看了上面的程序运行结果,相信您已经对简单优先分析法有了一定的了解,下面就让我们来具体看一下简单优先文法分析器的设计思路吧。
四、设计思路(1)文法结构的定义public struct MyData //文法结构定义(为方便分析将文法分为两部分) {public string s1, s2; //s1为文法的非终结符部分(等号前),s2为后半部分public int s2_length; //s2的长度(方便使用)}public int N = 50; //最多能输入的文法条数public MyData[] gam = new MyData[N]; //将所有文法都保存在数组中public int num = 0; //记录输入的文法条数(2)优先关系矩阵的求法分析优先关系的定义,不难得到以下结果:由①知:两个连在一起的字符关系为“±”;由②知:两个连在一起的字符,若后者P为非终结符,则前者L<P的推导的首字符;由③知:两个连在一起的字符,若前者W为非终结符,则W推导的尾字符>后者P及其推导的首字符(有推导时)。
根据以上理解,不难看出第一种关系求解过程相对简单,后两种则相对复杂。
为求解后两种关系,我们先来求解非终结符的推导的首、尾字符。
这里我使用递归的方法求推导,并将要求解的字符保存在字符串中,下面是求解算法。
////////此函数寻找ch的部分推导(可能有多个推导,但我们只需其中一部分)的第一个字符private string SearchDerivation(char ch,int depth){string str="";if (depth < 1) return str;for(int i=0;i<num;i++){if(gam[i].s1[0]==ch){str += gam[i].s2[0];if (gam[i].s2[0] >= 'A' && gam[i].s2[0] <= 'Z')str+=SearchDerivation(gam[i].s2[0],depth-1);}}return str;}/////此函数寻找ch的部分推导(可能有多个推导,但我们只需其中一部分)的最后一个字符private string SearchDerivation2(char ch,int depth){string str = "";if (depth < 1) return str;for (int i = 0; i < num; i++){if (gam[i].s1[0] == ch){char ch1=gam[i].s2[gam[i].s2_length-1];str += ch1;if (ch1 >= 'A' && ch1 <= 'Z')str += SearchDerivation2(ch1,depth-1);}}return str;}现在我们可以开始求解优先关系矩阵。
首先对表格进行初始化(用InitTable(window)进行初始化),对于文法G[S]:S::=(R)|a,R::=T ,T::=S,T|S 得到图2的效果。
图2 初始化优先关系矩阵紧接着对文法进行逐条扫描,根据上面的三点理解求解优先关系并填入表中,以下为实现过程。
其中SearchPosition(Form1 window,char ch1,char ch2) 用于寻找(ch1,ch2)在表中的位置,返回(ch1,ch2)的行号、列号,直接扫描表的行列进行比较即可实现该函数,这里就不累赘。
for (int i = 0; i < num;i++ ){if(gam[i].s2_length>1){for(int j=1;j<gam[i].s2_length;j++){int row1 = SearchPosition(window, gam[i].s2[j-1], gam[i].s2[j]).row;int col1= SearchPosition(window, gam[i].s2[j-1], gam[i].s2[j]).col;char tem1=window.listView1.Items[row1].SubItems[col1].Text[0];if(tem1=='e'||tem1=='=') //两个挨在一起的字符为相等关系window.listView1.Items[row1].SubItems[col1].Text = "=";elseMessageBox.Show("不是简单优先文法!");if(gam[i].s2[j]>='A'&&gam[i].s2[j]<='Z') //默认大写字母为终结符{ //这里判断是否为小于关系string str = SearchDerivation(gam[i].s2[j],num);for(int t=0;t<str.Length;t++){int row2 = SearchPosition(window, gam[i].s2[j-1],str[t]).row;int col2 = SearchPosition(window, gam[i].s2[j-1],str[t]).col;char tem2 = window.listView1.Items[row2].SubItems[col2].Text[0];if(tem2=='e'||tem2=='<')window.listView1.Items[row2].SubItems[col2].Text = "<";elseMessageBox.Show("不是简单优先文法!");}}if(gam[i].s2[j-1]>='A'&&gam[i].s2[j-1]<='Z') //默认大写字母为终结符{ //这里判断是否为大于关系string str1=SearchDerivation2(gam[i].s2[j-1],num);string str2 = gam[i].s2[j].ToString();if (gam[i].s2[j] >= 'A' && gam[i].s2[j] <= 'Z')str2 += SearchDerivation(gam[i].s2[j],num);for(int x=0;x<str1.Length;x++)for(int y=0;y<str2.Length;y++){int row3 = SearchPosition(window, str1[x], str2[y]).row;int col3 = SearchPosition(window, str1[x], str2[y]).col;char tem3 = window.listView1.Items[row3].SubItems[col3].Text[0];if (tem3 == 'e' || tem3 == '>')window.listView1.Items[row3].SubItems[col3].Text = ">";elseMessageBox.Show("不是简单优先文法!");}}}}}(3)符号串的分析(流程图)流程图中,S为符号栈,栈顶指针为i;TR为字符数组,用来存储输入符号串,j为下标。