📄 unit1.cpp
字号:
*/
if (CX>CXMAX) {
Form1->printfs("PROGRAM TOO LONG");
fprintf(FOUT,"PROGRAM TOO LONG\n");
fclose(FOUT);
exit(0);
}
CODE[CX].F=X; CODE[CX].L=Y; CODE[CX].A=Z;
CX++;
} /*GEN*/
//---------------------------------------------------------------------------
void TEST(SYMSET S1, SYMSET S2, int N) {/*测试当前单词符号是否合法*/
/*
S1:当语法分析进入或退出时某一语法单元时当前单词符号应属于的集合
S2:某一出错状态时,可恢复语法分析继续正常工作的补充单词符号集合
N:错误类型号
*/
if (!SymIn(SYM,S1)) {
Error(N);
while (!SymIn(SYM,SymSetUnion(S1,S2))) GetSym();
}
} /*TEST*/
//---------------------------------------------------------------------------
void ENTER(OBJECTS K, int LEV, int &TX, int &DX) { /*登录名字表*/
TX++;//当前的TABLE表的索引
strcpy(TABLE[TX].NAME,ID); TABLE[TX].KIND=K;
switch (K) {
case CONSTANT:
if (NUM>AMAX) { Error(31); NUM=0; }//数越界
TABLE[TX].VAL=NUM;
break;
case VARIABLE:
TABLE[TX].vp.LEVEL=LEV;
TABLE[TX].vp.ADR=DX;
DX++;
break;
case CHARACTOR:
TABLE[TX].vp.LEVEL=LEV;
TABLE[TX].vp.ADR=DX;
DX++;
break;
case PROCEDUR:
TABLE[TX].vp.LEVEL=LEV;
break;
}
} /*ENTER*/
//---------------------------------------------------------------------------
int POSITION(ALFA ID, int TX) {/*查找标识符在名字表中的位置*/
/*看是否有过正确的定义
*/
int i=TX;
strcpy(TABLE[0].NAME,ID);
while (strcmp(TABLE[i].NAME,ID)!=0) i--; //采用静态表搜索的方法,从后往前搜
return i;
} /*POSITION*/
//---------------------------------------------------------------------------
void ConstDeclaration(int LEV,int &TX,int &DX) { /*常量说明处理*/
if (SYM==IDENT) {
GetSym();
if (SYM==EQL||SYM==BECOMES) {
if (SYM==BECOMES) Error(1); //常数说明中的"="写成":="
GetSym();
if (SYM==NUMBER) {
ENTER(CONSTANT,LEV,TX,DX); GetSym();
}
else Error(2);//常数说明中的"="后边应是数字
}
else Error(3);//常数说明中的标识符后应该是"="
}
else Error(4);//Const ,var,procedure 后边应为标识符
} /*ConstDeclaration()*/
//---------------------------------------------------------------------------
void VarDeclaration(int LEV,int &TX,int &DX) { /*变量说明处理*/
if (SYM==IDENT) {
ENTER(VARIABLE,LEV,TX,DX); GetSym();
}
else Error(4); //Const ,var,procedure 后边应为标识符
} /*VarDeclaration()*/
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void CharDeclaration(int LEV,int &TX,int &DX) { /*字符说明处理*/
if (SYM==IDENT) {
ENTER(CHARACTOR,LEV,TX,DX); GetSym();
}
else Error(4); //Char,Const ,var,procedure 后边应为标识符
} /*CharDeclaration()*/
void ListCode(int CX0) { /*LIST CODE GENERATED FOR THIS Block*/
if (Form1->ListSwitch->ItemIndex==0)
for (int i=CX0; i<CX; i++) {
String s=IntToStr(i);
while(s.Length()<3)s=" "+s;
s=s+" "+MNEMONIC[CODE[i].F]+" "+IntToStr(CODE[i].L)+" "+IntToStr(CODE[i].A);
Form1->printfs(s.c_str());
fprintf(FOUT,"%3d%5s%4d%4d\n",i,MNEMONIC[CODE[i].F],CODE[i].L,CODE[i].A);
}
} /*ListCode()*/;
//---------------------------------------------------------------------------
void DOUBLEOP(int LEV,int &TX){ //++或--
int i;
SYMBOL DOP;
DOP=SYM;
GetSym();
if(SYM==IDENT){
i=POSITION(ID,TX);
if (i==0) Error(11); //标识符未说明
else{
if(TABLE[i].KIND==VARIABLE) GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
else Error(25);
GEN(LIT,0,1);
if(DOP==DOUBLEPLUS) GEN(OPR,0,2);
else GEN(OPR,0,3);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GetSym();
}
}
else Error(25);
}
void OPDOUBLE(int LEV,int i){
if(i==0) Error(11);
else {
if(TABLE[i].KIND==VARIABLE) GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
else Error(25);
GEN(LIT,0,1);
if(SYM==DOUBLEPLUS) GEN(OPR,0,2);
else GEN(OPR,0,3);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GetSym();
}
}
void FACTOR(SYMSET FSYS, int LEV, int &TX) { /*因子处理*/
//TX:当前的TABLE表的索引
int i;
bool ISVAR;
TEST(FACBEGSYS,FSYS,24);
while (SymIn(SYM,FACBEGSYS)) {
if (SYM==IDENT) {
ISVAR=false;
i=POSITION(ID,TX);
if (i==0) Error(11); //标识符未说明
else
switch (TABLE[i].KIND) {
case CONSTANT: GEN(LIT,0,TABLE[i].VAL);
break; //LIT 0 A 将常数值取到栈顶,A为常数值
case VARIABLE: GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
ISVAR=true;
break; //LOD L A 将变量值取到栈顶,A为偏移量,L为层差
case PROCEDUR: Error(21);
break; //表达式内标识符属性不能是过程
}
GetSym();
if(ISVAR==true && (SYM==DOUBLEPLUS||SYM==DOUBLEMINUS)){
OPDOUBLE(LEV,i);
}
}
else
if (SYM==NUMBER) {
if (NUM>AMAX) { Error(31); NUM=0; } //数越界
GEN(LIT,0,NUM);//LIT 0 A 将常数值取到栈顶,A为常数值
GetSym();
}
else
if (SYM==LPAREN) {
GetSym();
EXPRESSION(SymSetAdd(RPAREN,FSYS),LEV,TX);//表达式处理
if (SYM==RPAREN) GetSym();
else Error(22);//表达式中漏掉了右括号')'
}
TEST(FSYS,FACBEGSYS,23);
}
}/*FACTOR*/
//---------------------------------------------------------------------------
void TERM(SYMSET FSYS, int LEV, int &TX) { /*项处理*/
SYMBOL MULOP;
FACTOR(SymSetUnion(FSYS,SymSetNew(TIMES,SLASH)), LEV,TX);
while (SYM==TIMES || SYM==SLASH) {
MULOP=SYM; GetSym();
FACTOR(SymSetUnion(FSYS,SymSetNew(TIMES,SLASH)),LEV,TX);//因子处理
if (MULOP==TIMES)
GEN(OPR,0,4);//OPR 0 4 次栈顶乘以栈顶,退两个栈元素,结果值进栈
else GEN(OPR,0,5); //OPR 0 5 次栈顶除以栈顶,退两个栈元素,结果值进栈
}
} /*TERM*/;
//---------------------------------------------------------------------------
void EXPRESSION(SYMSET FSYS, int LEV, int &TX) { /*表达式处理*/
SYMBOL ADDOP;
if (SYM==PLUS || SYM==MINUS) {
ADDOP=SYM; GetSym();
TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX); //项处理
if (ADDOP==MINUS)
GEN(OPR,0,1); //OPR 0 1 栈顶元素取反
}
//改造增量运算开始-----------------------------------------------------
else if(SYM==DOUBLEPLUS||SYM==DOUBLEMINUS) //添加增量计算
DOUBLEOP(LEV,TX); //调用增量计算函数 ++或--
//改造增量运算结束-----------------------------------------------------
else TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX);
while (SYM==PLUS || SYM==MINUS) {
ADDOP=SYM; GetSym();
TERM(SymSetUnion(FSYS,SymSetNew(PLUS,MINUS)),LEV,TX);
if (ADDOP==PLUS)
GEN(OPR,0,2);//OPR 0 2 次栈顶与栈顶相加,退两个栈元素,结果值进栈
else GEN(OPR,0,3);//OPR 0 3 次栈顶减去栈顶,退两个栈元素,结果值进栈
}
} /*EXPRESSION*/
//---------------------------------------------------------------------------
void CONDITION(SYMSET FSYS,int LEV,int &TX) { /*条件处理*/
SYMBOL RELOP;
if (SYM==ODDSYM) {
GetSym();
EXPRESSION(FSYS,LEV,TX);//表达式处理
GEN(OPR,0,6); //OPR 0 6 栈顶元素的奇偶判断,结果值在栈顶
}
else {
EXPRESSION(SymSetUnion(SymSetNew(EQL,NEQ,LSS,LEQ,GTR,GEQ),FSYS),LEV,TX);
if (!SymIn(SYM,SymSetNew(EQL,NEQ,LSS,LEQ,GTR,GEQ))) Error(20); //应为关系运算
else {
RELOP=SYM; GetSym(); EXPRESSION(FSYS,LEV,TX);
switch (RELOP) {
case EQL: GEN(OPR,0,8); break;//OPR 0 8 次栈顶与栈顶是否相等,退两上栈元素,结果值进栈
case NEQ: GEN(OPR,0,9); break;//OPR 0 9 次栈顶与栈顶是否不等,退两个栈元素,结果值进栈
case LSS: GEN(OPR,0,10); break;//OPR 0 10 次栈顶是否小于栈顶,退两个栈元素,结果值进栈
case GEQ: GEN(OPR,0,11); break;//OPR 0 11 次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈
case GTR: GEN(OPR,0,12); break;//OPR 0 12 次栈顶是否大于栈顶,退两个栈元素,结果值进栈
case LEQ: GEN(OPR,0,13); break;//OPR 0 13 次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈
}
}
}
} /*CONDITION*/
//---------------------------------------------------------------------------
void STATEMENT(SYMSET FSYS,int LEV,int &TX) { /*语句部分处理*/
SYMBOL SYM1;
int i,CX1,CX2;
int count=' ';
switch (SYM) {
case IDENT:
i=POSITION(ID,TX); //TX:符号表的下标变量,在符号表中返回符号ID的位置
if (i==0) Error(11); //标识符未说明
else
if (TABLE[i].KIND!=VARIABLE && TABLE[i].KIND!=CHARACTOR) { /*对比类型属性是否为变量*/
Error(12); i=0; //赋值语句中,赋值号左部标识符属性应是变量
}
GetSym();
//改造开始------------------------------------------------------------
//以下扩展-=,+=,++,--,
if(SYM==BECOMES||SYM==PLUSBECOMES||SYM==MINUSBECOMES){
if(SYM==PLUSBECOMES||SYM==MINUSBECOMES){
if(i!=0){
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //LOD L A 将变量值取到栈顶,A为偏移量,L为层差
SYM1=SYM;
}
}
GetSym();
if(SYM==QUOT){
GetSym();
if(SYM==IDENT){
count=ID[0];
}
if (i!=0){
GEN(LIT,0,count);//将字符当作整型来处理
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //STO L A 将栈顶内容送入某一变量单元中,A为偏移量,L为层差
}
GetSym();
if(SYM==QUOT){ GetSym();
}
else Error(27);
}
else{
EXPRESSION(FSYS,LEV,TX);
if(SYM1==PLUSBECOMES) GEN(OPR,0,2);//+= ,OPR 0 2 次栈顶与栈顶相加,退两个栈元素,结果值进栈
else if(SYM1==MINUSBECOMES) GEN(OPR,0,3);//-= ,OPR 0 3 次栈顶减去栈顶,退两个栈元素,结果值进栈
if(i!=0){
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
}
}
}
else if(SYM==DOUBLEPLUS||SYM==DOUBLEMINUS){
if(i!=0){
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GEN(LIT,0,1);
if(SYM==DOUBLEPLUS) GEN(OPR,0,2);
else if(SYM==DOUBLEMINUS) GEN(OPR,0,3);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
}
GetSym();
}
else Error(13);
break;
//改造结束 -----------------------------------------------------------
//开始前++ .如++X,--X等等-----------------------------------------------------------------
case DOUBLEPLUS:
GetSym();
i=POSITION(ID,TX); //TX:符号表的下标变量,在符号表中返回符号ID的位置
if (i==0) Error(11); //标识符未说明
else if (TABLE[i].KIND!=VARIABLE) { //对比类型属性是否为变量
Error(12); i=0; //赋值语句中,赋值号左部标识符属性应是变量
}
if(i!=0){
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GEN(LIT,0,1);
GEN(OPR,0,2);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
}
GetSym();
break;
case DOUBLEMINUS:
GetSym();
i=POSITION(ID,TX); //TX:符号表的下标变量,在符号表中返回符号ID的位置
if (i==0) Error(11); //标识符未说明
else if (TABLE[i].KIND!=VARIABLE) { //对比类型属性是否为变量
Error(12); i=0; //赋值语句中,赋值号左部标识符属性应是变量
}
if(i!=0){
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
GEN(LIT,0,1);
GEN(OPR,0,3);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
}
GetSym();
break;
//结束前++ .如++X ,--X等等------------------------------------------------------
case READSYM: //READ 语句
GetSym();
if (SYM!=LPAREN) Error(34); //若不是左括号 则出错
else
do {
GetSym();
if (SYM==IDENT) i=POSITION(ID,TX); //在符号表中返回符号的位置
else i=0;
if (i==0) Error(28);
else {
GEN(OPR,0,16);//OPR 0 16 从命令行读入一个输入置于栈顶
//STO L A 将栈顶内容送入某一变量单元中,A为偏移量,L为层差
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
}
GetSym();
}while(SYM==COMMA); //直到SYM不是","号
if (SYM!=RPAREN) { //若不是右括号 则出错
Error(33);
while (!SymIn(SYM,FSYS)) GetSym();
}
else GetSym();
break; /* READSYM */
case WRITESYM: //WRITE语句
GetSym();
if (SYM==LPAREN) {//若是右括号 则继续
do {
GetSym();
EXPRESSION(SymSetUnion(SymSetNew(RPAREN,COMMA),FSYS),LEV,TX);
GEN(OPR,0,14);//OPR 0 14 栈顶值输出到屏幕
}while(SYM==COMMA);
if (SYM!=RPAREN) Error(33); //若不是右括号 则出错
else GetSym();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -