Skip to content

Instantly share code, notes, and snippets.

@erezsh
Created December 13, 2021 08:54
Show Gist options
  • Select an option

  • Save erezsh/c2b51a03273f2485317fc83e75fa162c to your computer and use it in GitHub Desktop.

Select an option

Save erezsh/c2b51a03273f2485317fc83e75fa162c to your computer and use it in GitHub Desktop.

Revisions

  1. erezsh created this gist Dec 13, 2021.
    101 changes: 101 additions & 0 deletions JSONLexer.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    # Generated from JSON.g4 by ANTLR 4.7.1
    # encoding: utf-8
    from __future__ import print_function
    from antlr4 import *
    from io import StringIO
    import sys


    def serializedATN():
    with StringIO() as buf:
    buf.write(u"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2")
    buf.write(u"\16\177\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4")
    buf.write(u"\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r")
    buf.write(u"\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22")
    buf.write(u"\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\6")
    buf.write(u"\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\t\3\t")
    buf.write(u"\3\n\3\n\3\13\3\13\3\13\7\13E\n\13\f\13\16\13H\13\13")
    buf.write(u"\3\13\3\13\3\f\3\f\3\f\5\fO\n\f\3\r\3\r\3\r\3\r\3\r\3")
    buf.write(u"\r\3\16\3\16\3\17\5\17Z\n\17\3\17\3\17\3\17\3\17\5\17")
    buf.write(u"`\n\17\3\17\5\17c\n\17\3\17\3\17\3\17\3\17\5\17i\n\17")
    buf.write(u"\3\17\5\17l\n\17\3\20\6\20o\n\20\r\20\16\20p\3\21\3\21")
    buf.write(u"\5\21u\n\21\3\21\3\21\3\22\6\22z\n\22\r\22\16\22{\3\22")
    buf.write(u"\3\22\2\2\23\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13")
    buf.write(u"\25\f\27\2\31\2\33\2\35\r\37\2!\2#\16\3\2\b\4\2$$^^\n")
    buf.write(u"\2$$\61\61^^ddhhppttvv\5\2\62;CHch\4\2GGgg\4\2--//\5")
    buf.write(u"\2\13\f\17\17\"\"\2\u0085\2\3\3\2\2\2\2\5\3\2\2\2\2\7")
    buf.write(u"\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3")
    buf.write(u"\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\35\3")
    buf.write(u"\2\2\2\2#\3\2\2\2\3%\3\2\2\2\5\'\3\2\2\2\7)\3\2\2\2\t")
    buf.write(u"+\3\2\2\2\13-\3\2\2\2\r\62\3\2\2\2\178\3\2\2\2\21=\3")
    buf.write(u"\2\2\2\23?\3\2\2\2\25A\3\2\2\2\27K\3\2\2\2\31P\3\2\2")
    buf.write(u"\2\33V\3\2\2\2\35k\3\2\2\2\37n\3\2\2\2!r\3\2\2\2#y\3")
    buf.write(u"\2\2\2%&\7.\2\2&\4\3\2\2\2\'(\7\177\2\2(\6\3\2\2\2)*")
    buf.write(u"\7_\2\2*\b\3\2\2\2+,\7<\2\2,\n\3\2\2\2-.\7v\2\2./\7t")
    buf.write(u"\2\2/\60\7w\2\2\60\61\7g\2\2\61\f\3\2\2\2\62\63\7h\2")
    buf.write(u"\2\63\64\7c\2\2\64\65\7n\2\2\65\66\7u\2\2\66\67\7g\2")
    buf.write(u"\2\67\16\3\2\2\289\7p\2\29:\7w\2\2:;\7n\2\2;<\7n\2\2")
    buf.write(u"<\20\3\2\2\2=>\7}\2\2>\22\3\2\2\2?@\7]\2\2@\24\3\2\2")
    buf.write(u"\2AF\7$\2\2BE\5\27\f\2CE\n\2\2\2DB\3\2\2\2DC\3\2\2\2")
    buf.write(u"EH\3\2\2\2FD\3\2\2\2FG\3\2\2\2GI\3\2\2\2HF\3\2\2\2IJ")
    buf.write(u"\7$\2\2J\26\3\2\2\2KN\7^\2\2LO\t\3\2\2MO\5\31\r\2NL\3")
    buf.write(u"\2\2\2NM\3\2\2\2O\30\3\2\2\2PQ\7w\2\2QR\5\33\16\2RS\5")
    buf.write(u"\33\16\2ST\5\33\16\2TU\5\33\16\2U\32\3\2\2\2VW\t\4\2")
    buf.write(u"\2W\34\3\2\2\2XZ\7/\2\2YX\3\2\2\2YZ\3\2\2\2Z[\3\2\2\2")
    buf.write(u"[\\\5\37\20\2\\]\7\60\2\2]_\5\37\20\2^`\5!\21\2_^\3\2")
    buf.write(u"\2\2_`\3\2\2\2`l\3\2\2\2ac\7/\2\2ba\3\2\2\2bc\3\2\2\2")
    buf.write(u"cd\3\2\2\2de\5\37\20\2ef\5!\21\2fl\3\2\2\2gi\7/\2\2h")
    buf.write(u"g\3\2\2\2hi\3\2\2\2ij\3\2\2\2jl\5\37\20\2kY\3\2\2\2k")
    buf.write(u"b\3\2\2\2kh\3\2\2\2l\36\3\2\2\2mo\4\62;\2nm\3\2\2\2o")
    buf.write(u"p\3\2\2\2pn\3\2\2\2pq\3\2\2\2q \3\2\2\2rt\t\5\2\2su\t")
    buf.write(u"\6\2\2ts\3\2\2\2tu\3\2\2\2uv\3\2\2\2vw\5\37\20\2w\"\3")
    buf.write(u"\2\2\2xz\t\7\2\2yx\3\2\2\2z{\3\2\2\2{y\3\2\2\2{|\3\2")
    buf.write(u"\2\2|}\3\2\2\2}~\b\22\2\2~$\3\2\2\2\16\2DFNY_bhkpt{\3")
    buf.write(u"\b\2\2")
    return buf.getvalue()


    class JSONLexer(Lexer):

    atn = ATNDeserializer().deserialize(serializedATN())

    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]

    T__0 = 1
    T__1 = 2
    T__2 = 3
    T__3 = 4
    T__4 = 5
    T__5 = 6
    T__6 = 7
    LCURLY = 8
    LBRACK = 9
    STRING = 10
    NUMBER = 11
    WS = 12

    channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]

    modeNames = [ u"DEFAULT_MODE" ]

    literalNames = [ u"<INVALID>",
    u"','", u"'}'", u"']'", u"':'", u"'true'", u"'false'", u"'null'",
    u"'{'", u"'['" ]

    symbolicNames = [ u"<INVALID>",
    u"LCURLY", u"LBRACK", u"STRING", u"NUMBER", u"WS" ]

    ruleNames = [ u"T__0", u"T__1", u"T__2", u"T__3", u"T__4", u"T__5",
    u"T__6", u"LCURLY", u"LBRACK", u"STRING", u"ESC", u"UNICODE",
    u"HEX", u"NUMBER", u"INT", u"EXP", u"WS" ]

    grammarFileName = u"JSON.g4"

    def __init__(self, input=None, output=sys.stdout):
    super(JSONLexer, self).__init__(input, output=output)
    self.checkVersion("4.7.1")
    self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
    self._actions = None
    self._predicates = None


    96 changes: 96 additions & 0 deletions JSONListener.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    # Generated from JSON.g4 by ANTLR 4.7.1
    from antlr4 import *

    # This class defines a complete listener for a parse tree produced by JSONParser.
    class JSONListener(ParseTreeListener):

    # Enter a parse tree produced by JSONParser#json.
    def enterJson(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#json.
    def exitJson(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#AnObject.
    def enterAnObject(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#AnObject.
    def exitAnObject(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#EmptyObject.
    def enterEmptyObject(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#EmptyObject.
    def exitEmptyObject(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#ArrayOfValues.
    def enterArrayOfValues(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#ArrayOfValues.
    def exitArrayOfValues(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#EmptyArray.
    def enterEmptyArray(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#EmptyArray.
    def exitEmptyArray(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#pair.
    def enterPair(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#pair.
    def exitPair(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#String.
    def enterString(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#String.
    def exitString(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#Atom.
    def enterAtom(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#Atom.
    def exitAtom(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#ObjectValue.
    def enterObjectValue(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#ObjectValue.
    def exitObjectValue(self, ctx):
    pass


    # Enter a parse tree produced by JSONParser#ArrayValue.
    def enterArrayValue(self, ctx):
    pass

    # Exit a parse tree produced by JSONParser#ArrayValue.
    def exitArrayValue(self, ctx):
    pass


    551 changes: 551 additions & 0 deletions JSONParser.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,551 @@
    # Generated from JSON.g4 by ANTLR 4.7.1
    # encoding: utf-8
    from __future__ import print_function
    from antlr4 import *
    from io import StringIO
    import sys

    def serializedATN():
    with StringIO() as buf:
    buf.write(u"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3")
    buf.write(u"\16<\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\3\2\3\2")
    buf.write(u"\5\2\17\n\2\3\3\3\3\3\3\3\3\7\3\25\n\3\f\3\16\3\30\13")
    buf.write(u"\3\3\3\3\3\3\3\3\3\5\3\36\n\3\3\4\3\4\3\4\3\4\7\4$\n")
    buf.write(u"\4\f\4\16\4\'\13\4\3\4\3\4\3\4\3\4\5\4-\n\4\3\5\3\5\3")
    buf.write(u"\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6:\n\6\3\6\2\2\7")
    buf.write(u"\2\4\6\b\n\2\2\2A\2\16\3\2\2\2\4\35\3\2\2\2\6,\3\2\2")
    buf.write(u"\2\b.\3\2\2\2\n9\3\2\2\2\f\17\5\4\3\2\r\17\5\6\4\2\16")
    buf.write(u"\f\3\2\2\2\16\r\3\2\2\2\17\3\3\2\2\2\20\21\7\n\2\2\21")
    buf.write(u"\26\5\b\5\2\22\23\7\3\2\2\23\25\5\b\5\2\24\22\3\2\2\2")
    buf.write(u"\25\30\3\2\2\2\26\24\3\2\2\2\26\27\3\2\2\2\27\31\3\2")
    buf.write(u"\2\2\30\26\3\2\2\2\31\32\7\4\2\2\32\36\3\2\2\2\33\34")
    buf.write(u"\7\n\2\2\34\36\7\4\2\2\35\20\3\2\2\2\35\33\3\2\2\2\36")
    buf.write(u"\5\3\2\2\2\37 \7\13\2\2 %\5\n\6\2!\"\7\3\2\2\"$\5\n\6")
    buf.write(u"\2#!\3\2\2\2$\'\3\2\2\2%#\3\2\2\2%&\3\2\2\2&(\3\2\2\2")
    buf.write(u"\'%\3\2\2\2()\7\5\2\2)-\3\2\2\2*+\7\13\2\2+-\7\5\2\2")
    buf.write(u",\37\3\2\2\2,*\3\2\2\2-\7\3\2\2\2./\7\f\2\2/\60\7\6\2")
    buf.write(u"\2\60\61\5\n\6\2\61\t\3\2\2\2\62:\7\f\2\2\63:\7\r\2\2")
    buf.write(u"\64:\5\4\3\2\65:\5\6\4\2\66:\7\7\2\2\67:\7\b\2\28:\7")
    buf.write(u"\t\2\29\62\3\2\2\29\63\3\2\2\29\64\3\2\2\29\65\3\2\2")
    buf.write(u"\29\66\3\2\2\29\67\3\2\2\298\3\2\2\2:\13\3\2\2\2\b\16")
    buf.write(u"\26\35%,9")
    return buf.getvalue()


    class JSONParser ( Parser ):

    grammarFileName = "JSON.g4"

    atn = ATNDeserializer().deserialize(serializedATN())

    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]

    sharedContextCache = PredictionContextCache()

    literalNames = [ u"<INVALID>", u"','", u"'}'", u"']'", u"':'", u"'true'",
    u"'false'", u"'null'", u"'{'", u"'['" ]

    symbolicNames = [ u"<INVALID>", u"<INVALID>", u"<INVALID>", u"<INVALID>",
    u"<INVALID>", u"<INVALID>", u"<INVALID>", u"<INVALID>",
    u"LCURLY", u"LBRACK", u"STRING", u"NUMBER", u"WS" ]

    RULE_json = 0
    RULE_obj = 1
    RULE_array = 2
    RULE_pair = 3
    RULE_value = 4

    ruleNames = [ u"json", u"obj", u"array", u"pair", u"value" ]

    EOF = Token.EOF
    T__0=1
    T__1=2
    T__2=3
    T__3=4
    T__4=5
    T__5=6
    T__6=7
    LCURLY=8
    LBRACK=9
    STRING=10
    NUMBER=11
    WS=12

    def __init__(self, input, output=sys.stdout):
    super(JSONParser, self).__init__(input, output=output)
    self.checkVersion("4.7.1")
    self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
    self._predicates = None



    class JsonContext(ParserRuleContext):

    def __init__(self, parser, parent=None, invokingState=-1):
    super(JSONParser.JsonContext, self).__init__(parent, invokingState)
    self.parser = parser

    def obj(self):
    return self.getTypedRuleContext(JSONParser.ObjContext,0)


    def array(self):
    return self.getTypedRuleContext(JSONParser.ArrayContext,0)


    def getRuleIndex(self):
    return JSONParser.RULE_json

    def enterRule(self, listener):
    if hasattr(listener, "enterJson"):
    listener.enterJson(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitJson"):
    listener.exitJson(self)




    def json(self):

    localctx = JSONParser.JsonContext(self, self._ctx, self.state)
    self.enterRule(localctx, 0, self.RULE_json)
    try:
    self.state = 12
    self._errHandler.sync(self)
    token = self._input.LA(1)
    if token in [JSONParser.LCURLY]:
    self.enterOuterAlt(localctx, 1)
    self.state = 10
    self.obj()
    pass
    elif token in [JSONParser.LBRACK]:
    self.enterOuterAlt(localctx, 2)
    self.state = 11
    self.array()
    pass
    else:
    raise NoViableAltException(self)

    except RecognitionException as re:
    localctx.exception = re
    self._errHandler.reportError(self, re)
    self._errHandler.recover(self, re)
    finally:
    self.exitRule()
    return localctx

    class ObjContext(ParserRuleContext):

    def __init__(self, parser, parent=None, invokingState=-1):
    super(JSONParser.ObjContext, self).__init__(parent, invokingState)
    self.parser = parser


    def getRuleIndex(self):
    return JSONParser.RULE_obj


    def copyFrom(self, ctx):
    super(JSONParser.ObjContext, self).copyFrom(ctx)



    class AnObjectContext(ObjContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ObjContext)
    super(JSONParser.AnObjectContext, self).__init__(parser)
    self.copyFrom(ctx)

    def pair(self, i=None):
    if i is None:
    return self.getTypedRuleContexts(JSONParser.PairContext)
    else:
    return self.getTypedRuleContext(JSONParser.PairContext,i)


    def enterRule(self, listener):
    if hasattr(listener, "enterAnObject"):
    listener.enterAnObject(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitAnObject"):
    listener.exitAnObject(self)


    class EmptyObjectContext(ObjContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ObjContext)
    super(JSONParser.EmptyObjectContext, self).__init__(parser)
    self.copyFrom(ctx)


    def enterRule(self, listener):
    if hasattr(listener, "enterEmptyObject"):
    listener.enterEmptyObject(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitEmptyObject"):
    listener.exitEmptyObject(self)



    def obj(self):

    localctx = JSONParser.ObjContext(self, self._ctx, self.state)
    self.enterRule(localctx, 2, self.RULE_obj)
    self._la = 0 # Token type
    try:
    self.state = 27
    self._errHandler.sync(self)
    la_ = self._interp.adaptivePredict(self._input,2,self._ctx)
    if la_ == 1:
    localctx = JSONParser.AnObjectContext(self, localctx)
    self.enterOuterAlt(localctx, 1)
    self.state = 14
    self.match(JSONParser.LCURLY)
    self.state = 15
    self.pair()
    self.state = 20
    self._errHandler.sync(self)
    _la = self._input.LA(1)
    while _la==JSONParser.T__0:
    self.state = 16
    self.match(JSONParser.T__0)
    self.state = 17
    self.pair()
    self.state = 22
    self._errHandler.sync(self)
    _la = self._input.LA(1)

    self.state = 23
    self.match(JSONParser.T__1)
    pass

    elif la_ == 2:
    localctx = JSONParser.EmptyObjectContext(self, localctx)
    self.enterOuterAlt(localctx, 2)
    self.state = 25
    self.match(JSONParser.LCURLY)
    self.state = 26
    self.match(JSONParser.T__1)
    pass


    except RecognitionException as re:
    localctx.exception = re
    self._errHandler.reportError(self, re)
    self._errHandler.recover(self, re)
    finally:
    self.exitRule()
    return localctx

    class ArrayContext(ParserRuleContext):

    def __init__(self, parser, parent=None, invokingState=-1):
    super(JSONParser.ArrayContext, self).__init__(parent, invokingState)
    self.parser = parser


    def getRuleIndex(self):
    return JSONParser.RULE_array


    def copyFrom(self, ctx):
    super(JSONParser.ArrayContext, self).copyFrom(ctx)



    class ArrayOfValuesContext(ArrayContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ArrayContext)
    super(JSONParser.ArrayOfValuesContext, self).__init__(parser)
    self.copyFrom(ctx)

    def value(self, i=None):
    if i is None:
    return self.getTypedRuleContexts(JSONParser.ValueContext)
    else:
    return self.getTypedRuleContext(JSONParser.ValueContext,i)


    def enterRule(self, listener):
    if hasattr(listener, "enterArrayOfValues"):
    listener.enterArrayOfValues(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitArrayOfValues"):
    listener.exitArrayOfValues(self)


    class EmptyArrayContext(ArrayContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ArrayContext)
    super(JSONParser.EmptyArrayContext, self).__init__(parser)
    self.copyFrom(ctx)


    def enterRule(self, listener):
    if hasattr(listener, "enterEmptyArray"):
    listener.enterEmptyArray(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitEmptyArray"):
    listener.exitEmptyArray(self)



    def array(self):

    localctx = JSONParser.ArrayContext(self, self._ctx, self.state)
    self.enterRule(localctx, 4, self.RULE_array)
    self._la = 0 # Token type
    try:
    self.state = 42
    self._errHandler.sync(self)
    la_ = self._interp.adaptivePredict(self._input,4,self._ctx)
    if la_ == 1:
    localctx = JSONParser.ArrayOfValuesContext(self, localctx)
    self.enterOuterAlt(localctx, 1)
    self.state = 29
    self.match(JSONParser.LBRACK)
    self.state = 30
    self.value()
    self.state = 35
    self._errHandler.sync(self)
    _la = self._input.LA(1)
    while _la==JSONParser.T__0:
    self.state = 31
    self.match(JSONParser.T__0)
    self.state = 32
    self.value()
    self.state = 37
    self._errHandler.sync(self)
    _la = self._input.LA(1)

    self.state = 38
    self.match(JSONParser.T__2)
    pass

    elif la_ == 2:
    localctx = JSONParser.EmptyArrayContext(self, localctx)
    self.enterOuterAlt(localctx, 2)
    self.state = 40
    self.match(JSONParser.LBRACK)
    self.state = 41
    self.match(JSONParser.T__2)
    pass


    except RecognitionException as re:
    localctx.exception = re
    self._errHandler.reportError(self, re)
    self._errHandler.recover(self, re)
    finally:
    self.exitRule()
    return localctx

    class PairContext(ParserRuleContext):

    def __init__(self, parser, parent=None, invokingState=-1):
    super(JSONParser.PairContext, self).__init__(parent, invokingState)
    self.parser = parser

    def STRING(self):
    return self.getToken(JSONParser.STRING, 0)

    def value(self):
    return self.getTypedRuleContext(JSONParser.ValueContext,0)


    def getRuleIndex(self):
    return JSONParser.RULE_pair

    def enterRule(self, listener):
    if hasattr(listener, "enterPair"):
    listener.enterPair(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitPair"):
    listener.exitPair(self)




    def pair(self):

    localctx = JSONParser.PairContext(self, self._ctx, self.state)
    self.enterRule(localctx, 6, self.RULE_pair)
    try:
    self.enterOuterAlt(localctx, 1)
    self.state = 44
    self.match(JSONParser.STRING)
    self.state = 45
    self.match(JSONParser.T__3)
    self.state = 46
    self.value()
    except RecognitionException as re:
    localctx.exception = re
    self._errHandler.reportError(self, re)
    self._errHandler.recover(self, re)
    finally:
    self.exitRule()
    return localctx

    class ValueContext(ParserRuleContext):

    def __init__(self, parser, parent=None, invokingState=-1):
    super(JSONParser.ValueContext, self).__init__(parent, invokingState)
    self.parser = parser


    def getRuleIndex(self):
    return JSONParser.RULE_value


    def copyFrom(self, ctx):
    super(JSONParser.ValueContext, self).copyFrom(ctx)



    class ObjectValueContext(ValueContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ValueContext)
    super(JSONParser.ObjectValueContext, self).__init__(parser)
    self.copyFrom(ctx)

    def obj(self):
    return self.getTypedRuleContext(JSONParser.ObjContext,0)


    def enterRule(self, listener):
    if hasattr(listener, "enterObjectValue"):
    listener.enterObjectValue(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitObjectValue"):
    listener.exitObjectValue(self)


    class StringContext(ValueContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ValueContext)
    super(JSONParser.StringContext, self).__init__(parser)
    self.copyFrom(ctx)

    def STRING(self):
    return self.getToken(JSONParser.STRING, 0)

    def enterRule(self, listener):
    if hasattr(listener, "enterString"):
    listener.enterString(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitString"):
    listener.exitString(self)


    class ArrayValueContext(ValueContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ValueContext)
    super(JSONParser.ArrayValueContext, self).__init__(parser)
    self.copyFrom(ctx)

    def array(self):
    return self.getTypedRuleContext(JSONParser.ArrayContext,0)


    def enterRule(self, listener):
    if hasattr(listener, "enterArrayValue"):
    listener.enterArrayValue(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitArrayValue"):
    listener.exitArrayValue(self)


    class AtomContext(ValueContext):

    def __init__(self, parser, ctx): # actually a JSONParser.ValueContext)
    super(JSONParser.AtomContext, self).__init__(parser)
    self.copyFrom(ctx)

    def NUMBER(self):
    return self.getToken(JSONParser.NUMBER, 0)

    def enterRule(self, listener):
    if hasattr(listener, "enterAtom"):
    listener.enterAtom(self)

    def exitRule(self, listener):
    if hasattr(listener, "exitAtom"):
    listener.exitAtom(self)



    def value(self):

    localctx = JSONParser.ValueContext(self, self._ctx, self.state)
    self.enterRule(localctx, 8, self.RULE_value)
    try:
    self.state = 55
    self._errHandler.sync(self)
    token = self._input.LA(1)
    if token in [JSONParser.STRING]:
    localctx = JSONParser.StringContext(self, localctx)
    self.enterOuterAlt(localctx, 1)
    self.state = 48
    self.match(JSONParser.STRING)
    pass
    elif token in [JSONParser.NUMBER]:
    localctx = JSONParser.AtomContext(self, localctx)
    self.enterOuterAlt(localctx, 2)
    self.state = 49
    self.match(JSONParser.NUMBER)
    pass
    elif token in [JSONParser.LCURLY]:
    localctx = JSONParser.ObjectValueContext(self, localctx)
    self.enterOuterAlt(localctx, 3)
    self.state = 50
    self.obj()
    pass
    elif token in [JSONParser.LBRACK]:
    localctx = JSONParser.ArrayValueContext(self, localctx)
    self.enterOuterAlt(localctx, 4)
    self.state = 51
    self.array()
    pass
    elif token in [JSONParser.T__4]:
    localctx = JSONParser.AtomContext(self, localctx)
    self.enterOuterAlt(localctx, 5)
    self.state = 52
    self.match(JSONParser.T__4)
    pass
    elif token in [JSONParser.T__5]:
    localctx = JSONParser.AtomContext(self, localctx)
    self.enterOuterAlt(localctx, 6)
    self.state = 53
    self.match(JSONParser.T__5)
    pass
    elif token in [JSONParser.T__6]:
    localctx = JSONParser.AtomContext(self, localctx)
    self.enterOuterAlt(localctx, 7)
    self.state = 54
    self.match(JSONParser.T__6)
    pass
    else:
    raise NoViableAltException(self)

    except RecognitionException as re:
    localctx.exception = re
    self._errHandler.reportError(self, re)
    self._errHandler.recover(self, re)
    finally:
    self.exitRule()
    return localctx





    63 changes: 63 additions & 0 deletions antlr_json_parser.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    __author__ = 'jszheng'

    import sys
    from antlr4 import *
    from antlr4.InputStream import InputStream

    from JSONLexer import JSONLexer
    from JSONParser import JSONParser
    from JSONListener import JSONListener


    class JsonEmitter(JSONListener):
    def __init__(self):
    self.xml = {}

    def exitAtom(self, ctx):
    return ctx.getText()

    def exitString(self, ctx):
    return ctx.getText()[1:-1].replace('\\"', '"')

    def exitObjectValue(self, ctx):
    return ctx.obj()

    def exitPair(self, ctx):
    return ctx.value()

    def exitAnObject(self, ctx):
    return ctx.pair()

    def exitArrayOfValues(self, ctx):
    return ctx.value()

    def exitArrayValue(self, ctx):
    return ctx.array()

    def exitEmptyArray(self, ctx):
    return []

    def exitJson(self, ctx):
    return ctx.getChild(0)


    if __name__ == '__main__':
    if len(sys.argv) > 1:
    input_stream = FileStream(sys.argv[1])
    else:
    input_stream = InputStream(sys.stdin.read())

    lexer = JSONLexer(input_stream)
    token_stream = CommonTokenStream(lexer)
    parser = JSONParser(token_stream)
    tree = parser.json()

    lisp_tree_str = tree.toStringTree(recog=parser)
    print(lisp_tree_str)

    # listener
    # print("Start Walking...")
    listener = JsonEmitter()
    walker = ParseTreeWalker()
    walker.walk(listener, tree)
    # print(listener.getXML(tree))
    145 changes: 145 additions & 0 deletions funcparselib_json.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,145 @@
    # -*- coding: utf-8 -*-

    r"""A JSON parser using funcparserlib.
    The parser is based on [the JSON grammar][1].
    [1]: http://tools.ietf.org/html/rfc4627
    """

    import sys
    import os
    import re
    import logging
    from re import VERBOSE
    from pprint import pformat
    from funcparserlib.lexer import make_tokenizer, Token, LexerError
    from funcparserlib.parser import (some, a, maybe, many, finished, skip,
    forward_decl, NoParseError)

    ENCODING = u'UTF-8'
    regexps = {
    u'escaped': ur'''
    \\ # Escape
    ((?P<standard>["\\/bfnrt]) # Standard escapes
    | (u(?P<unicode>[0-9A-Fa-f]{4}))) # uXXXX
    ''',
    u'unescaped': ur'''
    [^"\\] # Unescaped: avoid ["\\]
    ''',
    }
    re_esc = re.compile(regexps[u'escaped'], VERBOSE)


    def tokenize(str):
    """str -> Sequence(Token)"""
    specs = [
    (u'Space', (ur'[ \t\r\n]+',)),
    (u'String', (ur'"(%(unescaped)s | %(escaped)s)*"' % regexps, VERBOSE)),
    (u'Number', (ur'''
    -? # Minus
    (0|([1-9][0-9]*)) # Int
    (\.[0-9]+)? # Frac
    ([Ee][+-][0-9]+)? # Exp
    ''', VERBOSE)),
    (u'Op', (ur'[{}\[\]\-,:]',)),
    (u'Name', (ur'[A-Za-z_][A-Za-z_0-9]*',)),
    ]
    useless = [u'Space']
    t = make_tokenizer(specs)
    return [x for x in t(str) if x.type not in useless]


    def parse(seq):
    """Sequence(Token) -> object"""
    const = lambda x: lambda _: x
    tokval = lambda x: x.value
    toktype = lambda t: some(lambda x: x.type == t) >> tokval
    op = lambda s: a(Token(u'Op', s)) >> tokval
    op_ = lambda s: skip(op(s))
    n = lambda s: a(Token(u'Name', s)) >> tokval

    def make_array(n):
    if n is None:
    return []
    else:
    return [n[0]] + n[1]

    def make_object(n):
    return dict(make_array(n))

    def make_number(n):
    try:
    return int(n)
    except ValueError:
    return float(n)

    def unescape(s):
    std = {
    u'"': u'"', u'\\': u'\\', u'/': u'/', u'b': u'\b', u'f': u'\f',
    u'n': u'\n', u'r': u'\r', u't': u'\t',
    }

    def sub(m):
    if m.group(u'standard') is not None:
    return std[m.group(u'standard')]
    else:
    return unichr(int(m.group(u'unicode'), 16))

    return re_esc.sub(sub, s)

    def make_string(n):
    return unescape(n[1:-1])

    null = n(u'null') >> const(None)
    true = n(u'true') >> const(True)
    false = n(u'false') >> const(False)
    number = toktype(u'Number') >> make_number
    string = toktype(u'String') >> make_string
    value = forward_decl()
    member = string + op_(u':') + value >> tuple
    object = (
    op_(u'{') +
    maybe(member + many(op_(u',') + member)) +
    op_(u'}')
    >> make_object)
    array = (
    op_(u'[') +
    maybe(value + many(op_(u',') + value)) +
    op_(u']')
    >> make_array)
    value.define(
    null
    | true
    | false
    | object
    | array
    | number
    | string)
    json_text = object | array
    json_file = json_text + skip(finished)

    return json_file.parse(seq)


    def loads(s):
    """str -> object"""
    return parse(tokenize(s))


    def main():
    logging.basicConfig(level=logging.DEBUG)
    try:
    stdin = os.fdopen(sys.stdin.fileno(), 'rb')
    input = stdin.read().decode(ENCODING)
    tree = loads(input)
    # print pformat(tree)
    print tree
    except (NoParseError, LexerError), e:
    msg = (u'syntax error: %s' % e).encode(ENCODING)
    print >> sys.stderr, msg
    sys.exit(1)


    if __name__ == '__main__':
    main()