算符优先分析

第一章 概述

1.1 设计内容:

    题目 19

对文法 G:  EE+T|T  

TT*F|F   

F(E)|i    

采用教材P.985.3

 

+

*

(

)

i

#

+

>

<

<

>

<

>

*

>

>

<

>

<

>

(

<

<

<

=

<

e1

)

>

>

e2

>

e2

>

i

>

>

e2

>

e2

>

#

<

<

<

e3

<

e1

 

实现P.93描述的算符优先分析算法。

1.2设计要求

程序显示输出“移进-归约”的步骤要编制各出错处理子程序

第二章 设计的基本原理

   算符优先优先分析算法:

k:=1;    S[k]:=’#’;

REPEAT

        把下一个输入符号读进a;

        IF S[k]是终结符 then j:=k  else j:=k-1;

        WHILE S[j]>a DO

        BEGIN

        REPEAT

               Q:=S[j];

               IF S[j-1]属于终结符 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.i被归约,则检查其左端或右端是否有非终结符.如果有,则给出信息:”

达式间无运算符联接”.

3.如果()被规约,则检查是否在括号内有一非终结符.如果没有,则给出信息:”括号间无表达式”.

对应的如下

e1   当表达式以(结尾时,调用此程序

     (从栈顶移去 给出出错信息:非法左括号.

e2   i)后跟i(,调用此程序

     在输入端插入+ 给出错误信息:缺少运算符

e3   当表达式以(开始时,调用此程序 从输入端删除)

     给出错误信息:非法左括号.

e4   (1)若栈顶有非终结符E,则表达式分析完毕.

     (2) 若为空,则在输入端插入i

     给出错误信息:缺少表达式

第三章  程序设计

1总体方案设计

  输入表达式→算符分析→选择是移进还是归约(同时判断是否有错,调用相应的出错处理子程序)→完成(表达式的分析成功与失败)

 2 各模块设计

   首先是优先关系表的存储以及终结符的表示:

char functor[5]={'+','*','(',')','#'};

char table[6][6]={

//   +    *   (   )   i   #     // 程序涉及到的算符

    {'>','<','<','>','<','>'},

    {'>','>','<','>','<','>'},

    {'<','<','<','=','<','1'},

    {'>','>','2','>','2','>'},

    {'>','>','2','>','2','>'},

    {'<','<','<','3','<','4'},

};

char VTchar[6]={'+','*','(',')','i','#'};  //终结符数组  

//存储产生式:EE+T|T TT*F|F   F(E)|i;

char suanfu[5]={'+','*','(',')','#'};

char guiyuechar[5][3]={{'+','E','T'},{'*','T','F'},{'(',NULL,'E'},{')','E',NULL},{'#',NULL,'E'}};

char produce[2][2]= {{'E','+'},{'T','*'}};

 

             


归约栈的定义以及一些方法的定义

class stack

{

public:

stack(){top=0;sarray[0]='#';}

char poptop(){return array[top];}

void push(char a){top++;sarray[top]=a;}

CString sPrint(){

   CString change;

   for(int i=0;i<=top;i++)

   change+=sarray[i];

   return change;

}

char gets(int i){return sarray[i];}

int  point(){return top;}

void puts(int i,char a){ sarray[i]=a;}

void changetop(int i){ top=i;}

private:

char sarray[100];

int top;

};

终结符的判断函数

bool judgeSuanfu(char b)

{

for(int i=0;i<5;i++)

if(functor[i]==b)

  return true;

return false;

}

 

bool judgeVT(char a)//判断输入符号a是不是终结符

{

for(int i=0;i<6;i++)

if(VTchar[i]==a)

  return true;

return false;

}

优先级的判断

char precedence(char a,char b)

{//判断优先级

int i=0;

for(;i<6;i++)

if(VTchar[i]==a)

break;

int j=0;

for(;j<6;j++)

if(VTchar[j]==b)

break;

return table[i][j];

}

 进入实现模块

char Q;

int hang=0;

int count=1;

stack s;

int k=0;

//s.sPrint();

UpdateData(true);

m_list.InsertItem(hang,s.sPrint());

m_list.SetItemText(hang,1,m_input);

m_list.SetItemText(hang,2,"...........");

hang++;

CString expression=m_input;

CString viewexpression;

CString chanshengshi;

char a;

char b;

int exadr=0;

do{

a=expression[exadr];

int j;

if(judgeVT(s.gets(k)))

j=k;

else j=k-1;

if(precedence(s.gets(j),a)=='>')

{

while(precedence(s.gets(j),a)=='>'||precedence(s.gets(j),Q)=='=')

{

 

do{          

Q=s.gets(j);

if(judgeVT(s.gets(j-1)))

j--;

else j=j-2;

}while (precedence(s.gets(j),Q)=='>');

 

if(s.gets(j+1)=='i')

{

s.puts(j+1,'F');

chanshengshi="Fi";

}

 

else if(precedence(s.gets(j),Q)=='=')

{

s.puts(j,'F');

chanshengshi="F(E)";

if(a=='#')

{k=j;j--;}

else k=j;

s.changetop(k);

}

else

 

{

  if(Q=='+')

{

s.puts(j+1,'E');

k=j+1;s.changetop(k);

chanshengshi="EE+T";

}

if(Q=='*')

{

s.puts(j+1,'T');

k=j+1;s.changetop(k);

chanshengshi="TT*F"; }

}

m_list.InsertItem(hang,s.sPrint());

m_list.SetItemText(hang,1,viewexpression);

m_list.SetItemText(hang,2,chanshengshi);

hang++;

}

}

else

if(precedence(s.gets(j),a)=='<'||precedence(s.gets(j),a)=='=')

{

k++; exadr++;

viewexpression=expression;

viewexpression.Delete(0,count);

count++;

s.push(a);

m_list.InsertItem(hang,s.sPrint());

m_list.SetItemText(hang,1,viewexpression);

m_list.SetItemText(hang,2,"移进");

hang++;

}

else {

switch(precedence(s.gets(j),a))

{

 case '1':///当表达式以左括号结尾时,'('从栈顶移出   给出错误信息:非法左括号

{

int change=s.point();

change--;

s.changetop(change);

MessageBox( "非法左括号:'('  默认删除  '(' ", MB_OK );

expression.Delete(exadr,1);

if(judgeSuanfu(s.poptop()))

{

int xxx=s.point();

xxx--;

s.changetop(xxx);

}

m_list.InsertItem(hang,s.sPrint());

m_list.SetItemText(hang,1,viewexpression);

m_list.SetItemText(hang,2,"删除");

hang++;

break;

}

case '2':

{

//if(expression[exadr+1]=='i')

{

// i(后跟i)  在输入端插入'+'   给出错误信息:缺少运算符/

expression.Insert(exadr,"+");

MessageBox( "缺少运算符   默认在此之后


加上算符+", MB_OK );

}

break;

}

case '3':{

// 当表达式以右括号开始,调用此程序 从输入端删除')' 给出错信息:非法右括号/

MessageBox( "从输入端删除')'", MB_OK );

expression.Delete(0,1);

break;

}

case '4':{

// 1 若栈顶有非终结符E,则表达式分析结束 2 若为空则在输入端插入i

if(s.poptop()=='E') a='#';

if(s.poptop()=='#') expression.Insert(exadr,"i");

{

s.puts(j+1,'F');

s.changetop(j+1);

chanshengshi="Fi";

m_list.InsertItem(hang,s.sPrint());

m_list.SetItemText(hang,1,viewexpression);

m_list.SetItemText(hang,2,chanshengshi);

hang++;

}

break;

}

}

/出错处理子程序调入

}

}while(a!='#');    

第四章  程序测试

 1.程序测试:

2.出错处理的测试:

第五章  结论

 

参考文献

程序设计语言编译原理(3)陈火旺

编译原理及编译程序构造      秦振松

 

 

 

 
算符优先分析法 C++ 编译原理 运行环境:Visual Studio 2005 #include "SStack.h" #include <iostream> #include <string> using namespace std; class Functor { private : char ** table; string ** production; string prog;//待分析字符串 int p;//字符指针 int num;//终结符个数 int num1;//产生式个数 SStack <char> stack; public: Functor(int m,int n,char ** T,string **prod,string pr) { num=m; num1=n; table=T; production=prod; prog=pr; p=0; stack.push('$'); } void traversal() { while(p<(prog.length())) { stack.display(); cout<<prog.substr(p)<<" "; char ch; if(Getnum(stack.gettop())) { ch=stack.gettop(); } else { ch=stack.getsecond(); } switch(compare(ch,prog[p])) { case 1: case 2:stack.push(prog[p]);p++;cout<<"移入"<<endl;break; case 3:reduct();cout<<"归约"<<endl;break; } } cout<<"分析成功!"<<endl; } int Getnum(char ch) { for(int i=1;i<num;i++) { if(ch==table[i][0]) { return i; } } return 0; } int compare(char col,char row) { int c=Getnum(col); int r=Getnum(row); switch( table[c][r]) { case '>': return 3;break; case '<': return 2;break; case '=': return 1;break; default:cout<<endl<<"输入串有误,程序将终止!"<<endl;system("pause");exit(0);break; } } void reduct() { //待定 string token=""; int temp; string str=""; if(!Getnum(stack.gettop())) { token+=stack.gettop(); stack.pop(); } char ch=stack.gettop(); str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); bool Nover=true; while(Nover) { if(Getnum(stack.gettop())) { if(compare(stack.gettop(),ch)==2) { Nover=false; } else { ch=stack.gettop(); str=""; str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); } } else { token+=stack.gettop(); stack.pop(); } } string token2=""; //cout<<token<<" "; for(int i=token.length()-1;i>=0;i--) { token2+=token[i]; } //cout<<token2<<endl; if(Haven(token2)!= -1) { stack.push(production[Haven(token2)][0][0]); } else { cout<<"输入串有误!分析终止!"<<endl; system("pause"); exit(0); } } int Haven(string temp) { for(int i=0;i<num1;i++) { int j=1; while(production[i][j]!="") { if(temp==production[i][j]) { return i; } j++; } } return -1; } public: ~Functor(void) { } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值