我正在为表达式创建一个简单的解析器,这是我的代码:
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,但也无法解决这个问题。帮助赞赏。
我不能提供你提到的任何解析器的任何东西。你考虑过pyparsing吗?
id
被定义为一位数的数字标记。Forward
表示E
将在后面的代码中定义。 (这类似于在程序语言中使用'forward'。)<<
运算符将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']
也许值得详细说明@ rici的评论以及解决问题的方法:
E = E "+" E / id
实际上意味着:E = E "+" (E / id)
这是一个非结束的递归定义:
当E = E "+" E / id
取代右侧时,E
:
E = (E "+" (E / id)) "+" (E / id)
等
这意味着尽管+
的右操作数在您的示例表达式中立即匹配(选择id
生成,这是终端字符2
),但仍然会(无休止地)怀疑如何匹配左侧。
这就是为什么您提供的EBNF错误并将其更改为:
E = ( E "+" E ) / id
解决了这个问题。