📄 zcompile.cpp
字号:
///////////////////////////////////////////////////////////////
#include"zCompile.h"
///////////////////////////////////////////////////////////////
enum{
TYPE_ERROR, //错误类型号
TYPE_KEYWORD, //关键字类型号
TYPE_SYMBOL, //符号类型号
TYPE_NUMBER, //常量类型号
TYPE_OPWORD, //运算符类型号
TYPE_ENDWORD, //界符类型号
};
enum{FORM_NULL,FORM_PROC,FORM_CONST,FORM_VAR};
const char* const keytxt[MAX_KEYWORD]= //关键字
{
"procedure","call","begin","end","var","const",
"if","then","else","do","read","write",
"function","integer",
"real","char","repeat","for","until","to","downto","while"
};
enum
{
KW_PROCEDURE,KW_CALL,KW_BEGIN,KW_END,KW_VAR,KW_CONST,
KW_IF,KW_THEN,KW_ELSE,KW_DO,KW_READ,KW_WRITE,
KW_FUNCTION,KW_INTEGER,
KW_REAL,KW_CHAR,KW_REPEAT,KW_FOR,
KW_UNTIL,KW_TO,KW_DOWNTO,KW_WHILE
};
const char opatxt[MAX_OPWORDA]= //单字运算符
{
'+','-','*','/','<','>','=','#'
};
const char* const opbtxt[MAX_OPWORDB]= //双字运算符
{
"<=",">=",":=","<>"
};
enum
{
OW_PLUS,OW_MINUS,OW_TIMES,OW_SLASH,
OW_LT,OW_LG,OW_EQL,OW_NE,OW_LTE,OW_LGE,OW_DEF,OW_SB
};
const char eoptxt[MAX_ENDWORD]= //单字界符
{
',',';','(',')','.',':'
};
enum{EW_COMMA,EW_SEM,EW_LP,EW_RP,EW_END,EW_MAO};
const char* oprtxt[MAX_ASMWORD]= //单字界符
{
"LIT","LOD","STO","CAL","INT","JMP","JPC","OPR"
};
enum{OP_LIT,OP_LOD,OP_STO,OP_CAL,OP_INT,OP_JMP,OP_JPC,OP_OPR};
enum{
OPR_RET,OPR_NEG,OPR_ADD,OPR_SUB,OPR_MUL,OPR_DIV,
OPR_ODD,OPR_NUL,OPR_EQL,OPR_NE ,OPR_LT ,OPR_LGE,
OPR_LG ,OPR_LTE,OPR_WRT,OPR_WRN,OPR_RED,OPR_SB
};
const char* const errtxt[MAX_ERROR]= //错误提示信息
{
"程序结尾有多余字符", //0 ERR_ERREND
"", //1 (Reserved)
"常数说明中的\'=\'后应是正整数", //2 ERR_NEEDNUM
"常数说明中的标识符后应是\'=\'", //3 ERR_NEEDEQL
"const,var,procedure后缺少标识符", //4 ERR_NEEDSYM
"漏掉了\',\'或\';\'", //5 ERR_NEEDEND
"", //6 (Reserved)
"", //7 (Reserved)
"", //8 (Reserved)
"程序结尾丢了\'.\'或结尾不正常", //9 ERR_NOEND
"语句之间漏了\';\'或\'end\'", //10 ERR_NOTSEM
"标识符未说明", //11 ERR_NODEFSYM
"需赋值标识符属性应是变量", //12 ERR_NOTVAR
"赋值语句左部标识符后应是\':=\'", //13 ERR_NOTDEFOP
"call后应为标识符", //14 ERR_NOTSYM
"call后标识符属性应是过程", //15 ERR_NOTPROC
"条件语句中缺少\'then\'", //16 ERR_NOTTHEN
"read语句中缺少变量", //17 ERR_NEEDVAR
"while型循环语句中缺少\'do\'", //18 ERR_NOTDO
"", //19 (Reserved)
"应为关系运算符", //20 ERR_NOTRLOP
"表达式内标识符属性不能是过程", //21 ERR_NOPROC
"表达式中缺少\')\'", //22 ERR_NOTRP
"表达式中缺少标识符", //23 ERR_NOSYM
"表达式开始符不能是此符号", //24 ERR_WRONGOP
"标识符太长", //25 ERR_OVERSYMLEN
"常数越界", //26 ERR_OVERNUMLEN
"常数中含有字母", //27 ERR_NUMBER
"未定义的符号", //28 ERR_NOTDEF
"过程嵌套层次太多", //29 ERR_OVERLVL
"标识符表格溢出", //30 ERR_OVERFORM
"read/write中变量缺少括号", //31 ERR_NOTPAREN
"目标代码过长", //32 ERR_OVERASM
"还有更多的错误没有显示..." //33 ERR_OVERERR
};
///////////////////////////////////////////////////////////////
zCompile::zCompile()
{
memset(this,0,sizeof(zCompile));
}
///////////////////////////////////////////////////////////////
int zCompile::getsym()
{
int i,n=0,e=0; //序号/字符数/出错标记
int d=0;
i=sym.line;
memset(&sym,0,sizeof(SYM1));
sym.line=i;
while(!ISCHAR(*text)) //滤出前面的非字符
{
if(*text=='\n') sym.line++; //换行时,ln++
if(!*text) return 0; //如果无字符则退出
text++;
}
if(ISLETTER(*text)) //字母开头情况
{
while(ISLETTER(*text)||ISNUMBER(*text))
{
if(n<=MAX_SYMLEN) sym.name[n]=*text;
n++; text++;
}
sym.name[MAX_SYMLEN]=0; //符号结尾置0
if(n>MAX_SYMLEN) //超出符号最大长度
{
sym.type=TYPE_ERROR;
sym.id=ERR_OVERSYMLEN;
adderr(sym.name,ERR_OVERSYMLEN);
}
else
{
for(i=0;i<MAX_KEYWORD;i++)
if(strcmp(sym.name,keytxt[i])==0) break;
if(i<MAX_KEYWORD) //属于关键字
{
sym.type=TYPE_KEYWORD;
sym.id=i;
}
else //不属于关键字
{
sym.type=TYPE_SYMBOL; //符号类型
sym.id=0;
}
}
return n;
}
if(*text=='^'||*text=='&')//^=====+;&=====-
{
if(*text=='^')
{
if(n<=MAX_SYMLEN) sym.name[n]='+';
n++; text++;
if(ISNUMBER(*text)) //数字开头情况
{
e=0;
while(ISNUMBER(*text)||ISLETTER(*text)||*text=='.')
{
if(ISLETTER(*text)) e=1;//含字母则置出错标记
if(n<=MAX_SYMLEN) sym.name[n]=*text;
n++; text++;
}
sym.name[MAX_SYMLEN]=0; //数字尾置0
sym.type=TYPE_NUMBER;
sym.id=atoi(sym.name);
if(e) //含字母情况
adderr(sym.name,ERR_NUMBER);
else
if(n>MAX_NUMLEN||sym.id>MAX_NUMBER) //超出数字最大长度情况
adderr(sym.name,ERR_OVERNUMLEN);
return n;
}
}
else
{
if(n<=MAX_SYMLEN) sym.name[n]='-';
n++; text++;
if(ISNUMBER(*text)) //数字开头情况
{
e=0;
while(ISNUMBER(*text)||ISLETTER(*text)||*text=='.')
{
if(ISLETTER(*text)) e=1;//含字母则置出错标记
if(n<=MAX_SYMLEN) sym.name[n]=*text;
n++; text++;
}
sym.name[MAX_SYMLEN]=0; //数字尾置0
sym.type=TYPE_NUMBER;
sym.id=atoi(sym.name);
if(e) //含字母情况
adderr(sym.name,ERR_NUMBER);
else
if(n>MAX_NUMLEN||sym.id>MAX_NUMBER) //超出数字最大长度情况
adderr(sym.name,ERR_OVERNUMLEN);
return n;
}
}
}
if(ISNUMBER(*text)) //数字开头情况
{
e=0;
while(ISNUMBER(*text)||ISLETTER(*text)||*text=='.')
{
if(ISLETTER(*text)) e=1;//含字母则置出错标记
if(n<=MAX_SYMLEN) sym.name[n]=*text;
n++; text++;
}
sym.name[MAX_SYMLEN]=0; //数字尾置0
sym.type=TYPE_NUMBER;
sym.id=atoi(sym.name);
if(e) //含字母情况
adderr(sym.name,ERR_NUMBER);
else
if(n>MAX_NUMLEN||sym.id>MAX_NUMBER) //超出数字最大长度情况
adderr(sym.name,ERR_OVERNUMLEN);
return n;
}
for(i=0;i<MAX_OPWORDB;i++) //双字运算符情况
if(*(short*)text==*(short*)(opbtxt[i])) break;
if(i<MAX_OPWORDB)
{
sym.type=TYPE_OPWORD;
sym.id=MAX_OPWORDA+i;
*(short*)sym.name=*(short*)opbtxt[i];
sym.name[2]=0;
text+=2;
return 2;
}
sym.name[0]=*text;
sym.name[1]=0;
for(i=0;i<MAX_OPWORDA;i++) //单字运算符情况
if(*text==opatxt[i]) break;
if(i<MAX_OPWORDA)
{
sym.type=TYPE_OPWORD;
sym.id=i;
text++;
return 1;
}
for(i=0;i<MAX_ENDWORD;i++) //单字界符情况
if(*text==eoptxt[i]) break;
if(i<MAX_ENDWORD)
{
sym.type=TYPE_ENDWORD;
sym.id=i;
text++;
return 1;
}
sym.type=TYPE_ERROR;
sym.id=ERR_NOTDEF; //其他符号则出错
adderr(sym.name,ERR_NOTDEF);
text++;
return 1;
}
///////////////////////////////////////////////////////////////
int zCompile::addasm(char opr,char lvl,short adr)
{
if(asmnum==MAX_ASM)
{
adderr("",ERR_OVERASM);
return 1;
}
asms[asmnum].opr=opr;
asms[asmnum].lvl=lvl;
asms[asmnum].adr=adr;
asmnum++;
return 0;
}
///////////////////////////////////////////////////////////////
int zCompile::adderr(char *name,int id)
{
if(errnum==MAX_ERR) return 1;
*err[errnum].name=0;
strcpy(err[errnum].name,name);
err[errnum].id=id;
err[errnum].line=sym.line;
errnum++;
if(errnum==MAX_ERR-1)
adderr("",ERR_OVERERR);
return 0;
}
///////////////////////////////////////////////////////////////
int zCompile::getasm(char *buf)
{
int n=0;
char b[20];
for(int i=0;i<asmnum;i++)
{
sprintf(b,"%04u:%s %u %u\r\n",i,oprtxt[asms[i].opr],asms[i].lvl,asms[i].adr);
strcpy(buf+n,b);
n+=strlen(b);
if(!i||asms[i].opr==OP_OPR&&!asms[i].adr)
{
strcpy(buf+n,"\r\n");
n+=2;
}
}
buf[n]=0;
return i;
}
///////////////////////////////////////////////////////////////
int zCompile::geterr(char *buf)
{
int n=0;
char b[128];
for(int i=0;i<errnum;i++)
{
sprintf(b,"Line(%u):error[%u]:%s",err[i].line,err[i].id,errtxt[err[i].id],err[i].name);
strcpy(buf+n,b);
n+=strlen(b);
if(*err[i].name)
{
sprintf(b,":\"%s\"",err[i].name);
strcpy(buf+n,b);
n+=strlen(b);
}
strcpy(buf+n,"\r\n");
n+=2;
}
sprintf(b,"\r\n%u error(s)",errnum);
strcpy(buf+n,b);
buf[n+strlen(b)]=0;
return i;
}
///////////////////////////////////////////////////////////////
int zCompile::formpush(char *name,int type,int id)
{
if(formnum==MAX_FORM)
{
adderr("",ERR_OVERFORM);
return 1;
}
if(formlvl>=MAX_LEVEL)
{
adderr("",ERR_OVERLVL);
return 2;
}
form[formnum].type=type;
strcpy(form[formnum].name,name);
form[formnum].lvl=formlvl;
if(type==FORM_PROC)
{
formlvl++;
formadr[formlvl]=3;
}
if(type==FORM_VAR)
form[formnum].adr=formadr[formlvl]++;
else
form[formnum].adr=id;
formnum++;
return 0;
}
///////////////////////////////////////////////////////////////
int zCompile::formpop()
{
if(!formnum||!formlvl) return 1;
for(;form[--formnum].lvl==formlvl;);
formnum++;
formlvl--;
return 0;
}
///////////////////////////////////////////////////////////////
int zCompile::formget(char *name,FORM1 *fm)
{
for(int i=formnum-1;i>=0;i--)
if(!strcmp(form[i].name,name))
{
memcpy(fm,&form[i],sizeof(FORM1));
return i;
}
return -1;
}
///////////////////////////////////////////////////////////////
void zCompile::compile(char *txt)
{
memset(this,0,sizeof(zCompile));
text=txt;
sym.line=1;
formadr[0]=3;
addasm(OP_JMP,0,1);
if(getsym())
asms[0].adr=syn_block();
addasm(OP_OPR,0,OPR_RET);
do{
if(sym.type==TYPE_ENDWORD&&sym.id==EW_END)
{
if(getsym()) adderr("",ERR_ERREND);
return;
}
else
break;
}while(getsym());
adderr("",ERR_NOEND);
}
///////////////////////////////////////////////////////////////
int zCompile::syn_block()
{
char t[MAX_SYMLEN+1];
int s;
if(sym.type==TYPE_KEYWORD&&sym.id==KW_CONST)
{
_nextconst:
getsym();
if(sym.type==TYPE_SYMBOL)
{
strcpy(t,sym.name);
getsym();
if(sym.type==TYPE_OPWORD&&sym.id==OW_EQL)
{
getsym();
if(sym.type==TYPE_NUMBER)
{
formpush(t,FORM_CONST,sym.id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -