微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有哪些算法可以解析将运算符优先级定义为范围的语言?

如何解决有哪些算法可以解析将运算符优先级定义为范围的语言?

语言 TLA+ 使用范围作为其运算符优先级(请参阅Specifying Systems [PDF] 一书中第 271 页的表格)。引用:

如果两个运算符的范围重叠,则未指定它们的相对优先级。

例如,$ 运算符(优先级 9-13)与 + 运算符(优先级 10-10)冲突,但与 < 运算符(优先级 5-5)不冲突。

运算符优先级范围是形式语言中常用的甚至是预先存在的概念吗?通过一些搜索,我在网上找不到任何关于此的信息。是否有解析这种优先级方案的算法,或将此方案转换为标准的单值优先级方案?是否有任何解析器生成器处理运算符优先级范围?与单值优先级相比,通过这种方法获得了什么?

解决方法

运算符优先级范围是形式语言中常用的甚至是预先存在的概念吗?

没有

事实上,运算符优先级(没有范围)在形式语言中是一个被严重误解的概念。 (当我写完这篇论文时,您将能够在下面看到此声明的更长版本。)

是否有算法可以解析这种优先级方案,或者将该方案转换为标准的单值优先级方案?

您可以很容易地调整标准调车场算法,只需使用更复杂的优先级比较即可。在标准算法中,比较可以有三种可能的结果:小于(推送传入符号)、大于(减少左侧的表达式)和相等(组合括号或其他括号标记)。 (最后一个结果在大多数在线资源中都没有得到很好的描述,并且经常被添加一个额外的关联性测试所掩盖。同样,见下文。)

通过范围比较,您将得到四种可能的结果。您可以将左侧范围的结束与右侧范围的开始进行比较以表示小于,将左侧范围的开始与右侧范围的结束进行比较以表示大于。如果这些都不适用,您的范围就会重叠,并且您必须以某种方式将括号标记与错误情况区分开来。

是否有任何解析器生成器处理运算符优先级范围?

如今只有少数解析器生成器使用运算符优先级表,尽管分流码算法(或其等效物)的手写实现非常普遍。 yacc/bison 等解析器生成器在解析器构建时使用优先级声明,通过消除一些可能的解析动作来解决冲突;解析器本身不知道优先级,严格按照状态转换表进行操作。

ANTLR 是解析器生成器,它最接近于在解析过程中使用优先级。它根据文法描述中的产生式顺序计算自己的优先级数(分别为每个非终结符)。这些计算出的优先级被翻译成语义谓词,这些谓词在解析时执行,以便在不同的解析预测之间进行选择。由于没有明确的优先级声明,您将无法在任何地方声明范围,但您可以自己编写语义谓词,而不是让 ANTLR 为您生成它们(如果您有明确的谓词,它不会尝试插入冲突解析代码)。这将允许您使用与我上面概述的相同的策略,但我认为它不会完全令人满意。

与单值优先级相比,通过这种方法获得了什么?

在我看来,没什么。这是一个 hack,就像其他大多数优先级解析一样。如果它适用于特定的语法,那很酷,但它会遇到与广义运算符优先级解析相同的问题:你真的不知道你在解析什么语言,因为整个装置更像是一种启发式而不是形式框架。作为证明,很难找到一个手写的基于优先级的解析器,它在某些时候没有一些(希望注释掉)代码来处理优先级比较没有正确处理的异常,就像很难找到一个现实生活中的语法使用优先级声明,但最普通的风格在某些地方没有很长的注释来解释其他神秘的声明。

,

我想你可能已经“埋没了线索”。

在该部分之后,它说“如果由于两个运算符的优先级范围重叠并且它们不是关联中缀运算符的两个实例而未确定两个运算符的应用顺序,则表达式是非法的(语法不正确)。”

我读“未指定”为“随心所欲”,这表示它无效

ANTLR 是我选择的解析器,我不知道如何让解析器在语法上拒绝它(在解析阶段)。我可以看到您将在哪里应用设置的优先级,然后,一旦您拥有 ParseTree,您就可以使用在解析树中查找重叠优先级规则的代码来处理它,并在其上抛出错误。我不知道这有什么不利的一面。您仍然会将其标记为错误。只是 ANTLR 会根据您指定的优先级将树的解释交给您。

我可能可以用一个 ANTLR 侦听器代码示例(Java)扩展这个想法。

老实说,我有点难以理解这种优先级方案的打包版本。这很奇怪。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。