title: Contextual parsing of structured text configuration files using pyparsing
body: <p>I'm trying to build a simple parser using pyparsing.</p>
  
  <p>My example file looks as follows:</p>
  
  <pre><code># comment
  # comment
  
  name1 = value1
  name2 = value2
  
  
  example_list a
    foo
    bar
  
  
  grp1 (
  
  example_list2 aa
    foo
    bar
  
  
  example_list3 bb
    foo
    bar
  
  )
  
  
  
  grp2 (
  
  example_list4 x
    foo
    bar
  
  example_list5 x
    foo
    bar
  
  example_list6 x
    foo
    bar
  )
  </code></pre>
  
  <p>The parser I've come up with so far looks like this:</p>
  
  <pre><code>#!/usr/bin/python
  import sys
  from pyparsing import *
  
  blank_line = lineStart + restOfLine
  comment = Suppress("#") + restOfLine
  
  alias = Word(alphas, alphanums)
  name = Word(alphas, alphanums + "_")
  value = Word(printables)
  
  parameter = name + Suppress("=") + value
  flag = Literal("*") | Literal("#") | Literal("!")
  list_item = Optional(flag) + value
  list = name + alias + lineEnd + OneOrMore(list_item) + blank_line
  group = alias + Suppress("(") + lineEnd + OneOrMore(list) + lineStart + Suppress(")")
  script = ZeroOrMore(Suppress(blank_line) | Suppress(comment) | parameter ^ list ^ group)
  
  if __name__ == "__main__":
      print script.parseFile(sys.argv[1])
  </code></pre>
  
  <p>but of course it doesn't work.</p>
  
  <p>What I think I need is some way for the parser to know that if we have a string followed by an equals sign, that only then can we expect just one more string.</p>
  
  <p>If we have a string followed by a bracket, then we've started a group.</p>
  
  <p>And if we have two strings, then we've started a list.</p>
  
  <p>How do I do this?</p>
  
  <p>Also, comments could conceivably also appear on the end of lines...</p>