📄 parser.h
字号:
//---------------语法法分析parser.h-------------------------
#ifndef parser_comp
#define parser_comp
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "scanner.h"
using namespace std;
//------------------------ 语法分析程序-----------------------------
int kind;
int ent;
//四元式代码结构
struct code1
{
int op;
int ag1;
int ag2;
int result;
};
struct code1 code[TXMAX*10];
int codetab=0;
int gencode(int x,int y,int z,int r)
{
if(codetab<TXMAX*10-1)
{
code[codetab].op=x;
code[codetab].ag1=y;
code[codetab].ag2=z;
code[codetab].result=r;
codetab++;
}
return 0;
}
//----------算符优先文法-----------
struct opg
{
int opgnum[TXMAX];
int opgtab;
};
struct opg num_stack;//操作数栈
struct opg op_stack;//操作符栈
int popnum(struct opg& a,int& b)
{
if(a.opgtab>0)
{
a.opgtab-=1;
b=a.opgnum[a.opgtab];
return 0;
}
return -1;
}
int pushnum(struct opg& a,int b)
{
a.opgnum[a.opgtab]=b;
a.opgtab+=1;
return 0;
}
//算符优先矩阵
int opg_array[6][6]={
{2,2,1,1,1,2},
{2,2,1,1,1,2},
{2,2,2,2,1,2},
{2,2,2,2,1,2},
{1,1,1,1,1,0},
{2,2,2,2,-1,2},
};
int tab2=300;//临时变量存贮始址
//读入数值
int Getnum(ifstream& src)
{
int cRet;
src>>cRet;
return cRet;
}
//读入二元式
int getoken(ifstream& src)
{
kind=Getnum(src);
GetChar(src);
ent=Getnum(src);
return 0;
}
//-------判断运算符-------
int gequen(int i)
{
int j;
switch (i)
{
case 39:
j=4;
break;
case 40:
j=5;
break;
case 41:
j=2;
break;
case 43:
j=0;
break;
case 45:
j=1;
break;
case 48:
j=3;
break;
case 53:
j=9;
break;
case 54:
j=13;
break;
case 55:
j=8;
break;
case 56:
j=14;
break;
case 57:
j=7;
break;
case 58:
j=12;
break;
default:
break;
}
return j;
}
//查找变量说明地址
int position(int x)
{
if(x<300)
{
for(int i=0;i<x;i++)
{
if(strcmp(table[i].name,table[x].name)==0)
return i;
}
}
else
return x;
}
//if-while出口堆栈
struct opg ifchain_stack;//if跳转链栈
struct opg iffalse_stack;//if假出口栈
struct opg while_stack;//while真出口
struct opg whfalse_stack;//while假出口
bool else_if=false;//表明最近处理过else
//-----过程有关结构--------
struct procedure1
{
int name;
int goin;
int goinum;
int code_begin;
};
struct procedure1 proce[10];
int procenum=0;
int procecode=300;
struct opg goin_stack;
struct opg in_stack;
int find_proce(int x)
{
for(int i=0;i<procenum;i++)
{
if(proce[i].name==x)
return i;
}
}
//-----程序体处理----
void syntax(ifstream& src)
{
//程序头处理
getoken(src);
if(kind==22)
{
getoken(src);
if(kind==34)
{
getoken(src);
if(kind==52)
gencode( 5,-1,-1,-1);
}
}
//说明语句处理
if(kind==31)
{
while (kind!=52)
{
getoken(src);
while(kind!=50)
{
getoken(src);
if(kind==34)
getoken(src);
while(kind==44)
{
getoken(src);
if(kind==34)
getoken(src);
}
}
if(kind==50)
{
getoken(src);
if(kind==4||kind==7||kind==16||kind==24)
getoken(src);
}
}
}
// 算术运算处理
if(kind==34)
{
int i=ent;
getoken(src);
if(kind==51)
{
int op1=-1;
int op2=-1;
int num1=0;
int num2=0;
op_stack.opgtab=0;
getoken(src);
while(kind!=52&&kind!=44)
{
if(kind==35||kind==34)
{
pushnum(num_stack,position(ent));
getoken(src);
}
else if(kind==39||kind==40||kind==41||kind==43||kind==45||kind==48)
{
op2=gequen(kind);
while(op_stack.opgtab>0 && op1>=0 && op2>=0 && opg_array[op1][op2]==2)
{
popnum(num_stack,num2);
popnum(num_stack,num1);
gencode( op1,num1,num2,tab2);
pushnum(num_stack,tab2);
popnum(op_stack,op1);
tab2++;
if(op_stack.opgtab>0)
{
popnum(op_stack,op1);
op1=gequen(op1);
}
}
if(op_stack.opgtab>0 && op1>=0 && op2>=0 && opg_array[op1][op2]==0)
{
popnum(op_stack,op1);
popnum(op_stack,op1);
op1=gequen(op1);
op2=-1;
getoken(src);
}
else if(op_stack.opgtab==0 && op1>=0 && op2>=0 && opg_array[op1][op2]==2)
{
popnum(num_stack,num2);
popnum(num_stack,num1);
gencode( op1,num1,num2,tab2);
pushnum(num_stack,tab2);
tab2++;
pushnum(op_stack,kind);
getoken(src);
}
else
{
op1=gequen(kind);
op2=-1;
pushnum(op_stack,kind);
getoken(src);
}
}
}
if(kind==44)
{
while(op_stack.opgtab>0)
{
popnum(op_stack,op1);
op1=gequen(op1);
popnum(num_stack,num2);
popnum(num_stack,num1);
gencode( op1,num1,num2,tab2);
pushnum(num_stack,tab2);
tab2++;
}
if(num_stack.opgtab==1)
{
popnum(num_stack,num1);
gencode( 4,num1,-1,position(i));
}
}
if(kind==52)
{
while(op_stack.opgtab>0)
{
popnum(op_stack,op1);
op1=gequen(op1);
popnum(num_stack,num2);
popnum(num_stack,num1);
gencode( op1,num1,num2,tab2);
pushnum(num_stack,tab2);
tab2++;
}
if(num_stack.opgtab==1)
{
popnum(num_stack,num1);
gencode( 4,num1,-1,position(i));
}
//-------对于if语句的有关处理
while(iffalse_stack.opgtab==0 && ifchain_stack.opgtab>0 && else_if==true)
{
int back_chain;
popnum(ifchain_stack,back_chain);
code[back_chain].result=codetab;
else_if=false;
}
if(iffalse_stack.opgtab>0)
{
gencode( 6,-1,-1,-1);
pushnum(ifchain_stack,codetab-1);
getoken(src);
if(kind==10)
{
else_if=true;
int back;
popnum(iffalse_stack,back);
code[back].result=codetab;
}
}
//-------------对于while语句的处理
while(whfalse_stack.opgtab>0)
{
int head;
popnum(while_stack,head);
gencode( 6,-1,-1,head);
popnum(whfalse_stack,head);
code[head].result=codetab;
}
}
}
}
//If-then部分处理
if(kind==14)
{
int num1 ,num2,op;
getoken(src);
if(kind==34||kind==35)
{
num1=position(ent);
getoken(src);
if(kind>=53&&kind<=58)
{
op=gequen(kind);
getoken(src);
if(kind==34||kind==35)
{
num2=position(ent);
getoken(src);
}
}
}
if(kind==27)
{
gencode( op,num1,num2,codetab+2);
gencode( 6,-1,-1,-1);
pushnum(iffalse_stack,codetab-1);
}
}
//while-do处理部分
if(kind==32)
{
int num1 ,num2,op;
getoken(src);
if(kind==34||kind==35)
{
num1=position(ent);
getoken(src);
if(kind>=53&&kind<=58)
{
op=gequen(kind);
getoken(src);
if(kind==34||kind==35)
{
num2=position(ent);
getoken(src);
}
}
}
if(kind==9)
{
gencode( op,num1,num2,codetab+2);
pushnum(while_stack,codetab-1);
gencode( 6,-1,-1,-1);
pushnum(whfalse_stack,codetab-1);
}
}
//过程procedure处理
if(kind==21)
{
codetab=procecode;
getoken(src);
if(kind==34)
{
proce[procenum].name=ent;
getoken(src);
if(kind==39)
getoken(src);
while(kind!=40)
{
getoken(src);
if(kind==34)
{
proce[procenum].goin=ent;
proce[procenum].goinum++;
}
}
if(kind==40)
{
proce[procenum].code_begin=codetab;
procenum++;
getoken(src);
}
}
}
//end.处理与end;处理
if(kind==11)
{
getoken(src);
if(kind==46)
gencode( 11,-1,-1,-1);
else if(kind==52)
{
for(int i=0;i<=proce[procenum-1].goinum;i++)
{
gencode( 4,proce[procenum-1].goin-proce[procenum-1].goinum+i,-1,-1);
pushnum(goin_stack,codetab-1);
}
gencode( 6,-1,-1,-1);
pushnum(goin_stack,codetab-1);
procecode=codetab;
codetab=0;
}
}
//call 处理
if(kind==5)
{
int callin;
int in;
int back;
popnum(goin_stack,back);
getoken(src);
if(kind==34)
{
callin=position(ent);
callin=find_proce(callin);
getoken(src);
in=proce[callin].goin-proce[callin].goinum;
}
if(kind==39)
{
getoken(src);
while(kind!=40)
{
if(kind==34)
{
gencode( 4,position(ent),-1,in);
in++;
pushnum(in_stack,position(ent));
getoken(src);
}
else
getoken(src);
}
if(kind==40)
{
for(int i=0;i<=proce[callin].goinum;i++)
{
int p,k;
popnum(goin_stack,p);
popnum(in_stack,k);
code[p].result=k;
}
getoken(src);
if(kind==52)
{
gencode(6,-1,-1,proce[callin].code_begin);
code[back].result=codetab;
}
}
}
}
//write 语句处理
if(kind==33)
{
while(kind!=52&&kind!=44)
{
getoken(src);
if(kind==34)
gencode( 10,position(ent),-1,-1);
}
if(kind==52)
{
//--对于if语句的有关处理--
while (iffalse_stack.opgtab==0 && ifchain_stack.opgtab>0 && else_if==true )
{
int back_chain=0;
popnum(ifchain_stack,back_chain);
code[back_chain].result=codetab;
else_if=false;
}
if(iffalse_stack.opgtab>0)
{
gencode( 6,-1,-1,-1);
pushnum(ifchain_stack,codetab-1);
getoken(src);
if(kind==10)
{
else_if=true;
int back=0;
popnum(iffalse_stack,back);
code[back].result=codetab;
}
}
//对于while语句的处理
while(whfalse_stack.opgtab>0)
{
int head=0;
popnum(while_stack,head);
gencode( 6,-1,-1,head);
popnum(whfalse_stack,head);
code[head].result=codetab;
}
}
}
}
//输出四元式
int putcode(ofstream& codst)
{
int i;
for( i=0;i<codetab;i++)
{
codst<<i<<"("<<code[i].op<<" "<<arrow;
codst<<code[i].ag1<<" "<<arrow;
codst<<code[i].ag2<<" "<<arrow;
codst<<code[i].result<<")"<< enter;
}
for( i=300;i<procecode;i++)
{
codst<<i<<"("<<code[i].op<<" "<<arrow;
codst<<code[i].ag1<<" "<<arrow;
codst<<code[i].ag2<<" "<<arrow;
codst<<code[i].result<<")"<< enter;
}
return 0;
}
//-------------语法分析主程序-------------
int parser()
{
// 打开文件
ifstream src("token.txt");
if (src.fail())
{
cerr << "\aFailed openning \"" << endl;
return 1;
}
ofstream codst("four_code.txt");
// 开始解析并产生四元式
while (!src.eof())
syntax(src);
putcode(codst);
// 收尾工作
codst.close();
src.close();
cout << "The result of Syntax Analyzing is written into four_code.txt." << endl;
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -