Я использую грамматику 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
}
'''
Я использую среду выполнения Python antlr4 (после генерации лексера [lexer_class
], анализатора [parser_class
] и слушателя [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?
[EDIT]
Я использую следующую команду для генерации *Файлы .py (лексер, парсер и слушатель):
java -cp antlr-4.7.2-complete.jar org.antlr.v4.Tool -o ./generation -Dlanguage=Python3 JSON.g4