how to get more info from parse results

2005-03-06
2013-05-14
  • Klaas Hofstra
    Klaas Hofstra
    2005-03-06

    Hi,

    I really like the power and simplicity of pyparsing and have a question about how the library should be used.

    I'll first give a small example that hopefully helps to describe my problem.

    As an example, lets say the input looks like:

      const a = 1
      const b = 2
      c = a + b
      d = a - b
      e = d

    Now, The grammer could look like this:

      plus = Literal("+")
      minus = Literal("-")
      eq = Literal("=").suppress()

      constName = Word(alphanums)
      constValue = Word(nums)
      constExpr = Group(Literal("const") + constName + eq + constValue)

      varName = Word(alphanums)
      varOp = plus | minus
      opExpr = Group(varName + eq + varName + varOp + varName)
      assignExpr = Group(varName + eq + varName)

      grammer = ZeroOrMore(constExpr) + ZeroOrMore(opExpr) + ZeroOrMore(assignExpr)

      result = grammer.parseString(str)

    OK, now my problem/question is that I need to a little 'parsing' of the result in order to extract the constants/plus-min/assigment expressions. There surely must be a better way of doing this because the parser 'knows' which rule matched, so it should be able to give me that information. Is there a way for me to specify the grammar in a different way so I don't need to do the extra 'parsing'?

    So I'd like to avoid stuff like this:
      constants = {}
      plusmin = []
      assign = {}
      for x in result :
          if x[0] == "const" :
              constants[x[1]] = x[2]
          else :
              if len(x) == 2 :
                  assign[x[0]] = x[1]
              else :
                  plusmin.append(x)

      print "constants: ", constants
      print "assignments: ", assign
      print "add/sub: ", plusmin

    and replace it with:
      results.get_me_the_constants()
      etc.

    I hope y'all understand my question, and thanks in advance!

    Cheers,

    Klaas

     
    • Paul McGuire
      Paul McGuire
      2005-03-06

      Klaas -

      Welcome to the growing world of pyparsing!

      You are absolutely on the right track - the parser does indeed 'know' which rule matched the incoming text.

      I think the feature you are looking for is another method on ParserElement, setParseAction.  This allows you to define a method to be called when the rule matches.  The method must accept 3 arguments: a string (the original parse text string), an integer (the location in the string at which the matching text was found), and a ParseResults object containing the matching tokens.  You can access a ParseResults as a list (as you were doing in your example), or as a dictionary (if results names were defined in the grammar).

      Since you are delving into the world of arithmetic expressions and assignments, take a look at the fourFn.py example that comes with pyparsing.

      Good luck, and keep us informed on your progress!

      -- Paul McGuire

       
      • Klaas Hofstra
        Klaas Hofstra
        2005-03-06

        Paul,

        Thanks for your reply. I've tried setParseAction and it seems to be the way to go.

        I'm not really working on arithmetic expressions, that was just the simplest example I could come up with :) I'm working on a parser that takes a custom hardware template description and converts that to a VHDL framework.

        Cheers,

        Klaas