json: remove the old nitcc parser
authorAlexis Laferrière <alexis.laf@xymus.net>
Thu, 3 Aug 2017 16:46:30 +0000 (12:46 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Thu, 31 Aug 2017 14:16:17 +0000 (10:16 -0400)
And move the content of `string_parser` to `static` because of high
coupling.

Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/json/.gitattributes [deleted file]
lib/json/.gitignore [deleted file]
lib/json/Makefile [deleted file]
lib/json/error.nit
lib/json/json_lexer.nit [deleted file]
lib/json/json_parser.nit [deleted file]
lib/json/serialization_read.nit
lib/json/static.nit
lib/json/string_parser.nit [deleted file]

diff --git a/lib/json/.gitattributes b/lib/json/.gitattributes
deleted file mode 100644 (file)
index 041d62a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-json_lexer.nit         -diff
-json_parser.nit                -diff
diff --git a/lib/json/.gitignore b/lib/json/.gitignore
deleted file mode 100644 (file)
index 0f08b2b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-json.concrete_grammar.txt
-json.dfa.dot
-json.gram.dot
-json.lr.dot
-json.lr.txt
-json.nfa.dot
-json_test_parser.nit
diff --git a/lib/json/Makefile b/lib/json/Makefile
deleted file mode 100644 (file)
index a8a5eb9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-NITCCDIR=../../contrib/nitcc/
-
-pre-build: $(NITCCDIR)src/nitcc
-       $(NITCCDIR)src/nitcc $(NITCCDIR)examples/json.sablecc
-
-$(NITCCDIR)src/nitcc:
-       make -C $(NITCCDIR)
index 26a9952..f13d2fc 100644 (file)
@@ -8,25 +8,16 @@
 # You are allowed to redistribute it and sell it, alone or is a part of
 # another product.
 
-# Errors related to JSON parsing.
-module json::error
+# Intro `JsonParseError` which is exposed by all JSON reading APIs
+module error
 
-import nitcc_runtime
+import parser_base
 
-# Ill-formed JSON.
+# JSON format error at parsing
 class JsonParseError
        super Error
        serialize
 
-       # The location of the error in the original text.
-       var position: nullable Position
-
-       redef fun to_s do
-               var p = position
-               if p isa Position then
-                       return "Error Parsing JSON: [{p}] {super}"
-               else
-                       return super
-               end
-       end
+       # Location of the error in source
+       var location: nullable Location = null
 end
diff --git a/lib/json/json_lexer.nit b/lib/json/json_lexer.nit
deleted file mode 100644 (file)
index 32a82b2..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-# Lexer generated by nitcc for the grammar json
-module json_lexer is generated, no_warning "missing-doc"
-import nitcc_runtime
-import json_parser
-class Lexer_json
-       super Lexer
-       redef fun start_state do return dfastate_0
-end
-private fun dfastate_0: DFAState0 do return once new DFAState0
-private fun dfastate_1: DFAState1 do return once new DFAState1
-private fun dfastate_2: DFAState2 do return once new DFAState2
-private fun dfastate_3: DFAState3 do return once new DFAState3
-private fun dfastate_4: DFAState4 do return once new DFAState4
-private fun dfastate_5: DFAState5 do return once new DFAState5
-private fun dfastate_6: DFAState6 do return once new DFAState6
-private fun dfastate_7: DFAState7 do return once new DFAState7
-private fun dfastate_8: DFAState8 do return once new DFAState8
-private fun dfastate_9: DFAState9 do return once new DFAState9
-private fun dfastate_10: DFAState10 do return once new DFAState10
-private fun dfastate_11: DFAState11 do return once new DFAState11
-private fun dfastate_12: DFAState12 do return once new DFAState12
-private fun dfastate_13: DFAState13 do return once new DFAState13
-private fun dfastate_14: DFAState14 do return once new DFAState14
-private fun dfastate_15: DFAState15 do return once new DFAState15
-private fun dfastate_16: DFAState16 do return once new DFAState16
-private fun dfastate_17: DFAState17 do return once new DFAState17
-private fun dfastate_18: DFAState18 do return once new DFAState18
-private fun dfastate_19: DFAState19 do return once new DFAState19
-private fun dfastate_20: DFAState20 do return once new DFAState20
-private fun dfastate_21: DFAState21 do return once new DFAState21
-private fun dfastate_22: DFAState22 do return once new DFAState22
-private fun dfastate_23: DFAState23 do return once new DFAState23
-private fun dfastate_24: DFAState24 do return once new DFAState24
-private fun dfastate_25: DFAState25 do return once new DFAState25
-private fun dfastate_26: DFAState26 do return once new DFAState26
-private fun dfastate_27: DFAState27 do return once new DFAState27
-private fun dfastate_28: DFAState28 do return once new DFAState28
-private fun dfastate_29: DFAState29 do return once new DFAState29
-private fun dfastate_30: DFAState30 do return once new DFAState30
-private fun dfastate_31: DFAState31 do return once new DFAState31
-private fun dfastate_32: DFAState32 do return once new DFAState32
-private fun dfastate_33: DFAState33 do return once new DFAState33
-private fun dfastate_34: DFAState34 do return once new DFAState34
-class MyNToken
-       super NToken
-end
-private class DFAState0
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 8 then return null
-               if c <= 10 then return dfastate_1
-               if c <= 31 then return null
-               if c <= 32 then return dfastate_1
-               if c <= 33 then return null
-               if c <= 34 then return dfastate_2
-               if c <= 43 then return null
-               if c <= 44 then return dfastate_3
-               if c <= 45 then return dfastate_4
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_5
-               if c <= 58 then return dfastate_6
-               if c <= 90 then return null
-               if c <= 91 then return dfastate_7
-               if c <= 92 then return null
-               if c <= 93 then return dfastate_8
-               if c <= 101 then return null
-               if c <= 102 then return dfastate_9
-               if c <= 109 then return null
-               if c <= 110 then return dfastate_10
-               if c <= 115 then return null
-               if c <= 116 then return dfastate_11
-               if c <= 122 then return null
-               if c <= 123 then return dfastate_12
-               if c <= 124 then return null
-               if c <= 125 then return dfastate_13
-               return null
-       end
-end
-private class DFAState1
-       super DFAState
-       redef fun is_accept do return true
-       redef fun is_ignored do return true
-       redef fun make_token(position, source) do
-               return null
-       end
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 8 then return null
-               if c <= 10 then return dfastate_1
-               if c <= 31 then return null
-               if c <= 32 then return dfastate_1
-               return null
-       end
-end
-private class DFAState2
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c > 92 then return dfastate_2
-               if c <= 33 then return dfastate_2
-               if c <= 34 then return dfastate_29
-               if c <= 91 then return dfastate_2
-               return dfastate_30
-       end
-end
-private class DFAState3
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_44d_39d
-               t.text = ","
-               t.position = position
-               return t
-       end
-end
-private class DFAState4
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_5
-               return null
-       end
-end
-private class DFAState5
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new Nnumber
-               t.text = position.extract(source)
-               t.position = position
-               return t
-       end
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 45 then return null
-               if c <= 46 then return dfastate_24
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_5
-               if c <= 68 then return null
-               if c <= 69 then return dfastate_25
-               if c <= 100 then return null
-               if c <= 101 then return dfastate_25
-               return null
-       end
-end
-private class DFAState6
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_58d_39d
-               t.text = ":"
-               t.position = position
-               return t
-       end
-end
-private class DFAState7
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_91d_39d
-               t.text = "["
-               t.position = position
-               return t
-       end
-end
-private class DFAState8
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_93d_39d
-               t.text = "]"
-               t.position = position
-               return t
-       end
-end
-private class DFAState9
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 96 then return null
-               if c <= 97 then return dfastate_20
-               return null
-       end
-end
-private class DFAState10
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 116 then return null
-               if c <= 117 then return dfastate_17
-               return null
-       end
-end
-private class DFAState11
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 113 then return null
-               if c <= 114 then return dfastate_14
-               return null
-       end
-end
-private class DFAState12
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_123d_39d
-               t.text = "\{"
-               t.position = position
-               return t
-       end
-end
-private class DFAState13
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39d_125d_39d
-               t.text = "\}"
-               t.position = position
-               return t
-       end
-end
-private class DFAState14
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 116 then return null
-               if c <= 117 then return dfastate_15
-               return null
-       end
-end
-private class DFAState15
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 100 then return null
-               if c <= 101 then return dfastate_16
-               return null
-       end
-end
-private class DFAState16
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39dtrue_39d
-               t.text = "true"
-               t.position = position
-               return t
-       end
-end
-private class DFAState17
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 107 then return null
-               if c <= 108 then return dfastate_18
-               return null
-       end
-end
-private class DFAState18
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 107 then return null
-               if c <= 108 then return dfastate_19
-               return null
-       end
-end
-private class DFAState19
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39dnull_39d
-               t.text = "null"
-               t.position = position
-               return t
-       end
-end
-private class DFAState20
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 107 then return null
-               if c <= 108 then return dfastate_21
-               return null
-       end
-end
-private class DFAState21
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 114 then return null
-               if c <= 115 then return dfastate_22
-               return null
-       end
-end
-private class DFAState22
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 100 then return null
-               if c <= 101 then return dfastate_23
-               return null
-       end
-end
-private class DFAState23
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new N_39dfalse_39d
-               t.text = "false"
-               t.position = position
-               return t
-       end
-end
-private class DFAState24
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_28
-               return null
-       end
-end
-private class DFAState25
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 42 then return null
-               if c <= 43 then return dfastate_26
-               if c <= 44 then return null
-               if c <= 45 then return dfastate_26
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_27
-               return null
-       end
-end
-private class DFAState26
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_27
-               return null
-       end
-end
-private class DFAState27
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new Nnumber
-               t.text = position.extract(source)
-               t.position = position
-               return t
-       end
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_27
-               return null
-       end
-end
-private class DFAState28
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new Nnumber
-               t.text = position.extract(source)
-               t.position = position
-               return t
-       end
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_28
-               if c <= 68 then return null
-               if c <= 69 then return dfastate_25
-               if c <= 100 then return null
-               if c <= 101 then return dfastate_25
-               return null
-       end
-end
-private class DFAState29
-       super DFAState
-       redef fun is_accept do return true
-       redef fun make_token(position, source) do
-               var t = new Nstring
-               t.text = position.extract(source)
-               t.position = position
-               return t
-       end
-end
-private class DFAState30
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 33 then return null
-               if c <= 34 then return dfastate_2
-               if c <= 46 then return null
-               if c <= 47 then return dfastate_2
-               if c <= 91 then return null
-               if c <= 92 then return dfastate_2
-               if c <= 97 then return null
-               if c <= 98 then return dfastate_2
-               if c <= 101 then return null
-               if c <= 102 then return dfastate_2
-               if c <= 109 then return null
-               if c <= 110 then return dfastate_2
-               if c <= 113 then return null
-               if c <= 114 then return dfastate_2
-               if c <= 115 then return null
-               if c <= 116 then return dfastate_2
-               if c <= 117 then return dfastate_31
-               return null
-       end
-end
-private class DFAState31
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_32
-               if c <= 64 then return null
-               if c <= 90 then return dfastate_32
-               if c <= 96 then return null
-               if c <= 122 then return dfastate_32
-               return null
-       end
-end
-private class DFAState32
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_33
-               if c <= 64 then return null
-               if c <= 90 then return dfastate_33
-               if c <= 96 then return null
-               if c <= 122 then return dfastate_33
-               return null
-       end
-end
-private class DFAState33
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_34
-               if c <= 64 then return null
-               if c <= 90 then return dfastate_34
-               if c <= 96 then return null
-               if c <= 122 then return dfastate_34
-               return null
-       end
-end
-private class DFAState34
-       super DFAState
-       redef fun trans(char) do
-               var c = char.code_point
-               if c <= 47 then return null
-               if c <= 57 then return dfastate_2
-               if c <= 64 then return null
-               if c <= 90 then return dfastate_2
-               if c <= 96 then return null
-               if c <= 122 then return dfastate_2
-               return null
-       end
-end
diff --git a/lib/json/json_parser.nit b/lib/json/json_parser.nit
deleted file mode 100644 (file)
index 28094c0..0000000
+++ /dev/null
@@ -1,876 +0,0 @@
-# Parser generated by nitcc for the grammar json
-module json_parser is generated, no_warning("missing-doc","old-init")
-import nitcc_runtime
-class Parser_json
-       super Parser
-       redef fun start_state do return state_Start
-end
-private fun state_Start: LRStateStart do return once new LRStateStart
-private fun state_value: LRStatevalue do return once new LRStatevalue
-private fun state_number: LRStatenumber do return once new LRStatenumber
-private fun state_string: LRStatestring do return once new LRStatestring
-private fun state__39dtrue_39d: LRState_39dtrue_39d do return once new LRState_39dtrue_39d
-private fun state__39dfalse_39d: LRState_39dfalse_39d do return once new LRState_39dfalse_39d
-private fun state__39dnull_39d: LRState_39dnull_39d do return once new LRState_39dnull_39d
-private fun state__39d_123d_39d: LRState_39d_123d_39d do return once new LRState_39d_123d_39d
-private fun state__39d_91d_39d: LRState_39d_91d_39d do return once new LRState_39d_91d_39d
-private fun state_value_32dEof: LRStatevalue_32dEof do return once new LRStatevalue_32dEof
-private fun state__39d_123d_39d_32dmembers: LRState_39d_123d_39d_32dmembers do return once new LRState_39d_123d_39d_32dmembers
-private fun state__39d_123d_39d_32d_39d_125d_39d: LRState_39d_123d_39d_32d_39d_125d_39d do return once new LRState_39d_123d_39d_32d_39d_125d_39d
-private fun state__39d_123d_39d_32dpair: LRState_39d_123d_39d_32dpair do return once new LRState_39d_123d_39d_32dpair
-private fun state__39d_123d_39d_32dstring: LRState_39d_123d_39d_32dstring do return once new LRState_39d_123d_39d_32dstring
-private fun state__39d_91d_39d_32delements: LRState_39d_91d_39d_32delements do return once new LRState_39d_91d_39d_32delements
-private fun state__39d_91d_39d_32d_39d_93d_39d: LRState_39d_91d_39d_32d_39d_93d_39d do return once new LRState_39d_91d_39d_32d_39d_93d_39d
-private fun state__39d_91d_39d_32dvalue: LRState_39d_91d_39d_32dvalue do return once new LRState_39d_91d_39d_32dvalue
-private fun state__39d_123d_39d_32dmembers_32d_39d_125d_39d: LRState_39d_123d_39d_32dmembers_32d_39d_125d_39d do return once new LRState_39d_123d_39d_32dmembers_32d_39d_125d_39d
-private fun state__39d_123d_39d_32dmembers_32d_39d_44d_39d: LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d do return once new LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d
-private fun state__39d_123d_39d_32dstring_32d_39d_58d_39d: LRState_39d_123d_39d_32dstring_32d_39d_58d_39d do return once new LRState_39d_123d_39d_32dstring_32d_39d_58d_39d
-private fun state__39d_91d_39d_32delements_32d_39d_93d_39d: LRState_39d_91d_39d_32delements_32d_39d_93d_39d do return once new LRState_39d_91d_39d_32delements_32d_39d_93d_39d
-private fun state__39d_91d_39d_32delements_32d_39d_44d_39d: LRState_39d_91d_39d_32delements_32d_39d_44d_39d do return once new LRState_39d_91d_39d_32delements_32d_39d_44d_39d
-private fun state__39d_123d_39d_32dmembers_32d_39d_44d_39d_32dpair: LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d_32dpair do return once new LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d_32dpair
-private fun state__39d_123d_39d_32dstring_32d_39d_58d_39d_32dvalue: LRState_39d_123d_39d_32dstring_32d_39d_58d_39d_32dvalue do return once new LRState_39d_123d_39d_32dstring_32d_39d_58d_39d_32dvalue
-private fun state__39d_91d_39d_32delements_32d_39d_44d_39d_32dvalue: LRState_39d_91d_39d_32delements_32d_39d_44d_39d_32dvalue do return once new LRState_39d_91d_39d_32delements_32d_39d_44d_39d_32dvalue
-private fun goto_Nvalue: Goto_Nvalue do return once new Goto_Nvalue
-private fun reduce_Nvalue_number(parser: Parser) do
-               # REDUCE value::value_number=number
-               var n0 = parser.pop.as(Nnumber)
-               var p1 = new Nvalue_number(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_string(parser: Parser) do
-               # REDUCE value::value_string=string
-               var n0 = parser.pop.as(Nstring)
-               var p1 = new Nvalue_string(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_true(parser: Parser) do
-               # REDUCE value::value_true='true'
-               var n0 = parser.pop.as(N_39dtrue_39d)
-               var p1 = new Nvalue_true(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_false(parser: Parser) do
-               # REDUCE value::value_false='false'
-               var n0 = parser.pop.as(N_39dfalse_39d)
-               var p1 = new Nvalue_false(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_null(parser: Parser) do
-               # REDUCE value::value_null='null'
-               var n0 = parser.pop.as(N_39dnull_39d)
-               var p1 = new Nvalue_null(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_object_95d0(parser: Parser) do
-               # REDUCE value::value_object_0='{' members '}'
-               var n2 = parser.pop.as(N_39d_125d_39d)
-               var n1 = parser.pop.as(Nmembers)
-               var n0 = parser.pop.as(N_39d_123d_39d)
-               var p1 = new Nvalue_object(n0, n1, n2)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_object_95d1(parser: Parser) do
-               # REDUCE value::value_object_1='{' '}'
-               var n1 = parser.pop.as(N_39d_125d_39d)
-               var n0 = parser.pop.as(N_39d_123d_39d)
-               var p1 = new Nvalue_object(n0, null, n1)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_array_95d0(parser: Parser) do
-               # REDUCE value::value_array_0='[' elements ']'
-               var n2 = parser.pop.as(N_39d_93d_39d)
-               var n1 = parser.pop.as(Nelements)
-               var n0 = parser.pop.as(N_39d_91d_39d)
-               var p1 = new Nvalue_array(n0, n1, n2)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun reduce_Nvalue_array_95d1(parser: Parser) do
-               # REDUCE value::value_array_1='[' ']'
-               var n1 = parser.pop.as(N_39d_93d_39d)
-               var n0 = parser.pop.as(N_39d_91d_39d)
-               var p1 = new Nvalue_array(n0, null, n1)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nvalue)
-end
-private fun goto_Nmembers: Goto_Nmembers do return once new Goto_Nmembers
-private fun reduce_Nmembers_tail(parser: Parser) do
-               # REDUCE members::members_tail=members ',' pair
-               var n2 = parser.pop.as(Npair)
-               var n1 = parser.pop.as(N_39d_44d_39d)
-               var n0 = parser.pop.as(Nmembers)
-               var p1 = new Nmembers_tail(n0, n1, n2)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nmembers)
-end
-private fun reduce_Nmembers_head(parser: Parser) do
-               # REDUCE members::members_head=pair
-               var n0 = parser.pop.as(Npair)
-               var p1 = new Nmembers_head(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nmembers)
-end
-private fun goto_Npair: Goto_Npair do return once new Goto_Npair
-private fun reduce_Npair(parser: Parser) do
-               # REDUCE pair::pair=string ':' value
-               var n2 = parser.pop.as(Nvalue)
-               var n1 = parser.pop.as(N_39d_58d_39d)
-               var n0 = parser.pop.as(Nstring)
-               var p1 = new Npair(n0, n1, n2)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Npair)
-end
-private fun goto_Nelements: Goto_Nelements do return once new Goto_Nelements
-private fun reduce_Nelements_tail(parser: Parser) do
-               # REDUCE elements::elements_tail=elements ',' value
-               var n2 = parser.pop.as(Nvalue)
-               var n1 = parser.pop.as(N_39d_44d_39d)
-               var n0 = parser.pop.as(Nelements)
-               var p1 = new Nelements_tail(n0, n1, n2)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nelements)
-end
-private fun reduce_Nelements_head(parser: Parser) do
-               # REDUCE elements::elements_head=value
-               var n0 = parser.pop.as(Nvalue)
-               var p1 = new Nelements_head(n0)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.goto(goto_Nelements)
-end
-private fun goto_N_start: Goto_N_start do return once new Goto_N_start
-private fun reduce_NStart(parser: Parser) do
-               # REDUCE _start::Start=value Eof
-               var n1 = parser.pop.as(NEof)
-               var n0 = parser.pop.as(Nvalue)
-               var p1 = new NStart(n0, n1)
-               var prod = p1
-               parser.node_stack.push prod
-               parser.stop = true
-end
-redef class NToken
-       # guarded action for state Start
-       # 7 shift(s) and 0 reduce(s)
-       private fun action_sStart(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state value
-       # 1 shift(s) and 0 reduce(s)
-       private fun action_svalue(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '{'
-       # 2 shift(s) and 0 reduce(s)
-       private fun action_s_39d_123d_39d(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '['
-       # 8 shift(s) and 0 reduce(s)
-       private fun action_s_39d_91d_39d(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '{' members
-       # 2 shift(s) and 0 reduce(s)
-       private fun action_s_39d_123d_39d_32dmembers(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '{' string
-       # 1 shift(s) and 0 reduce(s)
-       private fun action_s_39d_123d_39d_32dstring(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '[' elements
-       # 2 shift(s) and 0 reduce(s)
-       private fun action_s_39d_91d_39d_32delements(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '{' members ','
-       # 1 shift(s) and 0 reduce(s)
-       private fun action_s_39d_123d_39d_32dmembers_32d_39d_44d_39d(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '{' string ':'
-       # 7 shift(s) and 0 reduce(s)
-       private fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser: Parser) do
-               parser.parse_error
-       end
-       # guarded action for state '[' elements ','
-       # 7 shift(s) and 0 reduce(s)
-       private fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser: Parser) do
-               parser.parse_error
-       end
-end
-class N_39d_123d_39d
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state__39d_123d_39d)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39d_123d_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state__39d_123d_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state__39d_123d_39d)
-       end
-       redef fun node_name do return "\'\{\'"
-end
-class N_39d_125d_39d
-       super NToken
-       redef fun action_s_39d_123d_39d(parser) do
-               parser.shift(state__39d_123d_39d_32d_39d_125d_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dmembers(parser) do
-               parser.shift(state__39d_123d_39d_32dmembers_32d_39d_125d_39d)
-       end
-       redef fun node_name do return "\'\}\'"
-end
-class N_39d_91d_39d
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state__39d_91d_39d)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39d_91d_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state__39d_91d_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state__39d_91d_39d)
-       end
-       redef fun node_name do return "\'[\'"
-end
-class N_39d_93d_39d
-       super NToken
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39d_91d_39d_32d_39d_93d_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements(parser) do
-               parser.shift(state__39d_91d_39d_32delements_32d_39d_93d_39d)
-       end
-       redef fun node_name do return "\']\'"
-end
-class Nnumber
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state_number)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state_number)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state_number)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state_number)
-       end
-       redef fun node_name do return "number"
-end
-class Nstring
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state_string)
-       end
-       redef fun action_s_39d_123d_39d(parser) do
-               parser.shift(state__39d_123d_39d_32dstring)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state_string)
-       end
-       redef fun action_s_39d_123d_39d_32dmembers_32d_39d_44d_39d(parser) do
-               parser.shift(state__39d_123d_39d_32dstring)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state_string)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state_string)
-       end
-       redef fun node_name do return "string"
-end
-class N_39dtrue_39d
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state__39dtrue_39d)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39dtrue_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state__39dtrue_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state__39dtrue_39d)
-       end
-       redef fun node_name do return "\'true\'"
-end
-class N_39dfalse_39d
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state__39dfalse_39d)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39dfalse_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state__39dfalse_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state__39dfalse_39d)
-       end
-       redef fun node_name do return "\'false\'"
-end
-class N_39dnull_39d
-       super NToken
-       redef fun action_sStart(parser) do
-               parser.shift(state__39dnull_39d)
-       end
-       redef fun action_s_39d_91d_39d(parser) do
-               parser.shift(state__39dnull_39d)
-       end
-       redef fun action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser) do
-               parser.shift(state__39dnull_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser) do
-               parser.shift(state__39dnull_39d)
-       end
-       redef fun node_name do return "\'null\'"
-end
-class N_39d_44d_39d
-       super NToken
-       redef fun action_s_39d_123d_39d_32dmembers(parser) do
-               parser.shift(state__39d_123d_39d_32dmembers_32d_39d_44d_39d)
-       end
-       redef fun action_s_39d_91d_39d_32delements(parser) do
-               parser.shift(state__39d_91d_39d_32delements_32d_39d_44d_39d)
-       end
-       redef fun node_name do return "\',\'"
-end
-class N_39d_58d_39d
-       super NToken
-       redef fun action_s_39d_123d_39d_32dstring(parser) do
-               parser.shift(state__39d_123d_39d_32dstring_32d_39d_58d_39d)
-       end
-       redef fun node_name do return "\':\'"
-end
-redef class NEof
-       super NToken
-       redef fun action_svalue(parser) do
-               parser.shift(state_value_32dEof)
-       end
-       redef fun node_name do return "Eof"
-end
-redef class LRGoto
-       private fun goto_s_39d_123d_39d(parser: Parser) do abort
-       private fun goto_s_39d_91d_39d(parser: Parser) do abort
-end
-class Goto_Nvalue
-       super LRGoto
-       redef fun goto_s_39d_91d_39d(parser) do
-               parser.push(state__39d_91d_39d_32dvalue)
-       end
-end
-class Goto_Nmembers
-       super LRGoto
-       redef fun goto_s_39d_123d_39d(parser) do
-               parser.push(state__39d_123d_39d_32dmembers)
-       end
-end
-class Goto_Npair
-       super LRGoto
-       redef fun goto_s_39d_123d_39d(parser) do
-               parser.push(state__39d_123d_39d_32dpair)
-       end
-end
-class Goto_Nelements
-       super LRGoto
-       redef fun goto_s_39d_91d_39d(parser) do
-               parser.push(state__39d_91d_39d_32delements)
-       end
-end
-class Goto_N_start
-       super LRGoto
-end
-class Nvalue
-       super NProd
-       redef fun node_name do return "value"
-end
-class Nvalue_number
-       super Nvalue
-       redef fun node_name do return "value_number"
-       var n_number: Nnumber
-       init(n_number: Nnumber) do
-               self.n_number = n_number
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_number
-               abort
-       end
-end
-class Nvalue_string
-       super Nvalue
-       redef fun node_name do return "value_string"
-       var n_string: Nstring
-       init(n_string: Nstring) do
-               self.n_string = n_string
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_string
-               abort
-       end
-end
-class Nvalue_true
-       super Nvalue
-       redef fun node_name do return "value_true"
-       var n_0: N_39dtrue_39d
-       init(n_0: N_39dtrue_39d) do
-               self.n_0 = n_0
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_0
-               abort
-       end
-end
-class Nvalue_false
-       super Nvalue
-       redef fun node_name do return "value_false"
-       var n_0: N_39dfalse_39d
-       init(n_0: N_39dfalse_39d) do
-               self.n_0 = n_0
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_0
-               abort
-       end
-end
-class Nvalue_null
-       super Nvalue
-       redef fun node_name do return "value_null"
-       var n_0: N_39dnull_39d
-       init(n_0: N_39dnull_39d) do
-               self.n_0 = n_0
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_0
-               abort
-       end
-end
-class Nvalue_object
-       super Nvalue
-       redef fun node_name do return "value_object"
-       var n_0: N_39d_123d_39d
-       var n_members: nullable Nmembers
-       var n_2: N_39d_125d_39d
-       init(n_0: N_39d_123d_39d, n_members: nullable Nmembers, n_2: N_39d_125d_39d) do
-               self.n_0 = n_0
-               self.n_members = n_members
-               self.n_2 = n_2
-       end
-       redef fun number_of_children do return 3
-       redef fun child(i) do
-               if i == 0 then return n_0
-               if i == 1 then return n_members
-               if i == 2 then return n_2
-               abort
-       end
-end
-class Nvalue_array
-       super Nvalue
-       redef fun node_name do return "value_array"
-       var n_0: N_39d_91d_39d
-       var n_elements: nullable Nelements
-       var n_2: N_39d_93d_39d
-       init(n_0: N_39d_91d_39d, n_elements: nullable Nelements, n_2: N_39d_93d_39d) do
-               self.n_0 = n_0
-               self.n_elements = n_elements
-               self.n_2 = n_2
-       end
-       redef fun number_of_children do return 3
-       redef fun child(i) do
-               if i == 0 then return n_0
-               if i == 1 then return n_elements
-               if i == 2 then return n_2
-               abort
-       end
-end
-class Nmembers
-       super NProd
-       redef fun node_name do return "members"
-end
-class Nmembers_tail
-       super Nmembers
-       redef fun node_name do return "members_tail"
-       var n_members: Nmembers
-       var n_1: N_39d_44d_39d
-       var n_pair: Npair
-       init(n_members: Nmembers, n_1: N_39d_44d_39d, n_pair: Npair) do
-               self.n_members = n_members
-               self.n_1 = n_1
-               self.n_pair = n_pair
-       end
-       redef fun number_of_children do return 3
-       redef fun child(i) do
-               if i == 0 then return n_members
-               if i == 1 then return n_1
-               if i == 2 then return n_pair
-               abort
-       end
-end
-class Nmembers_head
-       super Nmembers
-       redef fun node_name do return "members_head"
-       var n_pair: Npair
-       init(n_pair: Npair) do
-               self.n_pair = n_pair
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_pair
-               abort
-       end
-end
-class Npair
-       super NProd
-       redef fun node_name do return "pair"
-       var n_string: Nstring
-       var n_1: N_39d_58d_39d
-       var n_value: Nvalue
-       init(n_string: Nstring, n_1: N_39d_58d_39d, n_value: Nvalue) do
-               self.n_string = n_string
-               self.n_1 = n_1
-               self.n_value = n_value
-       end
-       redef fun number_of_children do return 3
-       redef fun child(i) do
-               if i == 0 then return n_string
-               if i == 1 then return n_1
-               if i == 2 then return n_value
-               abort
-       end
-end
-class Nelements
-       super NProd
-       redef fun node_name do return "elements"
-end
-class Nelements_tail
-       super Nelements
-       redef fun node_name do return "elements_tail"
-       var n_elements: Nelements
-       var n_1: N_39d_44d_39d
-       var n_value: Nvalue
-       init(n_elements: Nelements, n_1: N_39d_44d_39d, n_value: Nvalue) do
-               self.n_elements = n_elements
-               self.n_1 = n_1
-               self.n_value = n_value
-       end
-       redef fun number_of_children do return 3
-       redef fun child(i) do
-               if i == 0 then return n_elements
-               if i == 1 then return n_1
-               if i == 2 then return n_value
-               abort
-       end
-end
-class Nelements_head
-       super Nelements
-       redef fun node_name do return "elements_head"
-       var n_value: Nvalue
-       init(n_value: Nvalue) do
-               self.n_value = n_value
-       end
-       redef fun number_of_children do return 1
-       redef fun child(i) do
-               if i == 0 then return n_value
-               abort
-       end
-end
-class N_start
-       super NProd
-       redef fun node_name do return "_start"
-end
-class NStart
-       super N_start
-       redef fun node_name do return "Start"
-       var n_0: Nvalue
-       var n_1: NEof
-       init(n_0: Nvalue, n_1: NEof) do
-               self.n_0 = n_0
-               self.n_1 = n_1
-       end
-       redef fun number_of_children do return 2
-       redef fun child(i) do
-               if i == 0 then return n_0
-               if i == 1 then return n_1
-               abort
-       end
-end
-# State Start
-private class LRStateStart
-       super LRState
-       redef fun to_s do return "Start"
-       redef fun error_msg do return "value"
-       redef fun action(parser) do
-               parser.peek_token.action_sStart(parser)
-       end
-       redef fun goto(parser, goto) do
-               parser.push(state_value)
-       end
-end
-# State value
-private class LRStatevalue
-       super LRState
-       redef fun to_s do return "value"
-       redef fun error_msg do return "Eof"
-       redef fun action(parser) do
-               parser.peek_token.action_svalue(parser)
-       end
-end
-# State number
-private class LRStatenumber
-       super LRState
-       redef fun to_s do return "number"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_number(parser)
-       end
-end
-# State string
-private class LRStatestring
-       super LRState
-       redef fun to_s do return "string"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_string(parser)
-       end
-end
-# State 'true'
-private class LRState_39dtrue_39d
-       super LRState
-       redef fun to_s do return "\'true\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_true(parser)
-       end
-end
-# State 'false'
-private class LRState_39dfalse_39d
-       super LRState
-       redef fun to_s do return "\'false\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_false(parser)
-       end
-end
-# State 'null'
-private class LRState_39dnull_39d
-       super LRState
-       redef fun to_s do return "\'null\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_null(parser)
-       end
-end
-# State '{'
-private class LRState_39d_123d_39d
-       super LRState
-       redef fun to_s do return "\'\{\'"
-       redef fun error_msg do return "members, pair"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_123d_39d(parser)
-       end
-       redef fun goto(parser, goto) do
-               goto.goto_s_39d_123d_39d(parser)
-       end
-end
-# State '['
-private class LRState_39d_91d_39d
-       super LRState
-       redef fun to_s do return "\'[\'"
-       redef fun error_msg do return "elements, value"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_91d_39d(parser)
-       end
-       redef fun goto(parser, goto) do
-               goto.goto_s_39d_91d_39d(parser)
-       end
-end
-# State value Eof
-private class LRStatevalue_32dEof
-       super LRState
-       redef fun to_s do return "value Eof"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_NStart(parser)
-       end
-end
-# State '{' members
-private class LRState_39d_123d_39d_32dmembers
-       super LRState
-       redef fun to_s do return "\'\{\' members"
-       redef fun error_msg do return "\'\}\', \',\'"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_123d_39d_32dmembers(parser)
-       end
-end
-# State '{' '}'
-private class LRState_39d_123d_39d_32d_39d_125d_39d
-       super LRState
-       redef fun to_s do return "\'\{\' \'\}\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_object_95d1(parser)
-       end
-end
-# State '{' pair
-private class LRState_39d_123d_39d_32dpair
-       super LRState
-       redef fun to_s do return "\'\{\' pair"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nmembers_head(parser)
-       end
-end
-# State '{' string
-private class LRState_39d_123d_39d_32dstring
-       super LRState
-       redef fun to_s do return "\'\{\' string"
-       redef fun error_msg do return "\':\'"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_123d_39d_32dstring(parser)
-       end
-end
-# State '[' elements
-private class LRState_39d_91d_39d_32delements
-       super LRState
-       redef fun to_s do return "\'[\' elements"
-       redef fun error_msg do return "\']\', \',\'"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_91d_39d_32delements(parser)
-       end
-end
-# State '[' ']'
-private class LRState_39d_91d_39d_32d_39d_93d_39d
-       super LRState
-       redef fun to_s do return "\'[\' \']\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_array_95d1(parser)
-       end
-end
-# State '[' value
-private class LRState_39d_91d_39d_32dvalue
-       super LRState
-       redef fun to_s do return "\'[\' value"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nelements_head(parser)
-       end
-end
-# State '{' members '}'
-private class LRState_39d_123d_39d_32dmembers_32d_39d_125d_39d
-       super LRState
-       redef fun to_s do return "\'\{\' members \'\}\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_object_95d0(parser)
-       end
-end
-# State '{' members ','
-private class LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d
-       super LRState
-       redef fun to_s do return "\'\{\' members \',\'"
-       redef fun error_msg do return "pair"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_123d_39d_32dmembers_32d_39d_44d_39d(parser)
-       end
-       redef fun goto(parser, goto) do
-               parser.push(state__39d_123d_39d_32dmembers_32d_39d_44d_39d_32dpair)
-       end
-end
-# State '{' string ':'
-private class LRState_39d_123d_39d_32dstring_32d_39d_58d_39d
-       super LRState
-       redef fun to_s do return "\'\{\' string \':\'"
-       redef fun error_msg do return "value"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_123d_39d_32dstring_32d_39d_58d_39d(parser)
-       end
-       redef fun goto(parser, goto) do
-               parser.push(state__39d_123d_39d_32dstring_32d_39d_58d_39d_32dvalue)
-       end
-end
-# State '[' elements ']'
-private class LRState_39d_91d_39d_32delements_32d_39d_93d_39d
-       super LRState
-       redef fun to_s do return "\'[\' elements \']\'"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nvalue_array_95d0(parser)
-       end
-end
-# State '[' elements ','
-private class LRState_39d_91d_39d_32delements_32d_39d_44d_39d
-       super LRState
-       redef fun to_s do return "\'[\' elements \',\'"
-       redef fun error_msg do return "value"
-       redef fun action(parser) do
-               parser.peek_token.action_s_39d_91d_39d_32delements_32d_39d_44d_39d(parser)
-       end
-       redef fun goto(parser, goto) do
-               parser.push(state__39d_91d_39d_32delements_32d_39d_44d_39d_32dvalue)
-       end
-end
-# State '{' members ',' pair
-private class LRState_39d_123d_39d_32dmembers_32d_39d_44d_39d_32dpair
-       super LRState
-       redef fun to_s do return "\'\{\' members \',\' pair"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nmembers_tail(parser)
-       end
-end
-# State '{' string ':' value
-private class LRState_39d_123d_39d_32dstring_32d_39d_58d_39d_32dvalue
-       super LRState
-       redef fun to_s do return "\'\{\' string \':\' value"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Npair(parser)
-       end
-end
-# State '[' elements ',' value
-private class LRState_39d_91d_39d_32delements_32d_39d_44d_39d_32dvalue
-       super LRState
-       redef fun to_s do return "\'[\' elements \',\' value"
-       redef fun error_msg do return ""
-       redef fun action(parser) do
-               reduce_Nelements_tail(parser)
-       end
-end
index 0ac2bea..03b1267 100644 (file)
@@ -18,7 +18,6 @@ module serialization_read
 import ::serialization::caching
 private import ::serialization::engine_tools
 private import static
-private import string_parser
 import poset
 
 # Deserializer from a Json string.
index 9b68f31..09d463d 100644 (file)
@@ -22,9 +22,8 @@
 # This object can then be type checked as usual with `isa` and `as`.
 module static
 
-import error
-private import json_parser
-private import json_lexer
+import parser_base
+intrude import error
 
 redef class Text
 
@@ -42,14 +41,14 @@ redef class Text
        #
        #     assert not "string".json_need_escape
        #     assert "\\\"string\\\"".json_need_escape
-       protected fun json_need_escape: Bool do return has('\\')
+       private fun json_need_escape: Bool do return has('\\')
 
        # Escapes `self` from a JSON string to a Nit string
        #
        #     assert "\\\"string\\\"".json_to_nit_string == "\"string\""
        #     assert "\\nEscape\\t\\n".json_to_nit_string == "\nEscape\t\n"
        #     assert "\\u0041zu\\uD800\\uDFD3".json_to_nit_string == "Azu𐏓"
-       protected fun json_to_nit_string: String do
+       private fun json_to_nit_string: String do
                var res = new FlatBuffer.with_capacity(byte_length)
                var i = 0
                var ln = self.length
@@ -122,18 +121,7 @@ redef class Text
        #     var bad = "\{foo: \"bar\"\}".parse_json
        #     assert bad isa JsonParseError
        #     assert bad.position.col_start == 2
-       fun parse_json: nullable Serializable do
-               var lexer = new Lexer_json(to_s)
-               var parser = new Parser_json
-               var tokens = lexer.lex
-               parser.tokens.add_all(tokens)
-               var root_node = parser.parse
-               if root_node isa NStart then
-                       return root_node.n_0.to_nit_object
-               else if root_node isa NError then
-                       return new JsonParseError(root_node.message, root_node.position)
-               else abort
-       end
+       fun parse_json: nullable Serializable do return (new JSONStringParser(self.to_s)).parse_entity
 end
 
 redef class FlatText
@@ -146,133 +134,347 @@ redef class FlatText
        end
 end
 
-# A map that can be translated into a JSON object.
-interface JsonMapRead[K: String, V: nullable Serializable]
-       super MapRead[K, V]
-       super Serializable
-end
-
-# A JSON Object.
-class JsonObject
-       super JsonMapRead[String, nullable Serializable]
-       super HashMap[String, nullable Serializable]
-end
-
-# A sequence that can be translated into a JSON array.
-class JsonSequenceRead[E: nullable Serializable]
-       super Serializable
-       super SequenceRead[E]
-end
-
-# A JSON array.
-class JsonArray
-       super JsonSequenceRead[nullable Serializable]
-       super Array[nullable Serializable]
-end
-
-################################################################################
-# Redef parser
-
-redef class Nvalue
-       # The represented value.
-       private fun to_nit_object: nullable Serializable is abstract
-end
-
-redef class Nvalue_number
-       redef fun to_nit_object
-       do
-               var text = n_number.text
-               if text.chars.has('.') or text.chars.has('e') or text.chars.has('E') then return text.to_f
-               return text.to_i
+redef class Char
+       # Is `self` a valid number start ?
+       private fun is_json_num_start: Bool do
+               if self == '-' then return true
+               if self.is_numeric then return true
+               return false
        end
