LALR语法分析表
LALR语法分析表
1.LALR(向前看-LR)技术
2.在实践中常用,分析表比规范LR分析表小
LALR(1)项集族的内核的高效计算方法
1.构造G的LR(0)项集族的内核
2.确定自发生的符号
3.不断扫描所有项集的内核项,添加传播的符号
向前看符号的类型
public static class Determining { public int setId; public Production production; public int pos; public Terminal lookahead; /** 1自发生符号2传播符号 */ public int type; }
确定向前看符号
private List<Determining> determiningLookahead(Grammar grammar, Map<Integer, SetOfItems> setOfItemsResult, SetOfItems setOfItems, Item item, Terminal lookaheadStart) { LR1 lr1 = new LR1(); List<Determining> determinings = new ArrayList<>(); LR1Item lr1Item = LR1Item.of(item.getProduction(), item.getPos(), lookaheadStart); SetOfItems newSet = new SetOfItems(); newSet.add(lr1Item); SetOfItems closure = lr1.closure(newSet, grammar); Set<LR1Item> closureItems = closure.getItems(); for (LR1Item closureItem : closureItems) { Symbol symbolAfterDot = closureItem.getSymbolAfterDot(); if (symbolAfterDot == null) { continue; } Integer gotoId = setOfItems.getGotoMap().get(symbolAfterDot); if (gotoId == null) { continue; } SetOfItems gotoLalrSet = setOfItemsResult.get(gotoId); LR1Item old = (LR1Item) gotoLalrSet.getItem(closureItem.getProduction(), closureItem.getPos() + 1); for (Terminal lookahead : closureItem.getLookaheads()) { Terminal find = CollectionUtil.find(old.getLookaheads(), lookahead); if (find != null) { continue; } Determining determining = new Determining(); determining.lookahead = lookahead; determining.pos = old.getPos(); determining.production = old.getProduction(); determining.setId = gotoLalrSet.getId(); if (lookahead.equals(lookaheadStart)) { determining.type = 2;// 传播符号 } else { determining.type = 1;// 自发生符号 } determinings.add(determining); } } return determinings; }
LALR(1)项集族的内核高效计算方法
public List<SetOfItems> items(Grammar grammar) { LR0 lr0 = new LR0(); LR1 lr1 = new LR1(); // 1) 构造LR0项集族的内核 List<SetOfItems> lr0SetOfItem = lr0.items(grammar); Map<Integer, SetOfItems> lr0SetMap = new HashMap<>(); // 删除非内核项 for (SetOfItems setOfItems : lr0SetOfItem) { setOfItems.deleteNonKernelItems(grammar); SetOfItems pre = lr0SetMap.put(setOfItems.getId(), setOfItems); if (pre != null) { throw new RuntimeException("已经存在项集ID:" + setOfItems.getId()); } } // 用LR0项集初始化结果LALR项集 List<SetOfItems> result = new ArrayList<>(); Map<Integer, SetOfItems> setOfItemsResult = new HashMap<>(); for (SetOfItems setOfItems : lr0SetOfItem) { System.err.println("LR0 项集:" + setOfItems.getId()); for (Item item : setOfItems.getItems()) { System.err.println(item.toString()); } SetOfItems lalrSet = new SetOfItems(); lalrSet.setId(setOfItems.getId()); lalrSet.getGotoMap().putAll(setOfItems.getGotoMap()); Set<Item> items = setOfItems.getItems(); for (Item item : items) { if (item.getProduction().getHead().equals(grammar.start) && item.getPos() == 0) { // 初始项的自发生成的向前看符号$ lalrSet.add(LR1Item.of(item.getProduction(), item.getPos(), Terminal.dollar)); } else { lalrSet.add(LR1Item.of(item.getProduction(), item.getPos(), (Terminal) null)); } } result.add(lalrSet); setOfItemsResult.put(lalrSet.getId(), lalrSet); } // 2)确定自发生成的符号 for (SetOfItems lr0set : lr0SetOfItem) {// 项集族的每个项集 Set<Item> items = lr0set.getItems(); for (Item item : items) {// 项集中每个项 List<Determining> determiningList = determiningLookahead(grammar, setOfItemsResult, lr0set, item, Terminal.sharp); for (Determining determining : determiningList) { if (determining.type != 1) { continue; } SetOfItems lalrSet = setOfItemsResult.get(determining.setId); LR1Item gotoItem = (LR1Item) lalrSet.getItem(determining.production, determining.pos); gotoItem.addLookahead(determining.lookahead); } } } for (SetOfItems setOfItems : result) { System.err.println("初始 项集:" + setOfItems.getId()); for (Item item : setOfItems.getItems()) { System.err.println(item); } } // 3)不断扫描所有项集的内核项 boolean hasNew; int count = 0; do { hasNew = false; count++; System.err.println("第" + count + "趟扫描"); List<Determining> determinings = new ArrayList<>(); List<SetOfItems> tmpSets = new ArrayList<>(result); for (SetOfItems lalrSet : tmpSets) { Set<LR1Item> lalrItemSet = lalrSet.getItems(); for (LR1Item lalrItem : lalrItemSet) { if (lalrItem.getLookaheads() == null) { continue; } for (Terminal lookaheadStart : lalrItem.getLookaheads()) { List<Determining> determiningList = determiningLookahead(grammar, setOfItemsResult, lalrSet, lalrItem, lookaheadStart); for (Determining determining : determiningList) { if (determining.type == 1) { continue; } determinings.add(determining); hasNew = true; } } } } for (Determining determining : determinings) { SetOfItems setOfItems = setOfItemsResult.get(determining.setId); LR1Item old = (LR1Item) setOfItems.getItem(determining.production, determining.pos); old.addLookahead(determining.lookahead); System.err.println("状态" + determining.setId + "项" + old + "添加传播符号" + determining.lookahead); } for (SetOfItems setOfItems : result) { System.err.println("项集:" + setOfItems.getId()); for (Item item : setOfItems.getItems()) { System.err.println(item); } } } while (hasNew); // 将LALR(1)内核通过CLOSURE求闭包转换为LR(1)项集 List<SetOfItems> lr1Set = new ArrayList<>(); for (SetOfItems lalrSet : result) { SetOfItems closure = lr1.closure(lalrSet, grammar); closure.setId(lalrSet.getId()); closure.getGotoMap().putAll(lalrSet.getGotoMap()); lr1Set.add(closure); } return lr1Set; }
浙公网安备 33010602011771号