[英]Simplifying grammar via operator precedence
我正在尝试解析 C。 我一直在咨询一些自由上下文 C 语法,我观察到它们通常使用“链式”生产规则 model 表达式,例如 [here][1] 对 Z20F35E630DAF44DBFAC4C3F6
<logical-or-expression> ::= <logical-and-expression>
| <logical-or-expression> || <logical-and-expression>
<logical-and-expression> ::= <inclusive-or-expression>
| <logical-and-expression> && <inclusive-or-expression>
我说表达式是链式的,因为它们遵循以下结构:
expression with operator(N) ::= expression with operator(N+1)
| (expression with operator(N)) operator(N) (expression with operator(N+1))
其中 N 是运算符的优先级。 我知道目标是消除语言的歧义,并以纯粹的句法方式引入优先级和关联规则。
在具有运算符优先级支持的实际解析器中,这样的 model 表达式是否有任何理由? 我最初的想法是将它们简单地实现为:
constant_expression ::= expression1 binary_op expression2
其中 binary_op 是任何二元运算,然后通过设置所有运算符的优先级来消除歧义。 例如:
logical_expr ::= simple_expr | logical_expr && logical_expr | logical_expr || logical_expr
然后将 && 运算符的优先级设置为高于 ||。 我认为这种策略会给出一个更简单的语法,因为它会消除每个优先级的不同规则的必要性,但我不愿意使用它,因为我看到的所有实现都使用前一种策略,即使在解析器有优先支持。
许多 LR 风格的解析器可以使用语法本身外部的某种机制来处理运算符优先规则,部分原因是它允许您跳过这种“分层”方法来编写 CFG。 如果您有一个支持此功能的解析器生成器,则可以编写一个模棱两可的语法,然后添加这些外部规则以获得正确的优先级和关联性。
请注意 - CFG 和 BNF 规则的解析器通常对编写规则的顺序不敏感,因此仅列出从最高优先级到最低优先级的运算符是不够的。 (另一方面,PEG 解析器确实代表有序选择)。 此外,由于大多数解析器生成器的工作方式(具有与每个生产相关联的要执行的代码,并使用生产中的终端来确定运算符优先级),通常更容易拥有单独的规则,每个二元运算符一个,而不是拥有“Expr Operator Expr”形式的一条规则。 但除此之外,基本方法是合理的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.