-end
 
-redef class Nvalue_string
-       redef fun to_nit_object do return n_string.to_nit_string
-end
-
-redef class Nvalue_true
-       redef fun to_nit_object do return true
+       # Is `self` a valid JSON separator ?
+       private fun is_json_separator: Bool do
+               if self == ':' then return true
+               if self == ',' then return true
+               if self == '{' then return true
+               if self == '}' then return true
+               if self == '[' then return true
+               if self == ']' then return true
+               if self == '"' then return true
+               if self.is_whitespace then return true
+               return false
+       end
 end
 
-redef class Nvalue_false
-       redef fun to_nit_object do return false
-end
+# A simple ad-hoc JSON parser
+#
+# To parse a simple JSON document, read it as a String and give it to `parse_entity`
+# NOTE: if your document contains several non-nested entities, use `parse_entity` for each
+# JSON entity to parse
+class JSONStringParser
+       super StringProcessor
 
-redef class Nvalue_null
-       redef fun to_nit_object do return null
-end
+       # Parses a JSON Entity
+       #
+       # ~~~nit
+       # var p = new JSONStringParser("""{"numbers": [1,23,3], "string": "string"}""")
+       # assert p.parse_entity isa JsonObject
+       # ~~~
+       fun parse_entity: nullable Serializable do
+               var srclen = len
+               ignore_whitespaces
+               if pos >= srclen then return make_parse_error("Empty JSON")
+               var c = src[pos]
+               if c == '[' then
+                       pos += 1
+                       return parse_json_array
+               else if c == '"' then
+                       var s = parse_json_string
+                       return s
+               else if c == '{' then
+                       pos += 1
+                       return parse_json_object
+               else if c == 'f' then
+                       if pos + 4 >= srclen then make_parse_error("Error: bad JSON entity")
+                       if src[pos + 1] == 'a' and src[pos + 2] == 'l' and src[pos + 3] == 's' and src[pos + 4] == 'e' then
+                               pos += 5
+                               return false
+                       end
+                       return make_parse_error("Error: bad JSON entity")
+               else if c == 't' then
+                       if pos + 3 >= srclen then make_parse_error("Error: bad JSON entity")
+                       if src[pos + 1] == 'r' and src[pos + 2] == 'u' and src[pos + 3] == 'e' then
+                               pos += 4
+                               return true
+                       end
+                       return make_parse_error("Error: bad JSON entity")
+               else if c == 'n' then
+                       if pos + 3 >= srclen then make_parse_error("Error: bad JSON entity")
+                       if src[pos + 1] == 'u' and src[pos + 2] == 'l' and src[pos + 3] == 'l' then
+                               pos += 4
+                               return null
+                       end
+                       return make_parse_error("Error: bad JSON entity")
+               end
+               if not c.is_json_num_start then return make_parse_error("Bad JSON character")
+               return parse_json_number
+       end
 
