(编译原理)实现LL(1)文法分析

package com.wang;

import java.util.Stack;
public class LL1 {
	 // 加入同步符号的LL(1)分析表
	
    private String[][] analysisTable = new String[][] { 
    		{ "synch", "synch", "synch", "A", "A", "synch" },
            { "synch", "synch", "synch", "BE", "BE", "synch" }, 
            { "iBE", "synch", "ε", "synch", "synch", "ε" },
            { "synch", "synch", "synch", "CF", "CF", "synch" }, 
            { "ε", "+CF", "ε", "synch", "synch", "ε" },
            {"synch","synch","synch","(",")A*","synch"}};
    // 存储终结符
    private String[] VT = new String[] { "i", "+", "*", "(", ")", "#" };
    // 存储非终结符
    private String[] VN = new String[] { "S", "A", "E", "B", "F","C" };//E表示A',F表示B'
    // 输入串
    private StringBuilder strToken;
    // 分析栈4
    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 = 1;
 
    public LL1(StringBuilder strToken) {
        this.strToken = strToken;
        init();
        totalControlProgram();
        printf();
    }
 
    // 初始化
    protected void init() {
        strToken.append("#");
        stack.push("#");
        System.out.println("步骤\t" + "符号栈\t\t" + "                      输入串 \t" + "   产生式 ");
        stack.push("S");
        curCharacter();
        System.out.printf("%-6d %-20s %6s \n", count, stack.toString(), strToken.substring(cur, strToken.length()));
    }
 
    // 读取当前栈顶符号
    protected String stackPeek() {
        X = stack.peek();//栈顶元素(size-1)
        return X;
    }
 
    // 返回输入串中当前位置的字母
    private String curCharacter() {
        a = String.valueOf(strToken.charAt(cur));//默认0位为第一个字符
        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]=="’"){VN[i]=VN[i-1]+VN[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();//得到栈顶元素X有值了E
            
            if (XisVT() == true) {//判断是终结符
                if (X.equals(a)) {//栈顶元素与缓冲区首字符匹配
                    cur++;//缓冲区首位元素+1
                    a = curCharacter();//得到下一位字符
                    stack.pop();//缓冲区元素为终结符切等于栈顶字符,那么直接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();//是空则,直接把这个pop出,用下一个栈顶元素求
                    System.out.printf("%-6d %-20s %6s       %-1s->%-12s\n", (++count), stack.toString(),
                            strToken.substring(cur, strToken.length()), X, VNTI());
                } else {//有值,且就是这条线
                    pushStack();
                }
            } else {//什么都不是则,文法错误,不可分析
                ERROR();
            }
        }
    }
 
    // 出现错误5
    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) {
        StringBuilder strToken = new StringBuilder("(i(");
        new LL1(strToken);
    }
}

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值