📄 parser.java
字号:
while (statbegsys.get(symtype) || symtype == Symbol.semicolon) {
if (symtype == Symbol.semicolon)
nextsym();
else
Err.report(10); // 缺少分号
statement(nxtlev, lev);
}
if (symtype == Symbol.endsym)
nextsym();
else
Err.report(17); // 缺少end或分号
}
/**
* 分析<条件语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseIfStatement(BitSet fsys, int lev) {
int cx1;
BitSet nxtlev;
nextsym();
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.thensym); // 后跟符号为then或do ???
nxtlev.set(Symbol.dosym);
condition(nxtlev, lev); // 分析<条件>
if (symtype == Symbol.thensym)
nextsym();
else
Err.report(16); // 缺少then
cx1 = interp.cx; // 保存当前指令地址
interp.gen(Instr.jpc, 0, 0); // 生成条件跳转指令,跳转地址未知,暂时写0
statement(fsys, lev); // 处理then后的语句
interp.code[cx1].a = interp.cx; // 经statement处理后,cx为then后语句执行
// 完的位置,它正是前面未定的跳转地址
}
/**
* 分析<过程调用语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseCallStatement(BitSet fsys, int lev) {
int i;
nextsym();
if (symtype == Symbol.ident) {
i = table.position(sym.id);
if (i == 0) {
Err.report(11); // 过程未找到
} else {
Table.Item item = table.get(i);
if (item.kind == Table.Item.procedur)
interp.gen(Instr.cal, lev - item.level, item.adr);
else
Err.report(15); // call后标识符应为过程
}
nextsym();
} else {
Err.report(14); // call后应为标识符
}
}
/**
* 分析<写语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseWriteStatement(BitSet fsys, int lev) {
BitSet nxtlev;
nextsym();
if (symtype == Symbol.lparen) {
do {
nextsym();
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.rparen);
nxtlev.set(Symbol.comma);
expression(nxtlev, lev);
interp.gen(Instr.opr, 0, 14);
} while (symtype == Symbol.comma);
if (symtype == Symbol.rparen)
nextsym();
else
Err.report(33); // write()中应为完整表达式
}
interp.gen(Instr.opr, 0, 15);
}
/**
* 分析<读语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseReadStatement(BitSet fsys, int lev) {
int i;
nextsym();
if (symtype == Symbol.lparen) {
do {
nextsym();
if (symtype == Symbol.ident)
i = table.position(sym.id);
else
i = 0;
if (i == 0) {
Err.report(35); // read()中应是声明过的变量名
} else {
Table.Item item = table.get(i);
if (item.kind == Table.Item.variable) {
Err.report(32); // read()中的标识符不是变量, thanks to amd
} else {
interp.gen(Instr.opr, 0, 16);
interp.gen(Instr.sto, lev-item.level, item.adr);
}
}
nextsym();
} while (symtype == Symbol.comma);
} else {
Err.report(34); // 格式错误,应是左括号
}
if (symtype == Symbol.rparen) {
nextsym();
} else {
Err.report(33); // 格式错误,应是右括号
while (!fsys.get(symtype))
nextsym();
}
}
/**
* 分析<赋值语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseAssignStatement(BitSet fsys, int lev) {
int i;
BitSet nxtlev;
i = table.position(sym.id);
if (i > 0) {
Table.Item item = table.get(i);
if (item.kind == Table.Item.variable) {
nextsym();
if (symtype == Symbol.becomes)
nextsym();
else
Err.report(13); // 没有检测到赋值符号
nxtlev = (BitSet) fsys.clone();
expression(nxtlev, lev);
// expression将执行一系列指令,但最终结果将会保存在栈顶,执行sto命令完成赋值
interp.gen(Instr.sto, lev - item.level, item.adr);
} else {
Err.report(12); // 赋值语句格式错误
}
} else {
Err.report(11); // 变量未找到
}
}
/**
* 分析<表达式>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void expression(BitSet fsys, int lev) {
int addop;
BitSet nxtlev;
// 分析[+|-]<项>
if (symtype == Symbol.plus || symtype == Symbol.minus) {
addop = symtype;
nextsym();
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.plus);
nxtlev.set(Symbol.minus);
term(nxtlev, lev);
if (addop == Symbol.minus)
interp.gen(Instr.opr, 0, 1);
} else {
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.plus);
nxtlev.set(Symbol.minus);
term(nxtlev, lev);
}
// 分析{<加法运算符><项>}
while (symtype == Symbol.plus || symtype == Symbol.minus) {
addop = symtype;
nextsym();
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.plus);
nxtlev.set(Symbol.minus);
term(nxtlev, lev);
if (addop == Symbol.plus)
interp.gen(Instr.opr, 0, 2);
else
interp.gen(Instr.opr, 0, 3);
}
}
/**
* 分析<项>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void term(BitSet fsys, int lev) {
int mulop;
BitSet nxtlev;
// 分析<因子>
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.times);
nxtlev.set(Symbol.slash);
factor(nxtlev, lev);
// 分析{<乘法运算符><因子>}
while (symtype == Symbol.times || symtype == Symbol.slash) {
mulop = symtype;
nextsym();
factor(nxtlev, lev);
if (mulop == Symbol.times)
interp.gen(Instr.opr, 0, 4);
else
interp.gen(Instr.opr, 0, 5);
}
}
/**
* 分析<因子>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void factor(BitSet fsys, int lev) {
BitSet nxtlev;
test(facbegsys, fsys, 24); // 检测因子的开始符号
// the original while... is problematic: var1(var2+var3)
// thanks to macross
// while(inset(sym, facbegsys))
if (facbegsys.get(symtype)) {
if (symtype == Symbol.ident) { // 因子为常量或变量
int i = table.position(sym.id);
if (i > 0) {
Table.Item item = table.get(i);
switch (item.kind) {
case Table.Item.constant: // 名字为常量
interp.gen(Instr.lit, 0, item.val);
break;
case Table.Item.variable: // 名字为变量
interp.gen(Instr.lod, lev - item.level, item.adr);
break;
case Table.Item.procedur: // 名字为过程
Err.report(21); // 不能为过程
break;
}
} else {
Err.report(11); // 标识符未声明
}
nextsym();
} else if (symtype == Symbol.number) { // 因子为数
int num = sym.num;
if (num > PL0.amax) {
Err.report(31);
num = 0;
}
interp.gen(Instr.lit, 0, num);
nextsym();
} else if (symtype == Symbol.lparen) { // 因子为表达式
nextsym();
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.rparen);
expression(nxtlev, lev);
if (symtype == Symbol.rparen)
nextsym();
else
Err.report(22); // 缺少右括号
} else {
// 做补救措施
test(fsys, facbegsys, 23);
}
}
}
/**
* 分析<条件>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void condition(BitSet fsys, int lev) {
int relop;
BitSet nxtlev;
if (symtype == Symbol.oddsym) {
// 分析 ODD<表达式>
nextsym();
expression(fsys, lev);
interp.gen(Instr.opr, 0, 6);
} else {
// 分析<表达式><关系运算符><表达式>
nxtlev = (BitSet) fsys.clone();
nxtlev.set(Symbol.eql);
nxtlev.set(Symbol.neq);
nxtlev.set(Symbol.lss);
nxtlev.set(Symbol.leq);
nxtlev.set(Symbol.gtr);
nxtlev.set(Symbol.geq);
expression(nxtlev, lev);
if (symtype == Symbol.eql || symtype == Symbol.neq
|| symtype == Symbol.lss || symtype == Symbol.leq
|| symtype == Symbol.gtr || symtype == Symbol.geq) {
relop = symtype;
nextsym();
expression(fsys, lev);
switch (relop) {
case Symbol.eql:
interp.gen(Instr.opr, 0, 8);
break;
case Symbol.neq:
interp.gen(Instr.opr, 0, 9);
break;
case Symbol.lss:
interp.gen(Instr.opr, 0, 10);
break;
case Symbol.geq:
interp.gen(Instr.opr, 0, 11);
break;
case Symbol.gtr:
interp.gen(Instr.opr, 0, 12);
break;
case Symbol.leq:
interp.gen(Instr.opr, 0, 13);
break;
}
} else {
Err.report(20);
}
}
}
void debug(String msg) {
System.out.println("*** debug : " + msg);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -