【编译原理】非递归的预测分析法 JAVA实现

来源:互联网 发布:求n的阶乘c语言编程 编辑:程序博客网 时间:2024/05/23 22:07

定义一个语法分析接口

public interface GrammarHandler {    //用来代替空符    char NULL_WORD_CHAR = '☯';    String NULL_WORD_STR = "☯";    /**     * 添加文法规则     * @param k 非终结符     * @param s 规则     */    void addGrammar(char k, String s);    /**     * 输入语句验证是否符合文法规则     * @param s 被验证语句     * @return 成功返回true     */    boolean isMatch(String s);    /**     * 添加文法完毕后初始化才可验证语句     * @param firstK 启始非终结符     */    void init(char firstK);}

定义LL1语法分析实现类

import org.apache.commons.lang.StringUtils;import java.util.*;/** * @auther Buynow Zhao * @create 2017/11/12 */public class LL1Handler implements GrammarHandler{    //文法map 存储文法 key为非终结符    //用list储存该非终结符的所有规则    private Map<Character, Set<String>> grammarMap = new HashMap<Character, Set<String>>();    //选择集 map    private Map<Character, Map<Character,String>> selectMap = new HashMap<Character, Map<Character,String>>();    //标志位  是否初始化    //未初始化不得开始验证语句    private boolean isInit = false;    //启始非终结符    private Character firstK = null;    @Override    public void addGrammar(char k, String s) {        if (!grammarMap.containsKey(k)) {            grammarMap.put(k, new HashSet<String>());        }        grammarMap.get(k).add(s);    }    @Override    public boolean isMatch(String s) {        Stack<Character> gStack = new Stack<Character>();        Stack<Character> sStack = new Stack<Character>();        //添加结尾标记        gStack.push('#');        sStack.push('#');        //init gStack & sStack        gStack.push(firstK);        for (int i=s.length()-1;i>=0;i--) {            sStack.push(s.charAt(i));        }        String s1 = null;        //分析核心        while (!(gStack.isEmpty()||sStack.isEmpty())) {            while (!(gStack.isEmpty() || sStack.isEmpty())                             && gStack.peek() == sStack.peek()) {                gStack.pop();                sStack.pop();            }            //通过表查询 获得对应文法规则            if (gStack.isEmpty() || sStack.isEmpty()) {                break;            }            s1 = null;            if (selectMap.get(gStack.peek()) != null) {                s1 = selectMap.get(gStack.pop()).get(sStack.peek());            }            if (s1 == null) {                return false;            }            if (GrammarHandler.NULL_WORD_STR.equals(s1)) {                continue;            }            for (int i=s1.length()-1;i>=0;i--) {                gStack.push(s1.charAt(i));            }        }        //分析成功        if (sStack.isEmpty()&&gStack.isEmpty()){            return true;        }        return false;    }    @Override    public void init(char firstK) {        if (this.isInit) {            return;        }        this.firstK = firstK;        //计算SELECT集        getSelectMap();        this.isInit = true;    }    private void getSelectMap() {        //遍历非终结符        for (Character k : grammarMap.keySet()) {            select(k);        }    }    //求select    private void select(char k) {        if (selectMap.containsKey(k)) {            return;        }        selectMap.put(k, new HashMap<Character,String>());        //遍历该终结符的所有规则        for (String s : grammarMap.get(k)) {            //空            if (StringUtils.isEmpty(s)) {                follow(k);            }else{                //select 集为 s的first                selectMap.get(k).put(s.charAt(0),s);            }        }    }    //求follow    private void follow(char k) {        char[] charArr = null;        for (Character k1 : grammarMap.keySet()) {            for (String s : grammarMap.get(k1)) {                charArr = s.toCharArray();                for (int i=0;i<charArr.length;i++) {                    if (charArr[i] == k) {                        if (i == charArr.length - 1) {                            selectMap.get(k).put('#',GrammarHandler.NULL_WORD_STR);                            //后继为空                        }else{                            select(charArr[i+1]);                            for (Character c : selectMap.get(charArr[i + 1]).keySet()) {                                selectMap.get(k).put(c,GrammarHandler.NULL_WORD_STR);                            }                        }                    }                }            }        }    }    public static void main(String[] args) {        //构造一个LL1文法分析器        GrammarHandler handler = new LL1Handler();        //添加文法规则        handler.addGrammar('S',"dABA");//S->dABA        handler.addGrammar('A',"");//A->NULL        handler.addGrammar('A',"a");//A->a        handler.addGrammar('B',"bb");//B->bb        //初始化分析器 并设置启始非终结符        handler.init('S');        //待验证数组        String[] sArr = new String[]{"dbb","dab","dabba"};        //得出结果        for (String s : sArr) {            boolean result = handler.isMatch(s);            System.out.println(s+":"+result);        }    }}

运行演示

  • 测试的文法规则
    • S->dABA
    • A->NULL
    • A->a
    • B->bb
  • 添加规则到GrammarHandler
    • handler.addGrammar(‘S’,”dABA”);
    • handler.addGrammar(‘A’,”“);//A->NULL
    • handler.addGrammar(‘A’,”a”);//A->a
    • handler.addGrammar(‘B’,”bb”);//B->bb
  • 被测试的句子
    • String[] sArr = new String[]{“dbb”,”dab”,”dabba”};
  • 循环遍历数组中的句子验证是否符合
//得出结果for (String s : sArr) {    boolean result = handler.isMatch(s);    System.out.println(s+":"+result);}
  • 测试结果
    运行结果
阅读全文
1 0
原创粉丝点击