📄 pl0.cpp
字号:
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym==SYM_BEGIN)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
statement(fsys);
while(sym==SYM_SEMICOLON||inset(sym, statbegsys))
{
if (sym == SYM_SEMICOLON)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(10);
}
statement(set);
mask* mk;
i=position(id);
if(i==0)
{
error(11); /* Undeclared identifier.*/
}
else if(table[i].kind != ID_VARIABLE)
{
error(12); /* Illegal assignment.*/
i = 0;
}
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if (sym == SYM_BECOMES)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(13); /* ':=' expected.*/
}
expression(fsys);
mk = (mask*) &table[i];
if (i)
{
gen(STO, level - mk->level, mk->address);
}
gen(JMP,0,cx1);
}
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym!=SYM_END) error(34);
}
else
{
mask* mk;
i=position(id1);
if(i==0)
{
error(11); /* Undeclared identifier.*/
}
else if(table[i].kind != ID_VARIABLE)
{
error(12); /* Illegal assignment.*/
i = 0;
}
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if (sym == SYM_BECOMES)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(13); /* ':=' expected.*/
}
expression(fsys);
mk = (mask*) &table[i];
if (i)
{
gen(STO, level - mk->level, mk->address);
}
gen(JMP,0,cx1);
}
code[cx2].a=cx;
jx=cx;
}
//>>>>>>>>>>>>>>>>>>>>>>for语句填加结束<<<<<<<<<<<<<<<<<<<<//
else if (sym == SYM_WHILE) /*while 语句的处理*/
{ /* while statement*/
cx1 = cx;
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
set1 = createset(SYM_DO, SYM_NULL);
set = uniteset(set1, fsys);
condition(set);
destroyset(set1);
destroyset(set);
cx2 = cx;
gen(JPC, 0, 0);
if (sym == SYM_DO)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(18); /* 'do' expected.*/
}
statement(fsys);
gen(JMP, 0, cx1);
code[cx2].a = cx;
jx=cx;
}
//<<<<<<<<<<<<<<<<<加入的exit语句和break语句<<<<<<<<<<<<<<<<<<<<<
if(sym==SYM_EXIT)
{ //exit 语句
gen(JMP,0,jpx);
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else if(sym==SYM_BREAK)
{ //break 语句
gen(JMP,0,jx);
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
//<<<<<<<<<<<<<<<<<<exit语句和break语句结束<<<<<<<<<<<<<<<<<<<<<<<
set2=uniteset(fsys,createset(SYM_BREAK,SYM_ARRAY,SYM_EXIT,SYM_ELSE,SYM_NULL));
test(set2, phi, 19);
} /* statement*/
//////////////////////////////////////////////////////////////////
void block(symset fsys)
{
int cx0; /* initial code index*/
mask* mk;
int block_dx;
int savedTx;
symset set1, set;
dx = 3;//??????????
block_dx = dx;
mk = (mask*) &table[tx];
mk->address = cx;
gen(JMP, 0, 0);
if (level > MAXLEVEL)
{
error(32); /* There are too many levels.*/
}
do
{
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if (sym == SYM_CONST) /*定义常量的处理*/
{ /* constant declarations
const 声明常量时,总有';'结束,否则报错
const 可以声明多个常量,用','隔开
*/
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
do
{
constdeclaration();
while (sym == SYM_COMMA)//','
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
constdeclaration();
}
if (sym == SYM_SEMICOLON)//';'
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(5); /* Missing ',' or ';'.*/
}
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
while (sym == SYM_IDENTIFIER);
} /* if*/
if (sym == SYM_VAR) /*定义变量的处理*/
{ /* variable declarations*/
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
do
{
if(sym==SYM_ARRAY) arraydeclaration();
else vardeclaration();
while (sym == SYM_COMMA)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym==SYM_ARRAY) arraydeclaration();
if(sym==SYM_IDENTIFIER) vardeclaration();
}
if (sym == SYM_SEMICOLON)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(5); /* Missing ',' or ';'.*/
}
if(sym==SYM_ARRAY) arraydeclaration();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
while (sym == SYM_IDENTIFIER||sym==SYM_ARRAY);
block_dx = dx;
} /* if*/
//*************************************************************************
if(sym==SYM_BOOL)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
do
{
booldeclaration();
while(sym==SYM_COMMA)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if(sym==SYM_IDENTIFIER) booldeclaration();
}
if (sym == SYM_SEMICOLON)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(5); /* Missing ',' or ';'.*/
}
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
while (sym == SYM_IDENTIFIER);
block_dx = dx;
} /* if*/
//*************************************************************************
while (sym == SYM_PROCEDURE)
{ /* procedure declarations*/
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
if (sym == SYM_IDENTIFIER)
{
enter(ID_PROCEDURE);
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
}
if(sym==SYM_LPAREN) //函数处理procedure d(p,q)
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
fdeclaration();
} //函数处理
if (sym==SYM_SEMICOLON)//函数定义开始有';'
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
}
else
{
error(5); // Missing ',' or ';'
}
level++;
savedTx = tx;
set1 = createset(SYM_SEMICOLON, SYM_NULL);
set = uniteset(set1, fsys);
block(set);
destroyset(set1);
destroyset(set);
tx = savedTx;
level--;
if (sym == SYM_SEMICOLON)//函数结尾也有';'
{
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
set1 = createset(SYM_IDENTIFIER, SYM_PROCEDURE, SYM_NULL);
set = uniteset(statbegsys, set1);
test(set, fsys, 6);
destroyset(set1);
destroyset(set);
}
else
{
error(5); /* Missing ',' or ';'.*/
}
} /* while*/
set1 = createset(SYM_IDENTIFIER, SYM_NULL);
set = uniteset(statbegsys, set1);
test(set, declbegsys, 7);
destroyset(set1);
destroyset(set);
}while (inset(sym, declbegsys));
code[mk->address].a = cx;
mk->address = cx;
cx0 = cx;
gen(INT, 0, block_dx);
set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL);
set = uniteset(set1, fsys);
statement(set);
destroyset(set1);
destroyset(set);
gen(OPR, 0, OPR_RET); /* return*/
test(fsys, phi, 8); /* test for error: Follow the statement is an incorrect symbol.*/
listcode(cx0, cx);
} /* block*/
/*////////////////////////////////////////////////////////////////////*/
int base(int stack[], int currentLevel, int levelDiff)
{
int b = currentLevel;
while (levelDiff--)
b = stack[b];
return b;
} /* base*/
/*/////////////////////////////////////////////////////////////////////*/
/*/ interprets and executes codes.*/
void interpret() //解释程序
{
int pc; /* program counter*/
int stack[STACKSIZE];
int top; /* top of stack*/
int b; /* program, base, and top-stack register*/
instruction i; /* instruction register*/
printf("Begin executing PL/0 program.\n");
pc = 0;
b = 1;
top = 3;
stack[1] = stack[2] = stack[3] = 0;
do
{
i = code[pc++];
switch (i.f)
{
case LIT: //将常数置于栈顶
stack[++top] = i.a;
break;
case OPR: //一组算术或逻辑运算指令
switch (i.a) /* operator*/
{
case OPR_RET: //返回指令
top = b - 1;
pc = stack[top + 3];
b = stack[top + 2];
break;
case OPR_NEG: //求反指令
stack[top] = -stack[top];
break;
case OPR_ADD: //加法指令
top--;
stack[top] += stack[top + 1];
break;
case OPR_MIN: //减法指令
top--;
stack[top] -= stack[top + 1];
break;
case OPR_MUL: //乘法指令
top--;
stack[top] *= stack[top + 1];
break;
case OPR_DIV: //除法指令
top--;
if (stack[top + 1] == 0)
{
fprintf(stderr, "Runtime Error: Divided by zero.\n");
fprintf(stderr, "Program terminated.\n");
continue;
}
stack[top] /= stack[top + 1];
break;
case OPR_ODD:
stack[top] %= 2;
break;
case OPR_EQU: //等于指令
top--;
stack[top] = stack[top] == stack[top + 1];
break;
case OPR_NEQ: //不等于指令
top--;
stack[top] = stack[top] != stack[top + 1];
case OPR_LES: //小于指令
top--;
stack[top] = stack[top] < stack[top + 1];
break;
case OPR_GEQ: //大于等于指令
top--;
stack[top] = stack[top] >= stack[top + 1];
case OPR_GTR: //大于指令
top--;
stack[top] = stack[top] > stack[top + 1];
break;
case OPR_LEQ: //小于等于指令
top--;
stack[top] = stack[top] <= stack[top + 1];
//>>>>>>>>>>>>>>>>>>>>>>加入布尔运算符<<<<<<<<<<<<<<<<<<<<<<<<<<//
case OPR_AND: //'$$'指令
top--;
stack[top]*=stack[top+1];
break;
case OPR_OR: //'||'指令
top--;
stack[top]+=stack[top+1];
break;
case OPR_NOT: //'!' 指令
top--;
stack[top]=!stack[top+1];
break;
//>>>>>>>>>>>>>>>>>>>>布尔运算符结束<<<<<<<<<<<<<<<<<<<<<<<<<<<//
} /* switch*/
break;
case LOD: //将变量值置于栈顶
stack[++top] = stack[base(stack, b, i.l) + i.a];
break;
case STO: //将栈顶的值赋与某变量
stack[base(stack, b, i.l) + i.a] = stack[top];
printf("%d\n", stack[top]);
top--;
break;
case CAL: //用于过程调用的指令
stack[top + 1] = base(stack, b, i.l);
/* generate new block mark*/
stack[top + 2] = b;
stack[top + 3] = pc;
b = top + 1;
pc = i.a;
break;
case INT: //在数据栈中分配存贮空间
top += i.a;
break;
case JMP: //用于if, while语句的条件或无条件控制转移指令
pc = i.a;
break;
case JPC: //用于if, while语句的条件或无条件控制转移指令
if (stack[top] == 0)
pc = i.a;
top--;
break;
} /* switch*/
}
while (pc);
printf("End executing PL/0 program.\n");
} /* interpret*/
/*////////////////////////////////////////*/
void main (void )
{
char c;
FILE* hbin;
char s[80];
int i;
symset set, set1, set2;
printf("THE SOURCE FILE NAME IS: "); /* get file name to be compiled*/
scanf("%s", s);
if ((infile = fopen(s, "r")) == NULL)
{
printf(" The Source File %s can't be opened.\n", s);
exit(1);
}
phi = createset(SYM_NULL);
relset = createset(SYM_EQU, SYM_NEQ, SYM_LES, SYM_LEQ, SYM_GTR, SYM_GEQ, SYM_NULL);
/* create begin symbol sets*/
declbegsys = createset(SYM_CONST, SYM_VAR,SYM_BOOL, SYM_PROCEDURE, SYM_NULL);
statbegsys = createset(SYM_IDENTIFIER, SYM_BEGIN, SYM_CALL, SYM_IF, SYM_WHILE, SYM_NULL);
facbegsys = createset(SYM_IDENTIFIER, SYM_NUMBER, SYM_NULL);
err = cc = cx = ll = 0; /* initialize global variables*/
ch = ' ';
kk = MAXIDLEN;
//while(!feof(infile))
getsym();
if(sym==SYM_EXPL1) explanation();//处理pl0的注释
set1 = createset(SYM_PERIOD, SYM_NULL);
set2 = uniteset(declbegsys, statbegsys);
set = uniteset(set1, set2);
block(set);
destroyset(set1);
destroyset(set2);
destroyset(set);
destroyset(phi);
destroyset(relset);
destroyset(declbegsys);
destroyset(statbegsys);
destroyset(facbegsys);
if (sym != SYM_PERIOD)
error(9); /* '.' expected.*/
if (err == 0)
{
hbin = fopen("hbin.txt", "w");
for (i = 0; i < cx; i++)
fwrite(&code[i], sizeof(instruction), 1, hbin);
fclose(hbin);
}
if (err == 0)
{
printf("Ready to interpret? Y/N \n");
getchar();
c=getchar();
if(c=='y'||c=='Y')
{
interpret();
}
else exit(1);
}
else
printf("There are %d error(s) in PL/0 program.\n", err);
listcode(0, cx);
} /* main END OF PL0.c*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -