📄 complier_c0.cpp.bak
字号:
}
else
Error(curLine,"不合法的因子");
t=t1;
}
void Term(int &t){ // 项
int s1,s2,flag;
Factor(s1);
while(1){
if (sym.type!=TIMES && sym.type!=RDIV)
break;
flag=sym.type;
ReadSym();
Factor(s2);
_Opr(s1,s2,flag);
}
t=s1;
}
void Expression(int &t){ // 表达式
int s1,s2,flag=0;
bool isMinus=false; // 表达式是否带有负号
if (sym.type==MINUS){
_Emit("LOADI",-1);
isMinus=true;
}
if (sym.type==PLUS || sym.type==MINUS)
ReadSym();
Term(s1);
while(1){
if (sym.type!=PLUS && sym.type!=MINUS)
break;
flag=sym.type;
ReadSym();
Term(s2);
_Opr(s1,s2,flag);
}
if (isMinus)
_Opr(s1,INTEGER,TIMES);
t=s1;
}
void MainProc(){ // 主函数(处理过程)
char n[SMAX+1];
int t,j,k;
if (sym.type!=VOIDSYM)
Error(curLine,"主函数返回值类型应该为void");
t=NUL;
ReadSym(); // sym.type=MAINSYM;
strcpy(n,sym.name);
_Labprod(n);
_Emit("LOADI",-1);
_TbInsert(t,n,PROC);
j=0;
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
else
ReadSym();
Parameter(j,k);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emitstores(k);
ReadSym();
}
if (sym.type!=LBRACKET)
Error(curLine,"缺少{");
else
ReadSym();
ComSent();
_QuitTable();
_Emit("RETURN");
if (sym.type!=RBRACKET)
Error(curLine,"缺少}");
ReadSym();
}
void ParaTable(int j,int &k){ // 参数列表
int t; char n[SMAX+1];
while(IsType(sym.type)){
t=sym.type;
ReadSym();
if (sym.type!=IDENT)
Error(curLine,"缺少标识符");
else{
strcpy(n,sym.name);
_TbInsert(t,n,PARA);
_Upcnt(j,k); j=k;
ReadSym();
}
if (sym.type!=COMMA)
break;
ReadSym();
if (!IsType(sym.type))
Error(curLine,"不可识别的类型");
}
k=j;
}
void Parameter(int j,int &k){ // 参数
ParaTable(j,k);
}
void ComSent(){ // 复合语句
if (sym.type==CONSTSYM)
ConstDec();
if (IsType(sym.type))
VarDec();
if (IsIn(sym.type,SENTENCE))
SentList();
}
void ProcDef(){ // 无返回值函数定义部分
int t,j,k;
char n[SMAX+1];
t=NUL; // sym.type=VOIDSYM
ReadSym();
if (sym.type!=IDENT){
Error(curLine,"缺少标识符");
Ignore(SEMICOLON);
goto LComSent;
}
strcpy(n,sym.name);
_Labprod(n);
_TbInsert(t,n,FUNC);
j=0;
ReadSym();
if (sym.type!=LPARENT)
Error(curLine,"缺少(");
ReadSym();
Parameter(j,k);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emitstores(k);
ReadSym();
}
if (sym.type!=LBRACKET)
Error(curLine,"缺少{");
else
ReadSym();
LComSent:
ComSent();
if (sym.type!=RBRACKET){
Error(curLine,"缺少}");
return;
}
_QuitTable();
_Emit("RETURN");
ReadSym();
}
void FuncDef(){ // 有返回值函数定义部分
int t,j,k;
char n[SMAX+1];
if (!DecHead(t,n)){
Ignore(SEMICOLON);
goto LComSent;
}
_Labprod(n);
_TbInsert(t,n,FUNC);
j=0;
if (sym.type!=LPARENT){
Error(curLine,"缺少(");
Ignore(SEMICOLON);
goto LComSent;
}
ReadSym();
Parameter(j,k);
if (sym.type!=RPARENT)
Error(curLine,"缺少)");
else{
_Emitstores(k);
ReadSym();
}
if (sym.type!=LBRACKET)
Error(curLine,"缺少{");
else
ReadSym();
LComSent:
ComSent();
if (sym.type!=RBRACKET){
Error(curLine,"缺少}");
return;
}
_QuitTable();
ReadSym();
}
void VarDef(){ // 变量定义
int t,i; char n[SMAX+1];
if (!IsType(sym.type)){
Error(curLine,"没有这种类型");
return;
}
t=sym.type;
i=1;
do{
ReadSym();
if (sym.type!=IDENT){
Error(curLine,"缺少标识符");
Ignore(SEMICOLON);
break;
}
strcpy(n,sym.name);
_TbInsert(t,n,VAR);
_Emit("ALLOCATE",i);
ReadSym();
}while(sym.type==COMMA);
}
void VarDec(){ // 变量说明部分
do{
VarDef();
if (sym.type!=SEMICOLON){
Error(curLine,"缺少;");
Ignore(SEMICOLON);
continue;
}
ReadSym();
}while(IsType(sym.type) && buf[1].type!=LPARENT);
}
void Char(int &s,unionc &c){
s=CHARC;
c.cval=sym.name[0];
ReadSym();
}
void Integer(int &s,unionc &c){ // 整数
s=INTEGER;
c.ival=1;
if (sym.type==PLUS || sym.type==MINUS){
if (sym.type==MINUS)
c.ival=-1;
ReadSym();
}
if (sym.type==INTEGER){
c.ival*=atoi(sym.name);
ReadSym();
}
else
Error(curLine,"此处应该为整数");
}
void Float(int &s,unionc &c){ // 实数
s=REAL;
c.fval=1;
if (sym.type==PLUS || sym.type==MINUS){
if (sym.type==MINUS)
c.fval=-1;
ReadSym();
}
if (sym.type==REAL){
c.fval*=(float)atof(sym.name);
ReadSym();
}
else
Error(curLine,"此处应该为浮点数");
}
bool DecHead(int &t,char n[]){ // 声明头部
if (!IsType(sym.type))
Error(curLine,"不可识别的类型");
t=sym.type;
ReadSym();
if (sym.type!=IDENT){
Error(curLine,"缺少标识符");
return false;
}
strcpy(n,sym.name);
ReadSym();
return true;
}
void ConstDef(){ // 常量定义部分
int tp;
int t; char n[SMAX+1]; int s; unionc c;
int l,j;
t=tp=sym.type;
if (!IsType(sym.type)){
Error(curLine,"不可识别的类型");
Ignore(SEMICOLON);
return;
}
do{
ReadSym();
if (sym.type!=IDENT)
Error(curLine,"常量定义中缺少标识符");
else{
strcpy(n,sym.name);
ReadSym();
}
if (sym.type!=BECOME){
Error(curLine,"没有对常量进行初始化");
Ignore(SEMICOLON);
return;
}
ReadSym();
switch (tp){
case INTSYM:
Integer(s,c);
break;
case FLOATSYM:
Float(s,c);
break;
case CHARSYM:
Char(s,c);
break;
}
_Emit("ALLOCATE",1);
_TbInsert(t,n,CONST);
_Lookup(n,l,j);
_Pushi(s,c);
_Storin(t,s,l,j);
}while (sym.type==COMMA);
}
void ConstDec(){ // 常量说明部分
while (sym.type==CONSTSYM){
ReadSym();
ConstDef();
if (sym.type!=SEMICOLON){
Error(curLine,"缺少;");
return;
}
ReadSym();
}
}
void Program(){ // 程序
if (sym.type==CONSTSYM)
ConstDec();
if (IsType(sym.type) && (buf[1].type!=LPARENT))
VarDec();
_Emit("JSR","main"); // 跳转至主程序入口
while (IsType(sym.type) && buf[1].type==LPARENT) // 有返回值函数部分
FuncDef();
while (sym.type==VOIDSYM && buf[0].type==IDENT) // 无返回值函数部分
ProcDef();
if (sym.type==VOIDSYM && buf[0].type==MAINSYM)
MainProc();
else
Error(curLine,"缺少主程序main");
}
void _Emit(char p[]){
fprintf(fpOut," %s\n",p);
}
void _Emit(char p[],int i){
fprintf(fpOut," %s %d\n",p,i);
}
void _Emit(char p[],int i,int j){
fprintf(fpOut," %s <%d,%d>\n",p,i,j+NIL);
}
void _Emit(char p[],float f){
fprintf(fpOut," %s %f\n",p,f);
}
void _Emit(char p[],char s[]){
fprintf(fpOut," %s %s\n",p,s);
}
void _Insert(int t,char n[],unionc c,int s){ // 将常量填入符号表
if ((t==s+TYPEOFF) || (t==CHARC && s==INTEGER) || (t==INTEGER && s==CHARC)){
strcpy(symTable[tTop].name,n);
symTable[tTop].type=s;
symTable[tTop].kind=CONST;
symTable[tTop].val=c;
symTable[tTop].lev=level;
tTop++;
}
else
Error(lineNo,"Type is not matched!");
}
bool IsInTable(char n[]){ // 查看要填入符号表的标识符是否再符号表中已经定义
int i;
i=tTop;
do{
i--;
if (strcmp(symTable[i].name,n)==0)
return true;
}while (symTable[i].lev==level);
return false;
}
void _TbInsert(int t,char n[],int kind){ // 将变量填入符号表中
if (err!=0) return;
if (tTop>=SYMTOP){
Error(curLine,"符号表溢出");
}
if (IsInTable(n)){
Error(curLine,"标识符重复定义");
}
symTable[tTop].kind=kind;
symTable[tTop].lev=level;
symTable[tTop].type=t-TYPEOFF;
strcpy(symTable[tTop].name,n);
tTop++;
if (kind==PROC || kind==FUNC)
tbIndex[++level]=tTop;
}
void _Upcnt(int j,int &k){ // 统计参数个数
if (err!=0) return;
k=++j;
}
void _Emitstores(int k){ // 为过程或函数分配存储空间
int i;
if (err!=0) return;
if (k!=0)
_Emit("ALLOCATE",k); // 保存返回地址
_Emit("STO",level,1-NIL);
for (i=k;i>0;i--)
_Emit("STO",level,i); // 保存参数值
}
void _Opr(int &s1,int s2,int tp){ // 加 减 乘 除(不同操作数类型的转换)
if (err!=0) return;
if (s1==REAL && (s2==INTEGER || s2==CHARC)){
_Emit("CONVER $top-1");
s1=REAL;
}
if ((s1==INTEGER || s1==CHARC) && s2==REAL){
_Emit("CONVER $top");
s1=REAL;
}
if (s1!=REAL && s2!=REAL)
s1=INTEGER;
switch (tp){
case PLUS: _Emit("ADD");
break;
case MINUS: _Emit("SUB");
break;
case TIMES: _Emit("MULT");
break;
case RDIV: _Emit("DIV");
}
}
int _Lookup(char n[],int &l,int &j){ // 查符号表,返回层号和偏移值
int k=tTop-1;
if (err!=0) return 0;
while (symTable[k].lev==level){ // 本层符号表
if (strcmp(n,symTable[k].name)==0){
l=level;
j=k-tbIndex[l]+1;
return 1;
}
k--;
}
k=0;
while (symTable[k].lev==0){ // 全局符号表
if (strcmp(n,symTable[k].name)==0){
l=0;
j=k+1;
return 1;
}
k++;
}
return -1;
}
void _Type(int l,int j,int &t1){ // 通过查表,返回标识符的类型
if (err!=0) return;
t1=symTable[tbIndex[l]+j-1].type;
}
void _Storin(int t,int s,int l,int j){ // 将数据栈中的数据存入运行栈
if (err!=0) return;
if ((t==INTEGER || t==CHARC) && s==REAL)
Error(lineNo,"can't convert real to int");
else if (t==REAL && (s==INTEGER || s==CHARC)){
_Emit("CONVER $Top");
}
_Emit("STO",l,j);
}
void _GenLab(char lab[]){ // 产生标号 例:L1,L2...
if (err!=0) return;
char *p=new char[4];
strcpy(lab,"\0");
itoa(label,p,10);
strcat(lab,p);
label++;
}
void _Labprod(char y[]){ // 将标号填入代码段
if (err!=0) return;
char y1[SMAX+1];
strcpy(y1,y);
strcat(y1,": ");
fprintf(fpOut,"%s\n",y1);
}
void _Lggen(int t1,int t2,int t){ // 根据条件语句中的条件,生成转移代码
if (err!=0) return;
if (t1==REAL && t2==INTEGER)
_Emit("CONVER","$top");
if (t1==INTEGER && t2==REAL)
_Emit("CONVER","$top-1");
switch (t){
case EQL: _Emit("EQ"); break;
case NOTEQL: _Emit("NOTEQ"); break;
case LESS: _Emit("LES"); break;
case GREATER: _Emit("GT"); break;
case LESSEQL: _Emit("LE"); break;
case GREATEREQL: _Emit("GE"); break;
}
}
void _Pushi(int s,unionc c){ // 将数据压入数据栈
if (err!=0) return;
switch (s){
case INTEGER:_Emit("LOADI",c.ival);
break;
case REAL: _Emit("LOADI",c.fval);
break;
case CHARC:_Emit("LOADI",c.cval);
break;
}
}
void _Brcomp(char y[]){ // 判断栈顶元素是否相等,不等则跳转
if (err!=0) return;
_Emit("EQ");
_Emit("BRF",y);
}
bool _LookupProc(char n[],int &i,int &z){ // 根据函数名字查符号表,并返回符号表中位置和参数个数
int k=0;
if (err!=0) return false;
while (k<tTop){
if (strcmp(n,symTable[k].name)==0){
i=k;
while (symTable[++k].kind==PARA);
z=k-i-1;
return true;
}
k++;
}
return false;
}
bool _Chktype(int t,int i,int &m,int &z){ // 检查函数定义参数类型,个数与调用时参数类型个数是否匹配
if (err!=0) return false;
if (z<1){
Error(curLine,"参数个数不匹配");
return false;
}
m++;
if (t==INTEGER && symTable[i+m].kind==REAL){
Error(curLine,"参数类型不匹配");
return false;
}
z--;
return true;
}
bool _ChkLength(int z){ // 检查函数形参个数与实参个数是否相等
if (err!=0) return false;
if (z!=0){
Error(curLine,"参数个数不匹配");
return false;
}
return true;
}
void _Write(int t){ // 生成输出语句
if (err!=0) return;
switch(t){
case INTEGER: _Emit("WRITEI"); break;
case REAL: _Emit("WRITEF"); break;
case CHARC:_Emit("WRITEC"); break;
}
}
void _QuitTable(){ // 当函数结束时退符号表
if (err!=0) return;
int lv;
lv=level;
while(tTop>=0 && symTable[tTop].lev==lv){
tTop--;
}
tTop++;
while(symTable[tTop].kind==PARA){
strcpy(symTable[tTop].name,"\0");
symTable[tTop].lev=lv-1;
tTop++;
}
level--;
}
// 主函数
void main(int argc,char *argv[]){
int i;
Initial();
if (argc!=2){
printf("输入错误\n");
exit(0);
}
else
strcpy(fileIn,argv[1]);
strcpy(fileOut,"out.txt");
if ((fpIn=fopen(fileIn,"r"))==NULL){
printf("不存在该文件\n");
exit(0);
}
fpErr=fopen("Err.txt","w");
fprintf(fpErr,"\n");
fclose(fpErr);
fpOut=fopen(fileOut,"w");
GetChar();
sym=GetSym();
for (i=0;i<2;i++)
buf[i]=GetSym();
Program();
fclose(fpIn);
fclose(fpOut);
if (err==0){
printf("编译成功!\n");
printf("--------------------------------------------------------\n");
Interpreter(fileOut);
}
else{
fpOut=fopen(fileOut,"w");
printf("编译未通过! 源程序中共有%d处错误\n",err);
printf("详情见 Err.txt\n");
fprintf(fpOut,"编译未通过!源程序中共有%d处错误\n",err);
fprintf(fpOut,"详情见 Err.txt\n");
fclose(fpOut);
fprintf(fpErr,"源程序中共有%d处错误",err);
fclose(fpErr);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -