📄 fenxi.cpp
字号:
#include "Share.h"
int iCodeLine=0; //三地址代码行数
int iAddress=DATAADDRESS; //当前数据地址
extern char strFile[256]; //文件名
extern Symbol_table table;
extern ifstream infile;
extern int irow;
KeyWord key_table[23]=
{
{"program",'p'},{"var",'v'},{"array",'a'},{"of",'o'},{"integer",'n'},{"real",'r'},
{"function",'f'},{"procedure",'c'},{"begin",'b'},{"end",'e'},{"if",'i'},{"then",'t'},
{"else",'s'},{"while",'w'},{"do",'d'},{"not",'!'},{"div",'g'},{"mod",'m'},{"and",'&'},
{"or",'|'},{"record",'z'},{"read",'x'},{"write",'y'}
};
void SetTokenProperty(int iPointer,int iType,int iAddress,int iDomain)
{
table.setAddress(iPointer,iAddress);
table.setDimension(iPointer,iDomain);
table.setType(iPointer,iType);
}
int GetType(int iPointer)
{
return table.getType(iPointer);
}
int Insert(int iType,int iWidth) //插入指定类型的变量
{
int pos=table.insert("");
SetTokenProperty(pos,iType,iAddress,0);
iAddress+=iWidth;
return pos;
}
bool Program() //语法分析主程序 O -> program id ( idB ) ;CDE
{
TOKEN token;
int address=DATAADDRESS; //变量起始地址
char buffer[10240]={0};
irow=0;
infile.open(strFile,ios::binary);
//程序头,若程序头不出错,直接记录出错信息后返回
token=accidence(infile,irow,1); //获取第一个记号Program
if(token.iType!=KEYWORD ||token.dProperty!='p') //主程序关键字不对
{
WriteError("非法的程序头,应以program开始",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //获取下一个记号id
if(token.iType!=DESIGNATOR)
{
WriteError("非法的程序头,无程序名",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //获取下一个记号 (
if(token.dProperty!='(') //主程序关键字不对
{
WriteError("非法的程序头,缺少'('",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //读取标识符id
if(token.iType!=DESIGNATOR)
{
WriteError("非法的参数表",token.iPosition);
return false;
}
if(!IdentifierList()) //程序头参数类表
{
return false;
}
token=accidence(infile,irow,1); //获取下一个记号 )
if(token.dProperty!=')')
{
WriteError("非法的程序头,缺少')'",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //获取下一个记号 ;
if(token.dProperty!=';')
{
WriteError("非法的程序头,缺少';'",token.iPosition);
return false;
}
if(!Declations()) //声明
{
return false;
}
if(!SubprogramDeclarations()) //子程序声明
{
return false;
}
if(!CompoundStatement(buffer)) //复合语句
{
return false;
}
WriteCode(buffer);
return true;
}
bool IdentifierList() //标识符列表 B
{
TOKEN token;
token=accidence(infile,irow,0); //读取下一记号, 或)
if(token.iType!=KEYWORD)
{
WriteError("非法的参数表",token.iPosition);
return false;
}
if(token.dProperty==')') //B->空
{
return true;
}
else if(token.dProperty==',') //B->, idB
{
token=accidence(infile,irow,1);//读取下一记号,
token=accidence(infile,irow,1);//读取下一记号id
if(token.iType!=DESIGNATOR)
{
WriteError("非法的参数表",token.iPosition);
return false;
}
return IdentifierList();
}
WriteError("无效的关键字",token.iPosition);
return false;
}
bool Declations() //变量声明 C
{
TOKEN token;
int num;
token=accidence(infile,irow,0); //读取Var说明
if(token.iType!=KEYWORD)
{
WriteError("缺少关键字",token.iPosition);
return false;
}
if(token.dProperty=='c' || token.dProperty=='f' ||token.dProperty=='b')//C->空
{//没有变量声明
return true;
}
else if(token.dProperty=='v') //C -> var G;H
{//变量声明
int place=-1;
token=accidence(infile,irow,1); //指针移至Var之后
if(!Declation(place,&num))
{
return false;
}
token=accidence(infile,irow,1); //读取;
if(token.iType!=KEYWORD || token.dProperty!=';')
{
WriteError("缺少分号';'",token.iPosition);
return false;
}
if(!Declation1(&num))
{
return false;
}
return true;
}
WriteError("无效的关键字",token.iPosition);
return false;
}
//address为新定义的变量的起始地址
bool Declation(int iPlace,int *num) //处理变量声明 G→id H'
{
TOKEN token;
int iType=0,iTypelen=4,iDomain=0;
token=accidence(infile,irow,1); //读取id
if(token.iType!=DESIGNATOR)
{
WriteError("非法的变量声明",token.iPosition);
return false;
}
if(iPlace>=0)
{
table.setParam(iPlace,token.dProperty);
}
(*num)++;
if(!Declation2(iPlace,&iType,&iTypelen,&iDomain,num))
{
return false;
}
//更新符号表中变量的信息
SetTokenProperty(token.dProperty,iType,iAddress,iDomain);
//更新变量起始地址
iAddress+=iTypelen;
// WriteError("错误的变量声明",token.iPosition);
return true;
}
//处理变量声明
//address为新定义的变量的起始地址
bool Declation1(int *num) //H
{
TOKEN token;
token=accidence(infile,irow,0);
if(token.iType==DESIGNATOR) //H->G;H
{
int place=-1;
if(!Declation(place,num))
{
return false;
}
token=accidence(infile,irow,1); //读取;
if(token.iType!=KEYWORD ||token.dProperty!=';')
{
WriteError("缺少分号';'",token.iPosition);
}
return Declation1(num);
}
else if(token.iType==KEYWORD && (token.dProperty=='b'||token.dProperty=='f'||token.dProperty=='c'))
{ //H->空
return true;
}
WriteError("错误的变量声明",token.iPosition);
return false;
}
//处理变量声明,涉及到了数据类型和地址分配
//type返回数据类型,INTEGER为integer,REAL为real
//address为新定义的变量的起始地址
bool Declation2(int iPlace,int *iType,int *iTypelen,int *iDomain,int *num) //H'
{
TOKEN token;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD)
{
WriteError("错误的变量声明",token.iPosition);
return false;
}
if(token.dProperty==':') //H'->:I
{
if(!Type(iType,iTypelen,iDomain))
{
return false;
}
return true;
}
else if(token.dProperty==',')// H'→,id H'
{
token=accidence(infile,irow,1); //读取id
if(token.iType!=DESIGNATOR)
{
WriteError("错误的变量声明",token.iPosition);
return false;
}
if(iPlace>=0)
{
table.setParam(iPlace,token.dProperty);
}
(*num)++;
if(!Declation2(iPlace,iType,iTypelen,iDomain,num))
{
return false;
}
//更新符号表中变量信息
SetTokenProperty(token.dProperty,*iType,iAddress,*iDomain);
//更新变量起始地址
iAddress+=*iTypelen;
return true;
}
WriteError("错误的变量声明",token.iPosition);
return false;
}
bool Type(int *iType,int *iTypelen,int *iDomain) //获取类型 I
{
TOKEN token;
unsigned int start,end; //数组定义的起始
token=accidence(infile,irow,0);
if(token.iType!=KEYWORD)
{
WriteError("错误的变量声明",token.iPosition);
return false;
}
if(token.dProperty=='a')//I→array [ digits .. digits ] of J
{
token=accidence(infile,irow,1); //移动指针至array以后
token=accidence(infile,irow,1); //读取[
if(token.iType!=KEYWORD ||token.dProperty!='[')
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //digits
if(token.iType!=NUM)
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
start=token.dProperty;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!='.')//..
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
token=accidence(infile,irow,1); //digits
if(token.iType!=NUM)
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
if(token.dProperty<start)
{
WriteError("数组上界小于下界",token.iPosition);
}
end=token.dProperty;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=']')//]
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!='o')//of
{
WriteError("数组类型定义错误",token.iPosition);
return false;
}
if(!Type1(iType,iTypelen,iDomain))
{
return false;
}
*iType+=2; //转换为数组类型
*iTypelen=(*iTypelen)*(end-start+1);
*iDomain=start; //数组类型的维数保存下界
return true;
}
else if(token.dProperty=='r' ||token.dProperty=='n')//I→ J
{
if(!Type1(iType,iTypelen,iDomain))
{
return false;
}
return true;
}
WriteError("非法的数据类型",token.iPosition);
return false;
}
bool Type1(int *iType,int *iTypelen,int *iDomain) //获取类型 J
{
TOKEN token;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD)
{
WriteError("非法的数据类型",token.iPosition);
return false;
}
if(token.dProperty=='n')
{
*iType=INTEGER;
*iTypelen=INTWIDTH;
*iDomain=0;
return true;
}
if(token.dProperty=='r')
{
*iType=REAL;
*iTypelen=REALWIDTH;
*iDomain=0;
return true;
}
WriteError("非法的数据类型",token.iPosition);
return false;
}
bool SubprogramDeclarations() //子程序声明 D
{
TOKEN token;
token=accidence(infile,irow,0);
if(token.iType!=KEYWORD)
{
WriteError("缺少关键字",token.iPosition);
return false;
}
if(token.dProperty=='b') //D->空
{
return true;
}
else if(token.dProperty=='f' ||token.dProperty=='c')//D →K ;D
{
if(!SubprogramDeclaration())
{
return false;
}
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=';')
{
WriteError("缺少分号",token.iPosition);
return false;
}
return SubprogramDeclarations();
}
WriteError("错误的关键字",token.iPosition);
return false;
}
bool SubprogramDeclaration()//子程序声明K
{
char temp[4096]={0};
char buffer[100]={0};
int place;
if(!SubprogramHead(&place))
{
return false;
}
sprintf(buffer,"proc %d\r\n",place);
iCodeLine++;
if(!Declations())
{
return false;
}
if(!CompoundStatement(temp))
{
return false;
}
WriteCode(buffer);
WriteCode(temp);
sprintf(buffer,"endp %d\r\n",place);
WriteCode(buffer);
iCodeLine+=1;
return true;
}
bool SubprogramHead(int *iPlace)//L
{
TOKEN token;
int num=0;
int iType,iTypelen,iDomain;
token=accidence(infile,irow,1);
if(token.iType==KEYWORD)
{
if(token.dProperty=='f') //L->function id M : J ;
{
token=accidence(infile,irow,1);
if(token.iType!=DESIGNATOR)
{
WriteError("缺少函数名",token.iPosition);
return false;
}
if(!Arguments(token.dProperty,&num))
{
return false;
}
*iPlace=token.dProperty;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=':')
{
WriteError("错误的函数声明",token.iPosition);
return false;
}
if(!Type(&iType,&iTypelen,&iDomain))
{
return false;
}
SetTokenProperty(*iPlace,iType,0,num);
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=';')
{
WriteError("缺少分号",token.iPosition);
//return false;
}
return true;
}
else if(token.dProperty=='c') //L->procedure id M ;
{
token=accidence(infile,irow,1);
if(token.iType!=DESIGNATOR)
{
WriteError("缺少过程名",token.iPosition);
return false;
}
if(!Arguments(token.dProperty,&num))
{
return false;
}
*iPlace=token.dProperty;
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=';')
{
WriteError("缺少分号",token.iPosition);
// return false;
}
SetTokenProperty(*iPlace,PROC,0,num);
return true;
}
}
WriteError("缺少函数或过程声明关键字",token.iPosition);
return false;
}
bool Arguments(int iPlace,int *num)//M
{
TOKEN token;
token=accidence(infile,irow,0);
if(token.iType==KEYWORD)
{
token=accidence(infile,irow,1);
if(token.dProperty=='(')//M->(GG')
{
if(!Declation(iPlace,num))
{
return false;
}
if(!Arguments1(iPlace,num))
{
return false;
}
token=accidence(infile,irow,1);
if(token.iType!=KEYWORD ||token.dProperty!=')')
{
WriteError("错误的参数列表",token.iPosition);
return false;
}
return true;
}
}
WriteError("错误的参数列表",token.iPosition);
return false;
}
bool Arguments1(int iPlace,int *num)//G'
{
TOKEN token;
token=accidence(infile,irow,0);
if(token.iType==KEYWORD) //G->空
{
if(token.dProperty==')')
{
return true;
}
else if(token.dProperty==';')
{
token=accidence(infile,irow,1);
if(!Declation(iPlace,num))
{
return false;
}
if(!Arguments1(iPlace,num))
{
return false;
}
return true;
}
}
return true;
}
bool CompoundStatement(char* buffer) //复合语句E
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -