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

📄 yufaanalyse.java

📁 tiger编译器的驱动程序的描述 tiger编译器的驱动程序的描述
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

				while (word.getSym().equals("comma"))// 循环得到read语句的参数,直到该参数后不是逗号为止
				{
					word = CiFa.GetToken();
					if (word.getSym().equals("ident")) {
						i = position(word.getNam());
						if (i == -1) {
							errorNumber++;
							new erro(word.getLineNum(), 11);
						} else {
							pcodeArray.addElement(new pcode("opr", 0, 16));
							pcodeArray.addElement(new pcode("sto", lev
									- ((nameClass) nameArray.get(i)).getLev(),
									((nameClass) nameArray.get(i)).getAdr()));
						}
					}
					word = CiFa.GetToken();
				}
				if (!word.getSym().equals("rparen")) {
					errorNumber++;
					new erro(word.getLineNum(), 9);
				}// 如果不是预想的右括号,抛出9号错误
			} else {
				errorNumber++;
				new erro(word.getLineNum(), 0);
			}// 如果不是左括号,抛出0号错误
			word = CiFa.GetToken();
		} else if (word.getSym().equals("writesym")) {
			word = CiFa.GetToken();
			if (word.getSym().equals("lparen")) {
				word = CiFa.GetToken();
				expression();
				pcodeArray.addElement(new pcode("opr", 0, 14));
				while (word.getSym().equals("comma")) {
					word = CiFa.GetToken();
					expression();
					pcodeArray.addElement(new pcode("opr", 0, 14));
				}

				if (!word.getSym().equals("rparen")) {
					errorNumber++;
					new erro(word.getLineNum(), 9);
				} else {
					word = CiFa.GetToken();
				}
			}
			pcodeArray.addElement(new pcode("opr", 0, 15));
		}
	}

	public void condition() // 条件分析;
	{
		String relop = null;
		if (word.getSym().equals("oddsym")) // 如果是一元运算符
		{
			word = CiFa.GetToken();
			expression();// 对一元运算的表达式进行分析
			pcodeArray.addElement(new pcode("opr", 0, 6));// 生成奇偶判断指令
		} else // 不是一元运算符则是2元运算符
		{
			expression();// 对左边的表达式进行分析
			relop = word.getSym();// 把2元运算符保存起来
			word = CiFa.GetToken();
			expression();// 对右边的表达式进行分析 然后根据刚才保存的运算符,生成相应判断指令
			if (relop.equals("eql")) {
				pcodeArray.addElement(new pcode("opr", 0, 8));
			} else if (relop.equals("neq")) {
				pcodeArray.addElement(new pcode("opr", 0, 9));
			} else if (relop.equals("lss")) {
				pcodeArray.addElement(new pcode("opr", 0, 10));
			} else if (relop.equals("geq")) {
				pcodeArray.addElement(new pcode("opr", 0, 11));
			} else if (relop.equals("gtr")) {
				pcodeArray.addElement(new pcode("opr", 0, 12));
			} else if (relop.equals("leg")) {
				pcodeArray.addElement(new pcode("opr", 0, 13));
			} else {
				System.out.println(word.getNam() + "   " + relop);
				errorNumber++;
				new erro(word.getLineNum(), 20);
			}// 如果刚才保存的不是逻辑运算符,则抛出20号错误
		}
	}// 条件分析完毕

	public void expression() // 表达式的处理
	{
		String addop = null; // 保存表达式开头的符号 用于表示正负
		if (word.getSym().equals("plus") || word.getSym().equals("minus")) {
			addop = word.getSym();// 把正负号保存在string类型的addop中,继续读取一个token,正常应该为表达式的一个项
			word = CiFa.GetToken();
			term();// 进行项的分析
			if (addop.equals("minus")) // 如果保存下来的是个负号,则生成一条1号指令,取反运算
			{
				pcodeArray.addElement(new pcode("opr", 0, 1));
			}
		} else // 如果不是正负号开头,就应该是一个表达式的项开头,直接进行项的分析
		{
			term();
		}
		while (word.getSym().equals("plus") || word.getSym().equals("minus"))// 项后应该应该是加运算或者减法运算
		{
			addop = word.getSym();// 把运算符保存在addop中
			word = CiFa.GetToken();
			term();// 分析项
			if (addop.equals("plus")) // 项分析完毕后,如果刚才保存的是加号,则生成加法指令
			{
				pcodeArray.addElement(new pcode("opr", 0, 2));
			} else // 否则生成减法指令
			{
				pcodeArray.addElement(new pcode("opr", 0, 3));
			}
		}

	}// 表达式分析完毕

	public void term()// 项的处理
	{
		String mulop = null;
		factor();// 每个项都是由一个因子开头,所以直接调用因子分析方法
		while (word.getSym().equals("times") || word.getSym().equals("slash"))// 因子后应该遇到乘号或是除号
		{
			mulop = word.getSym(); // 把运算符保存在mulop中(乘法或是除法)
			word = CiFa.GetToken();
			factor();// 运算符后应该是一个因子,进行因子分析
			if (mulop.equals("times")) // 如果刚才保存的运算符为乘号则生成opr 4号乘法指令,
			{
				pcodeArray.addElement(new pcode("opr", 0, 4));
			} else // 如果刚才保存的不是乘号,则生成除法运算指令
			{
				pcodeArray.addElement(new pcode("opr", 0, 5));
			}
		}
	}// 项分析完毕

	public void factor() // 因子的分析处理;
	{
		int i;
		while (word.getSym().equals("ident") || word.getSym().equals("number")
				|| word.getSym().equals("lqaren"))// 循环处理因子
		{
			if (word.getSym().equals("ident"))// 如果遇到的是标识符,则查符号表
			{
				i = position(word.getNam());
				if (i == -1) // 如果查符号表后返回负值,则表示没有找到,抛出11号错误
				{
					errorNumber++;
					new erro(word.getLineNum(), 11);
				}
				// 如果返回的不是负值,则表示在符号表中的找到了该标识符,getKind返回该标识符的类型
				else if (((nameClass) nameArray.get(i)).getKind().equals(
						"constant"))
				// 如果该标识符为常量,则生成lit指令,把val放到栈顶
				{
					pcodeArray.addElement(new pcode("lit", 0,
							((nameClass) nameArray.get(i)).getVal()));
					word = CiFa.GetToken();
				} else if (((nameClass) nameArray.get(i)).getKind().equals(
						"variable")) { // 如果该标识符为变量,则生成lod指令,把变量放到栈顶
					pcodeArray.addElement(new pcode("lod", lev
							- ((nameClass) nameArray.get(i)).getLev(),
							((nameClass) nameArray.get(i)).getAdr()));
					word = CiFa.GetToken();
				} else if (((nameClass) nameArray.get(i)).getKind().equals(
						"procedure")) {// 如果该标识符为过程名,出错,抛出21号错误
					errorNumber++;
					new erro(word.getLineNum(), 21);
					word = CiFa.GetToken();
				}
			} else if (word.getSym().equals("number"))// 如果因子分析时遇到的为数字
			{
				int num = Integer.parseInt(word.getNam());
				if (num > 2047)// 判断数字大小超过允许最大值amax
				{
					errorNumber++;
					new erro(word.getLineNum(), 7);// 如果数字越界,则抛出7号错误,并把数字按0处理;
					num = 0;
				}
				pcodeArray.addElement(new pcode("lit", 0, num));// 生成lit指令,把这个数值字面常量放到栈顶
				word = CiFa.GetToken();
			} else if (word.getSym().equals("lqaren"))// 如果因子分析遇到的为左括号
			{
				word = CiFa.GetToken();// 继续读取一个token
				expression(); // 递归调用表达式分析
				if (word.getSym().equals("rqaren"))// 表达式分析完后,应该遇到右括号
				{
					word = CiFa.GetToken();
				} else {
					errorNumber++;
					new erro(word.getLineNum(), 22);
				}// 如果表达式分析完后,没有遇到右括号,则抛出22号错误
			}
		}
	} // 因子分析完毕

	public void printName() // 这段代码没用,仅仅是用来查看符号表内容的
	{
		for (int t = 0; t < nameArray.size(); t++)// 测试用
		{
			nameClass name = (nameClass) nameArray.get(t);
			System.out.println("符号表内容NAME " + name.getNam() + "  KIND "
					+ name.getKind() + "  VAL " + name.getVal() + "  LEVL "
					+ name.getLev() + "  ADR " + name.getAdr());
		}
	}

	public int base(int l) // 用来寻找各段基址的方法
	{
		int b1;
		b1 = b;
		while (l > 0) {
			b1 = s[b1];
			l--;
		}
		return b1;
	}

	public void interpret() {  //解释器,用于执行pcode代码
		s[1] = 0;
		s[2] = 0;
		// s[3]=0;
		System.out.println("start pl/0");
		do {
			i = (pcode) pcodeArray.get(p);
			p++;
			if (i.getF().equals("lit")) {
				t++;
				s[t] = i.getA();
			} else if (i.getF().equals("opr")) {
				if (i.getA() == 0) {
					t = b - 1;
					p = s[t + 3];
					b = s[t + 2];
				} else if (i.getA() == 1)// 返回指令
				{
					s[t] = -s[t];
				} else if (i.getA() == 2)// 加法操作
				{
					t--;
					s[t] = s[t] + s[t + 1];
				} else if (i.getA() == 3)// 3号减法操作
				{
					t--;
					s[t] = s[t] - s[t + 1];
				} else if (i.getA() == 4)// 4号乘法操作
				{
					t--;
					s[t] = s[t] * s[t + 1];
				} else if (i.getA() == 5)// 5号除法操作
				{
					t--;
					s[t] = s[t] / s[t + 1];
				} else if (i.getA() == 6)// 6号判断奇数操作
				{
					if (s[t] % 2 == 0)
						s[t] = 0;
					else
						s[t] = 1;
				} else if (i.getA() == 8)// 8号判等操作
				{
					t--;
					if (s[t] == s[t + 1])
						s[t] = 1;
					else
						s[t] = 0;
				} else if (i.getA() == 9)// 9号判断不等操作
				{
					t--;
					if (s[t] == s[t + 1])
						s[t] = 0;
					else
						s[t] = 1;
				} else if (i.getA() == 10)// 10号判断小于操作
				{
					t--;
					if (s[t] < s[t + 1])
						s[t] = 1;
					else
						s[t] = 0;
				} else if (i.getA() == 11)// 11号判断大于等于操作
				{
					t--;
					if (s[t] >= s[t + 1])
						s[t] = 1;
					else
						s[t] = 0;
				} else if (i.getA() == 12)// 12号判断大于操作
				{
					t--;
					if (s[t] > s[t + 1])
						s[t] = 1;
					else
						s[t] = 0;
				} else if (i.getA() == 13)// 13号判断小于等于操作
				{
					t--;
					if (s[t] <= s[t + 1])
						s[t] = 1;
					else
						s[t] = 0;
				} else if (i.getA() == 14)// 14号输出栈顶值操作
				{
					System.out.println(s[t]);
					t--;
				} else if (i.getA() == 15)// 15号输出换行操作
				{
					System.out.println();
				} else if (i.getA() == 16)// 16号接受键盘输入值到栈顶操作
				{
					System.out.println("请输入数字(0是退出):");
					int age;
					try {
						InputStreamReader fin = new InputStreamReader(System.in);
						BufferedReader br = new BufferedReader(fin);
						String name = br.readLine();
						age = Integer.parseInt(name);
					} catch (Exception e) {
						age = 0;
					}
					t++;
					s[t] = age;
				}

			} else if (i.getF().equals("lod")) {
				t++;
				s[t] = s[base(i.getL()) + i.getA()];
			} else if (i.getF().equals("sto")) {
				s[base(i.getL()) + i.getA()] = s[t];
				t--;
			} else if (i.getF().equals("cal")) {
				s[t + 1] = base(i.getL());
				s[t + 2] = b;
				s[t + 3] = p;
				b = t + 1;
				p = i.getA();
			} else if (i.getF().equals("int")) {
				t = t + i.getA();
			} else if (i.getF().equals("jmp")) {
				p = i.getA();
			} else if (i.getF().equals("jpc")) {
				if (s[t] == 0)
					p = i.getA();
				t--;
			} else if (i.getF().equals("wrt")) {
				System.out.println(s[t]);
				t--;
			}
		} while (p != 0);
		System.out.println("end pl/0");
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -