📄 grammer.java
字号:
//首先得给begin配个;吧!
if(!this.get_word())
return false;
if(!current_word.name.equals(";"))
{
return false;
}
else
{
if(!this.get_word())
return false;
}
while(!current_word.name.equals("end"))
{
if(!inner_code())
{
return false;
}
else
{
if(!this.get_word())
return false;
}
}
//->end
if(!current_word.name.equals("end"))
{
return false;
}
else
{
//一个while-do定义结束!
if(!this.get_word())
return false;
//回跳
int jmpback_addr=Glb.S_Unconfirm_do.pop();
Glb.ObjCode.addElement(new Injunction(InType.JMP,0,jmpback_addr));
//地址回填
int back_pos=Glb.S_Unconfirm_JPC.pop();
((Injunction)Glb.ObjCode.elementAt(back_pos)).A2=Glb.ObjCode.size();
}
//->";"
if(!current_word.name.equals(";"))
{
return false;
}
else
{}
}
else
{
//一句话形式
if(!inner_code())
{
return false;
}
else
{}
//一共就一句话,现在已经读完了
//回跳
int jmpback_addr=Glb.S_Unconfirm_do.pop();
Glb.ObjCode.addElement(new Injunction(InType.JMP,0,jmpback_addr));
//地址回填
int back_pos=Glb.S_Unconfirm_JPC.pop();
((Injunction)Glb.ObjCode.elementAt(back_pos)).A2=Glb.ObjCode.size();
//->";"
if(!current_word.name.equals(";"))
{
return false;
}
else
{}
}
}
return true;
}
boolean bool_exp()
{
String op="";
//!!调用此方法前不要预先读单词
if(!this.get_word())
return false;
if(current_word.name.equals("odd"))
{
//翻译odd语句构成的布尔表达式
//现在输入已经是odd了,只要判断下一个输入是不是一个变量或常量就可以了
if(!this.get_word())
return false;
if(!Glb.ID_defined(current_word))
{
if(current_word.type==WordType.ID)
return false;
}
else
{
//现在的输入是一个ID,要对他做odd操作
WordInfo from_table;
from_table=Glb.word_in_table(current_word);
Glb.ObjCode.addElement(new Injunction(InType.LOD,from_table.lever,from_table.addr));
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,6));
//读下一个单词
if(!this.get_word())
return false;
}
}
else
{
//翻译[表达式][运算符][表达式]形的布尔表达式
//算术表达式一
if(!math_exp())
return false;
//关系运算符
if(!Glb.is_a_rla_op(current_word))
{
return false;
}
else
{
op=current_word.name;
if(!this.get_word())
return false;
}
//算术表达式二
if(!math_exp())
return false;
//接着添加opr语句
{
if(op.equals("="))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,8));
if(op.equals("#"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,9 ));
if(op.equals("<"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,10));
if(op.equals(">="))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,11));
if(op.equals(">"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,12));
if(op.equals("<="))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,13));
}
}
return true;
}
boolean math_exp()
{
//进入一个表达式的描述
//现在的输入字符应该是表达式的第一个字符
//应该首先取得数字-标志符-运算符序列再说别的
//用来存储数学表达式的向量
Vector exp=new Vector();
//exp的逆波兰表示方式
Vector nbl=new Vector();
//取得数学表达式
for(;;)
{
if(Glb.can_in_mathexp(current_word))
{
exp.addElement(current_word);
if(!this.get_word())
return false;
}
else
{
if(!current_word.name.equals(";")&&!Glb.is_a_rla_op(current_word)&&!current_word.name.equals("then")&&!current_word.name.equals("do"))
{
return false;
}
else
{
//表达式输入正常结束
break;
}
}
}
if(exp.size()==0)
{
return false;
}
nbl=this.to_nbl(exp);
if(nbl==Glb.nbl_err)
return false;
//手里哆哆嗦嗦地那着这个来之不易的逆波兰表达式,心想,终于可以进行翻译了!!!!~~^_^~~
//开始翻译!!
int length=nbl.size();
WordInfo w_nbl;
for(int i=0;i<length;i++)
{
w_nbl=((WordInfo)nbl.elementAt(i));
if(w_nbl.type==WordType.NUM)
Glb.ObjCode.addElement(new Injunction(InType.LIT,0,w_nbl.val));
if(w_nbl.type==WordType.VAEIABLE||w_nbl.type==WordType.CONSTANT)
Glb.ObjCode.addElement(new Injunction(InType.LOD,w_nbl.lever,w_nbl.addr));
if(w_nbl.name.equals("+"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,2));
if(w_nbl.name.equals("-"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,3));
if(w_nbl.name.equals("*"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,4));
if(w_nbl.name.equals("/"))
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,5));
}
return true;
}
boolean write()
{
//要打印的变量
WordInfo tobe_write;
//这个比较简单
//只要能检测到一个 write ( <var><const>,<var><const>…… ) ;的序列,就可以添加write语句了
//现在已经有输入write了,下一步要判断输入的是不是“(”
if(!this.get_word())
return false;
if(!current_word.name.equals("("))
{
return false;
}
else
{
if(!this.get_word())
return false;
}
//变量序列
for(;;)
{
if(!Glb.ID_defined(current_word))
{
return false;
}
else
{
//识别到一个合法的变量,可以对它进行打印了
tobe_write=Glb.word_in_table(current_word);
Glb.ObjCode.addElement(new Injunction(InType.OPR,tobe_write.addr,14));
if(!this.get_word())
return false;
}
//要么结束();),要么以“,”为标志继续下一个变量的输入
if(!current_word.name.equals(")"))
{
if(!current_word.name.equals(","))
{
return false;
}
else
{
//下一个变量
if(!this.get_word())
return false;
continue;
}
}
else
{
//->";"
if(!this.get_word())
return false;
if(!current_word.name.equals(";"))
{
return false;
}
else
{
Glb.ObjCode.addElement(new Injunction(InType.OPR,0,15));
break;
}
}
}
return true;
}
boolean read()
{
//要输入的变量
WordInfo tobe_read;
//这个比较简单
//只要能检测到一个 read ( var ) ;的序列,就可以添加read语句了
//现在已经有输入read了,下一步要判断输入的是不是“(”
if(!this.get_word())
return false;
if(!current_word.name.equals("("))
{
return false;
}
else
{
if(!this.get_word())
return false;
}
//变量序列
for(;;)
{
if(!Glb.is_var(current_word))
{
return false;
}
else
{
//识别到一个合法的变量,可以对它进行输入了
tobe_read=Glb.word_in_table(current_word);
Glb.ObjCode.addElement(new Injunction(InType.OPR,tobe_read.addr,16));
if(!this.get_word())
return false;
}
//要么结束();),要么以“,”为标志继续下一个变量的输入
if(!current_word.name.equals(")"))
{
if(!current_word.name.equals(","))
{
return false;
}
else
{
//下一个变量
if(!this.get_word())
return false;
continue;
}
}
else
{
//->";"
if(!this.get_word())
return false;
if(!current_word.name.equals(";"))
{
return false;
}
else
{
break;
}
}
}
return true;
}
boolean call()
{
WordInfo w;
//这个方法巨简单
//只要call [procedure name] ;就可以了
//现在的输入已经是call了
//现在要求输入一个过程名
if(!this.get_word())
return false;
if(!Glb.ID_samename(current_word))
{
return false;
}
else
{
//表里有名字,那么,他是过程名吗?
w=Glb.word_in_table(current_word);
if(w.type!=WordType.PROCEDURE)
{
return false;
}
//过程的入口定义了吗?
if(w.addr<2)
{
return false;
}
else
{
//好了,可以添加指令了
Glb.ObjCode.addElement(new Injunction(InType.CAL,0,w.addr));
}
}
//->";"
if(!this.get_word())
return false;
if(!current_word.name.equals(";"))
{
return false;
}
return true;
}
void Message(String err_text)
{
MessageBox.show(err_text);
}
boolean get_word()
{
current_word=worder.get_a_word();
if(current_word==Glb.word_err)
{
return false;
}
else
return true;
}
//算术表达式转逆波兰表达式,输入是一个只含有数字,变量,常量和运算符(含括号)的序列
public Vector to_nbl(Vector exp)
{
Vector nbl=new Vector();
Stack sign=new Stack();
WordInfo w;
//错误检查标志
boolean num_sign=false;
boolean left_bracket=false;
int length=exp.size();
for(int i=0;i<length;i++)
{
w=(WordInfo)exp.elementAt(i);
if(!w.name.equals(")"))
left_bracket=false;
if(w.type==WordType.NUM)
{
if(num_sign)
{
return Glb.nbl_err;
}
num_sign=true;
nbl.addElement(w);
continue;
}
if(w.type==WordType.ID)
{
if(num_sign)
{
return Glb.nbl_err;
}
num_sign=true;
nbl.addElement(Glb.word_in_table(w));
continue;
}
//符号
if(w.type==WordType.SIGN)
{
if(w.name.equals("+")||w.name.equals("-")||w.name.equals("*")||w.name.equals("/"))
{
if(!num_sign)
{
return Glb.nbl_err;
}
num_sign=false;
}
//符号栈为空,直接将符号压入符号栈
if(sign.isEmpty())
{
sign.push(w);
continue;
}
//栈非空,需要做一些判断了
else
{
//左括号直接进栈
if(w.name.equals("("))
{
left_bracket=true;
sign.push(w);
continue;
}
//右括号,则将前面所有的符号拿出来进逆波兰串
if(w.name.equals(")"))
{
if(left_bracket)
{
return Glb.nbl_err;
}
else
left_bracket=false;
try
{
while(!((WordInfo)sign.peek()).name.equals("("))
{
nbl.addElement(sign.pop());
}
}
catch(EmptyStackException e)
{
return Glb.nbl_err;
}
//把“(”弹出来
sign.pop();
}
//若当前符号的优先级高于sign中栈顶符号的优先级,则进栈
if (
sign_pro(w.name)
>
sign_pro(
((WordInfo)sign.peek()).name
)
)
{
sign.push(w);
continue;
}
//!!当前输入符号的优先级不如sign中的栈顶符号优先级高
//麻烦了,前面的符号要拿出来进逆波兰串了
else
{
if(!w.name.equals(")"))
{
nbl.addElement(sign.pop());
sign.push(w);
continue;
}
}
}
}
}
//exp串扫描完了,现在把sign里剩下符号全都加到nbl中
while(!sign.isEmpty())
{
if( ((WordInfo)sign.peek()).name.equals("(") )
{
return Glb.nbl_err;
}
nbl.addElement(sign.pop());
}
return nbl;
}
public int sign_pro(String sign)
{
if(sign.equals("("))
return -1;
else
if(sign.equals(")"))
return -1;
else
if(sign.equals("+"))
return 1;
else
if(sign.equals("-"))
return 1;
else
if(sign.equals("*"))
return 2;
else
if(sign.equals("/"))
return 2;
else
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -