确定对递归解析器的最外层调用

时间:2018-09-19 15:36:08

标签: python pyparsing

我只需要在对递归解析器的最外层调用中运行一些代码,但无法想到使用pyparsing做到这一点的方法。这是我的代码:

from pyparsing import *
from itertools import count

L_PAR, R_PAR, = map(Suppress, '()')


def process_stmt(counter):
    """Closure counts up when nesting occurs"""

    def parse_action(tokens):
        for t in tokens:
            t["count"] = next(counter)
            # if not outermost:
            t["outermost"] = False

            # if outermost:
            #     t["outermost"] = True

    return parse_action


def outermost_true(tokens):
    tokens['outermost'] = True
    tokens['other'] = True


counter = count(0)
OR_stmt = Forward()
AND_stmt = Group(OneOrMore(Word("XYZ", exact=3)
                           ^ OR_stmt))("AND*")
AND_stmt.setParseAction(process_stmt(counter))
OR_stmt <<= Group(L_PAR
                  + OneOrMore(AND_stmt)
                  + R_PAR)("OR*")
OR_stmt.setParseAction(process_stmt(counter))
AND_stmt.addParseAction(outermost_true)

data = "(XXXYYY)ZZZ"

AND_stmt.runTests(data)

产生以下结果

(XXXYYY)ZZZ
[[[['XXX', 'YYY']], 'ZZZ']]
- AND: [[[['XXX', 'YYY']], 'ZZZ']]
  [0]:
    [[['XXX', 'YYY']], 'ZZZ']
    - OR: [[['XXX', 'YYY']]]
      [0]:
        [['XXX', 'YYY']]
        - AND: [['XXX', 'YYY']]
          [0]:
            ['XXX', 'YYY']
            - count: 0
            - outermost: False
        - count: 1
        - other: True
        - outermost: False
    - count: 2
    - outermost: False
- other: True
- outermost: True

如何将最外面的outermost属性设置为True

1 个答案:

答案 0 :(得分:0)

当我看到您将#include<stdio.h> #include<math.h> int main() { int a,g=10,m=1,c,num; printf("enter the number : "); scanf("%d",&a); c=log10(a); num=num+((a%10)*pow(10,c)); a=a/10; c=log10(a); while(m<=c){ if(m==c){ num=num+((a%10)*g)+a/10; break; } else{ num=num+((a%10)*g); g=g*10; a=a/10; m=m+1; } } printf("%d",num); } 中的outermost设置为TrueFalse时,我想我误会了您的意图。重新阅读您的问题,您希望代码仅在对递归解析器的最外层调用中运行。正如我在评论中所猜测的那样,该解决方案是创建一个外部process_stmt容器并将解析动作附加到该容器。这是您的代码,其中删除了对Forward的所有中间调用,而仅对包含process_stmt的最外层进行了一次调用:

Forward

给出:

counter = count(0)
OR_stmt = Forward()
AND_stmt = Group(OneOrMore(Word("XYZ", exact=3)
                           ^ OR_stmt))("AND*")
OR_stmt <<= Group(L_PAR
                  + OneOrMore(AND_stmt)
                  + R_PAR)("OR*")
outermost = Forward()
outermost <<= AND_stmt
outermost.addParseAction(outermost_true)

data = "(XXXYYY)ZZZ"

outermost.runTests(data)

如果您仍然希望为层次结构的每个级别调用一个parse动作,则我修改了process_stmt以打印每次调用时的进度:

(XXXYYY)ZZZ
[[[['XXX', 'YYY']], 'ZZZ']]
- AND: [[[['XXX', 'YYY']], 'ZZZ']]
  [0]:
    [[['XXX', 'YYY']], 'ZZZ']
    - OR: [[['XXX', 'YYY']]]
      [0]:
        [['XXX', 'YYY']]
        - AND: [['XXX', 'YYY']]
          [0]:
            ['XXX', 'YYY']
- other: True
- outermost: True

显示这些中间步骤-更好地可视化每个调用如何将内部级别def process_stmt(counter): """Closure counts up when nesting occurs""" def parse_action(tokens): for t in tokens: t["count"] = next(counter) # t["outermost"] = False t["outermost"] = (False, "used to be {!r}".format(t.outermost)) tokens['outermost'] = True print(tokens.dump()) print() return parse_action 重置为False,并将其最外部级别重置为True

outermost