📄 parse.cpp
字号:
lineno[0]=LINE;
strcpy(varname[Varcount++],token);//假设正确
if(lookahead==End)
{//记录类型的最后一条语句不能以';'结束
error(29,LINE-1);//注意此时end已经在下一行了
return;
}
match(id);
while(lookahead==comma)
{//一个或多个
match(comma);
lineno[Varcount]=LINE;
strcpy(varname[Varcount++],token);//假设正确
match(id);
}
match(colon);
VarType=searchtype(token);//判断类型
if(VarType<0)
error(5,LINE);
lookahead=nexttoken();//需要加吗?
//match(lookahead);
for(i=0;i<Varcount;i++)
{
if(field_rename(varname[i]))
{//重名
strcpy(errortype,varname[i]);
error(0,lineno[i]);
break;
}
//在域表和typelist中添加新表项
strcpy(field->name,varname[i]);
field->type=VarType;
typelist[typecount].bandwidth+=typelist[VarType].bandwidth;
field->next=new field_table;
field=field->next;
field->offset=typelist[typecount].bandwidth;
}
//match(lookahead);
}
//************************************************************************************************
//<变量定义部分>:
void var_define(){//<变量定义部份> -> var<变量定义>{<变量定义>}
match(Var);
do{//一个或多个
vardef();
}while(lookahead==id);
}
//<变量定义>:
void vardef()
{//<变量定义> -> <变量组>;
varlist(0);//varlist:变量访问;0:变量定义,1:传值,2:引用
match(semicolon);
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
// 变量组的语义分析函数
//-------------------------------------------------------------------------------------
//-----------------------
void varlist(int property)
{ //<变量组> -> <变量名>{,<变量名>}:<类型名>
//property=0:变量定义1:参数定义(值传)2:引用
int VarType;//类型编号
int Varcount=0,i;
char varname[SIZE][SIZE];//变量名数组
int lineno[SIZE];
lineno[Varcount]=LINE;
strcpy(varname[Varcount++],token);//假设正确
match(id);
while(lookahead==comma)
{//一个或多个
match(comma);
lineno[Varcount]=LINE;
strcpy(varname[Varcount++],token);//假设正确
match(id);
}
match(colon);
VarType=searchtype(token);//bool.int.new.unknown(-1)
if(VarType<=0)
{
error(5,LINE);//类型错误
match(lookahead);
return;
}
for(i=0;i<Varcount;i++)
{
if(var_rename(varname[i]))
{//若同一过程变量同名
strcpy(errortype,varname[i]);
error(0,lineno[i]);
break;
}
//在变量表中添加新表项
strcpy(cur_varlist->name,varname[i]);
cur_varlist->type=VarType;
switch(property)
{
case 1://传值
cur_proc->numofparam++;//参数个数++
cur_varlist->offset=off;
off=off-typelist[VarType].bandwidth;//off=0;initial
cur_varlist->ConstVal=1;
break;
case 2://引用
cur_proc->numofparam++;//参数个数++
cur_varlist->offset=off;
off--;
cur_varlist->ConstVal=2;
break;
default://=0变量定义
cur_varlist->offset=off;
off=off+typelist[VarType].bandwidth;
}
cur_varlist->next=new var_list;
cur_varlist=cur_varlist->next;
}
match(lookahead);
}
//<过程定义>:
void proc_define()
{// <过程定义> -> Procedure <过程名><过程块>;& <过程块> -> [(<形参表>)];<块体>
match(Procedure);
int lev=cur_proc->level;
int numofchild=cur_proc->numofchild;//old
cur_proc->numofchild++;//子过程数++
cur_proc->child[numofchild]=new proc_list;
proc_list* tmp=new proc_list;
tmp=cur_proc;
cur_proc=cur_proc->child[numofchild];
cur_proc->father=tmp;//
//在过程表中添加新表项
for(int i=0;i<SIZE;i++)
cur_proc->NewType[i]=-1;
cur_proc->numofnewtype=0;
cur_proc->numofchild=0;
cur_proc->ParamLength=0;
cur_proc->numofparam=0;
cur_proc->VarLength=0;
cur_proc->next=new var_list;
cur_proc->next=cur_varlist;
cur_proc->level=lev+1;
off=3;
if(proc_rename(token))
{//重名
strcpy(errortype,token);
error(0,LINE);
}
//------------------------目标代码生成------------------------------------
streampos VarPt,temp;
int offs,LineNo,oldp,newp;
cur_proc->offset=pfollow; //address of procedure starting
// outfile<<"ProcedureX";
outfile<<24<<' ';
//keep
LineNo=LINE;
VarPt=outfile.tellp();
oldp=pfollow;//cur_proc->offset
//refresh
outfile<<" "<<endl;
pfollow+=5;
strcpy(cur_proc->name,token);//
match(id);
if(lookahead==lpar)
{
match(lpar);
fparam_list();//<形参表>
if(lookahead!=rpar)
{
error(23,LINE);
exit(0);//这里连续报错好像有点困难
}
match(rpar);
}
match(semicolon);
block(newp);//<块体>
//-----------------------------目标代码生成---------------------------------------------//
outfile<<8<<' '<<cur_proc->ParamLength<<endl;//end of proc
pfollow+=2;
offs=newp-oldp;
temp=outfile.tellp();
outfile.seekp(VarPt);
outfile<<cur_proc->VarLength<<' '<<cur_proc->VarLength*3<<' '<<offs<<' '<<LineNo;
outfile.seekp(temp);
match(semicolon);
cur_proc=cur_proc->father;//回到父过程
}
//<形参表>:
void fparam_list()
{//<形参表> -> <参数定义>{;<参数定义>}
//match(lpar);//在proc_define()中并没有match'('
off=0;//方便形式参数的offset
param_define();//<参数定义>
while(lookahead==semicolon)
{//一个或多个
match(semicolon);//此处错误处理有些困难
param_define();
}
/*if(lookahead!=rpar)
{
error(23,LINE);
while(lookahead!=rpar)
match(lookahead);
}*/
//match(rpar);
/*if(lookahead!=rpar)
{
if(lookahead==10||lookahead==id)
error(23,LINE);
//match(lookahead);
//while(lookahead!=rpar)
// match(lookahead);
//return;
else error(28,LINE);
//lookahead=nexttoken();
}
match(rpar);*/
cur_proc->ParamLength=-off;//
off=3;//
var_list* temp=new var_list;
temp=cur_proc->next;
for(int i=0;i<cur_proc->numofparam;i++,temp=temp->next)
temp->offset=-(cur_proc->ParamLength)-(temp->offset);
}
//<参数定义>:
void param_define(){ //<参数定义>
int ifvalue=1;
if(lookahead==Var)
{//以var开头,传引用
ifvalue=2;
match(Var);
}
varlist(ifvalue);//变量组0:变量定义1:参数定义(值传)2:引用
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//
// 语句
//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
void sentence()
{//<语句> -> <赋值语句>|<过程语句>|<if语句>|<while语句>|<复合语句>|emPty
switch(lookahead){
case semicolon:
break;
case If: //<if语句> -> if<表达式>then <语句)[eIse <语句>]
if_sent();break;
case While: //<while语句> -> while<表达式> do<语句>
while_sent();break;
case Begin:com_sent();break;//<复合语句> -> begin <语句>{;<语句>}end
case End:break; //empty
case Read://<read语句>-〉read (<读变量>{,<读变量>})
match(Read);
match(lpar);
readvar();
while(lookahead==comma)
{
match(comma);
readvar();//<读变量>
}
match(rpar);
break;
case Write://<write语句>-> write(<写变量>{,<写变量>})
match(Write);
match(lpar);
writevar();//<写变量>
while(lookahead==comma){
match(comma);
writevar();
}
match(rpar);
break;
default:
switch(search(token,proc,var)){
case 0://过程语句
proc_sent();break;
case 1://赋值语句
assign_sent();break;
default://找不到
error(8,LINE);
while((lookahead!=semicolon)&&(lookahead!=End))
match(lookahead);
}
}//switch
}
// 赋值语句
//
/*varaccess(int&VarType1,int)将得到[:=]左边变量的类型;
再执行express(int&VarType2)得到右边变量的类型;
将VarType1,VarType2相比较,相等则赋值成功,
否则类型不符,错误。
*/
void assign_sent()
{//<赋值语句>-> <变量访问>:=<表达式>
//来到这个分支前,已经在search里做出判断是变量.
int VarType1,VarType2;
varaccess(VarType1,-1);
int lineno=LINE;
match(assign_op);
if(VarType1>3){
varaccess(VarType2,0);//只允许访问新类型
if(VarType1!=VarType2){
rightvar=VarType2;
leftvar=VarType1;
error(9,lineno);
return;
}
// outfile<<"Value("<<typelist[VarType1].bandwidth<<");"<<endl;
outfile<<28<<' '<<typelist[VarType1].bandwidth<<endl;
pfollow+=2;
// outfile<<"assign_sent("<<typelist[VarType1].bandwidth<<");"<<endl;
outfile<<2<<' '<<typelist[VarType1].bandwidth<<endl;
pfollow+=2;
return;
}
//int/bool
express(VarType2);
if(VarType1!=VarType2){
rightvar=VarType2;
leftvar=VarType1;
error(9,lineno);
return;
}
// outfile<<"assign_sent(1);"<<endl;
outfile<<2<<' '<<1<<endl;
pfollow+=2;
}
//<过程语句>:
void proc_sent(){//<过程语句> -> <过程名>[(实参表)]
//关于过程调用的层数问题:level有没有限制(如书中pascal)
int level,offs;
match(id);
if(proc->numofparam!=0){
match(lpar);
rparam_list();//
match(rpar);
}
//if 0
else{
if(lookahead==lpar){
error(10,LINE);
while((lookahead!=semicolon)&&(lookahead!=End))
match(lookahead);
}
}
level=cur_proc->level-proc->level+1;
offs=proc->offset-pfollow;
// outfile<<"proccall("<<level<<","<<offs<<");"<<endl;
outfile<<23<<' '<<level<<' '<<offs<<endl;
pfollow+=3;
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//
// 实参表
//
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
/*此时全局变量proc保存了被调用的过程的节点。
int numofparam=proc->numofparam;
得到该过程的形参个数
param=proc->next;
得到该过程的第一个形参的指针
for(j=0;j<numofparam;j++,param=param->next){//循环判断
if(param->ConstVal==1){// :传值
如果param是新类型,则varaccess()返回实际参数的类型
比较是否相等;
如果不是,则express()返回实际参数的类型,
比较是否相等;
}
if(param->ConstVal==2){//:传引用
varaccess()返回实际参数的类型,
比较是否相等
}
}
*/
void rparam_list(){//<实参表> -> <实参>{,<实参>}
int i=1,vartype;
var_list* param=new var_list;
proc_list* pro=new proc_list;
var_list* var=new var_list;
param=proc->next;//当前过程定义的变量表
int numofparam=proc->numofparam;
int j;
int lineno;
for(j=0;j<numofparam;j++,param=param->next){
/* if(j>numofparam){
error(10,LINE);
do{
if(lookahead==lpar)numoflpar++;
if(lookahead==rpar)numoflpar--;
if(numoflpar==0){
if(lookahead!=comma)
match(lookahead);
}
else{
if((lookahead!=comma)&&(lookahead!=rpar))
match(lookahead);
}
}while(numoflpar>=0);
}*/
lineno=LINE;
parameterth=j+1;//第j+1个
if(param->ConstVal==1)
{//value
if(param->type>3)
{//new type
varaccess(vartype,0);//0:只访问新变量,vartype获得变量类型
if(vartype!=param->type){
rightvar=vartype;
leftvar=param->type;
error(9,lineno);//the (j+1)'th error real parameters
// return;
}
// outfile<<"value("<<typelist[vartype].bandwidth<<");"<<endl;
outfile<<28<<' '<<typelist[vartype].bandwidth<<endl;
pfollow+=2;
}
else{//不是新类型,bool/int
express(vartype);//获得变量类型
if(vartype!=param->type){
rightvar=vartype;
leftvar=param->type;
error(9,lineno);//
// return;
}
}
}
else if(param->ConstVal==2){//address,only var's visit
if((search(token,pro,var)!=1)||(var->type==Const)){//不是变量,或者是常数
error(24,LINE);
match(lookahead);
}
else{
varaccess(vartype,-1);//-1:任意类型
if(vartype!=param->type){
rightvar=vartype;
leftvar=param->type;
error(9,lineno);//parameters error!
// return;
}
}
}
if(lookahead==comma)match(comma);
else break;
}//for
if(j<numofparam-1){//not enough parameters!
error(10,LINE);
//------------------------------连续报错----------------------------
int line1=LINE;
while(lookahead!=rpar)
{
match(lookahead);//
if(lookahead==Begin)
{
error(32,line1);
return;
}
if(lookahead==EOF)
{
error(32,line1);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
//return;
}
if(j>numofparam-1){//more than enough
error(34,LINE);
int line=LINE;
while(lookahead!=rpar)
{
match(lookahead);//
if(lookahead==Begin)
{
error(32,line);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -