使用pyparsing解析表达式列表

时间:2019-09-01 08:13:27

标签: expression pyparsing basic

我正在尝试使用pyparsing解析简单的基本程序:

import pyparsing as pp

pp.ParserElement.setDefaultWhitespaceChars(" \t")

EOL = pp.LineEnd().suppress()

# Identifiers is a string + optional $
identifier = pp.Combine(pp.Word(pp.alphas) + pp.Optional("$"))

# Literals (number or double quoted string)
literal = pp.pyparsing_common.number | pp.dblQuotedString

line_number = pp.pyparsing_common.integer

function = pp.Forward()


operand = function | identifier | literal
expression = pp.infixNotation(operand, [
    (pp.oneOf("* / %"), 2, pp.opAssoc.LEFT),
    (pp.oneOf("+ -"), 2, pp.opAssoc.LEFT),
])

assignment = identifier + "=" + expression

# Keywords
PRINT = pp.CaselessKeyword("print")
FOR = pp.CaselessKeyword("for")
TO = pp.CaselessKeyword("to")
STEP = pp.CaselessKeyword("step")
NEXT = pp.CaselessKeyword("next")
CHRS = pp.CaselessKeyword("chr$")

statement = pp.Forward()

print_stmt = PRINT + pp.ZeroOrMore(expression | ";")

for_stmt = FOR + assignment + TO + expression + pp.Optional(STEP + expression)
next_stmt = NEXT

chrs_fn = CHRS + "(" + expression + ")"

function <<= chrs_fn

statement <<= print_stmt | for_stmt | next_stmt | assignment

code_line = pp.Group(line_number + statement + EOL)

program = pp.ZeroOrMore(code_line)

test = """\
10 print 123;
20 print 234; 567;
25 next
30 print 890
"""

print(program.parseString(test).dump())

除了print子句,我还有其他所有工作。

这是输出:

[[10, 'print', 123, ';', 20, 'print', 234, ';', 567, ';', 25, 'next', 30, 'print', 890]]
[0]:
  [10, 'print', 123, ';', 20, 'print', 234, ';', 567, ';', 25, 'next', 30, 'print', 890]

基于一些建议,我修改了解析器,但是由于某种原因,sitll解析器泄漏到下一行。

如何定义要正确打印的项目列表?

1 个答案:

答案 0 :(得分:2)

这里发生了一件微妙的事情,使用ParserElement.setDefaultWhitespaceChars可以更好地记录文档。这只会为调用setDefaultWhitespaceChars后在 之后创建的表达式的解析解析更新空白字符。像dblQuotedString这样的内置表达式和pyparsing_common中的表达式都是在导入时定义的,因此可以跳过一组标准的空白字符,其中包括'\ n'。如果您使用expr.copy()或仅使用普通expr()创建它们的新副本,则将获得使用已更新的空白字符的新表达式。

更改:

literal = pp.pyparsing_common.number | pp.dblQuotedString
line_number = pp.pyparsing_common.integer

收件人:

literal = pp.pyparsing_common.number() | pp.dblQuotedString()
line_number = pp.pyparsing_common.integer()

我认为您的泄漏问题将得到解决。