编译原理 语法制导的翻译过程(L属性的翻译方案)实现带括号的整数加减乘除四则运算 JAVA实现

 

编译技术第6次上机内容

 

算术表达式的扩充

1. 实验目的

充分理解语义分析的方法及相关语义计算的执行时机。

掌握LR分析表的设计方法和语义加工程序的扩充。

2. 实验要求

参照算术表达式LR分析表的设计方法,设计扩充后的算术表达式LR分析表,并对原语义加工程序进行修改,加入新添加的内容。写一段程序,打印出计算结果E。

3. 实验内容

假设有以下文法:

L->En

E->E+T

E->E-T

E->T

T->T*F

T->T/F

T->F

F->(E)

F->id

设该文法进行自下而上计算时,打印出四则运算的计算结果。

E、T、F这些非终结符需要综合属性。以L属性的翻译方案为基础,将下表的语义规则嵌套在语法分析的过程中,即实现语法制导的翻译过程。

 

产  生  式 

语  义  规  则 

L®En

{print(E.val)}

E®E1+T

{ E.val=E1.val+T.val}

E®E1-T

{ E.val=E1.val-T.val}

E®T

{ E.val= T.val}

T®T1*F

{ T.val=T1.val*F.val}

T®T1/F

{ T.val=T1.val/F.val}

T®F

{ T.val= F.val}

F®(E)

{ F.val=E.val}

F®id

{ F.val=id.lexval}

 

 

 

2.以词法分析和语法分析部分的上机结果为基础,添加语义分析部分。即以LR文法为基础。当进行产生式归约时执行对应的语义动作。

 

3.输入:

5+3+8*2

输出:24

 

输入10-6/2

输出:7

 

 

4. 若输入有误,如:3++2

则应提示:重新输入!

 

5. 由于输入串是具体的数值,因此应调用相应的词法分析的功能。

 

扩展:

  1. 对浮点数和科学计数法的表示也能完成上述的操作。
  2. 增加减法和除法(也可继续扩展其他运算)对应的产生式,并能计算其语义结果。
  3. 在ftp中第五次上机的文件夹中有两个压缩包,用递归下降法实现的程序在压缩包“recursion_calculator.rar”中,用非递归的预测分析方法实现的程序在压缩包“predict_calculator.rar”中。可以任选其一作为基础进行改进,增加减法和除法的操作,写出改进后的文法,输出表达式的结果。
import java.util.Scanner;
import java.util.Stack;

//E->E+T	1
//E->E-T	2
//E->T		3
//T->T*F	4
//T->T/F	5
//T->F		6
//F->(E)	7
//F->id		8
public class Main {

