编译技术第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. 由于输入串是具体的数值,因此应调用相应的词法分析的功能。
扩展:
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、正常情况:
2、输入有错误,会提示error,程序会终止,但不会处理错误