首页 > 其他分享 >规范LR(1)语法分析表

规范LR(1)语法分析表

时间:2023-11-11 12:00:29浏览次数:28  
标签:return grammar LR1Item 规范 item LR result 语法分析

前面已经实现了SLR语法分析表,但是可能会出现即使语法不是二义性文法,也存在移入/规约冲突

状态 i 包含项[A ->α ],当状态 i 出现在栈顶时,栈中的可行前缀时βα且在任何最后句型中a都不可能跟在βA之后,

那么当输入a时不应该A->α进行规约

为了解决这个问题, 引入更强大的构造语法分析表方法:

1.规范LR(1)语法分析表

2.LALR语法分析表

 

一、规范LR(1)项

形式:[A -> α · β, a],a为一个终结符

作用:[A -> α · , a]只有在一下输入符号等于a时才要求按照A -> α进行规约

 

/**
 * LR(1)项 P166
 */
public class LR1Item extends Item {

    /** 向前看符号 */
    private List<Terminal> lookaheads;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        LR1Item lr1Item = (LR1Item) o;
        return Objects.equals(lookaheads, lr1Item.lookaheads);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), lookaheads);
    }
}

闭包函数

/**
     * LR(1)项集族的构造方法 P167
     * @param setOfItems
     * @param grammar
     * @return
     */
    public SetOfItems closure(SetOfItems setOfItems, Grammar grammar) {
        SetOfItems result = new SetOfItems();

        Set<LR1Item> oldItems = setOfItems.getItems();
        for (LR1Item item : oldItems) {
            result.add(item);
        }

        boolean hasAdd;
        do {
            hasAdd = false;
            Set<LR1Item> items = new HashSet<>(result.getItems());
            for (LR1Item item : items) {// I中的每个项[A → α·Bβ,a]

                Symbol symbolAfterDot = item.getSymbolAfterDot();// B
                if (symbolAfterDot == null) {
                    continue;
                }

                if (!(symbolAfterDot instanceof Nonterminal)) {
                    continue;
                }

                List<Symbol> symbolAfter = item.getSymbolAfterDot1();//β
                Set<Terminal> first = grammar.first(symbolAfter);// first(β)

                if (first.contains(Terminal.epsilon)) {
                    first.addAll(item.getLookaheads());
                }
                first.remove(Terminal.epsilon);// lookahead不包含ε

                List<Production> productionList = grammar.getProduction((Nonterminal) symbolAfterDot);
                for (Production production : productionList) {
                    LR1Item newItem = LR1Item.of(production, 0, new ArrayList<>(first));
                    if (!result.contains(newItem)) {
                        result.add(newItem);
                        hasAdd = true;
                    }
                }
            }

        } while (hasAdd);

        return result;
    }

 

构造SLR语法分析表

/**
     * P161 算法4.46 构造一个SLR语法分析表
     * @param grammar
     * @param setList
     * @return
     */
    public ParsingTable buildParsingTable(Grammar grammar, List<SetOfItems> setList) {
        ParsingTable result = new ParsingTable();

        for (SetOfItems from : setList) {

            Set<LR1Item> items = from.getItems();
            for (LR1Item item : items) {

                if (item.pos != item.getProduction().getBody().size()) {
                    continue;
                }

                Nonterminal head = item.getProduction().getHead();
                if (head.equals(grammar.start)) {
                    // 如果[S' -> S· $]在I中,那么将ACTION[i $]设置为接受
                    for (Terminal lookahead : item.getLookaheads()) {
                        result.addAction(from.getId(), lookahead, AcceptAction.of());
                    }
                } else {
                    // 如果[A -> α· a]在I中,那么将ACTION[i a]设置为规约
                    for (Terminal symbol : item.getLookaheads()) {
                        result.addAction(from.getId(), symbol, ReduceAction.of(item.getProduction()));
                    }
                }
            }

            for (Map.Entry<Symbol, SetOfItems> entry : from.getGotoMap().entrySet()) {
                Symbol symbol = entry.getKey();
                SetOfItems to = entry.getValue();

                // 如果[A -> α·aβ, b]在from中并且GOTO(from, a) = to,那么将Action[from,a]设置为移入to,a必须为一个终结符
                if (symbol instanceof Terminal) {
                    result.addAction(from.getId(), symbol, ShiftAction.of(to.getId()));
                } else {
                    result.addGoto(from.getId(), symbol, to.getId());
                }

            }
        }

        return result;
    }

 

