我编写了一个分析代码并使用lex和yacc减少代码的解析器(非常多。)
我想知道这个问题的一个方面。如果我有一套规则如下:
unary: IDENTIFIER
| IDENTIFIER '(' expr_list ')'
只要找到标识符,就可以减少只有IDENTIFIER的第一条规则。但是,如果输入还包括在括号之间写入的有效表达式列表,则只能减少第二个规则。
解析器如何在这样的情况下工作?
如果我立即减少第一个标识符,我可以保留结果并在我意识到第二个规则匹配时将其丢弃。如果第二条规则不匹配,那么我可以返回早期减少的结果。
这也意味着如果适用第二条规则,将会调用两个缩减函数。
我们是否希望保留早期减少并仅在适用第二个较长规则时应用它?
对于那些感兴趣的人,我在这个答案中添加了一个更完整的解析器语法版本:https://codereview.stackexchange.com/questions/41769/numeric-expression-parser-calculator/41786#41786
答案 0 :(得分:3)
自下而上的解析器(如bison
和yacc
)在到达生产结束之前不会减少。在他们需要之前,他们不必猜测他们将使用哪种减少量。因此,两个具有相同前缀的制作确实不是问题。从这个意义上讲,该算法与用于递归下降解析的自上而下算法完全不同。
为了使您提供的片段能够被LALR(1)解析器生成器解析 - 也就是说,一个自下而上的解析器,只能检查一个(1)
令牌之外的结尾。一个产品 - 语法必须是这样的,()可能没有unary
跟随的地方。只要这是真的,解析器可以看到< kbd>(足以防止单位缩减unary: IDENTIFIER
在其应该通过其他unary
制作减少的上下文中发生。
(这有点过于简单化,但我不认为在SO上重现LALR解析的标准文本是正确的。)