Python py解析中的递归

Python py解析中的递归,python,recursion,pyparsing,ebnf,Python,Recursion,Pyparsing,Ebnf,我无法将这个EBNF表达式翻译成Pyparsing,知道吗 token:: [A-Z] P:: !|token;P|(P^P)|(P*P) 问题是当使用递归时,解释器会失败。 这样的表达式应该是有效的: (ASD;!^FFF;!) A;B;C;! (((A;!^B;!)^C;D;!)*E;!) 要使用Pyparsing构建递归语法,您必须使用Pyparsing的Forward类从内到外进行一些思考。使用“前进”,可以为稍后定义的表达式定义空占位符。以下是此BNF的pyparsing的开始:

我无法将这个EBNF表达式翻译成Pyparsing,知道吗

token:: [A-Z]
P:: !|token;P|(P^P)|(P*P)
问题是当使用递归时,解释器会失败。 这样的表达式应该是有效的:

(ASD;!^FFF;!)
A;B;C;!
(((A;!^B;!)^C;D;!)*E;!)

要使用Pyparsing构建递归语法,您必须使用Pyparsing的Forward类从内到外进行一些思考。使用“前进”,可以为稍后定义的表达式定义空占位符。以下是此BNF的pyparsing的开始:

EXCLAM,SEMI,HAT,STAR = map(Literal,"!;^*")
LPAR,RPAR = map(Suppress,"()")
token = oneOf(list(alphas.upper()))
我使用Literal来定义运算符,但不使用grouping(),我们将使用pyparsing Group将结果物理地分组到子列表中

现在我们用Forward定义占位符表达式:

expr = Forward()

