1

我正在为表达式制作一个简单的解析器,这是我的代码:

import parsimonious as parmon

parser = parmon.Grammar(r"""
            E = E "+" E / id
            id = "0"/"1"/"2"/"3"/"4"/"5"/"6"/"7"/"8"/"9"
    """)

code = "2+2"

print(parser.parse(code))

我收到此错误:

IncompleteParseError(text, node.end, self)
parsimonious.exceptions.IncompleteParseError: Rule 'rules' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with '/ id
            id = "0"/"1"' (line 2, column 16).

我也尝试过 Lark-parser,但也无法解决这个问题。帮助表示赞赏。

4

2 回答 2

1

我无法提供您提到的任何解析器的任何内容。你考虑过 pyparsing吗?

  • id被定义为一位数字标记。
  • Forward表示E稍后将在代码中定义。(这类似于在程序语言中使用“前进”。)
  • 运算符将的<<定义插入E到自身中。括号要求“首先匹配”,这意味着如果可能,将应用“或”中的第一个表达式。
  • 解析器在这两个print函数中执行。

这是用于这种表达式的简单解析器。

from pyparsing import *

id = Word(nums, min=1, max=1)
E = Forward()
E << (id + '+' + E | id)

code = '2 + 2'

print (E.parseString(code))

print (E.parseString('3+4+5'))

此代码产生此结果。

['2', '+', '2']
['3', '+', '4', '+', '5']
于 2018-01-17T20:16:43.777 回答
1

也许值得详细说明@rici 的评论并解决您的问题:

E = E "+" E / id实际上意味着: E = E "+" (E / id)这是一个无休止的递归定义:

E = E "+" E / id何时E替换右侧:

E = (E "+" (E / id)) "+" (E / id), ETC。

这意味着尽管+在您的示例表达式中立即匹配右侧操作数(选择id作为终端字符的生产2),但仍然会(永无止境)怀疑如何匹配左侧。

这就是为什么您提供的 EBNF 错误并将其更改为:

E = ( E "+" E ) / id

解决问题。

于 2019-03-28T20:55:58.353 回答