Mess_LL(1)——递归下降的预测分析方法

import javax.imageio.plugins.tiff.ExifTIFFTagSet;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

public class Ex4 {

    private String input;

    private String lookahead;

    private int nextIndex;

    private final Map<String, String[]> map = new HashMap<>() {
        {
            // 匿名子类实例,中间添加静态代码块用于初始化
            // 存储同步集合
            put("F", new String[]{"(", "id", "+", "*", ")"});
            put("E", new String[]{"(", "id", ")"});
            put("E_sq", new String[]{"+", "ε", ")"});
            put("T", new String[]{"+", ")", "(", "id"});
            put("T_sq", new String[]{"+", ")", "*", "ε"});
        }
    };

    public Ex4() {
        input();
        process();
    }

    private void process() {
        // 递归算法,往后看产生子式,如果是非终结符,则匹配其 First
        // 如果是终结符,则直接匹配
        E();
    }

    public void input() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("target grammar : \n"
                + "E -> TE'\n"
                + "E' -> +TE'|ε\n"
                + "T -> FT'\n"
                + "T' -> *FT'|ε\n"
                + "F -> (E)|id\n");
        System.out.print("Please input a string to check:");
        input = scanner.nextLine() + "$";
        nextToken();
    }

    public void E() {
        if (lookahead.equals("(") || lookahead.equals("id")) {
            System.out.println("Use: E -> TE'");
            T();
            E_sq();
        }else{
            error("E");
        }
    }

    public void E_sq() {
        if (lookahead.equals("+")) {
            System.out.println("Use: E' -> +TE'");
            match("+");
            T();
            E_sq();
        } else {
            // 进入这个分支有两种可能,一、当前这个符号确实要交由下一个方法处理
            // 二、当前这个符号是错误的....
            // 暂时还没想出很好的解决方法
            // 也许能设置一个标志位?标记当前这个符号是取空集过去的?
            // 如果在最后监测这个标志位还在,说明这个符号始终没有解决?在回到这里?
            System.out.println("Use: E' -> ε");

        }
    }

    public void T() {
        if (lookahead.equals("(") || lookahead.equals("id")) {
            System.out.println("Use: T -> FT'");
            F();
            T_sq();
        }else{
            error("T");
        }
    }

    public void T_sq() {
        if (lookahead.equals("*")) {
            System.out.println("Use: T' -> *FT'");
            match("*");
            F();
            T_sq();
        } else {
            System.out.println("Use: T' -> ε");
        }
    }

    public void F() {
        if (lookahead.equals("(")) {
            System.out.println("Use: F -> (E)");
            match("(");
            E();
            match(")");
        } else if (lookahead.equals("id")) {
            System.out.println("Use: F -> id");
            match("id");
        } else {
            error("F");
        }
    }

    public void nextToken() {
        lookahead = input.charAt(nextIndex) + "";
        nextIndex++;

        if (lookahead.equals("i")) {
            lookahead = "id";
            nextIndex++;
        }
    }

    public void match(String terminal) {

        if (lookahead.equals(terminal)) {
            System.out.println("Match: " + "\"" + lookahead + "\"");
            nextToken();
        } else {
            // 错误出现?多了除了丢还能咋地?
            System.out.println("terminal matching error! Just drop \"" + lookahead + "\"!");
            nextToken();
            if (lookahead.equals("$")) {
                System.out.println("terminal matching error repair failed!Exit!");
                System.exit(0);
            }
            match(terminal);
        }

        if (lookahead.equals("$")) {
            System.out.println("accept! System exit!");
            System.exit(0);
        }
    }

    public void error(String non_terminal) {
        System.out.println("Something wrong!" + "Try to Recovery!");

        // 不断跳过元素直到碰见同步记号
        String[] sync = map.get(non_terminal);
        do {
            System.out.println("Recovery: Skip " + "\"" + lookahead + "\"");
            nextToken();
        } while (!lookahead.equals("$") && !Arrays.asList(sync).contains(lookahead));

        // 由于读到结束标记退出,恢复失败!
        if (lookahead.equals("$")) {
            System.out.println("Recovery failed! Exit!");
            System.exit(0);
        }

        // 读取到同步记号,有恢复成功的可能性
        // 通过反射机制 在断点重新调用方法
        Method method = null;
        try {
            method = this.getClass().getMethod(non_terminal);
            method.invoke(this);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void test(){
        if(!lookahead.equals("$")){
            System.out.println("accept after fixing!");
        }
    }

    public static void main(String[] args) {
        new Ex4().test();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值