算术表达式的算符优先分析法 逆波兰

算术表达式的算符优先分析法 逆波兰
算术表达式的算符优先分析法 逆波兰

目录

1 . 课程设计任务书 (2)

2 . 问题描述 (3)

3 . 语法分析 (3)

3 . 1 算符优先文法 (3)

3 . 2 算符优先分析表 (3)

4 . 算术表达式分析 (3)

3.1算术表达式合法性检测………………………………………………..3-5 3.2算术表达式到逆波兰式转化分析………………….…………………..5-6

5 . 程序流程图 (7)

6 . 源代码.……………………………………………………………………7-15

7 . 运行结果…………………………………………………………………15-16

8 . 设计收获与体会 (16)

9 . 参考文献 (16)

10 . 评分表 (17)

课程设计任务书

学生姓名:专业班级:软件0702 指导教师:工作单位:计算机科学与技术学院

题目:算术表达式的语法分析及语义分析程序设计

1.目的

通过设计、编制、调试语法及语义分析程序,加深对语法及语义分析原理理解。2.设计内容及要求

(1)使用算符优先分析法(或简单优先法)完成以上程序设计

(2)如1题写出符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(3)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

3.课程设计报告书的内容应包括:

1.设计题目、班级、学号、姓名、完成日期;

2.给出语法分析方法及中间代码形式的描述、文法和属性文法的设计;或者词法分

析方法及符号表和TOKEN代码的设计。

3.简要的分析与概要设计;

4.详细的算法描述;

5.源程序清单;

6.给出软件的测试方法和测试结果;

7.设计的评价、收获与体会。

时间安排:

第17周,周1-周4上午,周五全天

指导教师签名:年月日

系主任(或责任教师)签名:年月日

算术表达式的语法分析及语义分析程序设计

———算符优先法

1 . 问题描述

本次实验使用windows XP的visual C++软件,设计一个算术表达式的语法分析及语义分析程序设计,使用算符优先法。

2 . 语法分析

2.1 算符优先文法

E->E+T|E-T|T

T->T*F|T/F|F

F->(E)|i

2.2算符优先分析表:

3 . 算术表达式分析

3.1算术表达式合法性检测:

int check(char e3[100])

