【问题标题】:Is the order of reduction defined in Yacc?Yacc 中定义了减少的顺序吗?
【发布时间】:2012-09-08 13:20:42
【问题描述】:

这更像是一个“原则上”的问题,而不是一个实际的问题。是 Yacc 减少产生式并从定义的词法分析器中读取新标记的顺序。也就是说,如果我有以下一组标记:

INTEGER_BEGIN
INTEGER_VALUE
LESS_THAN
INTEGER_BEGIN
INTEGER_VALUE

Yacc 能否在其语义范围内从词法分析器中读取 LESS_THAN 标记,然后再将 INTEGER BEGIN INTEGER_VALUE 简化为单个事物,给定一组产生式,例如:

expr : expr LESS_THAN expr
     | integer

integer : INTEGER_BEGIN INTEGER_VALUE

如果这些规则是用语义动作定义的,这些规则会改变吗?

【问题讨论】:

    标签: parsing bison yacc parser-generator lalr


    【解决方案1】:

    是的,它可以。 Yacc 创建了一个 LALR(1) 解析器——(1) 表示前瞻的 1 个标记——因此它可能会在减少规则之前提前读取 1 个标记超出规则的标记末尾。语义动作的存在是无关紧要的,因为语义动作只是在减少规则之前运行的一些 C 代码。

    请注意,不能保证它总是会提前读取令牌。由 yacc 或 bison 创建的解析器有时会使用“默认缩减”——表示它可以缩减规则而不必先读取下一个标记。只要规则的缩减与下一个标记无关,就会发生这种情况。

    在这个特定示例中,默认缩减可用于 integer 规则,因此它可能会在没有前瞻的情况下缩减它,但同样不能保证 - 默认缩减是一些(但不是全部)实现使用的优化yacc 的。

    【讨论】:

    • 有没有办法知道这是否发生了?
    • gnu.org/software/bison/manual/html_node/Default-Reductions.html 包含对默认归约语义的完整描述,并且,正如您所指出的,它会导致词法分析器的延迟调用。
    • 在某些版本的 bison 中,您可以在操作中检查 if (yychar == YYEMPTY) 以查看您是否处于默认缩减状态(因此没有读取前瞻),但这并不是非常便携。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多