Я пытаюсь создать синтаксический анализатор для преобразования «пользовательского» файла в JSON, чтобы мне было проще манипулировать его содержимым (для аргумента, вызовите «пользовательский» формат .qwerty).
Я уже создал Lexer, который разбивает файл на отдельные лексемы (токены), структура которых [token_type, token_value].Сейчас я изо всех сил пытаюсь разобрать лексемы в их правильных словарях, поскольку трудно вставить данные в подпод словарь, поскольку ключи не являются постоянными.А также вставлять данные в массивы, хранящиеся в словарях.
Следует отметить, что я пытаюсь последовательно проанализировать токены в реальном json-объекте python, а затем выгрузить объект json.
Пример файла можно увидеть ниже, а также то, на что должен напоминать конечный результат.
ФАЙЛ: ABC.querty
Dict_abc_1{
Dict_abc_2{
HeaderGUID="";
Version_TPI="999";
EncryptionType="0";
}
Dict_abc_3{
FamilyName="John Doe";
}
Dict_abc_4{
Array_abc{
{TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
{TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
{TimeStamp="2018-11-07 01:00:00"; otherinfo="";}
{TimeStamp="2018-11-07 02:53:57"; otherinfo="";}
{TimeStamp="2018-11-07 02:53:57"; otherinfo="";}
}
Dict_abc_5{
LastContact="2018-11-08 01:00:00";
BatteryStatus=99;
BUStatus=PowerOn;
LastCallTime="2018-11-08 01:12:46";
LastSuccessPoll="2018-11-08 01:12:46";
CallResult=Successful;
}
}
}
Code=999999;
ФАЙЛ: ABC.json
{
"Dict_abc_1":{
"Dict_abc_2":{
"HeaderGUID":"",
"Version_TPI":"999",
"EncryptionType":"0"
},
"Dict_abc_3":{
"FamilyName":"John Doe"
},
"Dict_abc_4":{
"Array_abc":[
{"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
{"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
{"TimeStamp":"2018-11-07 01:00:00", "otherinfo":""},
{"TimeStamp":"2018-11-07 02:53:57", "otherinfo":""},
{"TimeStamp":"2018-11-07 02:53:57", "otherinfo":""}
],
"Dict_abc_5":{
"LastContact":"2018-11-08 01:00:00",
"BatteryStatus":99,
"BUStatus":"PowerOn",
"LastCallTime":"2018-11-08 01:12:46",
"LastSuccessPoll":"2018-11-08 01:12:46",
"CallResult":"Successful"
}
}
},
"Code":999999
}
Дополнительная информация о токене, типы токенов могут быть (с возможными значениями)
- ИДЕНТИФИКАТОР содержатьимя идентификатора переменной
- VARIABLE , содержащее фактические данные, принадлежащие родительскому ИДЕНТИФИКАТОРУ
- ОПЕРАТОР равно "="
- OPEN_BRACKET равно "{"
- CLOSE_BRACKET равно "}"
Пример лексем ABC.querty можно увидеть ЗДЕСЬ
основной логический фрагмент main.py
def main():
content = open_file(file_name) ## read file
lexer = Lexer(content) ## create lexer class
tokens = lexer.tokenize() ## create lexems as seen in pastebin
parser = Parser(tokens).parse() ## create parser class given tokens
print(json.dumps(parser, sort_keys=True,indent=4, separators=(',', ': ')))
parser.py
import re
class Parser(object):
def __init__(self, tokens):
self.tokens = tokens
self.token_index = 0
self.json_object = {}
self.current_object = {}
self.path = [self.json_object]
def parse(self):
while self.token_index < len(self.tokens):
token = self.getToken()
token_type = token[0]
token_value = token[1]
print("%s \t %s" % (token_type, token_value))
if token_type in "IDENTIFIER":
self.increment()
identifier_type = self.getToken()
if identifier_type[0] in "OPEN_BRACKET":
identifier_two_type = self.getToken(1)
if identifier_two_type[0] in ["OPERATOR","IDENTIFIER"]:
## make dict in current dict
pass
elif identifier_two_type[0] in "OPEN_BRACKET":
## make array in current dict
pass
elif identifier_type[0] in "OPERATOR":
## insert data into current dict
pass
if token_type in "CLOSE_BRACKET":
identifier_type = self.getToken()
if "OPEN_BRACKET" in identifier_type[0]:
#still in array of current dict
pass
elif "IDENTIFIER" in identifier_type[0]:
self.changeDirectory()
else:
#end script
pass
self.increment()
print(self.path)
return self.json_object
def changeDirectory(self):
if len(self.path) > 0:
self.path = self.path.pop()
self.current_object = -1
def increment(self):
if self.token_index < len(self.tokens):
self.token_index+=1
def getToken(self, x=0):
return self.tokens[self.token_index+x]
Дополнительная информация о разборе. В настоящее время я пытался сохранить текущий словарь в массиве путей, чтобы можно было вставлять его в словари и массивы в словарях.
Любые предложения илиРешения очень ценятся,
Спасибо.