【问题标题】:Recursive descent parsing for boolean grammar布尔语法的递归下降解析
【发布时间】:2015-11-05 19:51:24
【问题描述】:

我正在尝试通过示例学习编译器和递归下降解析。这不是家庭作业。我尝试查看其他一些答案,但无法理解它们。

我使用的示例是一个布尔表达式解析器,它返回表达式有效和无效的区域。

有效的语法是空格、括号、AND、OR 和小写单词。小写单词需要用布尔运算符分隔(即 cat AND mouse)。

这是如何工作的一些示例:

"cat AND mouse" = "cat <v>AND</v> mouse"
"cat AND mouse OR" = "cat <v>AND</v> mouse <i>OR</i>"
"pet OR ((domestic AND cat)" = "pet <v>OR</v> <i>(</i><v>(</v>domestic <v>AND</v> cat <v>)</v>"
"cat food" = "cat <i>?</i> food"

如您所见,我要输出的是每个括号和布尔运算符是否有效,方法是用“v”标签表示有效或用“i”标签表示无效。

我认为该语言的语法如下所示(如果我错了,请纠正我):

Expression -> 1 or more clauses
Clause -> lowercase_term | (lowercase_term bool_op lowercase_term)
Lowercase_Term -> 1 or more letters from [a-z]
Bool_Op -> AND | OR

但是,我不太确定如何从中制作递归下降解析器。我假设它需要是某种树,但不确定。

作为参考,我在 Java 中执行此操作,但非常感谢伪代码或任何有助于我理解的语言代码!

【问题讨论】:

  • 您可能希望在解析器前面放置一个词法分析器(lexer)。这将吐出诸如“cat”、“AND”、“mouse”之类的整个标记,而不必单独解析每个字符('c'、'a'、't')。

标签: java parsing recursion


【解决方案1】:

看看How To Build A Boolean Expression Evaluator - Using a recursive descent parser and the interpreter pattern。这看起来很像您要的东西。

关于检测输入的“有效”与“无效”部分:一个简单的方法是:首先尝试解析完整的文本。如果这可行,则全文有效。否则,将文本解析为倒数第二个字符等,直到您最终找到有效的输入前缀。之后的所有文本都是“无效的”。

【讨论】:

  • 嗯,这看起来有点相似,但我认为让我失望的是我想准确返回输入的哪些部分有效/无效。例如,如果一个括号不好,则需要在它不好的地方突出显示,我不知道该怎么做。
  • 这就是递归下降解析器的问题:由于回溯,找到错误的“确切”位置并不容易。如果您在其中一个非终端函数中发现错误,这并不意味着它确实是一个错误,因为不同的替代方案可能会找到更好/更长的匹配。
  • 这可能就是我如此困惑的原因。谢谢你的帮助!是否有其他解析算法不会遇到同样的问题?
  • 也许可以试试这个:一旦你发现一个错误,记住错误的位置作为“当前错误位置”。当您发现另一个错误时,如果它大于旧错误,请记住作为“当前错误位置”。如果您最终无法解析输入,则拆分的“当前错误位置”。
【解决方案2】:

您可以在这里阅读并尝试示例,我在那里解释了如何使用递归下降解析技术解析和解释算术表达式:

https://leanpub.com/pic/read#leanpub-auto-chapter-2---parsing-and-calculating-expressions

递归下降解析是 - 几乎 - 最直观的解析技术。编写自己的手工编码解释器就足够了,不仅可以使用算术表达式,还可以使用循环、if-else 语句等。

这是我使用递归下降解析技术编写的手工编码玩具解释器:

https://github.com/mehmetcoskun/contra

它是开源的,你可以下载和调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2015-08-07
    • 2012-05-21
    • 1970-01-01
    相关资源
    最近更新 更多