json-parser.sml 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. (* json-parser.sml
  2. *
  3. * COPYRIGHT (c) 2008 The Fellowship of SML/NJ (http://www.smlnj.org)
  4. * All rights reserved.
  5. *)
  6. structure JSONParser :> sig
  7. (* abstract type of JSON input *)
  8. type source = JSONSource.source
  9. (* open a text input stream as a source *)
  10. val openStream : TextIO.instream -> source
  11. (* open a text file as a source *)
  12. val openFile : string -> source
  13. (* open a string as a source *)
  14. val openString : string -> source
  15. (* close a source *)
  16. val close : source -> unit
  17. val parse : source -> JSON.value
  18. val parseFile : string -> JSON.value
  19. end = struct
  20. structure Lex = JSONLexer
  21. structure T = JSONTokens
  22. structure J = JSON
  23. datatype source = datatype JSONSource.source
  24. val openStream = JSONSource.openStream
  25. val openFile = JSONSource.openFile
  26. val openString = JSONSource.openString
  27. val close = JSONSource.close
  28. fun parse (Src{closed = ref true, ...}) = raise Fail "closed JSON source"
  29. | parse (src as Src{srcMap, strm, ...}) = let
  30. val errorMsg = JSONSource.errorMsg src
  31. fun error arg = raise Fail(errorMsg arg)
  32. val lexer = Lex.lex srcMap
  33. fun parseValue (strm : Lex.strm) = let
  34. val (tok, span, strm) = lexer strm
  35. in
  36. case tok
  37. of T.LB => parseArray strm
  38. | T.LCB => parseObject strm
  39. | T.KW_null => (strm, J.NULL)
  40. | T.KW_true => (strm, J.BOOL true)
  41. | T.KW_false => (strm, J.BOOL false)
  42. | T.INT n => (strm, J.INT n)
  43. | T.FLOAT f => (strm, J.FLOAT f)
  44. | T.STRING s => (strm, J.STRING s)
  45. | _ => error (span, "parsing value", tok)
  46. (* end case *)
  47. end
  48. and parseArray (strm : Lex.strm) = (case lexer strm
  49. of (T.RB, _, strm) => (strm, J.ARRAY[])
  50. | _ => let
  51. fun loop (strm, items) = let
  52. val (strm, v) = parseValue strm
  53. (* expect either a "," or a "]" *)
  54. val (tok, span, strm) = lexer strm
  55. in
  56. case tok
  57. of T.RB => (strm, v::items)
  58. | T.COMMA => loop (strm, v::items)
  59. | _ => error (span, "parsing array", tok)
  60. (* end case *)
  61. end
  62. val (strm, items) = loop (strm, [])
  63. in
  64. (strm, J.ARRAY(List.rev items))
  65. end
  66. (* end case *))
  67. and parseObject (strm : Lex.strm) = let
  68. fun parseField ((T.STRING s, _, strm), flds) = (case lexer strm
  69. of (T.COLON, _, strm) => let
  70. val (strm, v) = parseValue strm
  71. in
  72. parseFields (strm, (s, v)::flds)
  73. end
  74. | (tok, span, _) => error (span, "parsing field", tok)
  75. (* end case *))
  76. | parseField ((tok, span, _), _) = error (span, "parsing field", tok)
  77. and parseFields (strm, flds) = (case lexer strm
  78. of (T.RCB, span, strm) => (strm, J.OBJECT(List.rev flds))
  79. | (T.COMMA, span, strm) => parseField (lexer strm, flds)
  80. | (tok, span, _) => error (span, "parsing object", tok)
  81. (* end case *))
  82. in
  83. case lexer strm
  84. of (T.RCB, span, strm) => (strm, J.OBJECT[])
  85. | tokEtc => parseField (tokEtc, [])
  86. (* end case *)
  87. end
  88. val (inStrm, value) = parseValue (!strm)
  89. in
  90. strm := inStrm;
  91. value
  92. end
  93. fun parseFile fileName = let
  94. val inStrm = openFile fileName
  95. val v = parse inStrm
  96. handle ex => (close inStrm; raise ex)
  97. in
  98. close inStrm;
  99. v
  100. end
  101. end