标签:return,grammar,LR1Item,规范,item,LR,result,语法分析
From: https://www.cnblogs.com/kashin/p/17814053.html

相关文章

  • LRU算法 C++
    #pragmaonce#include<list>#include<unordered_map>usingnamespacestd;classLRUCache{public:LRUCache(intcapacity):cap(capacity){m.reserve(capacity);m.max_load_factor(0.75);}intget(intkey)......
  • 个人UI组件库如何适配各种模块规范以及支持按需加载组件和发布包到包管理市场公网或者
    相关代码地址:https://github.com/13476075014/lcc-ui从指令上去看具体实现逻辑yarninitLibsJs用指令把所有组件都让入一个js文件对外暴露,作为umd规范的入口文件yarnbuild:umdjs用webpack输出上面文件,作为umd规范的yarninitEsmsJs用指令把所有组件都让入一个js文件......
  • TALLRec: An Effective and Efficient Tuning Framework to Align Large Language Mod
    目录概TallRec代码BaoK.,ZhangJ.,ZhangY.,WangW.,FengF.andHeX.TALLRec:Aneffectiveandefficienttuningframeworktoalignlargelanguagemodelwithrecommendation,2023.概LoRA微调在推荐上的初步尝试.TallRecTallRec实际上就是一种特殊的指令......
  • 【Qt初入江湖】Qt QSqlRelationalTableModel 底层架构、原理详细描述
    鱼弦:内容合伙人、新星导师、全栈领域创作新星创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen) QtQSqlRelationalTableModel是Qt中用于实现具有关联表格的模型类,它继承自QSqlTableModel。QSqlRelationalTable......
  • 机器学习——批量规范化
    训练深层神经网络是十分困难的,特别是在较短的时间内使他们收敛更加棘手。本节将介绍批量规范化(batchnormalization) (IoffeandSzegedy,2015),这是一种流行且有效的技术,可持续加速深层网络的收敛速度。再结合在 7.6节中将介绍的残差块,批量规范化使得研究人员能够训练100层以......
  • Unity 搭建ILRuntime开发环境
    Unity热更新目前主流的方案有:Lua,ILRuntime,puerts,huatuo方案。前两个大家都比较熟悉了,puerts是基于TypeScript开发的热更新,huatuo是基于C#的方案。后两个大家会比较陌生。本系列分享基于ILRuntime来做热更新。 ILRuntime热更新原理 ILRuntime热更新原理是基于Unity......
  • Unity程序员要注意的编码规范
    Unity程序员如何写好代码,写代码的过程中要注意的哪些些点,今天给大家分享一些经验规则,通过遵守这些规则作出明智的架构决策,确保更高的团队开发效率和稳定的代码。避免抽象类我们在开发中经常喜欢抽象,其实抽象得过程中往往会产生设计过度和抽象过度,而这些抽象得代码可能会令人难以......
  • js前端编码规范
    1、编码风格1.1强制两行缩紧1.2强制统一以分号结束语句1.3强制逗号分隔多行结构,始终加上最后一个逗号1.4推荐使用大括号包裹代码块1.4.3强制不适用空代码块1.5强制空格风格1.6推荐文件末保留一行空行;在块末和新语句间插......
  • JMS规范及相关实现
    JMS是一种应用于异步消息传递的标准API,作为Java平台的一部分,JMS可以允许不同应用、不同模块之间实现可靠、异步数据通信。在JMS中,支持两种消息模型,点对点(Point-to-point)和发布-订阅(Publishandsubscribe),这两种模式分别对应于JMS中的两种消息目标(MessageDestination):队列及主题......
  • 编译原理--自顶向下语法分析方法
    frompixivLL(1)文法的判别LL(1)文法的定义在P71其是根据Select选择符号集来定义的Select定义在P71Select(A->α)含义为:非终结符A在遇到Select(A->α)中元素时才能够将A->α,否则会匹配不上First定义在P69First(A)含义为:非终结符A在推导(->)时遇到的第一个终结符......