📄 parse.cpp
字号:
#include<iostream.h>
#include<fstream.h>
#include<stdio.h>
#include<stdlib.h>
#include<iomanip.h>
#include<ctype.h>
#include<string.h>
#include"list.h"
#include"global.h"
#include"keyword.h"
#include"interpret.h"
//----------------------------------------------------------------------------------------------//
// 语法分析部分
//包括语法分析、符号表的建立与查找、语义分析(错误发现)、目标代码生成等
//----------------------------------------------------------------------------------------------//
//**********************************************************************************************//
//******************************调用函数的声明**************************************************//
//**********************************************************************************************//
void initialtypelist();
bool searchfield(char name[SIZE],struct type_list* mother,struct field_table* child);
int nexttoken();
int search(char name[SIZE],struct proc_list* pro ,struct var_list* var);
bool proc_rename(char name[SIZE]);
bool type_rename(char Typename[SIZE]);
bool field_rename(char fieldname[SIZE]);
int searchtype(char TypeName[SIZE]);
bool isconst(int&);
void error(int,int);
bool var_rename(char varname[SIZE]);
void match(int);
void consdef();
void const_define();
void array_type();
void rec_section();
void record_type();
void newtype();
void typdef();
void type_define();
void varlist(int);
void vardef();
void var_define();
void proc_define();
void block(int&);
void param_define();
void fparam_list();
void proc_define();
void com_sent();
void rparam_list();
void proc_sent();
void if_sent();
void while_sent();
void assign_sent();
void readvar();
void writevar();
void sentence();
void simple_expr(int&);
void term(int&);
void varaccess(int&,int);
void express(int&);
void gene(int&);
bool isrelational_op(int);
//**********************************************************************************************//
//************************函数的实现部分,语法分析和生成代码的主要部分**************************//
//**********************************************************************************************//
//typelist数组1、2、3元素的初始化部分
void initialtypelist()
{
strcpy(typelist[1].name,"const");//typelist[1]:const
strcpy(typelist[2].name,"boolean");//typelist[2]:boolean
strcpy(typelist[3].name,"integer");//typelist[3]:integer
for(int i=1;i<=3;i++)
{
typelist[i].bandwidth=1;
typelist[i].bandwidthOfelement=0;
typelist[i].type=i;
typelist[i].typeofelement=0;
}
}
void match(int t)
{//匹配向前看符号
int tt;
if(lookahead==EOF)
{
error(33,LINE);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
int line=LINE;//记录下';'不匹配时的行号
if(lookahead!=t)
{
tt=lookahead;
lookahead=t;
if(t==semicolon)
{//匹配';'失败
if(line<LINE)
error(1,line);
else error(1,LINE);
lookahead=tt;
return;
}
else error(1,LINE);//error函数应携带编码信息,编码文件输出相应的出错提示信息!!!
lookahead=tt;
if(t==Program)//如果连program都不匹配,则无需再往下判断
{
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
lookahead=nexttoken();
}
//<程序>
void program()
{// <程序> -> Program<程序名>;<块体>·
int offs,oldp,newp;
char Progname[SIZE];
initialtypelist();
streampos VarPt,temp;
lookahead=nexttoken();
match(Program);
//在过程表中添加新表项
cur_proc->offset=0;//
cur_proc->level=1;
cur_proc->father=NULL;
cur_proc->numofchild=0;
cur_proc->next=new var_list;
cur_proc->next=cur_varlist;
cur_proc->ParamLength=0;
cur_proc->numofparam=0;
cur_proc->VarLength=0;
for(int i=0;i<SIZE;i++)
cur_proc->NewType[i]=-1;
cur_proc->numofnewtype=0;
off=3;
//目标代码生成
outfile<<25<<' ';//programx()
int lineno=LINE;
VarPt=outfile.tellp();
oldp=pfollow;
pfollow+=5;
outfile<<" "<<endl;
strcpy(Progname,token);
match(id);
strcpy(cur_proc->name,Progname);
match(semicolon);
block(newp); //<块体>proccall
offs=newp-oldp;
//end of program
temp=outfile.tellp();
outfile.seekp(VarPt);
outfile<<cur_proc->VarLength<<' '<<cur_proc->VarLength*3<<' '<<offs<<' '<<lineno;
outfile.seekp(temp);
outfile<<7;// outfile<<"EndProg;"<<endl;
match(dot);
//----------------------判断后面是否还有注释,或者是其他非法内容----------------------//
//if 注释
while(lookahead==lbrace)
{
match(lbrace);
while(lookahead!=rbrace)
{
if(lookahead==EOF)
{
error(33,LINE);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
match(lookahead);
}
match(rbrace);
}
//if not
if(lookahead==EOF||lookahead==dot)
return;
else
{
error(33,LINE);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
//<块体>
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
// 块体的语义分析函数
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//uptill携带相关信息返回
void block(int& uptill)
{//<块体> -> [<常数定义部份>][<类型定义部份>][<变量定义部分>]{<过程定义>}<复合语句>
// int follow=0;
if(lookahead==Const)const_define();
if(lookahead==Type)type_define();
if(lookahead==Var) var_define();
cur_varlist->type=-1;//终结
cur_varlist->next=new var_list;//建立新表项
cur_varlist=cur_varlist->next;
cur_varlist->type=-1;//尚未填充
cur_proc->VarLength=off-3;//偏移(to b)以3开始
while(lookahead==Procedure)
proc_define();
uptill=pfollow;
com_sent();//<复合语句> -> begin <语句>{;<语句>}end
}
//<常数定义部分>:
void const_define(){//<常数定义部价> -> cons <常数定义>{常数定义}
match(Const);
do{//一个或多个
consdef();
}while(lookahead==id);
}
//<常数定义>:
void consdef(){//<常数定义> -> <常数名>=<常数>;
int consttype;
strcpy(Constname,token);
match(id);//<常数名>
if(var_rename(Constname))
{
int line=LINE;
strcpy(errortype,Constname);
error(0,LINE);
//出错,一直读到本语句末,这样可继续检查下面的语句
while(lookahead!=semicolon)
{
match(lookahead);
if(lookahead==Begin)
{
error(28,line);
//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
return;
}
if(lookahead==EOF)
{
error(28,line);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
match(semicolon);
return;
}
match(relop_EQ);
// int flag=0;//是否是负常数
// if(lookahead==minus_op)
// {
// match(minus_op);
// flag=1;
// }
if(!isconst(consttype))
{//若不是常数
strcpy(errortype,token);
error(25,LINE); //Const Defination Error!
match(lookahead);//跳过,继续往下
}
match(semicolon);
//将新定义的常数添加到符号表当前表项中
cur_varlist->type=Const;
cur_varlist->typeofconst=consttype;//0:boolean;1:integer
// if(flag==0)
cur_varlist->ConstVal=ConstVal;
// else cur_varlist->ConstVal=-ConstVal;
strcpy(cur_varlist->name,Constname);
cur_varlist->next=new var_list;
cur_varlist=cur_varlist->next;
cur_varlist->type=-1;
}
//<类型定义部分>
void type_define(){//<类型定义部份> -> type <类型定义>{类型定义}
match(Type);
do{//一个或多个
typdef();
}while(lookahead==id);
}
//<类型定义>:
void typdef()
{//<类型定义> -> <类型名>=<新类型>;
strcpy(Typename,token);
if(type_rename(Typename))
error(18,LINE);
match(id);
match(relop_EQ);
newtype();//<新类型>
match(semicolon);
}
//<新类型>:
void newtype()
{//<新类型> -> <数组类型>|<记录类型>
if(lookahead==Array)
{
array_type();
cur_proc->numofnewtype++;//定义了个新类型
return;
}
if(lookahead==Record)
{
record_type();
cur_proc->numofnewtype++;//定义了个新类型
return;
}
error(20,LINE);//如果不是则报错
//------------------------------连续报错----------------------------------------------------//
int line=LINE;//记录下';'不匹配的行数
while(lookahead!=semicolon)
{
match(lookahead);//
if(lookahead==Begin)
{
error(28,line);
//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
return;
}
if(lookahead==EOF)
{
error(28,line);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
}
//<数组类型>:
void array_type()
{//<数组类型> -> array[<下标域>] of <类型名>&<下标域> -> <常数>··<常数>
//---------> array[<常数>..<常数>] of <类型名>
int upper,lower,range;
int vartype;
match(Array); match(lbracket);
//int flag=0;
/*if(lookahead==minus_op)
{
flag=1;
error(4,LINE);
match(minus_op);//一般情况下是这样
}*/
bool flag1=isconst(vartype);
if(flag1==false||vartype==0)
{
//cout<<lookahead<<endl;
error(4,LINE);
int line=LINE;
//直到匹配到".."
while(lookahead!=dotdot)
{
match(lookahead);//
if(lookahead==Begin)
{
error(30,line);
//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
return;
}
if(lookahead==EOF)
{
error(30,line);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
}
//if(flag==0)
lower=ConstVal;
//else lower=-ConstVal;
match(dotdot);
/*if(lookahead==minus_op)
{
flag=1;
error(26,LINE);
match(lookahead);
}*/
bool flag2=isconst(vartype);
if(flag2==false||vartype==0)
{
error(26,LINE);
int line=LINE;
//直到匹配到']'
while(lookahead!=rbracket)
{
match(lookahead);//
if(lookahead==Begin)
{
error(31,line);
return;
}
if(lookahead==EOF)
{
error(28,line);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
}
//if(flag==0)
upper=ConstVal;
//else upper=-ConstVal;
if(lower>upper)
{
error(27,LINE);
//直到匹配到']'
int line=LINE;
while(lookahead!=rbracket)
{
match(lookahead);//
if(lookahead==Begin)
{
error(31,line);
return;
}
if(lookahead==EOF)
{
error(31,line);
cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
exit(0);
}
}
}
match(rbracket);
match(Of);
int lineno=LINE;
int eletype=searchtype(token);//
if(eletype<0)
error(5,lineno);//类型错误
match(lookahead);
//添加新表项到typelist中,同时将过程表的NewType数组增加一个项目
range=upper-lower+1;
cur_proc->NewType[cur_proc->numofnewtype]=typecount;//序号
typelist[typecount].bandwidthOfelement=typelist[eletype].bandwidth;
typelist[typecount].bandwidth=range*typelist[eletype].bandwidth;
typelist[typecount].upper=upper;
typelist[typecount].lower=lower;
typelist[typecount].type=Array;
strcpy(typelist[typecount].name,Typename);
typelist[typecount++].typeofelement=eletype;
}
//<记录类型>:
void record_type()
{//<记录类型> -> record<域表>end & <域表> -> <记录节>{;<记录节>}
//----------> <记录类型> -> record<记录节>{;<记录节>}end
match(Record);
//添加新表项到typelist中
typelist[typecount].type=Record;
typelist[typecount].bandwidth=0;//initial
typelist[typecount].fieldlist=new field_table;
strcpy(typelist[typecount].name,Typename);
//
field=typelist[typecount].fieldlist;//field:global var
field->offset=0;
rec_section();//<记录节>
while(lookahead==semicolon){//一个或多个
match(semicolon);
rec_section();
}
match(End);
cur_proc->NewType[cur_proc->numofnewtype]=typecount;//将过程表的NewType数组增加一个项目
typecount++; //
field->type=-1;//终结
field->offset=-1;
}
//<记录节>:
void rec_section()
{//<记录节> -> <域名>{,<域名>}:<类型名>
//对于纪录的域名来说,只需要内部不出现重名就可以了
int Varcount=0,i;
char varname[SIZE][SIZE];//域名数组
int lineno[SIZE];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -