pyparsing: Grouping guidelines -
pyparsing: below code put can parse nested function call , logical function call or hybrid call nests both function , logical function call. dump() data adds many unnecessary levels of braces because of grouping. removing group() results in wrong output. there guideline use group(parsers)?
also pyparsing document does'nt detail on how walk tree created , not of data available out there. please point me link/guide helps me write tree walker recursively parsed data test cases. translating parsed data valid tcl code.
from pyparsing import * pyparsing import oneormore, optional, word, delimitedlist, suppress # parse action -maker; # paul's example def makelrlike(numterms): if numterms none: # none operator can 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 number of terms, # convert flat list of tokens nested list def pa(s,l,t): t = t[0] if len(t) > initlen: ret = parseresults(t[:initlen]) = initlen while < len(t): ret = parseresults([ret] + t[i:i+incr]) += 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 logical if operatorprecedence used # works fine print line.parsestring("f(x, y)").dump() print line.parsestring("f(h())").dump() print line.parsestring("a , b").dump() print line.parsestring("f(a , b)").dump() print line.parsestring("f(g(x))").dump() print line.parsestring("f(a , 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) , g(f1(x), a, b, f2(x,y, k(x,y)))").dump() #does'nt work fine yet; #try changing flogical assignment logicalarg | flogic #print line.parsestring("a or b or c").dump() #print line.parsestring("f(a or b(x) or c)").dump()
Comments
Post a Comment