quase tudo feito so falta as cenas estaticas e prints melhores e escrever para file
This commit is contained in:
parent
19c572afab
commit
b79540bab8
3 changed files with 120 additions and 35 deletions
112
src/example.toml
112
src/example.toml
|
@ -1,31 +1,95 @@
|
||||||
title = "TOML Example"
|
# Example TOML file with syntax errors
|
||||||
[owner]
|
|
||||||
name = """Tom Preston-Werner
|
|
||||||
test"""
|
|
||||||
othername = """Tom \"The killer\" or \"yo\" or
|
|
||||||
'you' Preston-Werner"""
|
|
||||||
date = 2010-04-23
|
|
||||||
time = 21:30:00
|
|
||||||
"lol".yo = "tesaat"
|
|
||||||
|
|
||||||
[[fruits]]
|
title = "My Config File"
|
||||||
|
|
||||||
|
[author]
|
||||||
|
name = "John Doe"
|
||||||
|
email = "johndoe@example.com"
|
||||||
|
|
||||||
|
[database]
|
||||||
|
name = "my_database"
|
||||||
|
username = "admin"
|
||||||
|
password = "password123"
|
||||||
|
" " = "lmao"
|
||||||
|
"" = "lmao"
|
||||||
|
|
||||||
|
[server]
|
||||||
|
ip = "192.168.0.1"
|
||||||
|
port = 8080
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
enabled = true
|
||||||
|
level = "info"
|
||||||
|
|
||||||
|
[[fruit]]
|
||||||
name = "apple"
|
name = "apple"
|
||||||
|
|
||||||
[fruits.physical]
|
|
||||||
color = "red"
|
color = "red"
|
||||||
shape = "round"
|
|
||||||
|
|
||||||
[[fruits.varieties]]
|
[[fruit]]
|
||||||
name = "red delicious"
|
|
||||||
|
|
||||||
[[fruits.varieties]]
|
|
||||||
name = "granny smith"
|
|
||||||
|
|
||||||
[[fruits]]
|
|
||||||
name = "banana"
|
name = "banana"
|
||||||
|
color = "yellow"
|
||||||
|
|
||||||
|
|
||||||
|
[vegetables]
|
||||||
|
hello = "test"
|
||||||
|
|
||||||
|
[vegetables.yeet]
|
||||||
|
carrot = "orange"
|
||||||
|
tomato = "red"
|
||||||
|
potato = "yellow"
|
||||||
|
|
||||||
|
[[animal]]
|
||||||
|
name = "cat"
|
||||||
|
sound = "meow"
|
||||||
|
[[animal]]
|
||||||
|
name = "dog"
|
||||||
|
sound = "woof"
|
||||||
|
|
||||||
|
[paths]
|
||||||
|
data = "/path/to/data"
|
||||||
|
logs = "/path/to/logs"
|
||||||
|
|
||||||
|
[[servers]]
|
||||||
|
name = "server1"
|
||||||
|
ip = "192.168.0.10"
|
||||||
|
port = 8081
|
||||||
|
|
||||||
|
[[servers]]
|
||||||
|
name = "server2"
|
||||||
|
ip = "192.168.0.20"
|
||||||
|
port = 8082
|
||||||
|
|
||||||
|
|
||||||
|
[arrays]
|
||||||
|
integers = [ 1, 2, 3 ]
|
||||||
|
colors = [ "red", "yellow", "green" ]
|
||||||
|
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||||
|
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||||
|
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||||
|
|
||||||
|
# Mixed-type arrays are allowed
|
||||||
|
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||||
|
contributors = [
|
||||||
|
"Foo Bar <foo@example.com>",
|
||||||
|
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||||
|
]
|
||||||
|
|
||||||
|
[fruie]
|
||||||
|
apple.color = "red"
|
||||||
|
apple.taste.sweet = true
|
||||||
|
|
||||||
|
[fruie.apple.color]
|
||||||
|
test="oi"
|
||||||
|
[fruie.apple.taste]
|
||||||
|
test2="oi"
|
||||||
|
|
||||||
|
[fruie.apple.texture] # you can add sub-tables
|
||||||
|
smooth = true
|
||||||
|
smooth = false
|
||||||
|
|
||||||
|
|
||||||
|
points = [ { x = 1, y = 2, z = 3 },
|
||||||
|
{ x = 7, y = 8, z = 9 },
|
||||||
|
{ x = 2, y = 4, z = 8 } ]
|
||||||
|
|
||||||
[[fruits.varieties]]
|
|
||||||
name = "plantain"
|
|
||||||
integers2.name = "Nail"
|
|
||||||
integers2 = {"oi"=5}
|
|
||||||
|
|
||||||
|
|
16
src/lexer.py
16
src/lexer.py
|
@ -12,6 +12,7 @@ tokens = [
|
||||||
"BIN",
|
"BIN",
|
||||||
"OCT",
|
"OCT",
|
||||||
"FLOAT", # need to implement exponents check https://toml.io/en/
|
"FLOAT", # need to implement exponents check https://toml.io/en/
|
||||||
|
"BOOL",
|
||||||
"INF",
|
"INF",
|
||||||
"NAN",
|
"NAN",
|
||||||
"COMMENT",
|
"COMMENT",
|
||||||
|
@ -38,7 +39,7 @@ 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+(\s*\.\s*\d+)?([eE][-+]?\d+)?"
|
r"[+-]?\d+(_\d+)*\s*\.\s*\d+(_\d+)*([eE][-+]?\d+(_\d+)*)?"
|
||||||
#case where float appears on the left side with spaces in between
|
#case where float appears on the left side with spaces in between
|
||||||
if t.value.__contains__(' '):
|
if t.value.__contains__(' '):
|
||||||
t.type = "ID"
|
t.type = "ID"
|
||||||
|
@ -48,23 +49,23 @@ def t_FLOAT(t):
|
||||||
|
|
||||||
# needs number grouping (example : int6 = 5_349_221)
|
# needs number grouping (example : int6 = 5_349_221)
|
||||||
def t_INT(t):
|
def t_INT(t):
|
||||||
r"[-+]?\d+"
|
r"[-+]?(\d+(_\d+)*)"
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
# needs number grouping (example : hex3 = 0xdead_beef)
|
# needs number grouping (example : hex3 = 0xdead_beef)
|
||||||
def t_HEX(t):
|
def t_HEX(t):
|
||||||
r"0x[0-9a-fA-F]+"
|
r"0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*"
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
def t_BIN(t):
|
def t_BIN(t):
|
||||||
r"0b[01]+"
|
r"0b[01]+(_[01]+)*"
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
def t_OCT(t):
|
def t_OCT(t):
|
||||||
r"0o[0-7]+"
|
r"0o[0-7]+(_[0-7]+)*"
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,13 +93,14 @@ def t_ID(t):
|
||||||
|
|
||||||
|
|
||||||
def t_MLSTR(t):
|
def t_MLSTR(t):
|
||||||
r"(\"\"\"(?:[^\"\\]|\\.)+\"\"\")|(\'\'\'(?:[^\'\\]|\\.)+\'\'\')"
|
r"(\"\"\"(?:[^\"\\]|\\.)*\"\"\")|(\'\'\'.*\'\'\')"
|
||||||
|
t.value = t.value.strip("\"'")
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
# STR needs to be the first one to catch
|
# STR needs to be the first one to catch
|
||||||
def t_STR(t):
|
def t_STR(t):
|
||||||
r"(\"(?:[^\"\\]|\\.)+\")|(\'[^\']+\')"
|
r"(\"(?:[^\"\\]|\\.)*\")|(\'[^\']*\')"
|
||||||
t.value = t.value.strip("\"'")
|
t.value = t.value.strip("\"'")
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ def p_table_simple(p):
|
||||||
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
|
||||||
|
p.parser.current_header_name = p[2]
|
||||||
|
|
||||||
|
|
||||||
# isto ta errado
|
# isto ta errado
|
||||||
|
@ -68,6 +69,7 @@ def p_table_array(p):
|
||||||
temp[headers[-1]].append({})
|
temp[headers[-1]].append({})
|
||||||
temp = temp[headers[-1]][-1]
|
temp = temp[headers[-1]][-1]
|
||||||
p.parser.current_header = temp
|
p.parser.current_header = temp
|
||||||
|
p.parser.current_header_name = p[3]
|
||||||
|
|
||||||
|
|
||||||
def p_object(p):
|
def p_object(p):
|
||||||
|
@ -77,23 +79,30 @@ def p_object(p):
|
||||||
if p.parser.syntax_error:
|
if p.parser.syntax_error:
|
||||||
return
|
return
|
||||||
headers = p[1]
|
headers = p[1]
|
||||||
|
temp = p.parser.current_header
|
||||||
|
|
||||||
if isinstance(p[3],dict):
|
if isinstance(p[3],dict):
|
||||||
for table in p.parser.current_tables:
|
for table in p.parser.current_tables:
|
||||||
if p[1][0]==table[0]:
|
if p[1][0]==table[0]:
|
||||||
print("Error, trying to redefine a table")
|
print("Error, trying to redefine a table")
|
||||||
return
|
return
|
||||||
p.parser.current_inline_tables.append(p[1])
|
p.parser.current_inline_tables.append(p[1])
|
||||||
else:
|
elif len(p[1])>1:
|
||||||
for table in p.parser.current_inline_tables:
|
for table in p.parser.current_inline_tables:
|
||||||
if p[1][:len(table)]==table:
|
if p[1][:len(table)]==table:
|
||||||
print("Error, trying to redefine an inline table")
|
print("Error, trying to redefine an inline table")
|
||||||
return
|
return
|
||||||
p.parser.current_tables.append(p[1])
|
p.parser.current_tables.append(p[1])
|
||||||
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:
|
||||||
temp[header] = {}
|
temp[header] = {}
|
||||||
temp = temp[header]
|
temp = temp[header]
|
||||||
|
if not isinstance(temp,dict):
|
||||||
|
print("Error, cannot add {p[3]} to a {type(temp)} variable")
|
||||||
|
return
|
||||||
|
if headers[-1] in temp:
|
||||||
|
print(f"Error, cannot define {'.'.join(p.parser.current_header_name + p[1])} twice")
|
||||||
|
return
|
||||||
temp[headers[-1]] = p[3]
|
temp[headers[-1]] = p[3]
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +148,12 @@ def p_dict_empty(p):
|
||||||
def p_dictCont_multiple(p):
|
def p_dictCont_multiple(p):
|
||||||
"""dictCont : dictCont ',' dictElem"""
|
"""dictCont : dictCont ',' dictElem"""
|
||||||
# checar se os dicts nao teem keys repetidas
|
# checar se os dicts nao teem keys repetidas
|
||||||
p[0] = p[1].update(p[3])
|
duplicate_list = [k for k in p[1] if k in p[3]]
|
||||||
|
for dup in duplicate_list:
|
||||||
|
print(f"Duplicate inline-table key {dup}")
|
||||||
|
if len(duplicate_list)==0:
|
||||||
|
p[1].update(p[3])
|
||||||
|
p[0] = p[1]
|
||||||
|
|
||||||
|
|
||||||
def p_dictCont_single(p):
|
def p_dictCont_single(p):
|
||||||
|
@ -147,7 +161,7 @@ def p_dictCont_single(p):
|
||||||
p[0] = p[1]
|
p[0] = p[1]
|
||||||
|
|
||||||
|
|
||||||
def p_dictElem_object(p):
|
def p_dictElem(p):
|
||||||
"""dictElem : key '=' value
|
"""dictElem : key '=' value
|
||||||
| key '=' array
|
| key '=' array
|
||||||
| key '=' dict"""
|
| key '=' dict"""
|
||||||
|
@ -177,6 +191,7 @@ def p_key_rest(p):
|
||||||
| BIN
|
| BIN
|
||||||
| OCT
|
| OCT
|
||||||
| INF
|
| INF
|
||||||
|
| BOOL
|
||||||
| NAN"""
|
| NAN"""
|
||||||
p[0] = [p[1]]
|
p[0] = [p[1]]
|
||||||
|
|
||||||
|
@ -239,6 +254,9 @@ def p_value_nan(p):
|
||||||
"""value : NAN"""
|
"""value : NAN"""
|
||||||
p[0] = p[1]
|
p[0] = p[1]
|
||||||
|
|
||||||
|
def p_value_bool(p):
|
||||||
|
"""value : BOOL"""
|
||||||
|
p[0] = bool(p[1])
|
||||||
|
|
||||||
def p_error(p):
|
def p_error(p):
|
||||||
print(p)
|
print(p)
|
||||||
|
@ -248,6 +266,7 @@ parser = yacc.yacc()
|
||||||
|
|
||||||
parser.root_dict = dict()
|
parser.root_dict = dict()
|
||||||
parser.current_header = parser.root_dict
|
parser.current_header = parser.root_dict
|
||||||
|
parser.current_header_name = ""
|
||||||
parser.syntax_error = False
|
parser.syntax_error = False
|
||||||
parser.current_inline_tables = []
|
parser.current_inline_tables = []
|
||||||
parser.current_tables = []
|
parser.current_tables = []
|
||||||
|
|
Loading…
Reference in a new issue