expressanalysis.h
来自「一个pascal子集编译器。输入pascal原程序」· C头文件 代码 · 共 911 行 · 第 1/2 页
H
911 行
}
int GetCondecl()
{ //Condecl的规约 <condecl>→const <const>{,<const>};
int go;
do
{
if(FALSE==GetConst()) return FALSE;//分析const
if(FALSE==Match(tempword,SIGN_COMMA,SIGN_SEMI)) return FALSE;
if(tempword.type==SIGN_COMMA) go=1;//如果遇到“,”,继续分析const
else go=0;
tempword=was.GetOneWord();
}while(1==go);
return TRUE;
}
int Getvardecl()
{ //vardecl的规约 <vardecl>→var <id>{,<id>};
int go;
do
{
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;
tempaddfh.type=FH_VAR;
strcpy(tempaddfh.mgc,tempmhs);
AddFh(tempword.data,tempaddfh);//往符号表里添加该变量
GenCode("INT",0,1);//活动记录指针向上移一个单位,给变量分配空间
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_COMMA,SIGN_SEMI)) return FALSE;
if(tempword.type==SIGN_COMMA) go=1;//如果遇到“,”,继续分析标示符
else go=0;
tempword=was.GetOneWord();
}while(1==go);
return TRUE;
}
int GetProc()
{ //Proc的规约 <proc>→procedure <id>(<id>{,<id>});<block>{;<proc>}
char thismhs[L2MAX];
int go;
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//过程名必须是标示符
tempaddfh.type=FH_PRONAME;
strcpy(thismhs,tempmhs);
strcpy(tempaddfh.mgc,thismhs);
AddFh(tempword.data,tempaddfh);//往符号表里添加该过程
strcpy(tempmhs,tempword.data);
GenCode("INT",0,3);//活动记录指针向上移3,给新过程的返回地址、静态链、动态链开辟空间
tempword=was.GetOneWord();
if(strcmp("(",tempword.data)==0)
{
do
{
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;//形参名必须是标示符
tempaddfh.type=FH_XC;
strcpy(tempaddfh.mgc,tempmhs);
AddFh(tempword.data,tempaddfh);//往符号表里添加该形参
GenCode("INT",0,1);//留出位置给形参
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_RIGHTBRA,SIGN_COMMA)) return FALSE;
if(tempword.type==SIGN_COMMA) go=1;//如果形参后面接",",还需要继续分析形参
else go=0;
}
while(1==go);
tempword=was.GetOneWord();
}
if(FALSE==Match(tempword,SIGN_SEMI)) return FALSE;
tempword=was.GetOneWord();
if(FALSE==GetBlock()) return FALSE;
GenCode("OPR",0,OP_RETURN);//过程结束后要返回到被调用函数
if(tempword.type==SIGN_PROCEDURE)
{ //如果接下去有同一层的其他过程
tempword=was.GetOneWord();
strcpy(tempmhs,thismhs);
if(FALSE==GetProc()) return FALSE;
}
return TRUE;
}
int GetBlock()
{ //Block的规约 <block>→[<condecl>][<vardecl>][<proc>]<body>
char savemhs[L2MAX];
int t;
strcpy(savemhs,tempmhs);
if(tempword.type==SIGN_CONST)
{ //分析condecl
tempword=was.GetOneWord();
if(FALSE==GetCondecl()) return FALSE;
}
if(tempword.type==SIGN_VAR)
{ //分析vardecl
tempword=was.GetOneWord();
if(FALSE==Getvardecl()) return FALSE;
}
if(tempword.type==SIGN_PROCEDURE)
{ //分析proc
GenCode("JMP",0,0);
t=codenum-1;
tempword=was.GetOneWord();
if(FALSE==GetProc()) return FALSE;
Backpatch(t,codenum);
}
strcpy(tempmhs,savemhs);
if(GetBody()==FALSE) return FALSE;//分析body
else return TRUE;
}
int GetBody()
{ //Body的规约 <body>→begin <statement>{;<statement>} end
if(FALSE==Match(tempword,SIGN_BEGIN)) return FALSE;
tempword=was.GetOneWord();
if(FALSE==GetStatement()) return FALSE;
if(FALSE==Match(tempword,SIGN_END,SIGN_SEMI)) return FALSE;
while(tempword.type!=SIGN_END)
{//如果statement后面不是end,继续分析statement
tempword=was.GetOneWord();
if(FALSE==GetStatement()) return FALSE;//分析statement
if(FALSE==Match(tempword,SIGN_END,SIGN_SEMI)) return FALSE;
}
if(FALSE==Match(tempword,SIGN_END)) return FALSE;
tempword=was.GetOneWord();
return TRUE;
}
int GetFactor()
{ //Factor的规约 <factor>→<id>|<integer>|(<exp>)
switch(tempword.type)
{
case SIGN_INTEGER://如果是整数
GenCode("LIT",0,atoi(tempword.data));//将常量取到栈顶
tempword=was.GetOneWord();
break;
case SIGN_NAME://如果是标示符
//从符号表里查找标示符的类型
if(FindFh(tempword.data,tempmhs,&tempfindfh)==FALSE) return FALSE;
if(tempfindfh.type==FH_CONST)
{//标示符代表常量
GenCode("LIT",0,tempfindfh.value);//将常量取到栈顶
}
else if(tempfindfh.type==FH_VAR || tempfindfh.type==FH_XC)
{//标示符代表变量或形参
GenCode("LOD",tempfindfh.depth,tempfindfh.address);//将变量取到栈顶
}
else if(tempfindfh.type==FH_PRONAME)
{//标示符代表过程,出错
sprintf(error,"第%d行 不能为过程名",tempword.line);
return FALSE;
}
tempword=was.GetOneWord();
break;
case SIGN_LEFTBRA://如果是"(",递归地分析Exp
tempword=was.GetOneWord();
GetExp();
if(FALSE==Match(tempword,SIGN_RIGHTBRA)) return FALSE;
tempword=was.GetOneWord();
break;
default:
break;
}
return TRUE;
}
int GetTerm()
{ //Term的规约 <term>→<factor>{<mop><factor>}
char optemp[L2MAX];
if(FALSE==GetFactor()) return FALSE;
if(tempword.type==SIGN_MULTIPLY || tempword.type==SIGN_DEVIDE)
{//如果接的是mop
while(tempword.type==SIGN_MULTIPLY || tempword.type==SIGN_DEVIDE)
{
strcpy(optemp,tempword.data);
tempword=was.GetOneWord();
if(FALSE==GetFactor()) return FALSE;//递归地分析Factor
if(strcmp(optemp,"*")==0)
GenCode("OPR",0,OP_MUL);
else
GenCode("OPR",0,OP_DIV);
}
}
return TRUE;
}
int GetExp()
{ //Exp的规约 <exp>→[+|-]<term>{<aop><term>}
char optemp[L2MAX];
int t=0;
if(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
{ //如果前面有+或-
if(tempword.type==SIGN_SUBTRACT) t=1;
tempword=was.GetOneWord();
}
if(FALSE==GetTerm()) return FALSE;
if(1==t) GenCode("OPR",0,OP_NOT);//如果是-,要做取反操作
if(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
{//如果接的是aop
while(tempword.type==SIGN_ADD || tempword.type==SIGN_SUBTRACT)
{
strcpy(optemp,tempword.data);
tempword=was.GetOneWord();
if(FALSE==GetTerm()) return FALSE;//递归地分析Term
if(strcmp(optemp,"+")==0)
GenCode("OPR",0,OP_ADD);
else
GenCode("OPR",0,OP_SUB);
}
}
return TRUE;
}
int GetCondition(int *acgo,int *wago)
{ //Condition的规约 <lexp>→<exp><lop><exp>|odd<exp>
if(tempword.type==SIGN_ODD)
{
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_ODD);
}
else
{
if(FALSE==GetExp()) return FALSE;
switch(tempword.type)
{
case SIGN_EQUAL:
{// =
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_EQUAL);
break;
}
case SIGN_LESS:
{// <
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_LESS);
break;
}
case SIGN_LESSEQUAL:
{// <=
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_LESSQ);
break;
}
case SIGN_MORE:
{// >
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_MORE);
break;
}
case SIGN_MOREEQUAL:
{// >=
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_MOREQ);
break;
}
case SIGN_NOTEQUAL:
{// <>
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
GenCode("OPR",0,OP_NOEQUAL);
break;
}
default:
{
return FALSE;
break;
}
}
}
*acgo=codenum;//acgo表示条件符合时的链头
*wago=codenum+1;//wago表示条件不符合时的链头
GenCode("JPC",0,0);//条件跳转,如果条件为真,跳到目标指令
GenCode("JMP",0,0);//无条件跳转,当前一句指令JPC不做时(也就是条件为假),跳到目标位置
return TRUE;
}
void Backpatch(int p,int t)
{//将链头号为p的链的arg2设为t
int q;
while(p!=0)
{
q=code[p].arg2;
code[p].arg2=t;
p=q;
}
}
int GetStatement()
{ //Statement的规约
char strtemp1[L2MAX];
int acgo,wago,thengo,whilego,go;
switch(tempword.type)
{
case SIGN_NAME:
{ //<id>:=<exp>
strcpy(strtemp1,tempword.data);
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_EVAL)) return FALSE;//要匹配:=
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
//从符号表里查变量的相对层数和地址
if(FALSE==FindFh(strtemp1,tempmhs,&tempfindfh)) return FALSE;
if(tempfindfh.type==FH_XC || tempfindfh.type==FH_VAR)
{ //将栈顶元素存到变量里
GenCode("STO",tempfindfh.depth,tempfindfh.address);
}
else if(tempfindfh.type==FH_PRONAME)
{// 赋值号左边是过程名则出错
sprintf(error,"第%d行 赋值号左边不能是过程名",tempword.line);
return FALSE;
}
else if(tempfindfh.type==FH_CONST)
{// 常量不能被赋值
sprintf(error,"第%d行 常量不能被赋值",tempword.line);
return FALSE;
}
break;
}
case SIGN_IF:
{ //if <lexp> then <statement> [else <statement>]
tempword=was.GetOneWord();
if(FALSE==GetCondition(&acgo,&wago)) return FALSE;//处理条件语句
if(FALSE==Match(tempword,SIGN_THEN)) return FALSE;//匹配then
Backpatch(acgo,codenum);//回填真链
tempword=was.GetOneWord();
if(FALSE==GetStatement()) return FALSE;//生成真链指向的指令代码
if(tempword.type==SIGN_ELSE)
{ //如果有else
thengo=codenum;//真链指向的指令的最后一条的地址
//真链指向的指令执行结束,要跳到假链指向的指令后面,
//但由于假链指向的指令未生成,故目标指令地址暂时不填
GenCode("JMP",0,0);
Backpatch(wago,codenum);//回填假链
tempword=was.GetOneWord();
GetStatement();//生成假链指向的指令代码
Backpatch(thengo,codenum);//回填真链指向指令的最后一条
}
else Backpatch(wago,codenum);//回填假链
break;
}
case SIGN_WHILE:
{ //while <lexp> do <statement>
whilego=codenum;
tempword=was.GetOneWord();
if(FALSE==GetCondition(&acgo,&wago)) return FALSE;//处理条件语句
if(FALSE==Match(tempword,SIGN_DO)) return FALSE;//匹配do
Backpatch(acgo,codenum);//回填真链
tempword=was.GetOneWord();
if(FALSE==GetStatement()) return TRUE;//生成真链指向的指令代码
GenCode("JMP",0,0);//真链指向的指令执行完毕,要跳回到while处
Backpatch(codenum-1,whilego);//回填上一条指令
Backpatch(wago,codenum);//回填假链
break;
}
case SIGN_CALL:
{ //call <id> [(<exp>{,<exp>})]
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;
strcpy(strtemp1,tempword.data);//将过程名暂时记下
tempword=was.GetOneWord();
if(tempword.type==SIGN_LEFTBRA)
{//如果有"(",说明调用的过程有参数,处理参数
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;
while(tempword.type==SIGN_COMMA)
{//只要参数后面跟的是“,”,说明后面还有参数,继续处理
tempword=was.GetOneWord();
GetExp();
}
if(FALSE==Match(tempword,SIGN_RIGHTBRA)) return FALSE;
tempword=was.GetOneWord();
}
if(FALSE==FindFh(strtemp1,tempmhs,&tempfindfh)) return FALSE;
if(tempfindfh.type==FH_PRONAME)
{//call后面的标示符必须是过程名
//从符号表中查出被调用过程相对调用过程的相对层数和指令地址,生成机器码
GenCode("CAL",tempfindfh.depth,tempfindfh.address);
}
else
{
sprintf(error,"第%d行 call后面应该是过程名",tempword.line);
return FALSE;
}
break;
}
case SIGN_READ:
{ //read (<id>{,<id>})
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_LEFTBRA)) return FALSE;
do
{
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_NAME)) return FALSE;
if(FALSE==FindFh(tempword.data,tempmhs,&tempfindfh)) return FALSE;
if(tempfindfh.type==FH_VAR || tempfindfh.type==FH_XC)
{
GenCode("RED",tempfindfh.depth,tempfindfh.address);
}
else
{
sprintf(error,"第%d行 read后面应该是变量或形参",tempword.line);
return FALSE;
}
tempword=was.GetOneWord();
if(strcmp(tempword.data,",")==0) go=1;//变量或形参后面是“,”,说明还未处理完
else go=0;
if(1==go && Match(tempword,SIGN_COMMA)==FALSE) return FALSE;
if(0==go && Match(tempword,SIGN_RIGHTBRA)==FALSE) return FALSE;
}while(1==go);
tempword=was.GetOneWord();
break;
}
case SIGN_WRITE:
{ //write(<exp>{,<exp>})
tempword=was.GetOneWord();
if(FALSE==Match(tempword,SIGN_LEFTBRA)) return FALSE;
do
{
tempword=was.GetOneWord();
if(FALSE==GetExp()) return FALSE;//处理表达式
GenCode("WRT",0,0);
if(strcmp(tempword.data,",")==0) go=1;//表达式后面是“,”,说明还未处理完
else go=0;
if(1==go && Match(tempword,SIGN_COMMA)==FALSE) return FALSE;
if(0==go && Match(tempword,SIGN_RIGHTBRA)==FALSE) return FALSE;
}while(1==go);
tempword=was.GetOneWord();
break;
}
case SIGN_BEGIN:
{ //<body>
if(FALSE==GetBody()) return FALSE;//递归地处理body
break;
}
default:
{
sprintf(error,"第%d行 过程体有错",tempword.line);
return FALSE;
break;
}
}
if(tempword.type==SIGN_END && strcmp(tempmhs,"program")!=0)
{
}
return TRUE;
}
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?