-redef class Nstring
-       # The represented string.
-       private fun to_nit_string: String do return text.substring(1, text.length - 2).unescape_json.to_s
-end
+       # Parses a JSON Array
+       fun parse_json_array: Serializable do
+               var max = len
+               if pos >= max then return make_parse_error("Incomplete JSON array")
+               var arr = new JsonArray
+               var c = src[pos]
+               while not c == ']' do
+                       ignore_whitespaces
+                       if pos >= max then return make_parse_error("Incomplete JSON array")
+                       if src[pos] == ']' then break
+                       var ent = parse_entity
+                       #print "Parsed an entity {ent} for a JSON array"
+                       if ent isa JsonParseError then return ent
+                       arr.add ent
+                       ignore_whitespaces
+                       if pos >= max then return make_parse_error("Incomplete JSON array")
+                       c = src[pos]
+                       if c == ']' then break
+                       if c != ',' then return make_parse_error("Bad array separator {c}")
+                       pos += 1
+               end
+               pos += 1
+               return arr
+       end
 
-redef class Nvalue_object
-       redef fun to_nit_object do
+       # Parses a JSON Object
+       fun parse_json_object: Serializable do
+               var max = len
+               if pos >= max then return make_parse_error("Incomplete JSON object")
                var obj = new JsonObject
-               var members = n_members
-               if members != null then
-                       var pairs = members.pairs
-                       for pair in pairs do obj[pair.name] = pair.value
+               var c = src[pos]
+               while not c == '}' do
+                       ignore_whitespaces
+                       if pos >= max then return make_parse_error("Malformed JSON object")
+                       if src[pos] == '}' then break
+                       var key = parse_entity
+                       #print "Parsed key {key} for JSON object"
+                       if not key isa String then return make_parse_error("Bad key format {key or else "null"}")
+                       ignore_whitespaces
+                       if pos >= max then return make_parse_error("Incomplete JSON object")
+                       if not src[pos] == ':' then return make_parse_error("Bad key/value separator {src[pos]}")
+                       pos += 1
+                       ignore_whitespaces
+                       var value = parse_entity
+                       #print "Parsed value {value} for JSON object"
+                       if value isa JsonParseError then return value
+                       obj[key] = value
+                       ignore_whitespaces
+                       if pos >= max then return make_parse_error("Incomplete JSON object")
+                       c = src[pos]
+                       if c == '}' then break
+                       if c != ',' then return make_parse_error("Bad object separator {src[pos]}")
+                       pos += 1
                end
+               pos += 1
                return obj
        end
-end
-
-redef class Nmembers
-       # All the key-value pairs.
-       private fun pairs: Array[Npair] is abstract
-end
 
-redef class Nmembers_tail
-       redef fun pairs
-       do
-               var arr = n_members.pairs
-               arr.add n_pair
-               return arr
+       # Creates a `JsonParseError` with the right message and location
+       protected fun make_parse_error(message: String): JsonParseError do
+               var err = new JsonParseError(message)
+               err.location = hot_location
+               return err
        end
-end
 
-redef class Nmembers_head
-       redef fun pairs do return [n_pair]
-end
+       # Parses an Int or Float
+       fun parse_json_number: Serializable do
+               var max = len
+               var p = pos
+               var c = src[p]
+               var is_neg = false
+               if c == '-' then
+                       is_neg = true
+                       p += 1
+                       if p >= max then return make_parse_error("Bad JSON number")
+                       c = src[p]
+               end
+               var val = 0
+               while c.is_numeric do
+                       val *= 10
+                       val += c.to_i
+                       p += 1
+                       if p >= max then break
+                       c = src[p]
+               end
+               if c == '.' then
+                       p += 1
+                       if p >= max then return make_parse_error("Bad JSON number")
+                       c = src[p]
+                       var fl = val.to_f
+                       var frac = 0.1
+                       while c.is_numeric do
+                               fl += c.to_i.to_f * frac
+                               frac /= 10.0
+                               p += 1
+                               if p >= max then break
+                               c = src[p]
+                       end
+                       if c == 'e' or c == 'E' then
+                               p += 1
+                               var exp = 0
+                               if p >= max then return make_parse_error("Malformed JSON number")
+                               c = src[p]
+                               while c.is_numeric do
+                                       exp *= 10
+                                       exp += c.to_i
+                                       p += 1
+                                       if p >= max then break
+                                       c = src[p]
+                               end
+                               fl *= (10 ** exp).to_f
+                       end
+                       if p < max and not c.is_json_separator then return make_parse_error("Malformed JSON number")
+                       pos = p
+                       if is_neg then return -fl
+                       return fl
+               end
+               if c == 'e' or c == 'E' then
+                       p += 1
+                       if p >= max then return make_parse_error("Bad JSON number")
+                       var exp = src[p].to_i
+                       c = src[p]
+                       while c.is_numeric do
+                               exp *= 10
+                               exp += c.to_i
+                               p += 1
+                               if p >= max then break
+                               c = src[p]
+                       end
+                       val *= (10 ** exp)
+               end
+               if p < max and not src[p].is_json_separator then return make_parse_error("Malformed JSON number")
+               pos = p
+               if is_neg then return -val
+               return val
+       end
 
-redef class Npair
-       # The represented key.
-       private fun name: String do return n_string.to_nit_string
+       private var parse_str_buf = new FlatBuffer
 
-       # The represented value.
-       private fun value: nullable Serializable do return n_value.to_nit_object
-end
+       # Parses and returns a Nit string from a JSON String
+       fun parse_json_string: Serializable do
+               var src = src
+               var ln = src.length
+               var p = pos
+               p += 1
+               if p > ln then return make_parse_error("Malformed JSON String")
+               var c = src[p]
+               var ret = parse_str_buf
+               var chunk_st = p
+               while c != '"' do
+                       if c != '\\' then
+                               p += 1
+                               if p >= ln then return make_parse_error("Malformed JSON string")
+                               c = src[p]
+                               continue
+                       end
+                       ret.append_substring_impl(src, chunk_st, p - chunk_st)
+                       p += 1
+                       if p >= ln then return make_parse_error("Malformed Escape sequence in JSON string")
+                       c = src[p]
+                       if c == 'r' then
+                               ret.add '\r'
+                               p += 1
+                       else if c == 'n' then
+                               ret.add '\n'
+                               p += 1
+                       else if c == 't' then
+                               ret.add '\t'
+                               p += 1
+                       else if c == 'u' then
+                               var cp = 0
+                               p += 1
+                               for i in [0 .. 4[ do
+                                       cp <<= 4
+                                       if p >= ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                       c = src[p]
+                                       if c >= '0' and c <= '9' then
+                                               cp += c.code_point - '0'.code_point
+                                       else if c >= 'a' and c <= 'f' then
+                                               cp += c.code_point - 'a'.code_point + 10
+                                       else if c >= 'A' and c <= 'F' then
+                                               cp += c.code_point - 'A'.code_point + 10
+                                       else
+                                               make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                       end
+                                       p += 1
+                               end
+                               c = cp.code_point
+                               if cp >= 0xD800 and cp <= 0xDBFF then
+                                       if p >= ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                       c = src[p]
+                                       if c != '\\' then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                       p += 1
+                                       c = src[p]
+                                       if c != 'u' then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                       var locp = 0
+                                       p += 1
+                                       for i in [0 .. 4[ do
+                                               locp <<= 4
+                                               if p > ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                               c = src[p]
+                                               if c >= '0' and c <= '9' then
+                                                       locp += c.code_point - '0'.code_point
+                                               else if c >= 'a' and c <= 'f' then
+                                                       locp += c.code_point - 'a'.code_point + 10
+                                               else if c >= 'A' and c <= 'F' then
+                                                       locp += c.code_point - 'A'.code_point + 10
+                                               else
+                                                       make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
+                                               end
+                                               p += 1
+                                       end
+                                       c = (((locp & 0x3FF) | ((cp & 0x3FF) << 10)) + 0x10000).code_point
+                               end
+                               ret.add c
+                       else if c == 'b' then
+                               ret.add 8.code_point
+                               p += 1
+                       else if c == 'f' then
+                               ret.add '\f'
+                               p += 1
+                       else
+                               p += 1
+                               ret.add c
+                       end
+                       chunk_st = p
+                       c = src[p]
+               end
+               pos = p + 1
+               if ret.is_empty then return src.substring(chunk_st, p - chunk_st)
+               ret.append_substring_impl(src, chunk_st, p - chunk_st)
+               var rets = ret.to_s
+               ret.clear
+               return rets
+       end
 
-redef class Nvalue_array
-       redef fun to_nit_object
-       do
-               var arr = new JsonArray
-               var elements = n_elements
-               if elements != null then
-                       var items = elements.items
-                       for item in items do arr.add(item.to_nit_object)
+       # Ignores any character until a JSON separator is encountered
+       fun ignore_until_separator do
+               var max = len
+               while pos < max do
+                       if not src[pos].is_json_separator then return
                end
-               return arr
        end
 end
 
-redef class Nelements
-       # All the items.
-       private fun items: Array[Nvalue] is abstract
+# A map that can be translated into a JSON object.
+interface JsonMapRead[K: String, V: nullable Serializable]
+       super MapRead[K, V]
+       super Serializable
 end
 
-redef class Nelements_tail
-       redef fun items
-       do
-               var items = n_elements.items
-               items.add(n_value)
-               return items
-       end
+# A JSON Object.
+class JsonObject
+       super JsonMapRead[String, nullable Serializable]
+       super HashMap[String, nullable Serializable]
 end
 
-redef class Nelements_head
-       redef fun items do return [n_value]
+# A sequence that can be translated into a JSON array.
+class JsonSequenceRead[E: nullable Serializable]
+       super Serializable
+       super SequenceRead[E]
+end
+
+# A JSON array.
+class JsonArray
+       super JsonSequenceRead[nullable Serializable]
+       super Array[nullable Serializable]
 end
diff --git a/lib/json/string_parser.nit b/lib/json/string_parser.nit
deleted file mode 100644 (file)
index 5015754..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Simple ad-hoc implementation of a JSON parser for String inputs
-module string_parser
-
-import parser_base
-import static
-
-redef class Char
-       # Is `self` a valid number start ?
-       private fun is_json_num_start: Bool do
-               if self == '-' then return true
-               if self.is_numeric then return true
-               return false
-       end
-
-       # Is `self` a valid JSON separator ?
-       private fun is_json_separator: Bool do
-               if self == ':' then return true
-               if self == ',' then return true
-               if self == '{' then return true
-               if self == '}' then return true
-               if self == '[' then return true
-               if self == ']' then return true
-               if self == '"' then return true
-               if self.is_whitespace then return true
-               return false
-       end
-end
-
-# A simple ad-hoc JSON parser
-#
-# To parse a simple JSON document, read it as a String and give it to `parse_entity`
-# NOTE: if your document contains several non-nested entities, use `parse_entity` for each
-# JSON entity to parse
-class JSONStringParser
-       super StringProcessor
-
-       # Parses a JSON Entity
-       #
-       # ~~~nit
-       # var p = new JSONStringParser("""{"numbers": [1,23,3], "string": "string"}""")
-       # assert p.parse_entity isa JsonObject
-       # ~~~
-       fun parse_entity: nullable Serializable do
-               var srclen = len
-               ignore_whitespaces
-               if pos >= srclen then return make_parse_error("Empty JSON")
-               var c = src[pos]
-               if c == '[' then
-                       pos += 1
-                       return parse_json_array
-               else if c == '"' then
-                       var s = parse_json_string
-                       return s
-               else if c == '{' then
-                       pos += 1
-                       return parse_json_object
-               else if c == 'f' then
-                       if pos + 4 >= srclen then make_parse_error("Error: bad JSON entity")
-                       if src[pos + 1] == 'a' and src[pos + 2] == 'l' and src[pos + 3] == 's' and src[pos + 4] == 'e' then
-                               pos += 5
-                               return false
-                       end
-                       return make_parse_error("Error: bad JSON entity")
-               else if c == 't' then
-                       if pos + 3 >= srclen then make_parse_error("Error: bad JSON entity")
-                       if src[pos + 1] == 'r' and src[pos + 2] == 'u' and src[pos + 3] == 'e' then
-                               pos += 4
-                               return true
-                       end
-                       return make_parse_error("Error: bad JSON entity")
-               else if c == 'n' then
-                       if pos + 3 >= srclen then make_parse_error("Error: bad JSON entity")
-                       if src[pos + 1] == 'u' and src[pos + 2] == 'l' and src[pos + 3] == 'l' then
-                               pos += 4
-                               return null
-                       end
-                       return make_parse_error("Error: bad JSON entity")
-               end
-               if not c.is_json_num_start then return make_parse_error("Bad JSON character")
-               return parse_json_number
-       end
-
-       # Parses a JSON Array
-       fun parse_json_array: Serializable do
-               var max = len
-               if pos >= max then return make_parse_error("Incomplete JSON array")
-               var arr = new JsonArray
-               var c = src[pos]
-               while not c == ']' do
-                       ignore_whitespaces
-                       if pos >= max then return make_parse_error("Incomplete JSON array")
-                       if src[pos] == ']' then break
-                       var ent = parse_entity
-                       #print "Parsed an entity {ent} for a JSON array"
-                       if ent isa JsonParseError then return ent
-                       arr.add ent
-                       ignore_whitespaces
-                       if pos >= max then return make_parse_error("Incomplete JSON array")
-                       c = src[pos]
-                       if c == ']' then break
-                       if c != ',' then return make_parse_error("Bad array separator {c}")
-                       pos += 1
-               end
-               pos += 1
-               return arr
-       end
-
-       # Parses a JSON Object
-       fun parse_json_object: Serializable do
-               var max = len
-               if pos >= max then return make_parse_error("Incomplete JSON object")
-               var obj = new JsonObject
-               var c = src[pos]
-               while not c == '}' do
-                       ignore_whitespaces
-                       if pos >= max then return make_parse_error("Malformed JSON object")
-                       if src[pos] == '}' then break
-                       var key = parse_entity
-                       #print "Parsed key {key} for JSON object"
-                       if not key isa String then return make_parse_error("Bad key format {key or else "null"}")
-                       ignore_whitespaces
-                       if pos >= max then return make_parse_error("Incomplete JSON object")
-                       if not src[pos] == ':' then return make_parse_error("Bad key/value separator {src[pos]}")
-                       pos += 1
-                       ignore_whitespaces
-                       var value = parse_entity
-                       #print "Parsed value {value} for JSON object"
-                       if value isa JsonParseError then return value
-                       obj[key] = value
-                       ignore_whitespaces
-                       if pos >= max then return make_parse_error("Incomplete JSON object")
-                       c = src[pos]
-                       if c == '}' then break
-                       if c != ',' then return make_parse_error("Bad object separator {src[pos]}")
-                       pos += 1
-               end
-               pos += 1
-               return obj
-       end
-
-       # Creates a `JsonParseError` with the right message and location
-       protected fun make_parse_error(message: String): JsonParseError do
-               var err = new JsonParseError(message)
-               err.location = hot_location
-               return err
-       end
-
-       # Parses an Int or Float
-       fun parse_json_number: Serializable do
-               var max = len
-               var p = pos
-               var c = src[p]
-               var is_neg = false
-               if c == '-' then
-                       is_neg = true
-                       p += 1
-                       if p >= max then return make_parse_error("Bad JSON number")
-                       c = src[p]
-               end
-               var val = 0
-               while c.is_numeric do
-                       val *= 10
-                       val += c.to_i
-                       p += 1
-                       if p >= max then break
-                       c = src[p]
-               end
-               if c == '.' then
-                       p += 1
-                       if p >= max then return make_parse_error("Bad JSON number")
-                       c = src[p]
-                       var fl = val.to_f
-                       var frac = 0.1
-                       while c.is_numeric do
-                               fl += c.to_i.to_f * frac
-                               frac /= 10.0
-                               p += 1
-                               if p >= max then break
-                               c = src[p]
-                       end
-                       if c == 'e' or c == 'E' then
-                               p += 1
-                               var exp = 0
-                               if p >= max then return make_parse_error("Malformed JSON number")
-                               c = src[p]
-                               while c.is_numeric do
-                                       exp *= 10
-                                       exp += c.to_i
-                                       p += 1
-                                       if p >= max then break
-                                       c = src[p]
-                               end
-                               fl *= (10 ** exp).to_f
-                       end
-                       if p < max and not c.is_json_separator then return make_parse_error("Malformed JSON number")
-                       pos = p
-                       if is_neg then return -fl
-                       return fl
-               end
-               if c == 'e' or c == 'E' then
-                       p += 1
-                       if p >= max then return make_parse_error("Bad JSON number")
-                       var exp = src[p].to_i
-                       c = src[p]
-                       while c.is_numeric do
-                               exp *= 10
-                               exp += c.to_i
-                               p += 1
-                               if p >= max then break
-                               c = src[p]
-                       end
-                       val *= (10 ** exp)
-               end
-               if p < max and not src[p].is_json_separator then return make_parse_error("Malformed JSON number")
-               pos = p
-               if is_neg then return -val
-               return val
-       end
-
-       private var parse_str_buf = new FlatBuffer
-
-       # Parses and returns a Nit string from a JSON String
-       fun parse_json_string: Serializable do
-               var src = src
-               var ln = src.length
-               var p = pos
-               p += 1
-               if p > ln then return make_parse_error("Malformed JSON String")
-               var c = src[p]
-               var ret = parse_str_buf
-               var chunk_st = p
-               while c != '"' do
-                       if c != '\\' then
-                               p += 1
-                               if p >= ln then return make_parse_error("Malformed JSON string")
-                               c = src[p]
-                               continue
-                       end
-                       ret.append_substring_impl(src, chunk_st, p - chunk_st)
-                       p += 1
-                       if p >= ln then return make_parse_error("Malformed Escape sequence in JSON string")
-                       c = src[p]
-                       if c == 'r' then
-                               ret.add '\r'
-                               p += 1
-                       else if c == 'n' then
-                               ret.add '\n'
-                               p += 1
-                       else if c == 't' then
-                               ret.add '\t'
-                               p += 1
-                       else if c == 'u' then
-                               var cp = 0
-                               p += 1
-                               for i in [0 .. 4[ do
-                                       cp <<= 4
-                                       if p >= ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                       c = src[p]
-                                       if c >= '0' and c <= '9' then
-                                               cp += c.code_point - '0'.code_point
-                                       else if c >= 'a' and c <= 'f' then
-                                               cp += c.code_point - 'a'.code_point + 10
-                                       else if c >= 'A' and c <= 'F' then
-                                               cp += c.code_point - 'A'.code_point + 10
-                                       else
-                                               make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                       end
-                                       p += 1
-                               end
-                               c = cp.code_point
-                               if cp >= 0xD800 and cp <= 0xDBFF then
-                                       if p >= ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                       c = src[p]
-                                       if c != '\\' then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                       p += 1
-                                       c = src[p]
-                                       if c != 'u' then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                       var locp = 0
-                                       p += 1
-                                       for i in [0 .. 4[ do
-                                               locp <<= 4
-                                               if p > ln then make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                               c = src[p]
-                                               if c >= '0' and c <= '9' then
-                                                       locp += c.code_point - '0'.code_point
-                                               else if c >= 'a' and c <= 'f' then
-                                                       locp += c.code_point - 'a'.code_point + 10
-                                               else if c >= 'A' and c <= 'F' then
-                                                       locp += c.code_point - 'A'.code_point + 10
-                                               else
-                                                       make_parse_error("Malformed \uXXXX Escape sequence in JSON string")
-                                               end
-                                               p += 1
-                                       end
-                                       c = (((locp & 0x3FF) | ((cp & 0x3FF) << 10)) + 0x10000).code_point
-                               end
-                               ret.add c
-                       else if c == 'b' then
-                               ret.add 8.code_point
-                               p += 1
-                       else if c == 'f' then
-                               ret.add '\f'
-                               p += 1
-                       else
-                               p += 1
-                               ret.add c
-                       end
-                       chunk_st = p
-                       c = src[p]
-               end
-               pos = p + 1
-               if ret.is_empty then return src.substring(chunk_st, p - chunk_st)
-               ret.append_substring_impl(src, chunk_st, p - chunk_st)
-               var rets = ret.to_s
-               ret.clear
-               return rets
-       end
-
-       # Ignores any character until a JSON separator is encountered
-       fun ignore_until_separator do
-               var max = len
-               while pos < max do
-                       if not src[pos].is_json_separator then return
-               end
-       end
-end
-
-redef class Text
-       redef fun parse_json do return (new JSONStringParser(self.to_s)).parse_entity
-end
-
-redef class JsonParseError
-       serialize
-
-       # Location of the error in source
-       var location: nullable Location = null
-end