jsonParser.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. # jsonParser.py
  2. #
  3. # Implementation of a simple JSON parser, returning a hierarchical
  4. # ParseResults object support both list- and dict-style data access.
  5. #
  6. # Copyright 2006, by Paul McGuire
  7. #
  8. # Updated 8 Jan 2007 - fixed dict grouping bug, and made elements and
  9. # members optional in array and object collections
  10. #
  11. # Updated 9 Aug 2016 - use more current pyparsing constructs/idioms
  12. #
  13. json_bnf = """
  14. object
  15. { members }
  16. {}
  17. members
  18. string : value
  19. members , string : value
  20. array
  21. [ elements ]
  22. []
  23. elements
  24. value
  25. elements , value
  26. value
  27. string
  28. number
  29. object
  30. array
  31. true
  32. false
  33. null
  34. """
  35. import pyparsing as pp
  36. from pyparsing import pyparsing_common as ppc
  37. def make_keyword(kwd_str, kwd_value):
  38. return pp.Keyword(kwd_str).setParseAction(pp.replaceWith(kwd_value))
  39. TRUE = make_keyword("true", True)
  40. FALSE = make_keyword("false", False)
  41. NULL = make_keyword("null", None)
  42. LBRACK, RBRACK, LBRACE, RBRACE, COLON = map(pp.Suppress, "[]{}:")
  43. jsonString = pp.dblQuotedString().setParseAction(pp.removeQuotes)
  44. jsonNumber = ppc.number()
  45. jsonObject = pp.Forward()
  46. jsonValue = pp.Forward()
  47. jsonElements = pp.delimitedList( jsonValue )
  48. jsonArray = pp.Group(LBRACK + pp.Optional(jsonElements, []) + RBRACK)
  49. jsonValue << (jsonString | jsonNumber | pp.Group(jsonObject) | jsonArray | TRUE | FALSE | NULL)
  50. memberDef = pp.Group(jsonString + COLON + jsonValue)
  51. jsonMembers = pp.delimitedList(memberDef)
  52. jsonObject << pp.Dict(LBRACE + pp.Optional(jsonMembers) + RBRACE)
  53. jsonComment = pp.cppStyleComment
  54. jsonObject.ignore(jsonComment)
  55. if __name__ == "__main__":
  56. testdata = """
  57. {
  58. "glossary": {
  59. "title": "example glossary",
  60. "GlossDiv": {
  61. "title": "S",
  62. "GlossList":
  63. {
  64. "ID": "SGML",
  65. "SortAs": "SGML",
  66. "GlossTerm": "Standard Generalized Markup Language",
  67. "TrueValue": true,
  68. "FalseValue": false,
  69. "Gravity": -9.8,
  70. "LargestPrimeLessThan100": 97,
  71. "AvogadroNumber": 6.02E23,
  72. "EvenPrimesGreaterThan2": null,
  73. "PrimesLessThan10" : [2,3,5,7],
  74. "Acronym": "SGML",
  75. "Abbrev": "ISO 8879:1986",
  76. "GlossDef": "A meta-markup language, used to create markup languages such as DocBook.",
  77. "GlossSeeAlso": ["GML", "XML", "markup"],
  78. "EmptyDict" : {},
  79. "EmptyList" : []
  80. }
  81. }
  82. }
  83. }
  84. """
  85. results = jsonObject.parseString(testdata)
  86. results.pprint()
  87. print()
  88. def testPrint(x):
  89. print(type(x), repr(x))
  90. print(list(results.glossary.GlossDiv.GlossList.keys()))
  91. testPrint( results.glossary.title )
  92. testPrint( results.glossary.GlossDiv.GlossList.ID )
  93. testPrint( results.glossary.GlossDiv.GlossList.FalseValue )
  94. testPrint( results.glossary.GlossDiv.GlossList.Acronym )
  95. testPrint( results.glossary.GlossDiv.GlossList.EvenPrimesGreaterThan2 )
  96. testPrint( results.glossary.GlossDiv.GlossList.PrimesLessThan10 )