预测分析表(java实现)
1. 文法
前提是程序没有左递归符合LL(1)文法:
文法如下:
L → E;L|ε
E → TE’
E’ → +TE’|-TE’|ε
T → FT’
T’ → *FT’|/FT’|modFT’|ε
F → (E)|id|num
为了程序便于编写将E’替换为e,T’替换为t,num替换成n,mod替换成m,id替换成i
2. FIRST集合
FIRST(F)={(,i,num};
FIRST(E’)={+, -,ε};
FIRST(T)={(,i,num};
FIRST(T’)={*,/,mod,ε};
FIRST(E)={ (,i,num};
3. FALLOW集合
FOLLOW(L)={#};
FOLLOW(E)={),;};
FOLLOW(E’)={),:};
FOLLOW(T)={+,-,;,)};
FOLLOW(T’)={+,-,;,)};
FOLLOW(F)={+,-,*,/,mod,),;};
4. 预测分析表
id | n | + | - | * | / | m | ( | ) | ; | # | |
---|---|---|---|---|---|---|---|---|---|---|---|
E | E;L | E;L | E;L | ε | |||||||
E | Te | Te | Te | ||||||||
e | +Te | -Te | ε | ε | |||||||
T | Ft | Ft | Ft | ||||||||
t | ε | ε | *Ft | /Ft | mFt | ε | ε | ||||
F | id | n | (E) |
5. 代码实现
package com.xawl.oo;
import java.util.Scanner;
/**
* @author qin jin
* @date 2022/6/6 11:14
*
* 为了程序便于编写将E'替换为e,T'替换为t,mod替换成m,num替换成n
*/
public class GrammarMain {
public static void main(String[] args){
boolean isContinue = true;
while(isContinue) {
GrapparAnalyze analyze = new GrapparAnalyze();
Scanner scan = new Scanner(System.in);
System.out.println("请输入你要翻译的表达式:");
String inputExpression = scan.nextLine();
inputExpression = inputExpression.replace("id","i");
String srcdata = inputExpression.trim();
if("".equals(srcdata) || srcdata == null) {
System.out.println("输入表达式为空,请重新输入");
}else {
String result = analyze.work(srcdata);
System.out.println(result);
System.out.println("是否继续?y/n");
String yn = scan.nextLine();
if("no".equals(yn) || "n".equals(yn)) {
isContinue = false;
}
}
}
}
}
//自定义栈
class Stack {
private char s[];
private int top;
private int base;
private final int MAX = 200;
/* 初始化栈 */
public Stack() {
initStack();
}
private void initStack() {
s = new char[MAX];
base = 0;
top = 0;
}
public boolean isEmpty() {
if(top == base) {
return true;
}else {
return false;
}
}
/**
* @Description: 获取栈顶元素
* @return 返回栈顶元素
*/
public char getTop() {
return s[top-1];
}
/**
* @Description: 进栈方法
* @param str 进栈的字符
*/
public void push(String str) {
for (int i = str.length() - 1; i >= 0; i--) {
s[top++] = str.charAt(i);
}
}
/**
* @Description: 清空栈
*/
public void clear() {
top = base;
}
/**
* @Description: 出栈
* @return 栈顶元素出栈并返回出栈的元素
*/
public char pop() {
return s[--top];
}
/**
* @Description: 返回栈中元素个数
* @return 栈中元素个数
*/
public int size() {
return top;
}
/**
* 打印栈里面的元素
*/
public String toString() {
StringBuffer tempStack = new StringBuffer();
for (int i = 0; i < top; i++) {
tempStack.append(s[i]);
}
return tempStack.toString();
}
}
//分析器
class GrapparAnalyze {
//分析表将E'替换为e,T'替换t,$为空
private String tab[][] = {
{ "$", "i", "n", "+", "-", "*", "/", "m", "(", ")", ";", "#" },
{ "L", "E;L", "E;L", "$", "$", "$", "$", "$", "E;L", "$", "$", "ε" },
{ "E", "Te" , "Te", "$", "$", "$", "$", "$", "Te", "$", "$", "$" },
{ "e", "$" , "$" , "+Te", "-Te", "$", "$", "$", "$", "ε", "ε", "$" },
{ "T", "Ft", "Ft", "$", "$", "$", "$", "$", "Ft", "$", "$", "$" },
{ "t", "$", "$", "ε", "ε", "*Ft", "/Ft", "mFt", "$", "ε", "ε", "$" },
{ "F", "i", "n", "$", "$", "$", "$", "$", "(E)", "$", "$", "$" }
};
private String input; //input中存放输入的表达式
private StringBuffer tempBuffer; //存放要输出的字符串
private int ptr, row, col, step; //指针,预测表中的行,列,当前步骤
private boolean symbol;
private Stack stack;
public GrapparAnalyze(){
stack = new Stack();
tempBuffer = new StringBuffer();
symbol=true;
input="";
stack.clear();
stack.push("#");
row=1;
ptr=0;
step=1;
}
public int column(char c) { //判断预测表中的列
switch (c) {
case 'i':
return 1;
case 'n':
return 2;
case '+':
return 3;
case '-':
return 4;
case '*':
return 5;
case '/':
return 6;
case 'm':
return 7;
case '(':
return 8;
case ')':
return 9;
case ';':
return 10;
case '#':
return 11;
default:
return -1;
}
}
public int line(char c) { //判定预测表中的行
switch (c) {
case 'L':
return 1;
case 'E':
return 2;
case 'e':
return 3;
case 'T':
return 4 ;
case 't':
return 5;
case 'F':
return 6;
default:
return -1;
}
}
public void show(String str) {
tempBuffer.append(String.format("%-7d%-14s%-20s%-20s\r\n",
step, filter(stack.toString()), filter(input.substring(ptr)), filter(str)));
step++;
}
public void analyse() {
stack.push(tab[row][0]); //预测表中的第一个元素‘E’
show("初始化");
String tmp;
char ctmp; //栈顶元素
while (!(input.charAt(ptr) == '#' && stack.getTop() == '#')) {
ctmp = stack.getTop();//获取栈顶的元素
if (input.charAt(ptr) == ctmp) { //与栈顶元素比较
stack.pop();
ptr++;
show("" + ctmp + "匹配");
continue;
}
//判断ptr位置的终结符所在预测表的列位置
col = column(input.charAt(ptr));
if (col == -1) {
symbol = false;
show("未定义的字符");
ptr++;
break;
}
//判断栈顶位置所在预测表的行位置
row = line(ctmp);
if (row == -1) {
symbol = false;
show("出错");
stack.pop();
if (input.charAt(ptr) != '#') {
ptr++;
}
continue;
}
tmp = tab[row][col];
if (tmp.charAt(0) == '$') {
symbol = false;
show("出错");
stack.pop();
if (input.charAt(ptr) != '#') {
ptr++;
}
} else if (tmp.charAt(0) == 'ε') {
stack.pop();
show("" + ctmp + "->" + 'ε');
} else {
stack.pop();
stack.push(tmp);
show("" + ctmp + "->" + tmp);
}
}
}
//过滤方法将打印的字符串中e和t替换为E'和T'
public String filter(String src) {
if(src.contains("e") || src.contains("t")|| src.contains("i")|| src.contains("m")|| src.contains("n")) {
StringBuffer result = new StringBuffer();
char item;
for(int i = 0;i < src.length(); i++) {
item = src.charAt(i);
if(item == 'e') {
result.append("E'");
continue;
}else if(item == 't') {
result.append("T'");
continue;
}else if(item == 'i'){
result.append("id");
continue;
}else if(item == 'n'){
result.append("num");
continue;
}else if(item == 'm'){
result.append("mod");
continue;
}
result.append(item);
}
return result.toString();
}else {
return src;
}
}
public String work(String inputExpression) {
input = inputExpression + '#';
symbol = true;
tempBuffer.append(String.format("%-8s%-20s%-20s%-20s\r\n",
"步骤","分析栈","剩余输入栈","所用产生式"));
analyse();
if (symbol) {
tempBuffer.append("\r是正确的符号串\r");
return tempBuffer.toString();
} else {
tempBuffer.append("\r不是正确的符号串\r");
return tempBuffer.toString();
}
}
public StringBuffer getTempBuffer() {
return tempBuffer;
}
public void setTempBuffer(StringBuffer tempBuffer) {
this.tempBuffer = tempBuffer;
}
public Stack getStack() {
return stack;
}
public void setStack(Stack stack) {
this.stack = stack;
}
public String[][] getTab() {
return tab;
}
public void setTab(String[][] tab) {
this.tab = tab;
}
public String getInput() {
return input;
}
public void setInput(String ns) {
this.input = ns;
}
public int getPtr() {
return ptr;
}
public void setPtr(int ptr) {
this.ptr = ptr;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public boolean isBoo() {
return symbol;
}
public void setBoo(boolean boo) {
this.symbol = boo;
}
}