[PARSER/LEXER] id in lexer now returns a list with the headers, fixed

parser code.
This commit is contained in:
Tiago Sousa 2023-05-26 16:24:37 +01:00
parent a4e60dd218
commit 6e465cab3d
3 changed files with 40 additions and 27 deletions

View file

@ -16,8 +16,8 @@ table : '[' ID ']'
| '[' '[' ID ']' ']' | '[' '[' ID ']' ']'
object : key '=' value object : key '=' value
| key '=' array -- | key '=' array
| key '=' dict -- talvez coloque isto numa regra separada chamada inlinetable | key '=' dict
array : '[' aCont ']' array : '[' aCont ']'
| '[' ']' | '[' ']'
@ -35,12 +35,20 @@ dict : '{' dictCont '}'
dictCont : dictCont ',' dictElem dictCont : dictCont ',' dictElem
| dictElem | dictElem
dictElem : object dictElem : key '=' value
| key '=' array
| key '=' dict
key : ID key : ID
| STR | STR
| FLOAT | DATE
| INT | INT
| FLOAT
| HEX
| BIN
| OCT
| INF
| NAN
value : STR value : STR
| DATE | DATE

View file

@ -38,7 +38,11 @@ def t_TIME(t):
# needs number grouping (example : flt8 = 224_617.445_991_228) # needs number grouping (example : flt8 = 224_617.445_991_228)
def t_FLOAT(t): def t_FLOAT(t):
r"[+-]?\d+(\.\d+)?([eE][-+]?\d+)?" r"[+-]?\d+(\s*\.\s*\d+)?([eE][-+]?\d+)?"
#case where float appears on the left side with spaces in between
if t.value.__contains(' '):
t.type = "ID"
t.value = [s.strip(' ') for s in t.value.split('.')]
return t return t
@ -71,6 +75,7 @@ def t_INF(t):
def t_NAN(t): def t_NAN(t):
r"[+-]?nan" r"[+-]?nan"
return t
# booleans are always lowercase # booleans are always lowercase
@ -82,6 +87,7 @@ def t_BOOL(t):
# ID needs to be the last so it doesnt catch everything (literally) # ID needs to be the last so it doesnt catch everything (literally)
def t_ID(t): def t_ID(t):
r"(([\w_]+)|(\"[\w_]+\"|\'[\w_]+\')\s*\.\s*([\w_]+|\"[\w_]+\"|\'[\w_]+\'))(\s*\.\s*([\w_]+|\"[\w_]+\"|\'[\w_]+\'))*" r"(([\w_]+)|(\"[\w_]+\"|\'[\w_]+\')\s*\.\s*([\w_]+|\"[\w_]+\"|\'[\w_]+\'))(\s*\.\s*([\w_]+|\"[\w_]+\"|\'[\w_]+\'))*"
t.value = [s.strip(" \"'") for s in t.value.split('.')]
return t return t

View file

@ -26,7 +26,7 @@ def p_tomlEntries_object(p):
def p_table_simple(p): def p_table_simple(p):
"""table : '[' ID ']'""" """table : '[' ID ']'"""
p.parser.syntax_error = False p.parser.syntax_error = False
headers = p[2].split('.') headers = p[2]
temp = p.parser.root_dict temp = p.parser.root_dict
for header in headers[:-1]: for header in headers[:-1]:
if header not in temp: if header not in temp:
@ -40,7 +40,7 @@ def p_table_simple(p):
temp[headers[-1]] = {} temp[headers[-1]] = {}
temp = temp[headers[-1]] temp = temp[headers[-1]]
else: else:
print('Cannot define the same table twice') print("Cannot define the same table twice")
p.parser.syntax_error = True p.parser.syntax_error = True
p.parser.current_header = temp p.parser.current_header = temp
@ -49,7 +49,7 @@ def p_table_simple(p):
def p_table_array(p): def p_table_array(p):
"""table : '[' '[' ID ']' ']'""" """table : '[' '[' ID ']' ']'"""
p.parser.syntax_error = False p.parser.syntax_error = False
headers = p[3].split('.') headers = p[3].split(".")
temp = p.parser.root_dict temp = p.parser.root_dict
for header in headers[:-1]: for header in headers[:-1]:
if header not in temp: if header not in temp:
@ -59,7 +59,7 @@ def p_table_array(p):
temp[headers[-1]] = [{}] temp[headers[-1]] = [{}]
else: else:
if not isinstance(temp[headers[-1]], list): if not isinstance(temp[headers[-1]], list):
print('Error, type of object is not list') print("Error, type of object is not list")
p.parser.syntax_error = True p.parser.syntax_error = True
temp[headers[-1]].append({}) temp[headers[-1]].append({})
temp = temp[headers[-1]][-1] temp = temp[headers[-1]][-1]
@ -72,7 +72,7 @@ def p_object(p):
| key '=' dict""" | key '=' dict"""
if p.parser.syntax_error: if p.parser.syntax_error:
return return
headers = p[1].split('.') headers = p[1].split(".")
temp = p.parser.current_header temp = p.parser.current_header
for header in headers[:-1]: for header in headers[:-1]:
if header not in temp: if header not in temp:
@ -135,7 +135,7 @@ def p_dictElem_object(p):
"""dictElem : key '=' value """dictElem : key '=' value
| key '=' array | key '=' array
| key '=' dict""" | key '=' dict"""
headers = p[1].split('.') headers = p[1]
p[0] = {} p[0] = {}
temp = p[0] temp = p[0]
for header in headers[:-1]: for header in headers[:-1]:
@ -145,25 +145,24 @@ def p_dictElem_object(p):
temp[headers[-1]] = p[3] temp[headers[-1]] = p[3]
# id comes from the lexer as a list of headers
def p_key_id(p): def p_key_id(p):
"""key : ID""" """key : ID"""
p[0] = p[1] p[0] = p[1]
# the rest of the cases are the specific cases where the key as the same format as a float/int/etc
def p_key_str(p): # so we need make them a singleton list.
"""key : STR""" def p_key_rest(p):
p[0] = p[1] """key : STR
| DATE
| INT
def p_key_float(p): | FLOAT
"""key : FLOAT""" | HEX
p[0] = p[1] | BIN
| OCT
| INF
def p_key_int(p): | NAN"""
"""key : INT""" p[0] = [p[1]]
p[0] = p[1]
def p_value_str(p): def p_value_str(p):
"""value : STR""" """value : STR"""
@ -235,7 +234,7 @@ parser.root_dict = dict()
parser.current_header = parser.root_dict parser.current_header = parser.root_dict
parser.syntax_error = False parser.syntax_error = False
f = open('example.toml', 'r') f = open("example.toml", "r")
parser.parse(f.read()) parser.parse(f.read())
print(json.dumps(parser.root_dict, indent=2)) print(json.dumps(parser.root_dict, indent=2))