【问题标题】:pyparsing not parsing the whole stringpyparsing 不解析整个字符串
【发布时间】:2017-02-10 20:19:10
【问题描述】:

我有以下语法和测试用例:

from pyparsing import Word, nums, Forward, Suppress, OneOrMore, Group

#A grammar for a simple class of regular expressions
number = Word(nums)('number')
lparen = Suppress('(')
rparen = Suppress(')')

expression = Forward()('expression')

concatenation = Group(expression + expression)
concatenation.setResultsName('concatenation')

disjunction = Group(lparen + OneOrMore(expression + Suppress('|')) + expression + rparen)
disjunction.setResultsName('disjunction')

kleene = Group(lparen + expression + rparen + '*')
kleene.setResultsName('kleene')

expression << (number | disjunction | kleene | concatenation)

#Test a simple input
tests = """
(8)*((3|2)|2)
""".splitlines()[1:]

for t in tests:
    print t
    print expression.parseString(t)
    print

结果应该是

[['8', '*'],[['3', '2'], '2']]

但相反,我只得到

[['8', '*']]

如何让 pyparsing 解析整个字符串?

【问题讨论】:

    标签: pyparsing


    【解决方案1】:

    parseString 有一个参数parseAll。如果你用parseAll=True 调用parseString,如果你的语法没有解析整个字符串,你会收到错误消息。从那里出发!

    【讨论】:

      【解决方案2】:

      你的concatenation 表达式没有做你想做的事,并且接近于左递归(幸运的是它是你表达式中的最后一项)。如果你这样做,你的语法就会起作用:

      expression << OneOrMore(number | disjunction | kleene)
      

      有了这个改变,我得到了这个结果:

      [['8', '*'], [['3', '2'], '2']]
      

      编辑: 如果您改用&lt;&lt;= 运算符,您还可以避免&lt;&lt; 优先于|:

      expression <<= OneOrMore(number | disjunction | kleene)
      

      【讨论】:

      • 谢谢!但是,为什么仅仅写出连接的定义却不起作用?
      • 因为您的原始表达式与kleene 匹配,而您原始expression 定义中的任何内容都没有说要在之后继续解析。当您将concatenation 作为expression 的一部分包含在内时,这会传达这个想法,但会让您陷入左递归兔子洞。或者,如果您将 | 运算符替换为 ^ 运算符(以给出“匹配最长”或表达式而不是 MatchFirst),那么您也会得到串联评估 - 但同样,您将通过尝试左递归通过评估 expression 来评估 expression。
      • 您使用的是什么版本的 pyparsing?当前版本包括一些有用的方法,尤其是expression.runTests,它将采用多行测试输入字符串并对每一行运行您的表达式并打印解析结果或诊断输出。在您的示例中,您可以将最后的 for 循环替换为 expression.runTests(tests)。事实是,这些年来我已经写了大约一千次完全相同的 for 循环,我终于意识到表达式的辅助方法会很有用。
      猜你喜欢
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多