pyparsing:分组指南

时间:2017-07-25 14:23:27

标签: pyparsing

pyparsing:下面是我提出的代码,它可以解析嵌套函数调用,逻辑函数调用或嵌套函数和逻辑函数调用的混合调用。由于分组,dump()数据添加了太多不必要的括号级别。删除Group()会导致输出错误。是否有使用Group(解析器)的指南?

此外,Pyparsing文档还详细介绍了如何遍历创建的树,并且没有太多可用的数据。请指向一个链接/指南,它帮助我为我的测试用例编写树步行器以递归解析数据。 我将把解析后的数据转换为有效的tcl代码。

from pyparsing import *
from pyparsing import OneOrMore, Optional, Word, delimitedList,  Suppress

# parse action -maker; # from Paul's example
def makeLRlike(numterms):
if numterms is None:
    # None operator can only by binary op
    initlen = 2
    incr = 1
else:
    initlen = {0:1,1:2,2:3,3:5}[numterms]
    incr = {0:1,1:1,2:2,3:4}[numterms]

# define parse action for this number of terms,
# to convert flat list of tokens into nested list
def pa(s,l,t):
    t = t[0]
    if len(t) > initlen:
        ret = ParseResults(t[:initlen])
        i = initlen
        while i < len(t):
            ret = ParseResults([ret] + t[i:i+incr])
            i += incr
        return ParseResults([ret])
return pa


line        = Forward()
fcall       = Forward().setResultsName("fcall")
flogical    = Forward()

lparen      = Literal("(").suppress()
rparen      = Literal(")").suppress()

arg         = Word(alphas,alphanums+"_"+"."+"+"+"-"+"*"+"/")
args        = delimitedList(arg).setResultsName("arg") 

fargs       = delimitedList(OneOrMore(flogical) | OneOrMore(fcall)  | 
OneOrMore(arg))
fname       = Word(alphas,alphanums+"_")
fcall       << Group(fname.setResultsName('func') + Group(lparen + 
Optional(fargs) + rparen).setResultsName('fargs'))

flogic      = Keyword("or") | Keyword("and") | Keyword("not")
logicalArg  = delimitedList(Group(fcall.setResultsName("fcall")) | 
Group(arg.setResultsName("arg")))
#logicalArg.setDebug()

flogical << Group(logicalArg.setResultsName('larg1') + 
flogic.setResultsName('flogic') + logicalArg.setResultsName('larg2')) 


#logical    = operatorPrecedence(flogical, [(not, 1, opAssoc.RIGHT, 
makeLRlike(2)),
#                                           (and, 2, opAssoc.LEFT, 
makeLRlike(2)),
#                                           (or , 2, opAssoc.LEFT, 
makeLRlike(2))])


line    = flogical | fcall #change to logical if operatorPrecedence is used


# Works fine
print line.parseString("f(x, y)").dump()
print line.parseString("f(h())").dump()
print line.parseString("a and b").dump()
print line.parseString("f(a and b)").dump()
print line.parseString("f(g(x))").dump()
print line.parseString("f(a and b) or h(b not c)").dump()
print line.parseString("f(g(x), y)").dump()
print line.parseString("g(f1(x), a, b, f2(x,y, k(x,y)))").dump()
print line.parseString("f(a not c) and g(f1(x), a, b, f2(x,y, 
k(x,y)))").dump()

#Does'nt work fine yet; 
#try changing flogical assignment to  logicalArg | flogic
#print line.parseString("a or b or c").dump()
#print line.parseString("f(a or b(x) or c)").dump()

0 个答案:

没有答案