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"
|
||||
[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"
|
||||
# Example TOML file with syntax errors
|
||||
|
||||
[[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"
|
||||
|
||||
[fruits.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "red delicious"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "granny smith"
|
||||
|
||||
[[fruits]]
|
||||
[[fruit]]
|
||||
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",
|
||||
"OCT",
|
||||
"FLOAT", # need to implement exponents check https://toml.io/en/
|
||||
"BOOL",
|
||||
"INF",
|
||||
"NAN",
|
||||
"COMMENT",
|
||||
|
@ -38,7 +39,7 @@ def t_TIME(t):
|
|||
|
||||
# needs number grouping (example : flt8 = 224_617.445_991_228)
|
||||
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
|
||||
if t.value.__contains__(' '):
|
||||
t.type = "ID"
|
||||
|
@ -48,23 +49,23 @@ def t_FLOAT(t):
|
|||
|
||||
# needs number grouping (example : int6 = 5_349_221)
|
||||
def t_INT(t):
|
||||
r"[-+]?\d+"
|
||||
r"[-+]?(\d+(_\d+)*)"
|
||||
return t
|
||||
|
||||
|
||||
# needs number grouping (example : hex3 = 0xdead_beef)
|
||||
def t_HEX(t):
|
||||
r"0x[0-9a-fA-F]+"
|
||||
r"0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*"
|
||||
return t
|
||||
|
||||
|
||||
def t_BIN(t):
|
||||
r"0b[01]+"
|
||||
r"0b[01]+(_[01]+)*"
|
||||
return t
|
||||
|
||||
|
||||
def t_OCT(t):
|
||||
r"0o[0-7]+"
|
||||
r"0o[0-7]+(_[0-7]+)*"
|
||||
return t
|
||||
|
||||
|
||||
|
@ -92,13 +93,14 @@ def t_ID(t):
|
|||
|
||||
|
||||
def t_MLSTR(t):
|
||||
r"(\"\"\"(?:[^\"\\]|\\.)+\"\"\")|(\'\'\'(?:[^\'\\]|\\.)+\'\'\')"
|
||||
r"(\"\"\"(?:[^\"\\]|\\.)*\"\"\")|(\'\'\'.*\'\'\')"
|
||||
t.value = t.value.strip("\"'")
|
||||
return t
|
||||
|
||||
|
||||
# STR needs to be the first one to catch
|
||||
def t_STR(t):
|
||||
r"(\"(?:[^\"\\]|\\.)+\")|(\'[^\']+\')"
|
||||
r"(\"(?:[^\"\\]|\\.)*\")|(\'[^\']*\')"
|
||||
t.value = t.value.strip("\"'")
|
||||
return t
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ def p_table_simple(p):
|
|||
print("Cannot define the same table twice")
|
||||
p.parser.syntax_error = True
|
||||
p.parser.current_header = temp
|
||||
p.parser.current_header_name = p[2]
|
||||
|
||||
|
||||
# isto ta errado
|
||||
|
@ -68,6 +69,7 @@ def p_table_array(p):
|
|||
temp[headers[-1]].append({})
|
||||
temp = temp[headers[-1]][-1]
|
||||
p.parser.current_header = temp
|
||||
p.parser.current_header_name = p[3]
|
||||
|
||||
|
||||
def p_object(p):
|
||||
|
@ -77,23 +79,30 @@ def p_object(p):
|
|||
if p.parser.syntax_error:
|
||||
return
|
||||
headers = p[1]
|
||||
temp = p.parser.current_header
|
||||
|
||||
if isinstance(p[3],dict):
|
||||
for table in p.parser.current_tables:
|
||||
if p[1][0]==table[0]:
|
||||
print("Error, trying to redefine a table")
|
||||
return
|
||||
p.parser.current_inline_tables.append(p[1])
|
||||
else:
|
||||
elif len(p[1])>1:
|
||||
for table in p.parser.current_inline_tables:
|
||||
if p[1][:len(table)]==table:
|
||||
print("Error, trying to redefine an inline table")
|
||||
return
|
||||
p.parser.current_tables.append(p[1])
|
||||
temp = p.parser.current_header
|
||||
for header in headers[:-1]:
|
||||
if header not in 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]
|
||||
|
||||
|
||||
|
@ -139,7 +148,12 @@ def p_dict_empty(p):
|
|||
def p_dictCont_multiple(p):
|
||||
"""dictCont : dictCont ',' dictElem"""
|
||||
# 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):
|
||||
|
@ -147,7 +161,7 @@ def p_dictCont_single(p):
|
|||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_dictElem_object(p):
|
||||
def p_dictElem(p):
|
||||
"""dictElem : key '=' value
|
||||
| key '=' array
|
||||
| key '=' dict"""
|
||||
|
@ -177,6 +191,7 @@ def p_key_rest(p):
|
|||
| BIN
|
||||
| OCT
|
||||
| INF
|
||||
| BOOL
|
||||
| NAN"""
|
||||
p[0] = [p[1]]
|
||||
|
||||
|
@ -239,6 +254,9 @@ def p_value_nan(p):
|
|||
"""value : NAN"""
|
||||
p[0] = p[1]
|
||||
|
||||
def p_value_bool(p):
|
||||
"""value : BOOL"""
|
||||
p[0] = bool(p[1])
|
||||
|
||||
def p_error(p):
|
||||
print(p)
|
||||
|
@ -248,6 +266,7 @@ parser = yacc.yacc()
|
|||
|
||||
parser.root_dict = dict()
|
||||
parser.current_header = parser.root_dict
|
||||
parser.current_header_name = ""
|
||||
parser.syntax_error = False
|
||||
parser.current_inline_tables = []
|
||||
parser.current_tables = []
|
||||
|
|
Loading…
Reference in a new issue