	private static boolean guiyuefou = false;
	private static String Str = null; // 输入串
	private static String Sub = null;
	private static boolean acc = false;// 是否已处理完输入串
	private static boolean bResult = false;// 是否出错
	private static int lookahead = 0;// 当前字符
	private static int[] yylex = new int[20];
	private static int yyval = 0;
	private static int flag = 0;// 计数
	private static int[][] Goto = new int[][] { { 1, 3, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 7, 3, 9 },
			{ 0, 0, 0 }, { 0, 3, 12 }, { 0, 0, 0 }, { 0, 15, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0, 0 },
			{ 0, 14, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; // Goto表
	private static Stack stack1 = new Stack();
	private static Stack stack = new Stack();// 栈
	// 这是一段记号的定义
	public static int ADD = 0; // +
	public static int MUL = 1; // *
	public static int SUB = 2; // -
	public static int DIV = 3; // \
	public static int LBRACE = 4; // (
	public static int RBRACE = 5; // )
	public static int NUM = 6; // number
	public static int END = 7; // #
	public static int OTHER = 8; // other

	public static int nextToken() {
		int i = 0;
		int y = 0;
		while (Sub.charAt(i) == ' ')
			i++;
		y = i;
		while (Sub.charAt(y) >= '0' && Sub.charAt(y) <= '9') {
			y++;
		}
		if (y != i) {
			yylex[flag++] = Integer.parseInt(Sub.substring(i, y));

			Sub = Sub.substring(y, Sub.length());
			return NUM;
		} else {
			switch (Sub.charAt(i)) {
			case '+':
				Sub = Sub.substring(1, Sub.length());
				return ADD;
			case '-':
				Sub = Sub.substring(1, Sub.length());
				return SUB;
			case '*':
				Sub = Sub.substring(1, Sub.length());
				return MUL;
			case '/':
				Sub = Sub.substring(1, Sub.length());
				return DIV;
			case '#':
				Sub = Sub.substring(1, Sub.length());
				return END;
			case '(':
				Sub = Sub.substring(1, Sub.length());
				return LBRACE;
			case ')':
				Sub = Sub.substring(1, Sub.length());
				return RBRACE;
			default:
				Sub = Sub.substring(1, Sub.length());
				return OTHER;
			}
		}

	}

	public static void Gto(int state, char fzjf) {
		int i = -1;
		if (fzjf == 'E')
			i = 0;
		if (fzjf == 'F')
			i = 1;
		if (fzjf == 'T')
			i = 2;

		stack.push(fzjf + "");
		stack.push(Goto[state][i] + "");

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("请输入串:");
		Scanner in = new Scanner(System.in);
		Str = in.nextLine();
		Sub = Str;
		in.close();

		// 0状态先进栈
		stack.push(String.valueOf(0));
		int i = 0;
		while (!bResult && acc == false) {
			if (!guiyuefou) {
				lookahead = nextToken();
			}
			if (lookahead == NUM) {
				yyval = yylex[i++];
			}
			switch (stack.peek().charAt(0)) {
			case '0':
				if (lookahead == NUM) {
					stack.push("id");
					stack.push("" + 5);
					guiyuefou = false;

				} else if (lookahead == LBRACE) {
					stack.push("(");
					stack.push("" + 4);
					guiyuefou = false;

				} else {
					System.out.println("error!");
					bResult = true;
				}
				break;
			case '1':
				if ("1".equals(stack.peek())) {
					if (lookahead == ADD) {
						stack.push("+");
						stack.push("" + 6);
						guiyuefou = false;
					} else if (lookahead == SUB) {
						stack.push("-");
						stack.push("" + 16);
						guiyuefou = false;
					} else if (lookahead == END) {
						acc = true;
						System.out.println("接受!");
					} else {
						System.out.println("error!");
						bResult = true;
					}
					break;
				} else if (stack.peek().charAt(1) == '0') {
					if (lookahead == RBRACE) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');

					} else if (lookahead == END) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					} else if (lookahead == ADD) {
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					} else if (lookahead == SUB) {
						stack.pop();
						stack.pop();
						guiyuefou = true;

						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					} else if (lookahead == DIV) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					} else if (lookahead == MUL) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					} else {
						System.out.println("error");
						bResult = true;
					}
					break;
				} else if (stack.peek().charAt(1) == '2') {
					if (lookahead == RBRACE) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x + y;
						stack1.push(z);
					} else if (lookahead == END) {
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x + y;
						stack1.push(z);
					} else if (lookahead == ADD) {
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x + y;
						stack1.push(z);
					} else if (lookahead == SUB) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x + y;
						stack1.push(z);
					} else if (lookahead == DIV) {
						stack.push("/");
						stack.push(13 + "");
						guiyuefou = false;
					} else if (lookahead == MUL) {
						stack.push("*");
						stack.push("" + 8);
						guiyuefou = false;

					} else {
						System.out.println("error");
						bResult = true;
					}
					break;
				} else if (stack.peek().charAt(1) == '3') {
					if (lookahead == NUM) {
						stack.push("id");
						stack.push("" + 5);
						guiyuefou = false;
					} else if (lookahead == LBRACE) {
						stack.push(")");
						guiyuefou = false;
						stack.push("" + 4);
					} else {
						System.out.println("error");
						bResult = true;
					}
				} else if (stack.peek().charAt(1) == '4') {
					if (lookahead == RBRACE) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else if (lookahead == END) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else if (lookahead == ADD) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else if (lookahead == SUB) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else if (lookahead == DIV) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else if (lookahead == MUL) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x / y;
						stack1.push(z);
					} else {
						System.out.println("error");
						bResult = true;
					}
					break;
				} else if (stack.peek().charAt(1) == '5') {
					if (lookahead == RBRACE) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else if (lookahead == END) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else if (lookahead == ADD) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else if (lookahead == SUB) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else if (lookahead == DIV) {
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else if (lookahead == MUL) {
						stack.pop();
						stack.pop();
						guiyuefou = true;
						stack.pop();
						stack.pop();
						stack.pop();
						stack.pop();
						Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
						int y = stack1.pop().intValue();
						int x = stack1.pop().intValue();
						int z = x * y;
						stack1.push(z);
					} else {
						System.out.println("error");
						bResult = true;
					}
					break;
				}
			case '2':
				if (lookahead == MUL) {
					stack.push("*");
					stack.push("" + 8);
					guiyuefou = false;
				} else if (lookahead == RBRACE) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == END) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == ADD) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == SUB) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == DIV) {
					stack.push("/");
					stack.push(13 + "");
					guiyuefou = false;
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '3':
				if (lookahead == END) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else if (lookahead == ADD) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else if (lookahead == SUB) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else if (lookahead == DIV) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else if (lookahead == RBRACE) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else if (lookahead == MUL) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'T');
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '4':
				if (lookahead == NUM) {
					stack.push("id");
					stack.push("" + 5);
					guiyuefou = false;
				} else if (lookahead == LBRACE) {
					stack.push("(");
					stack.push("" + 4);
					guiyuefou = false;
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '5':
				if (lookahead == RBRACE) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else if (lookahead == END) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else if (lookahead == ADD) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else if (lookahead == SUB) {
					stack.pop();
					guiyuefou = true;
					stack.pop();
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else if (lookahead == DIV) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else if (lookahead == MUL) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'F');
					stack1.push(yyval);
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '6':
				if (lookahead == NUM) {
					stack.push("id");
					stack.push("" + 5);
					guiyuefou = false;
				} else if (lookahead == LBRACE) {
					stack.push("(");
					stack.push("" + 4);
					guiyuefou = false;
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '7':
				if (lookahead == RBRACE) {
					stack.push(")");
					stack.push("" + 10);
					guiyuefou = false;
				} else if (lookahead == ADD) {
					stack.push("+");
					guiyuefou = false;
					stack.push("" + 6);
				} else if (lookahead == SUB) {
					stack.push("-");
					stack.push("" + 16);
					guiyuefou = false;
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '8':
				if (lookahead == NUM) {
					stack.push("id");
					stack.push("" + 5);
					guiyuefou = false;
				} else if (lookahead == LBRACE) {
					stack.push("(");
					guiyuefou = false;
					stack.push("" + 4);
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			case '9':
				if (lookahead == MUL) {
					stack.push("*");
					stack.push("" + 8);
					guiyuefou = false;
				} else if (lookahead == RBRACE) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == END) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == ADD) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == SUB) {
					stack.pop();
					stack.pop();
					guiyuefou = true;
					Gto((int) stack.peek().charAt(0) - (int) '0', 'E');
				} else if (lookahead == DIV) {
					stack.push("/");
					stack.push(13 + "");
					guiyuefou = false;
				} else if (lookahead == MUL) {
					stack.push("*");
					stack.push(8 + "");
					guiyuefou = false;
				} else {
					System.out.println("error");
					bResult = true;
				}
				break;
			}

		}
		if (acc)

		{
			System.out.println("匹配成功");
		}

		System.out.println("The Answer is " + stack1.peek().intValue());
	}

}

 程序运行效果如下:

1、正常情况:

编译原理 语法制导的翻译过程(L属性的翻译方案)实现带括号的整数加减乘除四则运算 JAVA实现_第1张图片

2、输入有错误,会提示error,程序会终止,但不会处理错误

编译原理 语法制导的翻译过程(L属性的翻译方案)实现带括号的整数加减乘除四则运算 JAVA实现_第2张图片

你可能感兴趣的:(编译原理 语法制导的翻译过程(L属性的翻译方案)实现带括号的整数加减乘除四则运算 JAVA实现)