{

int k=0,m=0,n=0;

while(e3[k]!=0)

{

if(e3[k]=='(')

m=m+1;

if(e3[k]==')')

n=n+1;

k++;

}

if(m!=n)

{cout<<"表达式非法!左右括号数量不匹配!";return -1;}

k=0;

while(e3[k]!=0)

{

if(e3[0]=='+'||e3[0]=='-'||e3[0]=='/'||e3[0]=='*'||e3[0]==')')

{cout<<"表达式非法!不能以"<

else {k++;continue;}

if(e3[k]=='@')

{

if(e3[k-1]!='+'&&e3[k-1]!='-'&&e3[k-1]!='*'&&e3[k-1]!='/'&&e3[k-1]!='@'&&e 3[k-1]!='(')

{cout<<"表达式非法!操作数后不能接"<

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e 3[k+1]==0)

{cout<<"表达式非法!操作符"<

}

if(e3[k]=='(')

{

if(e3[k-1]!='+'&&e3[k-1]!='-'&&e3[k-1]!='*'&&e3[k-1]!='/'&&e3[k-1]!='(') {cout<<"表达式非法!操作数后不能接"<

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e 3[k+1]==0)

{cout<<"表达式非法!操作符"<

}

if(e3[k]=='+'||e3[k]=='-'||e3[k]=='*'||e3[k]=='/')

{

if(e3[k-1]=='+'||e3[k-1]=='-'||e3[k-1]=='*'||e3[k-1]=='/'||e3[k-1]=='@'||e 3[k-1]=='(')

{cout<<"表达式非法!操作符后不能接再接操作符!";return -1;}

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e 3[k+1]==0)

{cout<<"表达式非法!操作符"<

}

if(e3[k]==')')

{

if(e3[k-1]=='+'||e3[k-1]=='-'||e3[k-1]=='*'||e3[k-1]=='/'||e3[k-1]=='@'||e 3[k-1]=='(')

{cout<<"表达式非法!操作符后不能接再接操作符!";return -1;}

if(e3[k+1]!='+'&&e3[k+1]!='-'&&e3[k+1]!='*'&&e3[k+1]!='/'&&e3[k+1]!=0&&e3[ k+1]!=')')

{cout<<"表达式非法!操作符')'不能接操作数和'@','('操作符!";return -1;}

}

k++;

}

return 0;

}

3.2算术表达式到逆波兰式转化分析:

//算术表达式分析,输出逆波兰式过程

void postfix(char e1[100],char e2[100]){

SqCharStack OPTR;//操作符栈

initStack(OPTR);

push(OPTR,'#');

char C,X;

int i=0;//控制e1

int j=0;//控制e2

C=e1[i++];

while(C!=0){

if(C!='+'&& C!='-'&& C!='/'&& C!='*'&& C!='('&& C!=')'&& C!='@'){//如果是非操作符,直接加入到输出序列e2中

//运算符用优先数法

e2[j++]=C;

if(e1[i]=='+'||e1[i]=='-'||e1[i]=='/'||e1[i]=='*'||e1[i]=='('||e1[i]==')'||e1[i]=='@'||e1[i]==0)//有可能下一个还是非操作字符

//中间不能用空格,这里先进行判断

e2[j++]=' ';

}//if

else{//是操作符

if(C==')'){

//连续出栈,直到遇到'('

while(getTop(OPTR)!='('){

X=pop(OPTR);

e2[j++]=X;

cout<<"操作符"<

e2[j++]=' ';

}//while

X=pop(OPTR);//

}//if

else{

//比较优先数

while(isp(getTop(OPTR))>=icp(C)){

//如果栈中的操作符的优先级大于或等于新的操作符,

//则将栈中操作符出栈,加入到输出序列e2中

X=pop(OPTR);

cout<<"操作符"<

e2[j++]=X;

e2[j++]=' ';

}//while

push(OPTR,C);//否则进栈

cout<<"操作符"<

}//else

}//else

C=e1[i++];//表达式的下一个字符

}//while

while(getTop(OPTR)!='#'){

//弹出栈中剩余的运算符号

X=pop(OPTR);

e2[j++]=X;

cout<<"操作符"<

e2[j++]=' ';

}//while

e2[j++]='#';

}//postfix

4 . 程序主要流程图

#include

using namespace std;

/*************构造一个保存操作数的栈及基本操作过程**************/ #define STACK_INT_SIZE 100

#define STACK_INCREMENT 10

typedef struct{

int* base;//栈底

int* top;//栈顶指针

int stacksize;//栈的大小

}SqIntStack;//栈的顺序存储表示

//构造一个空栈

void initStack(SqIntStack& stack){

stack.base=(int *)malloc(STACK_INT_SIZE*sizeof(int));

stack.top=stack.base;//初态,栈为空

stack.stacksize=STACK_INT_SIZE;

}//initStack

//用e返回stack的栈顶元素

int getTop(SqIntStack stack){

int e;

e=*(stack.top-1);

return e;

}//getTop

//插入元素e为栈顶元素

void push(SqIntStack& stack,int e){

if(stack.top-stack.base>=stack.stacksize){

//栈满,追加存储空间

stack.base=(int*)realloc(stack.base,(stack.stacksize+STACK_INCREMENT)*sizeof(int)); stack.top=stack.base+stack.stacksize;//栈顶指针重新定向

stack.stacksize+=STACK_INCREMENT;//栈大小发生改变

}//if

*stack.top++=e;

}//push

//删除栈顶元素,用e返回

int pop(SqIntStack&s){

int e;

e=*(--s.top);

return e;

}//pop

/*************构造一个用来保存操作符的栈及基本操作过程*************/

#define STACK_INT_SIZE 100

#define STACK_INCREMENT 10

typedef struct{

char* base;

char* top;//指向栈顶的前一个元素

int stacksize;//栈的大小

}SqCharStack;//栈的顺序表示

//构造一个空栈

void initStack(SqCharStack& stack){

stack.base=(char*)malloc(STACK_INT_SIZE*sizeof(char));

stack.top=stack.base;

stack.stacksize=STACK_INT_SIZE;

}//initStack

//用e返回stack的栈顶元素

char getTop(SqCharStack stack){

char e;

e=*(stack.top-1);

return e;

}//getTop

//插入元素e为栈顶元素

void push(SqCharStack& stack,char e){

if(stack.top-stack.base>=stack.stacksize){

//栈满,追加存储空间

stack.base=(char*)realloc(stack.base,(stack.stacksize+STACK_INCREMENT)*sizeof(char)); stack.top=stack.base+stack.stacksize;

stack.stacksize+=STACK_INCREMENT;

}//if

*stack.top++=e;

}//push

//删除栈顶元素,用e返回

char pop(SqCharStack& stack){

char e;

e=*(--stack.top);

return e;

}//pop

/*****************其他函数*****************/

//判断在栈内的运算符的优先级

int isp(char e){

switch(e){

case'+':

return 1;

case'-':

return 1;

case'*':

return 2;

case'/':

return 2;

case'@':

return 3;

case'(':

return 0;

case'#':

return -1;

default:

exit(1);

}//switch

}//isp

//判断在栈外,C的运算符的优先权

int icp (char e){

switch(e){

case'+':

return 1;

case'-':

return 1;

case'*':

return 2;

case'/':

return 2;

case'@':

return 3;

case'(':

return 4;

default:

exit(1);

}//switch

}//icp

//算术表达式分析,输出逆波兰式过程

void postfix(char e1[100],char e2[100]){

SqCharStack OPTR;//操作符栈

initStack(OPTR);

push(OPTR,'#');

char C,X;

int i=0;//控制e1

int j=0;//控制e2

C=e1[i++];

while(C!=0){

if(C!='+'&& C!='-'&& C!='/'&& C!='*'&& C!='('&& C!=')'&& C!='@'){//如果是非操作符,直接加入到输出序列e2中

//运算符用优先数法

e2[j++]=C;

if(e1[i]=='+'||e1[i]=='-'||e1[i]=='/'||e1[i]=='*'||e1[i]=='('||e1[i]==')'||e1[i]=='@'|| e1[i]==0)//有可能下一个还是非操作字符

//中间不能用空格,这里先进行判断

e2[j++]=' ';

}//if

else{//是操作符

if(C==')'){

//连续出栈,直到遇到'('

while(getTop(OPTR)!='('){

X=pop(OPTR);

e2[j++]=X;

cout<<"操作符"<

e2[j++]=' ';

}//while

X=pop(OPTR);//

}//if

else{

//比较优先数

while(isp(getTop(OPTR))>=icp(C)){

//如果栈中的操作符的优先级大于或等于新的操作符,

//则将栈中操作符出栈,加入到输出序列e2中

X=pop(OPTR);

cout<<"操作符"<

e2[j++]=X;

e2[j++]=' ';

}//while

push(OPTR,C);//否则进栈

cout<<"操作符"<

}//else

}//else

C=e1[i++];//表达式的下一个字符

}//while

while(getTop(OPTR)!='#'){

//弹出栈中剩余的运算符号

X=pop(OPTR);

e2[j++]=X;

cout<<"操作符"<

e2[j++]=' ';

}//while

e2[j++]='#';

}//postfix

//对T1,T2进行运算求值

int T1toT2(int t1,int t2,char to){

switch(to){

case'+':

return t1+t2;

case'-':

return t1-t2;

case'*':

return t1*t2;

case'/':

return t1/t2;

default:

return 0;

}//switch

}//T1toT2

//对T1进行运算求值

int T1toT2(int t1,char to){

switch(to){

case'@':

return t1=t1*(-1);

default:

return 0;

}//switch

}//T1

//对纯整型数字逆波兰式求出运算结果

int evaluate(char e2[100]){

SqIntStack OPND;

initStack(OPND);

char C;

int j=0;

int n;

C=e2[j++];

while(C!='#'){

if(C>='0'&& C<='9'){

n=C-'0';//数字字符到整数的转化

while(e2[j]!=' '){//处理多位数

n=n*10+(e2[j]-'0');

j++;

}//while

push(OPND,n);

}//if

else if(C=='@'){

int T1=pop(OPND);

int T=T1toT2(T1,C);//对T1进行求值运算

push(OPND,T);//求值结果继续入栈,供下一次使用

}//else if

else{

int T2=pop(OPND);

int T1=pop(OPND);

int T=T1toT2(T1,T2,C);//对T1,T2进行求值运算

push(OPND,T);//求值结果继续入栈,供下一次使用

}//else

C=e2[j++];

if(C==' ')//跳过空格

C=e2[j++];

}//while

return pop(OPND);

}//evaluate

//表达式合法性检测

int check(char e3[100])

{

int k=0,m=0,n=0;

while(e3[k]!=0)

{

if(e3[k]=='(')

m=m+1;

if(e3[k]==')')

n=n+1;

k++;

}

if(m!=n)

{cout<<"表达式非法!左右括号数量不匹配!";return -1;}

k=0;

while(e3[k]!=0)

{

if(e3[0]=='+'||e3[0]=='-'||e3[0]=='/'||e3[0]=='*'||e3[0]==')')

{cout<<"表达式非法!不能以"<

else {k++;continue;}

if(e3[k]=='@')

{

if(e3[k-1]!='+'&&e3[k-1]!='-'&&e3[k-1]!='*'&&e3[k-1]!='/'&&e3[k-1]!='@'&&e3[k-1]!='(') {cout<<"表达式非法!操作数后不能接"<

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e3[k+1]==0) {cout<<"表达式非法!操作符"<

if(e3[k]=='(')

{

if(e3[k-1]!='+'&&e3[k-1]!='-'&&e3[k-1]!='*'&&e3[k-1]!='/'&&e3[k-1]!='(')

{cout<<"表达式非法!操作数后不能接"<

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e3[k+1]==0) {cout<<"表达式非法!操作符"<

if(e3[k]=='+'||e3[k]=='-'||e3[k]=='*'||e3[k]=='/')

{

if(e3[k-1]=='+'||e3[k-1]=='-'||e3[k-1]=='*'||e3[k-1]=='/'||e3[k-1]=='@'||e3[k-1]=='(') {cout<<"表达式非法!操作符后不能接再接操作符!";return -1;}

if(e3[k+1]=='+'||e3[k+1]=='-'||e3[k+1]=='*'||e3[k+1]=='/'||e3[k+1]==')'||e3[k+1]==0) {cout<<"表达式非法!操作符"<

if(e3[k]==')')

{

if(e3[k-1]=='+'||e3[k-1]=='-'||e3[k-1]=='*'||e3[k-1]=='/'||e3[k-1]=='@'||e3[k-1]=='(') {cout<<"表达式非法!操作符后不能接再接操作符!";return -1;}

if(e3[k+1]!='+'&&e3[k+1]!='-'&&e3[k+1]!='*'&&e3[k+1]!='/'&&e3[k+1]!=0&&e3[k+1]!=')') {cout<<"表达式非法!操作符')'不能接操作数和'@','('操作符!";return -1;} }

k++;

}

return 0;

}

/*****************主函数*****************/

void main(){

char expre1[100];//存放算术表达式

char expre2[100];//存放逆波兰表达式

cout<<"请输入算术表达式"<

cin>>expre1;

int int_check=check(expre1);

if(int_check==0)

{

postfix(expre1,expre2);//进行算术表达式到逆波兰转化

int h=0,g=0;

char s;

cout<<"转化后的逆波兰式:";

while(expre2[h]!='#'){

cout<

s=expre2[h];

if(s>='0'&&s<='9'||s=='+'||s=='-'||s=='*'||s=='/'||s=='@'||s=='('||s==')'||s==' ') g++;

h++;

}

cout<

if(h==g)

{

int result=evaluate(expre2);

cout<<"该算术表达式是纯整型数字表达式,其结果是:"<

}

}

}

6 . 运行结果

整形与字符型混合表达式时

输入整型数字表达式时

7 . 设计的收获与体会

本次课程设计中完成了对算术表达式的合法性检测,算术表达式的逆波兰式转化输出的设计,加深了语法分析和语义分析的理解。在本次课设中涉及到了栈的使用,复习了栈使用的方法,加强了练习,得到了巩固。在本次课设中,对算术表达式转化后的逆波兰式,如果是整型数字表达式,还能对其进行求值。

同时设计过程中,总会碰到这样或那样的难题,通过查询资料,大部分都得到了解决,在这次课设中,对数字表达式求值时,只对整型数求值,若出现小数时则仍然只输出逆波兰式,而不计算结果。

本次课设中,代码重复的地方比较多,没有进行优化,使得有些地方比较繁冗,以后要多加练习优化。

8 . 参考文献

[1]张素琴、吕映芝、蒋维杜、戴桂兰等.编译原理(第2版).清华大学出版社.2005

年2月

[2]《编译原理》主编:张幸儿.科学出版社 .1999年4月

[3]《编译原理与技术》(第二版)主编:陈意云 .中国科学技术大学出版社.2002年1月

[4]《程序设计语言编译原理》(第3版).陈火旺、刘春林等.国防工业出版社.2003年

2月

算符优先分析器设计实验报告--宁剑

编译原理实验报告 题目: 算符优先分析法分析器 学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 xxxx 2015年xx 月xx 日 算符优先分析法分析器 装 订 线

一、实验目的 1.理解自底向上优先分析,比较和自顶向下优先分析的不同。 2.理解算符优先分析的特点,体会其和简单优先分析方法的不同。 3.加深对编译器语法分析的理解。 二、实验原理 1.自底向上优先分析方法,也称移进-归约分析,粗略地说它的思想是对输入符号串自左向右进行扫描,并将输入符号逐个移入一个后进先出栈,边移入边分析,一旦栈顶符号串形成某个句型的句柄或可归约串时,就将该产生式的左部非终极符代替相应的右边文法符号串。 2.算符优先分析法的基本思想 首先确定算符(确切地说是终结符)之间的优先关系和结合性质,然后借助这种关系,比较相邻算符之间的优先级来确定句型的可归约串,并进行归约。 注意:算符优先分析过程是自下而上的归约过程,但它的可归约串未必是句柄,也就是说,算符优先分析过程不是一种规归约。 3.终结符号间优先关系的确定,用FIRSTVT和LASTVT计算。 4.最左素短语 所谓素短语是指这样一个短语,它至少含有一个终结符,并且除它自身之外不再含有其它素短语。最左素短语是指处于句型最左边的那个素短语。最左素短语是算符优先分析算法的可归约串。 5.计算得到所给文法的算符优先矩阵

6.算符优先分析的基本过程 三、实验要求 使用算符优先分析算法分析下面的文法: E’→#E# E→E+T|T T→T*F|F F→P^F|P

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

编译原理课程设计报告_算符优先分析法 编译原理课程设计报告 选题名称: 算符优先分析法 系(院): 计算机工程学院 专业: 计算机科学与技术 班级: 姓名: 学号: 指导教师: 学年学期: 7>2012 ~ 2013 学年第 1 学期 2012年 12 月 04 日 设计任务书 课题名称算符优先分析法 设计 目的 通过一周的课程设计,对算符优先分析法有深刻的理解,达到巩固理论知识、锻炼实践能力、构建合理知识结构的目的。实验环境Windows2000以上操作系统,Visual C++6.0编译环境 任务要求 1.判断文法是否为算符优先文法,对相应文法字符串进行算符优先分析; 2.编写代码,实现算符优先文法判断和相应文法字符串的算符优先分析; 3.撰写课程设计报告; 4提交报告。工作进度计划序号起止日期工作内容 1 理论辅导,搜集资料 2 ~编写代码,上机调试

3 撰写课程设计报告 4 提交报告 指导教师(签章): 年月日 摘要: 编译原理是计算机专业重要的一门专业基础课程,内容庞大,涉及面广,知识点多。本次课程设计的目的正是基于此,力求为学生提供一个理论联系实际的机会,通过布置一定难度的课题,要求学生独立完成。我们这次课程设计的主要任务是编程实现对输入合法的算符优先文法的相应的字符串进行算符优先分析,并输出算符优先分析的过程。算符优先分析法特别有利于表达式的处理,宜于手工实现。算符优先分析过程是自下而上的归约过程,但这种归约未必是严格的规范归约。而在整个归约过程中,起决定作用的是相继连个终结符之间的优先关系。因此,所谓算符优先分析法就是定义算符之间的某种优先关系,并借助这种关系寻找句型的最左素短语进行归约。通过实践,建立系统设计的整体思想,锻炼编写程序、调试程序的能力,学习文档编写规范,培养独立学习、吸取他人经验、探索前言知识的习惯,树立团队协作精神。同时,课程设计可以充分弥补课堂教学及普通实验中知识深度与广度有限的缺陷。 关键字:编译原理;归约;算符优先分析;最左素短语; 目录 1 课题综述 1 1.1 课题来源 1 1.2课题意义 1 1.3 预期目标 1 1.4 面对的问题 1 2 系统分析 2

实验4 算符优先分析法.

实验名称: 实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 实验容: 有上下无关文法如下: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明:优先关系矩阵的构造过程: (1) = 关系由产生式 F->(E) 知‘(’=‘)’ FIRSTVT集及LASTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F)

/F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E) (3) > 关系 E+ 则有: LASTVT(E) > + E- 则有: LASTVT(E) > - T* 则有: LASTVT(T) > * T/ 则有: LASTVT(T) > / E) 则有: LASTVT(E) > ) (4)请大家画出优先关系矩阵 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。程序的功能描述:程序由文件读入字符串(以#结束),然后进行算符优先分析,分析过程中如有错误,则终止程序并报告错误位置,最终向屏幕输出移近——规约过程。

(5)依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。算法描述如下: for 每个形如 P->X1X2…Xn的产生式 do for i =1 to n-1 do begin if Xi和Xi+1都是终结符 then Xi = Xi+1 if i<= n-2, Xi和Xi+2 是终结符, 但Xi+1 为非终结符 then Xi = Xi+2 if Xi为终结符, Xi+1为非终结符 then for FirstVT 中的每个元素 a do Xi < a if Xi为非终结符, Xi+1为终结符 then for LastVT 中的每个元素 a do a > Xi+1 end (6)构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度

编译原理 实验3 算符优先分析

编译原理实验3 算符优先分析 一、实验目的 通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法,对给定的符号串进行分析的方法。 二、实验内容 1. 给定一文法G,输出G的每个非终结符的FIRSTVT集和LASTVT集。 2. 构造算符优先表。 3. 对给定的符号串进行分析,包含符号栈,符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。 三、程序思路 在文法框内输入待判断文法产生式,格式E->a|S,注意左部和右部之间是“->”,每个产生式一行,ENTER键换行。文法结束再输入一行G->#E# 1. 先做文法判断,即可判断文法情况。 2. 若是算符优先文法,则在优先表栏显示优先表。 3. 写入要分析的句子,按回车即可。 4. 在分析过程栏,可以看到整个归约过程情况 四、实验结果 FunctorFirst.h #include #include #include #include usingnamespace std;

#define rightlength 20 #define product_num 20 // 产生式最多个数 #define num_noterminal 26 // 非终结符最多个数 #define num_terminal 26 // 终结符最多个数 struct Production { char Left; char Right[rightlength]; int num; }; struct VT { bool vt[num_noterminal][num_terminal]; }; struct Stack { char P; char a; }; class CMyDlg { public:CMyDlg(); void InputRule(); CString showLastVT(); CString showFirstVT(); CString shownoTerminal(char G[]); CString showTerminal(char g[]); CString showLeftS(char S[], int j, int k); void InitAll(); CString showSentence(CString sen, int start); CString showStack(char S[], int n); void Initarry(char arry[], int n); CString ProdtoCStr(Production prod); int selectProd(int i, int j, char S[]); void preFunctor(CString sen); void insertFirstVT(Stack S[], int&sp, char P, char a); void insertLastVT(Stack S[], int&sp, char P, char a); void ShowPreTable(); void createPreTable();

算符优先分析算法(c语言).(优选)

编译原理实验 一实验目的 设计、编制并调试一个算符优先分析算法,加深对此分析法的理解 二实验过程 先在算符栈置“$”,然后开始顺序扫描表达式,若读来的单词符号是操作数,这直接进操作数栈,然后继续读下一个单词符号。分析过程从头开始,并重复进行;若读来的是运算符θ2则将当前处于运算符栈顶的运算符θ1的入栈优先数f与θ2的比较优先函数g进行比较。 2.2 各种单词符号对应的种别码 2.3 算符优先程序的功能 完成一个交互式面向对象的算符优先分析程序,而一个交互式面向对象的算符优先分析程序基本功能是: (1)输入文法规则 (2)对文法进行转换 (3)生成每个非终结符的FirstVT和LastVT (4)生成算符优先分析表 (5)再输入文法符号 (6)生成移进规约步骤 三设计源码 算符优先分析器 #include "stdio.h"

#include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; int m,n,N; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标 void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i

算符优先分析程序

南华大学 实验名称:算符优先分析程序 学院:计算机学院 专业班级:本2010 电气信息类03班 学号:20104030342 姓名:谢志兴 指导教师:吴取劲 日期:2012 年 6 月12 日

实验二算符优先分析程序 一、实验目的 调试并完成一个算符优先分析程序,加深对算符优先分析原理的理解。 二、实验要求 算符优先分析程序的功能: 输入:所给文法的源程序字符串、待匹配字符串。 输出:转化后的文法、每个非终结符的FIRSTVT集和LASTVT集、算符优先分析表、规约过程。 三、源程序代码: #include "stdio.h" #include "stdlib.h" #include "iostream.h" char data[20][20]; //算符优先关系 char s[100]; //模拟符号栈s char lable[20]; //文法终极符集 char input[100]; //文法输入符号串 char string[20][10]; //用于输入串的分析 int k; char a; int j; char q; int r; //文法规则个数 int r1; //转化后文法规则个数 char st[10][30]; //用来存储文法规则 char first[10][10]; //文法非终结符FIRSTVT集 char last[10][10]; //文法非终结符LASTVT集 int fflag[10]={0}; //标志第i个非终结符的FIRSTVT集是否已求出

int lflag[10]={0}; //标志第i个非终结符的LASTVT集是否已求出 int deal(); //对输入串的分析 int zhongjie(char c); //判断字符c是否是终极符 int xiabiao(char c); //求字符c在算符优先关系表中的下标void out(int j,int k,char *s); //打印s栈 void firstvt(char c); //求非终结符c的FIRSTVT集 void lastvt(char c); //求非终结符c的LASTVT集 void table(); //创建文法优先关系表 void main() { int i,j,k=0; printf("请输入文法规则数:"); scanf("%d",&r); printf("请输入文法规则:\n"); for(i=0;i'Z') { printf("不是算符文法!\n"); exit(-1); } if(st[i][j]>='A'&&st[i][j]<='Z') {

算符优先报告及代码

实验任务: 对下述描述算符表达式的算符优先文法G[E],给出算符优先分析的实验结果。 E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 说明: 优先关系矩阵的构造过程: (1)= 关系 由产生式F->(E) 知‘(’=‘)’ FIRSTVT集 FIRSTVT(E)={ +,-,*,/,(,i } FIRSTVT(F)={ (,i } FIRSTVT(T)={ *,/,(,i } LASTVT(E)={ +,-,*,/,),i } LASTVT(F)={ ),i } LASTVT(T)={ *,/,),i } (2) < 关系 +T 则有:+ < FIRSTVT(T) -T 则有:- < FIRSTVT(T) *F 则有:* < FIRSTVT(F) /F 则有:/ < FIRSTVT(F) (E 则有:( < FIRSTVT(E)

(3) > 关系 E+ 则有:LASTVT(E) > + E- 则有:LASTVT(E) > - T* 则有:LASTVT(T) > * T/ 则有:LASTVT(T) > / E) 则有:LASTVT(E) > ) (4)优先关系矩阵 + - * / ( ) i # + > > < < < > < > - > > < < < > < > * > > > > < > < > / > > > > < > < > ( < < < < < = < ) > > > > > > i > > > > > > # < < < < < < = 终结符之间的优先关系是唯一的,所以该文法是算符优先文法。 程序的功能描述: 程序由文件读入字符串(以#结束),然后进行算符优先分析,

编译原理实验报告5-语法分析程序的设计(2)

实验5 语法分析程序的设计(2) 一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算法优先分析方法。 二、实验内容 设计一个文法的算法优先分析程序,判断特定表达式的正确性。 三、实验要求 1、给出文法如下: G[E] E->T|E+T; T->F|T*F; F->i|(E); + * ( ) i + * ( ) i 2、计算机中表示上述优先关系,优先关系的机内存放方式有两种1)直接存放,2)为 优先关系建立优先函数,这里由学生自己选择一种方式; 1、给出算符优先分析算法如下: k:=1; S[k]:=‘#’; REPEAT 把下一个输入符号读进a中; IF S[k]∈V T THEN j:=k ELSE j:=k-1; WHILE S[j] a DO BEGIN REPEAT Q:=S[j]; IF S[j-1]∈V T THEN j:=j-1 ELSE j:=j-2 UNTIL S[j] Q 把S[j+1]…S[k]归约为某个N; k:=j+1;

S[k]:=N; END OF WHILE; IF S[j] a OR S[j] a THEN BEGIN k:=k+1;S[k]:=a END ELSE ERROR UNTIL a=‘#’ 1、 根据给出算法,利用适当的数据结构实现算符优先分析程序; 2、 利用算符优先分析程序完成下列功能: 1) 手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束; 2) 读入文本文件中的表达式; 3) 调用实验2中的词法分析程序搜索单词; 4) 把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语 言),若错误,应给出错误信息; 5) 完成上述功能,有余力的同学可以对正确的表达式计算出结果。 四、实验环境 PC 微机 DOS 操作系统或 Windows 操作系统 Turbo C 程序集成环境或 Visual C++ 程序集成环境 五、实验步骤 1、 分析文法中终结符号的优先关系; 2、 存放优先关系或构造优先函数; 3、利用算符优先分析的算法编写分析程序; 4、写测试程序,包括表达式的读入和结果的输出; 5、程序运行效果,测试数据可以参考下列给出的数据。 六、测试数据 输入数据: 编辑一个文本文文件expression.txt ,在文件中输入 如下内容: 正确 结果: (1)10; 输出:正确 (2)1+2; 输出:正确 (3)(1+2)*3+(5+6*7); 输出:正确 (4)((1+2)*3+4 10; 1+2; (1+2)*3+(5+6*7); ((1+2)*3+4; 1+2+3+(*4+5); (a+b)*(c+d); ((ab3+de4)**5)+1;

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

一、实验目的与任务 算术表达式和赋值语句的文法可以是(你可以根据需要适当改变): S→i=E E→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; else return FALSE; } h) { k = TRUE; h == 'E') { n ++; } return n; } 词结束(遇到“#”号),无法移进,需要规约,返回:1 词没有结束,需判断是否可以移进 栈单词<=单词:移进后返回:2 栈单词>单词:不能移进,需要规约,返回:1 单词没有优先关系:出错,返回:-1 int MoveIn() { SToken s,t; h = '#';

编译原理-语法分析-算符优先文法分析器

编译原理实验报告 实验名称:编写语法分析分析器实验类型: 指导教师: 专业班级: 学号: 电子邮件: 实验地点: 实验成绩:

一、实验目的 通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。 1、选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序,至少选一题。 2、选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验过程 编写算符优先分析器。要求: (a)根据算符优先分析算法,编写一个分析对象的语法分析程序。读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入: Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。 Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。 (c)有运行实例。对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。 三、实验结果 算符优先分析器: 测试数据:E->E+T|T T->T*F|F F->(E)|i 实验结果:(输入串为i+i*i+i)

四、讨论与分析 自下而上分析技术-算符优先分析法: 算符文法:一个上下无关文法G,如果没有且没有P→..QR...(P ,Q ,R属于非终结符),则G是一个算符文法。 FIRSTVT集构造 1、若有产生式P →a...或P →Qa...,则a∈FIRSTVT(P)。 2、若有产生式P→...,则FIRSTVT(R)包含在FIRSTVT(P)中。由优先性低于的定义和firstVT集合的定义可以得出:若存在某个产生式:…P…,则对所有:b∈firstVT(P)都有:a≦b。 构造优先关系表: 1、如果每个非终结符的FIRSTVT和LASTVT集均已知,则可构造优先关系表。 2、若产生式右部有...aP...的形式,则对于每个b∈FIRSTVT(P)都有

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

华北水利水电学院编译原理实验报告 一、实验题目:语法分析(算符优先分析程序) (1)选择最有代表性的语法分析方法算符优先法; (2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。 二、实验内容 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (4) 分析的句子为: (i+i)*i和i+i)*i 三、程序源代 #include #include #include #include #define SIZE 128 char 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()//构造算符优先关系表,并将其存入数组中 {

c语言实现算符优先语法分析

#include char prog[100],zhongjian[100],shu[500]; char ch,zh; int syn,p,q,a,b,c,d; //p指向prog,q指向zhongjian 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 zhan[100];//数组栈 int z,j;//z为栈顶指针,j为zhongjian数组指针 void push(char ch)//入栈 { zhan[z++]=ch; } void pop()//出栈 { z--; } void putzhan()//打印栈内字符 { for(int i=0;i

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

实验三算符优先分析算法的设计与实现 (8学时) 一、实验目的 根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。 二、实验要求 1、输入文法。可以是如下算术表达式的文法(你可以根据需要适当改变): E→E+T|E-T|T T→T*F|T/F|F F→(E)|i 2、对给定表达式进行分析,输出表达式正确与否的判断。 程序输入/输出示例: 输入: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] then begin F[P,a] = true; //(P,a)进栈 end; Procedure FirstVT; Begin for 对每个非终结符 P和终结符 a do F[P,a] = false for 对每个形如 P a…或 P→Qa…的产生式 do Insert(P,a) while stack 非空 begin 栈顶项出栈,记为(Q,a) for 对每条形如 P→Q…的产生式 do insert(P,a) end; end. 同理,可构造计算LASTVT的算法。 3、构造算符优先分析表 依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。 算法描述如下: for 每个形如 P->X1X2…X n的产生式 do for i =1 to n-1 do begin if X i和X i+1都是终结符 then X i = X i+1 if i<= n-2, X i和X i+2 是终结符, 但X i+1 为非终结符 then X i = X i+2 if X i为终结符, X i+1为非终结符 then for FirstVT 中的每个元素 a do X i < a ; if X i为非终结符, X i+1为终结符 then for LastVT 中的每个元素 a do a > X i+1 ; end 4、构造总控程序 算法描述如下: stack S; k = 1; //符号栈S的使用深度 S[k] = ‘#’ REPEAT

编译原理 六章 算符优先分析法

第六章算符优先分析法 课前索引 【课前思考】 ◇什么是自下而上语法分析的策略? ◇什么是移进-归约分析? ◇移进-归约过程和自顶向下最右推导有何关系? ◇自下而上语法分析成功的标志是什么? ◇什么是可归约串? ◇移进-归约过程的关键问题是什么? ◇如何确定可归约串? ◇如何决定什么时候移进,什么时候归约? ◇什么是算符文法?什么是算符优先文法? ◇算符优先分析是如何识别可归约串的? ◇算符优先分析法的优缺点和局限性有哪些? 【学习目标】 算符优先分析法是自下而上(自底向上)语法分析的一种,尤其适应于表达式的语法分析,由于它的算法简单直观易于理解,因此,也是学习其它自下而上语法分析的基础。通过本章学习学员应掌握: ◇对给定的文法能够判断该文法是否是算符文法 ◇对给定的算符文法能够判断该文法是否是算符优先文法 ◇对给定的算符文法能构造算符优先关系表,并能利用算符优先关系表判断该文法是否是算符优先文法。 ◇能应用算符优先分析算法对给定的输入串进行移进-归约分析,在分析的每一步能确定当前应移进还是归约,并能判断所给的输入串是否是该文法的句子。 ◇了解算符优先分析法的优缺点和实际应用中的局限性。 【学习指南】 算符优先分析法是自下而上语法分析的一种,它的算法简单、直观、易于理解,所以通常作为学习其它自下而上语法分析的基础。为学好本章内容,学员应复习有关语法分析的知识,如:什么是语言、文法、句子、句型、短语、简单短语、句柄、最右推导、规范归约基本概念。 【难重点】 ◇通过本章学习后,学员应该能知道算符文法的形式。 ◇对一个给定的算符文法能构造算符优先关系分析表,并能判别所给文法是否为算符优先文法。 ◇分清规范句型的句柄和最左素短语的区别,进而分清算符优先归约和规范归约的区别。 ◇算符优先分析的可归约串是句型的最左素短语,在分析过程中如何寻找可归约串是算符优先分析的关键问题。对一个给定的输入串能应用算符优先关系分析表给出分析(归约)步骤,并最终判断所给输入串是否为该文法的句子。 ◇深入理解算符优先分析法的优缺点和实际应用中的局限性。 【知识点】

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

数学与计算机学院编译原理实验报告 年级专业学号姓名成绩 实验题目算符优先分析法分析器的设计实验日期 一、实验目的: 设计一个算符优先分析器,理解优先分析方法的原理。 二、实验要求: 设计一个算符优先分析器 三、实验内容: 使用算符优先分析算法分析下面的文法: E’→#E# E →E+T | T T →T*F | F F →P^F | P P →(E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 四、实验结果及主要代码: 1.主要代码 void operatorp()

{ char s[100]; char a,Q; int k,j,i,l; string input,temp; cin>>input; cout<<"步骤"<<'\t'<<"栈"<<'\t'<<"优先关系"<<'\t'<<"当前符号"<<'\t'<<"剩余输入串"<<'\t'<<"移进或归约"<') { cout<<'('<

for(l=1;l'<<'\t'<

算符优先分析算法

数学与计算机学院编译原理实验报告 年级09软工学号姓名成绩 专业软件工程实验地点主楼指导教师湛燕 实验项目算符优先关系算法实验日期2012.6.6 一、实验目的和要求 设计一个算符优先分析器,理解优先分析方法的原理。 重点和难点:本实验的重点是理解优先分析方法的原理;难点是如何构造算符优先关系。 二、实验内容 使用算符优先分析算法分析下面的文法: E’→ #E# E → E+T | T T → T*F | F F → P^F | P P → (E) | i 其中i可以看作是一个终结符,无需作词法分析。具体要求如下: 1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况; 2、如果输入符号串不是正确句子,则指示出错位置。 三、程序设计 全局变量有一下几个: static string input;//记录输入串 char s[20];//栈 int top=-1;//栈顶指针 有三个函数: int analyze(string input);//分析输入的串是否符合标准 void process();//进行归约的函数 int main() input是一个全局变量,记录输入串,用analyze(input)分析输入的是不是符合标准的字符串,(例如“i+i*i^(i+i)”)如果不符合标准,提示用户重新输入。 进行归约的函数主要思想是:先构造优先关系矩阵,有“<”,“>”,“=”和空格四种关系。Char a 记录栈中最高位的终结符,如果栈中是#E+E,则 a 的赋

值是“+”,如果形如“#E+”或“#E+i”则a 赋值“+”或“i”。charnowchar 记录当前的字符。a 与 nowchar 按照算符优先关系矩阵找出优先关系。如果优先关系是“<”,则进行移进;如果优先关系是“>”,则进行归约;如果是“=”,则去掉括号或分析成功。 五、代码和截图 自己编写代码如下: #include #include using namespace std; static string input;//输入串 char s[20];//栈 int top=-1;//栈顶指针 char VT[7]={'+','*','^','i','(',')','#'};//终结符 static char matrix[7][7]={ '>','<','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','>',' ',' ','>','>', '<','<','<','<','<','=',' ', '>','>','>',' ',' ','>','>', '<','<','<','<','<',' ','='}; //优先关系矩阵,不存在优先关系时为空格 int analyze(string input);//分析输入的串是否符合标准 void process();//规约 int main() { //cout<<"输入一个符号串!"<>input; if(analyze(input)==0) flag=1; else flag=0; } cout<<"***********************************************************"<<

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

实验二语法分析程序(算符优先分析法) 一、实验目的 通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。 二、实验要求 (1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件); (2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程) (3)实验要求独立完成,不允许有抄袭现象。 (4)实验完成后,要求提交源程序和上交实验报告(包括源程序清单)。 (附:实验报告格式) 三、实验内容 (1)给定表达式文法为: G(E’): E’→#E# E→E+T | T T→T*F |F F→(E)|i (2)分析的句子为: (i+i)*i和i+i)*i (1)分析 1,判断为算符优先文法: 文法没有A->…BC…且BC均为非终结符,因此它为OG文法 文法没有同时存在①A->…ab…或A->….aBb…. ②A->…aB…且B=>b….或B=>Cb…. ③A->…Bb….且B=>…a或B=>…aC 文法为算符优先文法 2,求FirstVT集和LastVT集 FirstVT(E)={+, * , ( , i } LastVT(E)= {+, - , * , / , ) , i } FirstVT(T)={* , ( , i } LastVT(T)= {* , / , ( , i } FirstVT(F)={ ( , i } LastVT(F)={ ) , i } FirstVT(E’)={ #} LastVT(E’)={ #} 3,根据FirstVT和LastVT集构造算符优先表

基于算符优先分析方法

基于算符优先分析方法 的表达式语法分析器 年级:2007级 班级:计算机科学与技术四班姓名:毛群晖 学号:20074042154 指导老师:段明秀 年月日

摘要: 算符优先分析法是Floyd在1963年首先提出来的,是一种古典而又实用的方法,用这种方法在分析程序语言中的各类表达式时尤为有效。不少编译程序中都使用这种方法分析表达式。算符优先分析法就是仿照算术表达式的运算过程而提出的一种自底向上的语法分析方法。其基本思想是:首先规定算符,这里是文法的终极符之间的优先关系,然后根据这种优先关系,通过比较相邻算符的优先次序来确定句型中的“句柄”,然后进行归约。算符优先分析法的关键:算符优先分析法的关键就是寻找当前句型中的最左素短语,并归约它。 关键字:小于、大于、等于、句柄、归约、

一、对表达式文法G[ E’]构造算符优先关系表。 计算算符优先只针对于终结符,终结符之间的优先关系有三种,在计算优先关系之前我们先定义两个集合,对于任意两个终结符(a,b)FIRSTVT(B)={b|B=>b…或B=>Cb…},其中…表示V*中的符号串。LASTVT(B)={a|B=>…a或B=>…aC} 三种优先关系:(1)等于关系:可直接查看产生式的右部,对如下形式 的产生式A->…ab… A->… aBb…则有a=b成立。 (2)小于关系:求出每个非终结符B的FIRSTVT(B),观察如下形式的产生式A->…aB…对每一 b∈FIRSTVT(B)有a≮b成立 (3)大于关系:计算每个非终结符B的LASTVT(B), 观察如下形式的产生式A->…Bb…对每一 a∈LASTVT(B)有a≯b成立 表达式文法G[ E’]: E’→# E # E → E + Q | Q Q → Q - T | T T → T * F | F F → F/ M|M M → M^ P|P P → ( E )|i

相关文档
最新文档