现在我们可以使用这个占位符来构建表达式(我们必须使用“”,这使得Lisp符号工作xD

from pyparsing import *

def pushFirst( strg, loc, toks ):
    toks[0][2], toks[0][1] = toks[0][1], toks[0][2]

def parseTerm(term):
    """
    EBNF syntax elements
    EXCLAM =  !
    HAT =  ^ 
    STAR =  *
    SEMI =  ; 
    LPAR =  (
    RPAR =  )
    """

    EXCLAM,HAT,STAR = map(Literal,"!^*")
    LPAR,RPAR = map(Suppress,"()")
    SEMI = Suppress(";")

    token = oneOf(list(alphas.upper()))
    expr = Forward()
    expr <<=    (
                    EXCLAM | 
                    Group(Word(alphas.upper()) + SEMI + ungroup(expr)) | 
                    Group(LPAR + expr + HAT + expr + RPAR).setParseAction( pushFirst ) | 
                    Group(LPAR + expr + STAR + expr + RPAR).setParseAction( pushFirst )
                )
    try:
        result = expr.parseString(term)   
    except ParseException as pe:
        print ' '*pe.loc + '^'
        print pe
    return result[0]



def computeTerm(term):
    print term


term = (parseTerm("(((AXX;!^B;!)^C;D;!)*E;!)"))

computeTerm(term)
从pyparsing导入*
def推送优先(strg、loc、toks):
toks[0][2],toks[0][1]=toks[0][1],toks[0][2]
定义解析术语(术语):
"""
EBNF语法元素
感叹号=!
帽子=^
星=*
半=;
LPAR=(
RPAR=)
"""
感叹号、帽子、星星=地图(文字“!^*”)
LPAR,RPAR=map(抑制“()”)
半自动=抑制(“;”)
token=list(alphas.upper())中的一个
expr=Forward()

expr-Woow你做到了!还有一个问题……我想将二进制运算符,如*和^to-prefix-notation,如Lisp更新。在文档中有一个使用字符串的示例,但不确定如何将其转换为数组。类似于:`Group(LPAR+expr+HAT+expr+RPAR)到Group(LPAR+expr+expr+HAT+RPAR)`
expr-expr-HAT
对我来说听起来像后缀符号。这不就是你的工作方式吗?如果你想让STAR和HAT具有同等的优先级,试试
Group(LPAR+expr+expr+(STAR | HAT)+RPAR)
。好吧,这是蛮力,但看起来你已经超越了PyParsiness的第二个层次,使用解析操作。恭喜你,PyParsiness玩得很开心!
(ASD;!^FFF;!)
  ^
Expected ";" (at char 2), (line:1, col:3)

A;B;C;!
['A', ';', 'B', ';', 'C', ';', '!']

(((A;!^B;!)^C;D;!)*E;!)
[[[['A', ';', '!', '^', 'B', ';', '!'], '^', 'C', ';', 'D', ';', '!'], '*', 'E', ';', '!']]
expr <<= (EXCLAM | 
          OneOrMore(token) + SEMI + expr | 
          Group(LPAR + expr + HAT + expr + RPAR) | 
          Group(LPAR + expr + STAR + expr + RPAR))
(ASD;!^FFF;!)
[['A', 'S', 'D', ';', '!', '^', 'F', 'F', 'F', ';', '!']]

A;B;C;!
['A', ';', 'B', ';', 'C', ';', '!']

(((A;!^B;!)^C;D;!)*E;!)
[[[['A', ';', '!', '^', 'B', ';', '!'], '^', 'C', ';', 'D', ';', '!'], '*', 'E', ';', '!']]
expr <<= (EXCLAM | 
          Group(OneOrMore(token) + SEMI + ungroup(expr)) | 
          Group(LPAR + expr + HAT + expr + RPAR) | 
          Group(LPAR + expr + STAR + expr + RPAR) )
(ASD;!^FFF;!)
[[['A', 'S', 'D', ';', '!'], '^', ['F', 'F', 'F', ';', '!']]]

A;B;C;!
[['A', ';', 'B', ';', 'C', ';', '!']]

(((A;!^B;!)^C;D;!)*E;!)
[[[[['A', ';', '!'], '^', ['B', ';', '!']], '^', ['C', ';', 'D', ';', '!']], '*', ['E', ';', '!']]]
from pyparsing import *

EXCLAM,SEMI,HAT,STAR = map(Literal,"!;^*")
LPAR,RPAR = map(Suppress,"()")
token = oneOf(list(alphas.upper()))
expr = Forward()
expr <<= (EXCLAM | 
          Group(OneOrMore(token) + SEMI + ungroup(expr)) | 
          Group(LPAR + expr + HAT + expr + RPAR) | 
          Group(LPAR + expr + STAR + expr + RPAR) )

tests = """\
(ASD;!^FFF;!)
A;B;C;!
(((A;!^B;!)^C;D;!)*E;!)""".splitlines()

for t in tests:
    print t
    try:
        print expr.parseString(t).dump()
    except ParseException as pe:
        print ' '*pe.loc + '^'
        print pe
    print
[[['ASD', ';', '!'], '^', ['FFF', ';', '!']]]
from pyparsing import *

def pushFirst( strg, loc, toks ):
    toks[0][2], toks[0][1] = toks[0][1], toks[0][2]

def parseTerm(term):
    """
    EBNF syntax elements
    EXCLAM =  !
    HAT =  ^ 
    STAR =  *
    SEMI =  ; 
    LPAR =  (
    RPAR =  )
    """

    EXCLAM,HAT,STAR = map(Literal,"!^*")
    LPAR,RPAR = map(Suppress,"()")
    SEMI = Suppress(";")

    token = oneOf(list(alphas.upper()))
    expr = Forward()
    expr <<=    (
                    EXCLAM | 
                    Group(Word(alphas.upper()) + SEMI + ungroup(expr)) | 
                    Group(LPAR + expr + HAT + expr + RPAR).setParseAction( pushFirst ) | 
                    Group(LPAR + expr + STAR + expr + RPAR).setParseAction( pushFirst )
                )
    try:
        result = expr.parseString(term)   
    except ParseException as pe:
        print ' '*pe.loc + '^'
        print pe
    return result[0]



def computeTerm(term):
    print term


term = (parseTerm("(((AXX;!^B;!)^C;D;!)*E;!)"))

computeTerm(term)