📄 semantic.cpp
字号:
#include "common.h"
NametabItem *LastName;
ObjItem *ProgramBlock();
void Expression();
void Sentences();
void Factor();
void GotoNextSymbol()
{
if(CurSymbol->Next)
CurSymbol=CurSymbol->Next;
else
{
Error(4);
exit(3);
}
}
void ArrayItemAddress(NametabItem *array)
{ //数组元素地址的计算代码
int dimension[MAXDIMENSION*2],i=0;
ArrayItem *array_info=(ArrayItem *)array->Ref;
if(!array_info)
{
Error(13);
return;
}
for(;array_info;array_info=array_info->Elref)
{
dimension[i++]=array_info->Size;
dimension[i++]=array_info->Low;
}
GotoNextSymbol();
if(CurSymbol->Type!=LPAREN)
Error(22);
else
GotoNextSymbol();
Factor();
if(dimension[--i])
{
GenerateCode(LIT,0,dimension[i]);
GenerateCode(SUB,0,0); //减去下界值
}
while(CurSymbol->Type==COMMA)
{
GotoNextSymbol();
GenerateCode(LIT,0,dimension[--i]);
GenerateCode(MULT,0,0); //乘某一维的长度
Factor();
if(dimension[--i])
{
GenerateCode(LIT,0,dimension[i]);
GenerateCode(SUB,0,0);
}
GenerateCode(ADD,0,0);
}
if(CurSymbol->Type!=RPAREN)
Error(22);
else
GotoNextSymbol();
GenerateCode(LODA,array->Level,array->Value);
GenerateCode(ADD,0,0); //准备变址寻址
return;
}
#include "declaration.cpp"
#include "expression.cpp"
void AssignmentSentence()
{ //赋值语句
char *lvar_name; //赋值号左边的变量名
NametabItem *lvar;
assert(CurSymbol->Type==IDENT);
lvar_name=CurSymbol->Value.lpValue;
lvar=FindLowLevelNametabItem(lvar_name,VARIABLE);
if(!lvar)
Error(11);
if(lvar->Type!=TARRAY)
{
if(lvar->Normal>=0)
GenerateCode(LODA,lvar->Level,lvar->Value);
else
GenerateCode(LOD,lvar->Level,lvar->Value);
GotoNextSymbol();
}
else
ArrayItemAddress(lvar);
if(CurSymbol->Type!=BECOME)
Error(23);
GotoNextSymbol();
Expression(); //表达式处理
GenerateCode(STO,0,0);
}
void IfStatement()
{
ObjItem *fillback_true,*fillback_false;
assert(CurSymbol->Type==IFSYM);
GotoNextSymbol();
Expression();
if(CurSymbol->Type!=THENSYM)
Error(25);
fillback_false=GenerateCode(JPC,0,0);
GotoNextSymbol();
Sentences();
if(CurSymbol->Type==ELSESYM)
{
fillback_true=GenerateCode(JMP,0,0);
fillback_false->DestOp.iValue=CurrentCode->LineNum;
GotoNextSymbol();
Sentences();
fillback_true->DestOp.iValue=CurrentCode->LineNum;
}
else
{
fillback_true=NULL;
fillback_false->DestOp.iValue=CurrentCode->LineNum;
}
}
void WhileStatement()
{
ObjItem *jmp_back,*fillback_false;
assert(CurSymbol->Type==WHILESYM);
GotoNextSymbol();
jmp_back=CurrentCode;
Expression();
fillback_false=GenerateCode(JPC,0,0);
if(CurSymbol->Type!=DOSYM)
Error(26);
GotoNextSymbol();
Sentences();
GenerateCode(JMP,0,jmp_back->LineNum);
fillback_false->DestOp.iValue=CurrentCode->LineNum;
}
void CompoundSentences()
{
assert(CurSymbol->Type==BEGINSYM);
GotoNextSymbol();
Sentences();
while(CurSymbol->Type==SEMICOLON)
{
GotoNextSymbol();
Sentences();
}
if(CurSymbol->Type!=ENDSYM)
Error(9);
GotoNextSymbol();
}
void StandardProcedure(char *proc_name)
{
int instruction;
NametabItem *variable;
if(!stricmp(proc_name,"READ"))
{
instruction=RED;
}
if(!stricmp(proc_name,"WRITE"))
{
instruction=WRT;
}
if(CurSymbol->Type==LPAREN)
{
GotoNextSymbol();
if(CurSymbol->Type!=IDENT || !(variable=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE)))
Error(28);
if(variable->Normal>=0)
GenerateCode(LODA,variable->Level,variable->Value);
else
GenerateCode(LOD,variable->Level,variable->Value);
GenerateCode(instruction,0,variable->Type==TINT?0:1);
GotoNextSymbol();
while(CurSymbol->Type==COMMA)
{
GotoNextSymbol();
if(CurSymbol->Type!=IDENT || !(variable=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE)))
Error(28);
if(variable->Normal>=0)
GenerateCode(LODA,variable->Level,variable->Value);
else
GenerateCode(LOD,variable->Level,variable->Value); GenerateCode(instruction,0,variable->Type==TINT?0:1);
GotoNextSymbol();
}
}
if(CurSymbol->Type!=RPAREN)
Error(22);
GotoNextSymbol();
}
void CallStatement()
{
char *proc_name;
NametabItem *procedure,*var_para;
int var_define[MAXVARNUMBER],i;
NametabItem *para;
assert(CurSymbol->Type==CALLSYM);
GotoNextSymbol();
proc_name=CurSymbol->Value.lpValue;
procedure=FindLowLevelNametabItem(proc_name,PROCEDURE);
if(!procedure)
Error(21);
GotoNextSymbol();
if(!procedure->Level)
{
StandardProcedure(proc_name);
return;
}
for(para=((BlockItem *)(procedure->Ref))->LastPar,i=0;para;para=para->Link,i++)
var_define[i]=((para->Normal)==-1?1:0);
GenerateCode(OPAC,0,0);
if(CurSymbol->Type==LPAREN)
{
GotoNextSymbol();
if(i<=0)
Error(27);
if(var_define[--i])
{
if(CurSymbol->Type!=IDENT)
Error(28);
var_para=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE);
if(!var_para)
Error(28);
if(var_para->Type!=TARRAY)
{
if(var_para->Normal>=0)
GenerateCode(LODA,var_para->Level,var_para->Value);
else
GenerateCode(LOD,var_para->Level,var_para->Value);
GotoNextSymbol();
}
else
ArrayItemAddress(var_para);
}
else
Expression();
while(CurSymbol->Type==COMMA)
{
GotoNextSymbol();
if(i<=0)
Error(27);
if(var_define[--i])
{
if(CurSymbol->Type!=IDENT)
Error(28);
var_para=FindLowLevelNametabItem(CurSymbol->Value.lpValue,VARIABLE);
if(!var_para)
Error(28);
if(var_para->Type!=TARRAY)
{
if(var_para->Normal>=0)
GenerateCode(LODA,var_para->Level,var_para->Value);
else
GenerateCode(LOD,var_para->Level,var_para->Value);
GotoNextSymbol();
}
else
ArrayItemAddress(var_para);
}
else
Expression();
}
if(i)
Error(27);
}
if(CurSymbol->Type!=RPAREN)
Error(22);
GotoNextSymbol();
GenerateCode(CAL,procedure->Level,procedure->Value);
if(DisplayLevel-1>procedure->Level)
GenerateCode(UDIS,procedure->Level,DisplayLevel-1);
}
void Sentences()
{ //语句处理
switch(CurSymbol->Type)
{
case IDENT: //赋值语句
AssignmentSentence();
break;
case IFSYM: //条件语句if
IfStatement();
break;
case WHILESYM: //循环语句while
WhileStatement();
break;
case BEGINSYM: //复合语句
CompoundSentences();
break;
case CALLSYM: //过程调用语句
CallStatement();
break;
default: //空语句
return;
}
}
void Program()
{
ObjItem *fill_back_var_size;
LastName=NULL;
if(CurSymbol->Type!=PROGRAMSYM)
Error(3);
GotoNextSymbol();
if(CurSymbol->Type!=IDENT)
Error(5);
GotoNextSymbol();
if(CurSymbol->Type!=SEMICOLON)
Error(6);
GotoNextSymbol();
EnterBlock();
fill_back_var_size=GenerateCode(ENTP,1,0);
ProgramBlock();
fill_back_var_size->DestOp.iValue=Display[1]->PSize+Display[1]->VSize;
QuitBlock();
GenerateCode(ENDP,0,0);
if(CurSymbol->Type!=PERIOD)
Error(10);
}
ObjItem *ProgramBlock()
{ //程序体
ObjItem *fillback;
fillback=GenerateCode(JMP,0,0);
if(CurSymbol->Type==CONSTSYM)
{
GotoNextSymbol();
while(CurSymbol->Type==IDENT)
{
//常量说明
ConstDeclaration();
}
}
if(CurSymbol->Type==TYPESYM)
{
GotoNextSymbol();
while(CurSymbol->Type==IDENT)
{
//类型说明
TypeDeclaration();
}
}
if(CurSymbol->Type==VARSYM)
{
GotoNextSymbol();
while(CurSymbol->Type==IDENT)
{
//变量说明
VarDeclaration();
}
}
while(CurSymbol->Type==PROCSYM)
{ //过程说明
ProcedureDeclaration();
}
if(CurSymbol->Type==BEGINSYM)
{
fillback->DestOp.iValue=CurrentCode->LineNum;
do
{
GotoNextSymbol();
//语句处理
Sentences();
}
while(CurSymbol->Type==SEMICOLON);
if(CurSymbol->Type==ENDSYM)
{
GotoNextSymbol();
return fillback;
}
else
Error(9);
}
else
Error(8);
return fillback;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -