⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grammer.java

📁 用java写的一段PL0编译程序.用户可以在文本框内输入一段PL0代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
					//首先得给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 + -