修改的部分:
1、原本只有 if-then 改成 if-then-else
2、增加for循环
3、增加break
4、增加了一些运算【*= /= += -= ++ -- 】和 将不等号 # 改成 <>
需要增加的关键字有:【在Symbol枚举类中增加】
elsesym,forsym,returnsym,breaksym, tosym,downtosym, stepsym,untilsym,
//增加的运算符 *=,/=,+=,-=,++,--
timeseq,slasheq,pluseq,minuseq,doubleplus,doubleminus,
一、增加else ---->> if -then-else
1、在Scanner类中的String[] word 中按照字典顺序加入else【因为使用的是折半查找法】
word = new String[] {"begin","break", "call", "const", "do","downto", "else","end", "for","if",
"odd", "procedure", "read","return", "step","then","to","until", "var", "while", "write"
};
Symbol[] wsym中按照word数组中的else顺序加入elsesym
wsym[6] = Symbol.elsesym;
2、在Parser类中修改parseIfStatement方法
/**
* 分析<条件语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseIfStatement(SymSet fsys, int lev) {
int cx1;
SymSet nxtlev;
nextSym();
nxtlev = (SymSet) fsys.clone();
nxtlev.set(Symbol.thensym); // 后跟符号为then或do ???
nxtlev.set(Symbol.dosym);
parseCondition(nxtlev, lev); // 分析<条件>
if (sym == Symbol.thensym)
nextSym();
else
Err.report(16); // 缺少then
cx1 = interp.cx; // 保存当前指令地址
interp.gen(Fct.JPC, 0, 0); // 生成条件跳转指令,跳转地址未知,暂时写0
parseStatement(fsys, lev); // 处理then后的语句
//TODO...以下是增加的else
/* then 语句对应的是JPC指令----->应该跳转到JMP【else】指令的后面
* 如果存在else语句,应该先创建else对应的JMP
* */
if(sym==Symbol.elsesym){
nextSym();
int cx2=interp.cx;
interp.gen(Fct.JMP, 0, 0);//经statement处理后,cx为then后语句执行
// 完的位置,它正是前面未定的跳转地址
interp.code[cx1].a = interp.cx;
parseStatement(fsys, lev);//处理else之后的语句 会改变interp.cx的值
interp.code[cx2].a = interp.cx;
}else {
interp.code[cx1].a = interp.cx;// 经statement处理后,cx为then后语句执行
// 完的位置,它正是前面未定的跳转地址
}
}
二、增加for循环【两种for循环】
第一种: FOR <变量>:=<表达式>STEP<表达式> UNTIL<表达式>DO<语句>
1、word = new String[] {"begin","break", "call", "const", "do","downto", "else","end", "for","if", "odd", "procedure", "read","return", "step","then","to","until", "var", "while", "write" };
Symbol[] wsym中按照word数组中的else顺序加入elsesym
wsym[6] = Symbol.elsesym;
2、在Parser中创建新的方法
private void parseForStatement(SymSet fsys,int lev)
/**FOR <变量>:=<表达式>STEP<表达式> UNTIL<表达式>Do<语句>
* 分析<for循环语句>
* @param fsys 后跟符号集
* @param lev 当前层次
*/
private void parseForStatement(SymSet fsys,int lev) {
//关键字break 压进一个栈 ,代表一个循环体, indexStack这个数值代表这个循环体
circulationStack.push(indexStack++);
int cx1,cx2;//cx1保存判断条件的位置,