antlr4 python:解析json时侦听器不会显示所有内容

时间:2019-03-05 15:41:54

标签: python json antlr antlr4

我正在使用here给定的g4 json语法:

grammar JSON;

json
   : value
   ;

obj
   : '{' pair (',' pair)* '}'
   | '{' '}'
   ;

pair
   : STRING ':' value
   ;

array
   : '[' value (',' value)* ']'
   | '[' ']'
   ;

value
   : STRING
   | NUMBER
   | obj
   | array
   | 'true'
   | 'false'
   | 'null'
   ;


STRING
   : '"' (ESC | SAFECODEPOINT)* '"'
   ;


fragment ESC
   : '\\' (["\\/bfnrt] | UNICODE)
   ;
fragment UNICODE
   : 'u' HEX HEX HEX HEX
   ;
fragment HEX
   : [0-9a-fA-F]
   ;
fragment SAFECODEPOINT
   : ~ ["\\\u0000-\u001F]
   ;


NUMBER
   : '-'? INT ('.' [0-9] +)? EXP?
   ;


fragment INT
   : '0' | [1-9] [0-9]*
   ;

// no leading zeros

fragment EXP
   : [Ee] [+\-]? INT
   ;

// \- since - means "range" inside [...]

WS
   : [ \t\n\r] + -> skip
;

这是来自维基百科的json示例,我想使用上面的语法进行解析:

to_parse = r'''
{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    },
    {
      "type": "mobile",
      "number": "123 456-7890"
    }
  ],
  "children": [],
  "spouse": null
}
'''

我正在使用antlr4 python运行时(生成了lexer [lexer_class],解析器[parser_class]和listener [listener_class]之后):

class MyListener(listener_class):

    def enterJson(self, ctx):
        print(inspect.stack()[0][3])

    def exitJson(self, ctx):
        print(inspect.stack()[0][3])

    def enterObj(self, ctx):
        print(inspect.stack()[0][3])

    def exitObj(self, ctx):
        print(inspect.stack()[0][3])

    def enterPair(self, ctx):
        print(inspect.stack()[0][3])

    def exitPair(self, ctx):
        print(inspect.stack()[0][3])

    def enterArray(self, ctx):
        print(inspect.stack()[0][3])

    def exitArray(self, ctx):
        print(inspect.stack()[0][3])

    def enterValue(self, ctx):
        print(inspect.stack()[0][3])

    def exitValue(self, ctx):
        print(inspect.stack()[0][3])


input_stream = InputStream(to_parse)
lexer = lexer_class(input_stream)
token_stream = CommonTokenStream(lexer)
parser = parser_class(token_stream)
# Entry point in the json g4 grammar: json
tree = parser.json()
my_listener = MyListener()
walker = ParseTreeWalker()
walker.walk(my_listener, tree)

仅输出:

enterJson
enterValue
exitValue
exitJson

我的代码不显示任何数组obj是正常的吗?

[编辑]

我正在使用以下命令来生成* .py文件(词法分析器,解析器和侦听器):

java -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -o ./generation -Dlanguage=Python3 JSON.g4

1 个答案:

答案 0 :(得分:1)

我无法复制。当我根据您发布的语法生成类时,然后运行以下脚本:

from antlr4 import *
from JSONLexer import JSONLexer as lexer_class
from JSONParser import JSONParser as parser_class
from JSONListener import JSONListener as listener_class


class MyListener(listener_class):

    def enterJson(self, ctx):
        print("enterJson")

    def exitJson(self, ctx):
        print("exitJson")

    def enterObj(self, ctx):
        print("enterObj")

    def exitObj(self, ctx):
        print("exitObj")

    def enterPair(self, ctx):
        print("enterPair")

    def exitPair(self, ctx):
        print("exitPair")

    def enterArray(self, ctx):
        print("enterArray")

    def exitArray(self, ctx):
        print("exitArray")

    def enterValue(self, ctx):
        print("enterValue")

    def exitValue(self, ctx):
        print("exitValue")


to_parse = r'''
{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    },
    {
      "type": "mobile",
      "number": "123 456-7890"
    }
  ],
  "children": [],
  "spouse": null
}
'''

input_stream = InputStream(to_parse)
lexer = lexer_class(input_stream)
token_stream = CommonTokenStream(lexer)
parser = parser_class(token_stream)
tree = parser.json()
my_listener = MyListener()
walker = ParseTreeWalker()
walker.walk(my_listener, tree)

以下内容会打印到我的控制台上:

enterJson
enterValue
enterObj
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
enterObj
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
exitObj
exitValue
exitPair
enterPair
enterValue
enterArray
enterValue
enterObj
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
exitObj
exitValue
enterValue
enterObj
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
exitObj
exitValue
enterValue
enterObj
enterPair
enterValue
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
exitObj
exitValue
exitArray
exitValue
exitPair
enterPair
enterValue
enterArray
exitArray
exitValue
exitPair
enterPair
enterValue
exitValue
exitPair
exitObj
exitValue
exitJson