您的位置:首页 > 编程语言 > Java开发

编译原理语法分析实验(Java实现)

2015-05-31 00:09 911 查看
import java.util.Stack;

public class LL1 {

//加入同步符号的LL(1)分析表
private  String [][] analysisTable = new String[][]{
{"TZ","","","TZ","synch","synch"},
{"","+TZ","","","ε","ε"},
{"FY","synch","","FY","synch","synch"},
{"","ε","*FY","","ε","ε"},
{"i","synch","synch","(E)","synch","synch"}
};

//存储终结符
private String [] VT = new String[]{"i","+","*","(",")","#"};

//存储终结符
private String [] VN = new String[]{"E","Z","T","Y","F"};

//输入串
private StringBuilder strToken = new StringBuilder(")i*+i");

//分析栈
private Stack<String> stack = new Stack<String>();

//a保存从输入串中读取的一个输入符号,当前符号
private String a = null;

//X中保存stack栈顶符号
private String X = null;

//flag标志预测分析是否成功
private boolean flag = true;

//记录输入串中当前字符的位置
private int cur = 0;

//记录步数
private int count = 0;

//初始化
protected void init(){
strToken.append("#");
stack.push("#");
System.out.printf("%-9s %-38s %6s %-20s\n","步骤 ","符号栈 ","输入串 ","所用产生式 ");
stack.push("E");
curCharacter();
System.out.printf("%-6d %-20s %6s \n",count,stack.toString(),strToken.substring(cur, strToken.length()));
}

//读取当前栈顶符号
protected String stackPeek(){
X = stack.peek();
return X;
}

//返回输入串中当前位置的字母
private String curCharacter(){
a = String.valueOf(strToken.charAt(cur));
return a;
}

//判断X是否是终结符
protected boolean XisVT(){
for(int i = 0 ; i < (VT.length - 1); i++){
if(VT[i].equals(X)){
return true;
}
}
return false;
}

//查找X在非终结符中分析表中的横坐标
protected String VNTI(){
int Ni = 0 , Tj = 0;
for(int i = 0 ; i < VN.length ; i++){
if(VN[i].equals(X)){
Ni = i;
}
}
for(int j = 0 ; j < VT.length ; j++){
if(VT[j].equals(a)){
Tj = j;
}
}
return analysisTable[Ni][Tj];
}

//判断M[A,a]={X->X1X2...Xk}
//把X1X2...Xk推进栈
//X1X2...Xk=ε,不推什么进栈
protected boolean productionType(){
if(VNTI() != ""){
return true;
}
return false;
}

//推进stack栈
protected void pushStack(){
stack.pop();
String M = VNTI();
String ch;
for(int i = (M.length() -1) ; i >= 0 ; i--){
ch = String.valueOf(M.charAt(i));
stack.push(ch);
}
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,M);
}

//总控程序
protected void totalControlProgram(){
while(flag == true){
stackPeek();
if(XisVT() == true){
if(X.equals(a)){
cur++;
a = curCharacter();
stack.pop();
System.out.printf("%-6d %-20s %6s \n",(++count),stack.toString(),strToken.substring(cur, strToken.length()));
}else{
ERROR();
}
}else if(X.equals("#")){
if(X.equals(a)){
flag = false;
}else{
ERROR();
}
}else if(productionType() == true){
if(VNTI().equals("synch")){
ERROR();
}else if(VNTI().equals("ε")){
stack.pop();
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,VNTI());
}else{
pushStack();
}
}else{
ERROR();
}
}
}

//出现错误
protected void ERROR(){
System.out.println("输入串出现错误,无法进行分析");
System.exit(0);
}

//打印存储分析表
protected void printf(){
if(flag == false){
System.out.println("========分析成功");
}else {
System.out.println("========分析失败");
}

}

public static void main(String[] args) {
LL1 ll1 = new LL1();
ll1.init();
ll1.totalControlProgram();
ll1.printf();
}

}


测试数据1:i*i+i

测试结果1:

步骤        符号栈                                      输入串  所用产生式
0      [#, E]               i*i+i#
1      [#, Z, T]            i*i+i# E->TZ
2      [#, Z, Y, F]         i*i+i# T->FY
3      [#, Z, Y, i]         i*i+i# F->i
4      [#, Z, Y]             *i+i#
5      [#, Z, Y, F, *]       *i+i# Y->*FY
6      [#, Z, Y, F]           i+i#
7      [#, Z, Y, i]           i+i# F->i
8      [#, Z, Y]               +i#
9      [#, Z]                  +i# Y->ε
10     [#, Z, T, +]            +i# Z->+TZ
11     [#, Z, T]                i#
12     [#, Z, Y, F]             i# T->FY
13     [#, Z, Y, i]             i# F->i
14     [#, Z, Y]                 #
15     [#, Z]                    # Y->ε
16     [#]                       # Z->ε
========分析成功


测试数据2:)i*+i

测试结果2:

步骤        符号栈                                      输入串  所用产生式
0      [#, E]               )i*+i#
输入串出现错误,无法进行分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 编译原理