代码针对以下文法:
//E -> E+T | T
//T -> T*F | F
//F -> (E) | id
输入中的元素需要用空格分开,并以$符号结尾
输入样例:
id * id + id $
(由于暗物质的堆积,第一次跑可能会出现玄学错误,再跑一次就好了)
以下为代码:
import java.util.*;
public class LR {
public static void main(String[] args){
int acc = 0;
int now = 0;
Stack s = new Stack();
s.push("0");
System.out.println("请输入想要分析的表达式(以$结尾):");
Scanner scanner = new Scanner(System.in);
String ins = scanner.nextLine();
String [] str = ins.split(" ");
while(acc==0){
if(s.peek().equals("0")||s.peek().equals("4")||s.peek().equals("6")||s.peek().equals("7")){
if(str[now].equals("id")){
now++;
System.out.println("移进id");
s.push("id");
s.push("5");
}else if(str[now].equals("(")){
now++;
System.out.println("移进( ");
s.push("(");
s.push("4");
}
else {
System.out.println("移进时出现错误!");
break;
}
}
else if(s.peek().equals("1")){
if(str[now].equals("+")){
now++;
System.out.println("移进 +");
s.push("+");
s.push("6");
}else if(str[now].equals("$")){
acc = 1;
System.out.println("接受");
}
else {
System.out.println("移进时出现错误!");
break;
}
}
else if(s.peek().equals("2")){
if(str[now].equals("*")){
now++;
System.out.println("移进 *");
s.push("*");
s.push("7");
}else if(str[now].equals("+")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按E->T进行归约");
s.pop();
s.pop();
if(s.peek().equals("0")){
s.push("E");
s.push("1");
}else if(s.peek().equals("4")){
s.push("E");
s.push("8");
}
else{
System.out.println("归约时出现错误!");
}
}else {
System.out.println("移进时出现错误!");
break;
}
}
else if(s.peek().equals("3")){
if(str[now].equals("+")||str[now].equals("*")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按T->F进行归约");
s.pop();
s.pop();
if(s.peek().equals("0")||s.peek().equals("4")){
s.push("T");
s.push("2");
}else if(s.peek().equals("6")){
s.push("T");
s.push("9");
}
else{
System.out.println("归约时出现错误!");
}
}
else{
System.out.println("移进时出现错误!");
}
}
else if(s.peek().equals("5")){
if(str[now].equals("+")||str[now].equals("*")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按F->id进行归约");
s.pop();
s.pop();
if(s.peek().equals("0")||s.peek().equals("4")||s.peek().equals("6")){
s.push("F");
s.push("3");
}else if(s.peek().equals("7")){
s.push("F");
s.push("10");
}
else{
System.out.println("归约时出现错误!");
}
}
else{
System.out.println("移进时出现错误!");
}
}
else if(s.peek().equals("8")){
if(str[now].equals("+")){
now++;
System.out.println("移进 +");
s.push("+");
s.push("6");
}else if(str[now].equals(")")){
now++;
System.out.println("移进 )");
s.push(")");
s.push("11");
}
else {
System.out.println("移进时出现错误!");
break;
}
}
else if(s.peek().equals("9")){
if(str[now].equals("*")){
now++;
System.out.println("移进 *");
s.push("*");
s.push("7");
}else if(str[now].equals("+")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按E->E+T进行归约");
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
if(s.peek().equals("0")){
s.push("E");
s.push("1");
}else if(s.peek().equals("4")){
s.push("E");
s.push("8");
}
else{
System.out.println("归约时出现错误!");
}
}else {
System.out.println("移进时出现错误!");
break;
}
}
else if(s.peek().equals("10")){
if(str[now].equals("+")||str[now].equals("*")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按T->T*F进行归约");
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
if(s.peek().equals("0")||s.peek().equals("4")){
s.push("T");
s.push("2");
}else if(s.peek().equals("6")){
s.push("T");
s.push("9");
}
else{
System.out.println("归约时出现错误!");
}
}
else{
System.out.println("移进时出现错误!");
}
}
else if(s.peek().equals("11")){
if(str[now].equals("+")||str[now].equals("*")||str[now].equals(")")||str[now].equals("$")){
System.out.println("按F->(E)进行归约");
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
if(s.peek().equals("0")||s.peek().equals("4")||s.peek().equals("6")){
s.push("F");
s.push("3");
}else if(s.peek().equals("7")){
s.push("F");
s.push("10");
}
else{
System.out.println("归约时出现错误!");
}
}
else{
System.out.println("移进时出现错误!");
}
}
}
}
}