当前位置: 首页 > 知识库问答 >
问题:

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

蒲曦
2023-03-14

我使用的是这里给出的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
;
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
}
'''
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

我使用以下命令生成*.py文件(lexer、parser和listener):

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

共有1个答案

潘胤
2023-03-14

我不能复制它。当我从您发布的语法生成类,然后运行以下脚本时:

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
 类似资料:
  • 问题内容: 解析JSON之后,我将数据保存在ViewController的arraOfData中,但collectionView不会显示此数据。如果我使用静态数组,一切正常。collectionview.reloadData()无法正常工作。我认为,需要以某种方式等待解析的数据,然后尝试加载collectionView。我尝试使用refreshControler来等待数据,但是我不知道put方法“

  • 问题内容: 我制作了一个Python脚本,该脚本可以执行很多操作,因此它具有许多选项,因此我将其划分为一些子解析器,这些子解析器也使用父解析器进行常见选项分组。 我想要一个帮助选项,该选项将显示所有命令及其选项的帮助,是否可以不覆盖format_help方法? 我看到了类似的问题,但是分组对我来说并不重要,我只想在那里找到选项。 例如: 在这种情况下,我希望如果有人运行./script.py -h

  • 我正在使用版本来使用来自主题的消息。在使用者配置中,自动提交设置为,而设置为。与服务器协商为10秒。 在收到消息后,我将它的一部分保存到数据库中。我的数据库有时会非常慢,这会导致kafka侦听器会话超时: 组MyGroup得自动偏移量提交失败:无法完成提交,因为组已重新平衡并将分区分配给另一个成员.这意味着对poll()的后续调用之间的时间比配置的session.timeout.ms长,这通常意味

  • 我使用fiddler监控一个简单的html内容从一个PHP文件运行在localhost。但是每当我按f5刷新页面(浏览器)时,在fiddler中有时整个web会话的字体变成蓝色,即当它实际显示内容(html)时,相反的情况发生在web会话是灰色的时候,它不显示html内容。 注意:始终显示请求/响应标题,这仅用于内容。我还尝试了点技巧(“:80”)并从localhost切换到127.0。0.1.

  • 在处理下一个表时,当我单击复选框选择一行时,无法启动侦听器。有人知道我做错了什么吗? 谢谢 我想做与基于复选框的选择示例相同的事情(http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionRadioCheckbox.jsf); 但是使用文档(Primefaces用户指南v3.3第141页)中所述的rowSelectCheckb

  • 问题说明: