在减少一个表达式的过程中调用几个解析器减少函数是否合乎逻辑



我写了一个解析器,它分析代码并像lex和yacc一样减少代码(相当多。)

我想知道这件事的一个方面。如果我有一套规则,如以下:

unary: IDENTIFIER
| IDENTIFIER '(' expr_list ')'

只要找到标识符,就可以减少只有IDENTIFIER的第一个规则。然而,只有当输入还包括写在括号之间的表达式的有效列表时,才能减少第二条规则。

在这种情况下,解析器应该如何工作?

如果我立即减少第一个标识符,我可以保留结果,如果我意识到第二个规则匹配,就把它扔掉。如果第二条规则不匹配,那么我可以返回早期减少的结果。

这也意味着,如果第二条规则适用,两个归约函数都将被调用。

相反,我们是否应该坚持早期的削减,只有在第二条更长的规则适用的情况下才适用?


对于那些感兴趣的人,我在这个答案中放了一个更完整的解析器语法版本:https://codereview.stackexchange.com/questions/41769/numeric-expression-parser-calculator/41786#41786

自下而上的解析器(如bisonyacc)在达到生产结束时才会减少。在他们需要之前,他们不必猜测他们将使用哪个缩减。因此,有两个前缀相同的产品真的不是问题。从这个意义上说,该算法与自上而下的算法截然不同,例如,递归下降解析中使用的算法。

为了使您提供的片段可由LALR(1)解析器生成器解析——也就是说,一个自底向上的解析器,能够在生产结束后只检查一个(1)令牌——语法必须确保unary后面没有()。只要这是真的,解析器就可以看到<kbd](>足以防止单位减少unary: IDENTIFIER在其应与其他unary生产一起减少的情况下发生。

(这有点过于简单化,但我认为在SO上重现LALR解析的标准文本是不正确的。)

最新更新