macroExpander.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # macroExpander.py
  2. #
  3. # Example pyparsing program for performing macro expansion, similar to
  4. # the C pre-processor. This program is not as fully-featured, simply
  5. # processing macros of the form:
  6. # #def xxx yyyyy
  7. # and replacing xxx with yyyyy in the rest of the input string. Macros
  8. # can also be composed using other macros, such as
  9. # #def zzz xxx+1
  10. # Since xxx was previously defined as yyyyy, then zzz will be replaced
  11. # with yyyyy+1.
  12. #
  13. # Copyright 2007 by Paul McGuire
  14. #
  15. from pyparsing import *
  16. # define the structure of a macro definition (the empty term is used
  17. # to advance to the next non-whitespace character)
  18. identifier = Word(alphas+"_",alphanums+"_")
  19. macroDef = "#def" + identifier("macro") + empty + restOfLine("value")
  20. # define a placeholder for defined macros - initially nothing
  21. macroExpr = Forward()
  22. macroExpr << NoMatch()
  23. # global dictionary for macro definitions
  24. macros = {}
  25. # parse action for macro definitions
  26. def processMacroDefn(s,l,t):
  27. macroVal = macroExpander.transformString(t.value)
  28. macros[t.macro] = macroVal
  29. macroExpr << MatchFirst(map(Keyword, macros.keys()))
  30. return "#def " + t.macro + " " + macroVal
  31. # parse action to replace macro references with their respective definition
  32. def processMacroRef(s,l,t):
  33. return macros[t[0]]
  34. # attach parse actions to expressions
  35. macroExpr.setParseAction(processMacroRef)
  36. macroDef.setParseAction(processMacroDefn)
  37. # define pattern for scanning through the input string
  38. macroExpander = macroExpr | macroDef
  39. # test macro substitution using transformString
  40. testString = """
  41. #def A 100
  42. #def ALEN A+1
  43. char Astring[ALEN];
  44. char AA[A];
  45. typedef char[ALEN] Acharbuf;
  46. """
  47. print(macroExpander.transformString(testString))
  48. print(macros)