如何使用运算符和括号解析组

How to parse groups with operator and brackets

首先我想说我刚刚开始使用 pyparsing,我需要一些帮助来解决以下问题。所以这里是上下文:

我有一个包含文本行的文件。每行可以有一个 sequence 或者可以是一组与并发运算符 || 组合的序列。表示可以是 (seq1)||(seq2)||... 等,也可以只是 seq1.

序列seq_是一组事件,以question开始,后跟一个或多个答案,序列顺序由运算符所在行的答案顺序定义->=> 介于两者之间。解释是系统读取该行应该执行 question 然后检查答案是否与行中定义的答案相同,按照定义的顺序,因此是序列。前面定义的一个line where several sequences 运行 concurrently 简单的说就是先执行每个sequence开头的问题,然后系统才会对每个问题的答案进行独立的检查(并发执行和检查)。

question 格式本身就是 qtn(elm,sub,num1[,num2,num3,...]),其中 [] 之间的内容是可选的,elmsub 是名称,num_ 是数字。

答案比较复杂,可以是以下之一:

所以我的想法是定义不同大元素的通用语法(我不确定这是最好的方法):

qtn = Regex(r'qtn\([a-z0-9]+,[a-z]+(,[ex0-9_.]+)+\)')
ans = Combine(Regex(r'ans\([a-z0-9]+,[a-z]+(,[a-z0-9_.]+)+\)') + Regex('(<[0-9]+)*'))

也许最好分别定义什么是num,什么是timeout,什么是id,比如elma,然后根据这些定义组成答案.在将 seq 的每个元素放入列表并将所有序列的列表放入一行后,我打算在代码的后面部分解释每个元素。

我现在卡住的地方是如何定义答案的一般语法,这很复杂,这样可以根据 ()& 评估解析的输出和 | 运算符。我试图理解 fourFn.py pyparsing 示例,但到目前为止我一无所知。

欢迎您提供任何帮助。

您的 Regex 和示例字符串是定义简单解析器的良好输入,通常以 BNF 的形式更正式一些,但这些已经足够了。这是您的简单 ans 格式的基本实现,您应该能够从这里概括出问题的样子:

import pyparsing as pp

LPAR, RPAR, COMMA, LT = map(pp.Suppress, "(),<")

element = pp.Word(pp.alphas.lower(), pp.alphanums.lower())
action = pp.Word(pp.alphas.lower())
subject = pp.Word(pp.alphas.lower())
number = pp.pyparsing_common.number()
timeout_expr = LT + number("timeout")

# put the pieces together into a larger expression
ans_expr = pp.Group(pp.Literal('ans')
                    + LPAR
                    + element('element')
                    + COMMA
                    + action('action')
                    + COMMA
                    + subject('subject')
                    + COMMA
                    + number('num*')
                    + (COMMA + number('num*'))[...]
                    + RPAR
                    + pp.Optional(timeout_expr)
                    )

# use runTests to try it out, will also flag parse errors
ans_expr.runTests("""
    ans(first, act, sub, 1000)
    ans(first, act, sub, 1000, 2000)
    ans(first, act, sub, 1000, 2000) < 50

    # example of a parsing error
    ans(first, act1, sub, 1000)
    """)

将打印:

ans(first, act, sub, 1000)
[['ans', 'first', 'act', 'sub', 1000]]
[0]:
  ['ans', 'first', 'act', 'sub', 1000]
  - action: 'act'
  - element: 'first'
  - num: [1000]
  - subject: 'sub'

ans(first, act, sub, 1000, 2000)
[['ans', 'first', 'act', 'sub', 1000, 2000]]
[0]:
  ['ans', 'first', 'act', 'sub', 1000, 2000]
  - action: 'act'
  - element: 'first'
  - num: [1000, 2000]
  - subject: 'sub'

ans(first, act, sub, 1000, 2000) < 50
[['ans', 'first', 'act', 'sub', 1000, 2000, 50]]
[0]:
  ['ans', 'first', 'act', 'sub', 1000, 2000, 50]
  - action: 'act'
  - element: 'first'
  - num: [1000, 2000]
  - subject: 'sub'
  - timeout: 50

# example of a parsing error
ans(first, act1, sub, 1000)
              ^
FAIL: Expected ',', found '1'  (at char 14), (line:1, col:15)

注意使用结果名称来帮助您按名称访问结果,这将使您的解析器更易于维护和使用。