# indentedGrammarExample.py # # Copyright (c) 2006, Paul McGuire # # A sample of a pyparsing grammar using indentation for # grouping (like Python does). # from pyparsing import * data = """\ def A(z): A1 B = 100 G = A2 A2 A3 B def BB(a,b,c): BB1 def BBA(): bba1 bba2 bba3 C D """ indentStack = [1] def checkPeerIndent(s,l,t): curCol = col(l,s) if curCol != indentStack[-1]: if (not indentStack) or curCol > indentStack[-1]: raise ParseFatalException(s,l,"illegal nesting") raise ParseException(s,l,"not a peer entry") def checkSubIndent(s,l,t): curCol = col(l,s) if curCol > indentStack[-1]: indentStack.append( curCol ) else: raise ParseException(s,l,"not a subentry") def checkUnindent(s,l,t): curCol = col(l,s) if not(curCol < indentStack[-1] and curCol <= indentStack[-2]): raise ParseException(s,l,"not an unindent") def doUnindent(): indentStack.pop() INDENT = lineEnd.suppress() + empty + empty.copy().setParseAction(checkSubIndent) UNDENT = (stringEnd | FollowedBy(empty).setParseAction(checkUnindent)) UNDENT.setParseAction(doUnindent) stmt = Forward() suite = Group( OneOrMore( empty + stmt.setParseAction( checkPeerIndent ) ) ) identifier = Word(alphas, alphanums) funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") funcDef = Group( funcDecl + INDENT + suite + UNDENT ) rvalue = Forward() funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") rvalue << (funcCall | identifier | Word(nums)) assignment = Group(identifier + "=" + rvalue) stmt << ( funcDef | assignment | identifier ) print data parseTree = suite.parseString(data) import pprint pprint.pprint( parseTree.asList() )