【编译原理】非递归的预测分析法 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
- 【编译原理】非递归的预测分析法 JAVA实现
- 编译原理 预测分析表的实现
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 编译原理实现预测分析法(LL(1))
- 【编译原理】自上而下的语法分析之预测分析法
- 编译原理(预测分析法)
- 编译原理_预测分析法
- 编译原理:递归向下分析程序建立语法分析树的Java实现(一)
- 编译原理:递归向下分析程序建立语法分析树的Java实现(二)
- 编译原理与编译构造 预测分析程序的构造
- 编译原理实验之预测分析算法的设计与实现
- 编译原理之算术表达式文法的预测分析算法c实现
- 编译原理实习(应用预测分析法LL(1)实现语法分析)
- 编译原理(五) LL(1)文法分析法-预测分析表的构造
- 快速排序 的原理及其java实现(递归与非递归)
- 编译原理实验——预测分析法
- 预测分析法进行语法分析(编译原理)
- StringBuffer和StringBuilder
- 【关键字】图解static关键字
- 字符串全排列问题
- Unit15
- React创建组件的三种方式及其区别
- 【编译原理】非递归的预测分析法 JAVA实现
- 设计模式-策略模式
- Xlua入门案例二
- Spring Boot application.properties或application.yml相关配置
- 小游戏-五子棋
- 银行存钱
- codeforces 817E 字典树计数
- 【JAVAWEB基础】JSP & Servlet开发讲解
- 习题6.10