📄 pl0.cpp
字号:
{
getsym();
statement(fsys, tableIndex, lev);
}
else
error(10);
}
}
else error(10);
}
if (sym == ENDSYM)
getsym();
else
error(17);
}
else if (sym == WHILESYM) {
codeIndex1 = codeIndex;
getsym();
symset tempsys;
tempsys.insert(ODDSYM);
tempsys.insert(PLUS);
tempsys.insert(MINUS);
tempsys.insert(LPAREN);
tempsys.insert(IDENT);
tempsys.insert(NUMBER);
condition(tempsys, tableIndex, lev);
codeIndex2 = codeIndex;
gen(JPC, 0, 0);
if (sym == DOSYM)
getsym();
else error(18);
statement(fsys, tableIndex, lev);
gen(JMP, 0, codeIndex1);
code[codeIndex2].addr = codeIndex;
}
else if (sym == READSYM) {
getsym();
if (sym == LPAREN) {
do {
getsym();
if (sym == IDENT)
i = position(id,tableIndex);
else i=0;
if (i == 0)
error(34);
else
{
if (table[i].kind != VARIABLE) {
error(32);
}
else
{
gen(OPR,0,16);
gen(STO, lev - table[i].level, table[i].addr);
}
}
getsym();
} while (sym == COMMA);
}
else
{
error(33);
do {
if (sym == IDENT)
i = position(id,tableIndex);
else i=0;
if (i == 0)
error(34);
else
{
if (table[i].kind != VARIABLE) {
error(32);
}
else
{
gen(OPR,0,16);
gen(STO, lev - table[i].level, table[i].addr);
}
}
getsym();
} while (sym == COMMA);
}
if (sym != RPAREN)
error(22);
else
getsym();
}
else if (sym == WRITESYM) {
getsym();
if (sym == LPAREN) {
do {
getsym();
if (sym == IDENT)
i = position(id,tableIndex);
else i=0;
if (i == 0)
error(35);
else
{
gen(LOD, lev - table[i].level, table[i].addr);
gen(OPR,0,14);
gen(OPR,0,15);
}
getsym();
} while (sym == COMMA);
}
else
{
error(36);
do {
if (sym == IDENT)
i = position(id,tableIndex);
else i=0;
if (i == 0)
error(35);
else
{
gen(LOD, lev - table[i].level, table[i].addr);
gen(OPR,0,14);
gen(OPR,0,15);
}
getsym();
} while (sym == COMMA);
}
if (sym != RPAREN)
error(22);
else
getsym();
}
symset s2;
s2.insert(PERIOD);
s2.insert(SEMICOLON);
s2.insert(ENDSYM);
symset tempsys1=fsys;
tempsys1.insert(CONSTSYM);
tempsys1.insert(VARSYM);
tempsys1.insert(PROCSYM);
// tempsys.clear(); //blank
test(s2, tempsys1, 19);
DEBUG(-1, ">-statement()");
}
void Pl0::expression(symset fsys,int tableIndex, int lev)//表达式
{
if (sourceEnd == true)
return;
DEBUG(1, "<-expression();");
symset s2;
s2.insert(PERIOD);
s2.insert(SEMICOLON);
s2.insert(ENDSYM);
s2.insert(RPAREN);
s2.insert(THENSYM);
s2.insert(DOSYM);
s2.insert(EQL);
s2.insert(NEQ);
s2.insert(LSS);
s2.insert(GTR);
s2.insert(LEQ);
s2.insert(GEQ);
test(fsys,s2,40);
symbol addop;
if (sym >= PLUS && sym <= MINUS) {
addop = sym;
getsym();
term(facbegsys, tableIndex, lev);
if (addop == MINUS)
gen(OPR, 0, 1);
}
else term(facbegsys, tableIndex, lev);
while(sym >= PLUS && sym <= MINUS) {
addop = sym;
getsym();
term(facbegsys, tableIndex, lev);
if (addop == PLUS)
gen(OPR, 0, 2);
else gen(OPR, 0, 3);
}
symset tempsys=fsys;
tempsys.insert(CONSTSYM);
tempsys.insert(VARSYM);
tempsys.insert(PROCSYM);
test(s2,tempsys,41);
DEBUG(-1, ">-expression();");
}
void Pl0::term(symset fsys,int tableIndex, int lev)//项
{
if (sourceEnd == true)
return;
DEBUG(1, "<-term();");
symset s2;
s2.insert(PERIOD);
s2.insert(SEMICOLON);
s2.insert(ENDSYM);
s2.insert(RPAREN);
s2.insert(THENSYM);
s2.insert(DOSYM);
s2.insert(PLUS);
s2.insert(MINUS);
s2.insert(EQL);
s2.insert(NEQ);
s2.insert(LSS);
s2.insert(GTR);
s2.insert(LEQ);
s2.insert(GEQ);
test(fsys,s2,43);
symbol mulop;
factor(facbegsys, tableIndex, lev);
while(sym >= TIMES && sym <= SLASH) {
mulop = sym;
getsym();
factor(facbegsys, tableIndex, lev);
if (mulop == TIMES)
gen(OPR, 0, 4);
else gen(OPR, 0, 5);
}
symset tempsys=fsys;
tempsys.insert(CONSTSYM);
tempsys.insert(VARSYM);
tempsys.insert(PROCSYM);
test(s2,tempsys,42);
DEBUG(-1, ">-term();");
}
void Pl0::factor(symset fsys,int tableIndex, int lev)
{
if (sourceEnd == true)
return;
DEBUG(1, "<-factor();");
int i;
symset s2;
s2.insert(PERIOD);
s2.insert(SEMICOLON);
s2.insert(ENDSYM);
s2.insert(RPAREN);
s2.insert(THENSYM);
s2.insert(DOSYM);
s2.insert(PLUS);
s2.insert(MINUS);
s2.insert(TIMES);
s2.insert(SLASH);
s2.insert(EQL);
s2.insert(NEQ);
s2.insert(LSS);
s2.insert(GTR);
s2.insert(LEQ);
s2.insert(GEQ);
test(fsys,s2,42);
while(facbegsys.find(sym) != facbegsys.end()) { //因子开始字符
if (sym == IDENT) {
i = position(id, tableIndex);
if (i == 0)
error(11);
else {
switch(table[i].kind) {
case CONSTANT:
gen(LIT, 0, table[i].val);
break;
case VARIABLE:
gen(LOD, lev - table[i].level, table[i].addr);
break;
case PROCEDURE:
error(21);
break;
default:
break;
}
}
getsym();
}
else if (sym == NUMBER) {
if (number > numMax) {
error(31);
number = 0;
}
gen(LIT, 0, number);
getsym();
}
else if (sym == LPAREN) {
getsym();
symset tempsys;
tempsys.insert(PLUS);
tempsys.insert(MINUS);
tempsys.insert(LPAREN);
tempsys.insert(IDENT);
tempsys.insert(NUMBER);
expression(tempsys, tableIndex, lev);
if (sym == RPAREN)
getsym();
else error(22);
}
// test(fsys, tempsys, 23); //some bugs
symset tempsys=fsys;
tempsys.insert(CONSTSYM);
tempsys.insert(VARSYM);
tempsys.insert(PROCSYM);
test(s2,tempsys,23);
DEBUG(-1, ">-factor();");
}
}
void Pl0::condition(symset fsys,int tableIndex, int lev)//条件语句模块
{
DEBUG(1, "<-condition();");
symset s2;
s2.insert(THENSYM);
s2.insert(DOSYM);
test(fsys,s2,44);
symbol relop;
symset s;
s.insert(PLUS);
s.insert(MINUS);
s.insert(LPAREN);
s.insert(IDENT);
s.insert(NUMBER);
if (sym == ODDSYM) {
getsym();
expression(s, tableIndex, lev);
gen(OPR, 0, 6);
}
else {
expression(s, tableIndex, lev);
if (!(sym == EQL || sym == NEQ || sym == LSS || sym == GTR || sym == LEQ || sym == GEQ))
error(20);
else {
relop = sym;
getsym();
expression(s, tableIndex, lev);
switch(relop) {
case EQL: gen(OPR, 0, 8);
break;
case NEQ: gen(OPR, 0, 9);
break;
case LSS: gen(OPR, 0, 10);
break;
case GEQ: gen(OPR, 0, 11);
break;
case GTR: gen(OPR, 0, 12);
break;
case LEQ: gen(OPR, 0, 13);
break;
default:
break;
}
}
}
symset tempsys=fsys;
tempsys.insert(CONSTSYM);
tempsys.insert(VARSYM);
tempsys.insert(PROCSYM);
test(s2,tempsys,45);
DEBUG(-1, ">-condition();");
}
int Pl0::base(int bas, int *store, int l)
{
int bas1;
bas1 = bas; //查找外层基址
for (; l > 0; l--)
bas1 = store[bas1];
return bas1;
}
void Pl0::interpret()//解释执行目标程序函数
{
DEBUG(1, "<-interpret();");
const int stackSize = 500;
int prog, bas, topReg;
instruction instReg;
int store[stackSize];
topReg = 0;
bas = 1;
prog = 0;
store[1] = 0;
store[2] = 0;
store[3] = 0;
// cout << "Start PL/0." << endl;
OUTPUT("Start PL/0.", 888);
DEBUG(0, "Start PL/0.");
do {
instReg = code[prog];
prog++;
switch(instReg.func) {//以目标代码函数功能划分
case LIT:
topReg++;
store[topReg] = instReg.addr;
break;
case OPR:
switch(instReg.addr) {
case 0:
topReg = bas - 1;
prog = store[topReg + 3];
bas = store[topReg + 2];
break;
case 1:
store[topReg] = -store[topReg];
break;
case 2:
topReg--;
store[topReg] += store[topReg + 1];
break;
case 3:
topReg--;
store[topReg] -= store[topReg + 1];
break;
case 4:
topReg--;
store[topReg] *= store[topReg + 1];
break;
case 5:
topReg--;
if(store[topReg + 1]==0)//判断除数是否为零
{
error(47);
return;
}
store[topReg] /= store[topReg + 1];
break;
case 6: //odd(s[t]) 奇偶判断
store[topReg] = ((store[topReg] % 2 == 1) ? 1 : 0);
/*if (store[topReg] % 2 == 1)
store[topReg] = 1;
else store[topReg] = 0;*/
break;
case 8:
topReg--;
store[topReg] = ((store[topReg] == store[topReg + 1]) ? 1 : 0);
break;
case 9:
topReg--;
store[topReg] = ((store[topReg] != store[topReg + 1]) ? 1 : 0);
break;
case 10:
topReg--;
store[topReg] = ((store[topReg] < store[topReg + 1]) ? 1 : 0);
break;
case 11:
topReg--;
store[topReg] = ((store[topReg] >= store[topReg + 1]) ? 1 : 0);
break;
case 12:
topReg--;
store[topReg] = ((store[topReg] > store[topReg + 1]) ? 1 : 0);
break;
case 13:
topReg--;
store[topReg] = ((store[topReg] <= store[topReg + 1]) ? 1 : 0);
break;
case 14:
cout << "输出:" << store[topReg] << endl;
OUTPUT(" :output", store[topReg]);
DEBUG(0, "output:", store[topReg]);
topReg--;
break;
case 15:
cout << "换行:"<< endl;
cout<<endl;
OUTPUT(" :output", '\n');
DEBUG(0, "output:", '\n');
break;
case 16:
cout << "输入一个数:" << endl;
topReg++;
cin >> store[topReg];
OUTPUT(":input.", store[topReg]);
DEBUG(0, "input a number:", store[topReg]);
break;
default:
break;
}
break;
case LOD:
topReg++;
store[topReg] = store[base(bas, store, instReg.lev) + instReg.addr];
break;
case STO:
store[base(bas, store, instReg.lev) + instReg.addr] = store[topReg];
topReg--;
break;
case CAL:
store[topReg + 1] = base(bas, store, instReg.lev);
store[topReg + 2] = bas;
store[topReg + 3] = prog;
bas = topReg + 1;
prog = instReg.addr;
break;
case INT:
topReg += instReg.addr;
break;
case JMP:
prog = instReg.addr;
break;
case JPC:
if (store[topReg] == 0)
prog = instReg.addr;
topReg--;
break;
default:
break;
}
} while(prog != 0);
// cout << "END PL/0." << endl;
OUTPUT("END PL/0.", 888);
DEBUG(0, "END PL/0.");
DEBUG(-1, ">-interpret();");
}
void Pl0::OUTPUT(char *msg1, char *msg2, int i, int j, int k)
{
#ifdef OUTPUT
out << msg1 << i << " " << " " << msg2 << " " << j << " " << k << endl;
#endif OUTPUT
}
void Pl0::OUTPUT(char *msg, int i)
{
#ifdef OUTPUT
out << i << " " << msg << endl;
#endif OUTPUT
}
///////////////////////////////////////////////////////// DEBUG信息输出
void Pl0::DEBUG(int into, char *msg, char c) {
#ifdef DEBUG
// cout << msg << " " <<endl;
if (into == 0)
debugOut << "| " ;
if (into == 1)
++ counter;
for (int i = 0; i < counter; i++)
debugOut << "| " ;
if (into == -1)
-- counter;
debugOut << msg << " " << c << endl;
#endif
}
void Pl0::DEBUG(int into, char *msg, int i, int j) {
#ifdef DEBUG
// cout << msg << " " << i <<endl;
if (into == 0)
debugOut << "| " ;
if (into == 1)
++ counter;
for (int k = 0; k < counter; k++)
debugOut << "| " ;
if (into == -1)
-- counter;
debugOut << msg << " " << i << " ";
if (j != 99999)
debugOut << j;
debugOut << endl;
#endif
}
//////////////////////////////////////////////////////////
string Pl0::errorInfo[]={" ",
"error 0001: 常数说明中“=”写成“:=”",
"error 0002: 常数说明中的“=”后应为数字",
"error 0003: 常数说明中的标识符后应是“=”",
"error 0004: const,var,procedure后应为标识符",
"error 0005: 漏掉了‘,’或‘;’",
"error 0006: 过程说明后的符号不正确(应是语句开始符或过程开始符)",
"error 0007: 应是语句开始符",
"error 0008: 过程体内语句部分的后跟符不正确",
"error 0009: 程序皆为丢了句号‘.’",
"error 0010: 语句之间漏了‘;’",
"error 0011: 标识符没说明",
"error 0012: 赋值语句中,赋值号左部标识符属性应是变量",
"error 0013: 赋值语句左部标识符应是赋值号:=",
"error 0014: call后应为标识符",
"error 0015: call后标识符属性应为过程",
"error 0016: 条件语句中丢了then",
"error 0017: 丢了end或;",
"error 0018: while型循环语句中丢了do",
"error 0019: 语句后的标识符不正确",
"error 0020: 应为关系运算符",
"error 0021: 表达式内标识符属性不能是过程",
"error 0022: 表达式中漏掉了右括号‘)’",
"error 0023: 因子后的非法符号",
"error 0024: 表达式开始符不能是此符号",
"error 0025: 文件在不该结束的地方结束了",
"error 0026: 结束符出现在不该结束的地方",
"error 0027: 无法识别的字符!",
"error 0028: 缺少'=',单独的':'不是运算符!",
"error 0029: 数的位数超过14位!",
"error 0030: 嵌套层数超过3层!",
"error 0031: 数越界,超过系统所允许的最大数",
"error 0032: read语句括号中标识符不是变量",
"error 0033: read后应为左括号!",
"error 0034: 标识符没声明或read语句括号中标识符不是变量!",
"error 0035: 标识符没声明或write语句括号中标识符不是变量!",
"error 0036: write后应为左括号!",
"error 0037: 分程序应以变量声明或语句开始!",
"error 0038: 分程序丢失结束符';'或'.'",
"error 0039: 分程序结束符应是';',不是'.'",
"error 0040: 表达式开始符不正确!",
"error 0041: 表达式后的标识符不正确",
"error 0042: 项后的标识符不正确",
"error 0043: 项的开始符不正确!",
"error 0043: 因子的开始符不正确!",
"error 0044: 条件的开始符不正确!",
"error 0045: 条件的结束符不正确!",
"error 0046: 分程序遗漏了结束符';'!",
"error 0047: 除数不能为零!"
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -