Skip to content

Commit

Permalink
Add: Identifier concatenation with '.'
Browse files Browse the repository at this point in the history
  • Loading branch information
glx22 committed Jan 18, 2025
1 parent b1ec6b0 commit 927b3b9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 38 deletions.
80 changes: 44 additions & 36 deletions nml/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def p_include_define_list(self, t):
t[0] = t[1] | t[3]

def p_include_define(self, t):
"include_define : ID EQ expression"
"include_define : identifier EQ expression"
t[0] = {t[1].value: t[3]}

def p_main_block(self, t):
Expand Down Expand Up @@ -190,6 +190,14 @@ def p_main_block(self, t):
| constant"""
t[0] = t[1]

def p_identifier(self, t):
"""identifier : ID
| identifier DOT identifier"""
if len(t) == 4:
t[0] = expression.Identifier(t[1].value + t[3].value)
else:
t[0] = t[1]

#
# Expressions
#
Expand All @@ -198,7 +206,7 @@ def p_expression(self, t):
| FLOAT
| param
| variable
| ID
| identifier
| STRING_LITERAL
| string"""
t[0] = t[1]
Expand Down Expand Up @@ -284,7 +292,7 @@ def p_variable(self, t):
t[0].pos = t.lineno(1)

def p_function(self, t):
"expression : ID LPAREN expression_list RPAREN"
"expression : identifier LPAREN expression_list RPAREN"
t[0] = expression.FunctionCall(t[1], t[3], t[1].pos)

def p_array(self, t):
Expand All @@ -305,7 +313,7 @@ def p_assignment_list(self, t):
t[0] = t[1] + [t[2]]

def p_assignment(self, t):
"assignment : ID COLON expression SEMICOLON"
"assignment : identifier COLON expression SEMICOLON"
t[0] = assignment.Assignment(t[1], t[3], t[1].pos)

def p_param_desc(self, t):
Expand All @@ -325,7 +333,7 @@ def p_setting_list(self, t):
t[0] = t[1] + [t[2]]

def p_setting(self, t):
"setting : ID LBRACE setting_value_list RBRACE"
"setting : identifier LBRACE setting_value_list RBRACE"
t[0] = grf.ParameterSetting(t[1], t[3])

def p_setting_value_list(self, t):
Expand All @@ -341,7 +349,7 @@ def p_setting_value(self, t):
t[0] = t[1]

def p_names_setting_value(self, t):
"setting_value : ID COLON LBRACE name_string_list RBRACE SEMICOLON"
"setting_value : identifier COLON LBRACE name_string_list RBRACE SEMICOLON"
t[0] = assignment.Assignment(t[1], t[4], t[1].pos)

def p_name_string_list(self, t):
Expand Down Expand Up @@ -375,8 +383,8 @@ def p_expression_list(self, t):
t[0] = [] if len(t) == 1 else t[1]

def p_non_empty_id_list(self, t):
"""non_empty_id_list : ID
| non_empty_id_list COMMA ID"""
"""non_empty_id_list : identifier
| non_empty_id_list COMMA identifier"""
if len(t) == 2:
t[0] = [t[1]]
else:
Expand Down Expand Up @@ -428,8 +436,8 @@ def p_property_list(self, t):
t[0] = t[1] + [t[2]]

def p_property_assignment(self, t):
"""property_assignment : ID COLON expression SEMICOLON
| ID COLON expression UNIT SEMICOLON
"""property_assignment : identifier COLON expression SEMICOLON
| identifier COLON expression UNIT SEMICOLON
| NUMBER COLON expression SEMICOLON
| NUMBER COLON expression UNIT SEMICOLON"""
name = t[1]
Expand Down Expand Up @@ -557,9 +565,9 @@ def p_produce_cargo_list(self, t):
t[0] = t[2]

def p_produce(self, t):
"""produce : PRODUCE LPAREN ID COMMA expression_list RPAREN SEMICOLON
| PRODUCE LPAREN ID COMMA produce_cargo_list COMMA produce_cargo_list COMMA expression RPAREN
| PRODUCE LPAREN ID COMMA produce_cargo_list COMMA produce_cargo_list RPAREN"""
"""produce : PRODUCE LPAREN identifier COMMA expression_list RPAREN SEMICOLON
| PRODUCE LPAREN identifier COMMA produce_cargo_list COMMA produce_cargo_list COMMA expression RPAREN
| PRODUCE LPAREN identifier COMMA produce_cargo_list COMMA produce_cargo_list RPAREN"""
if len(t) == 8:
t[0] = produce.ProduceOld([t[3]] + t[5], t.lineno(1))
elif len(t) == 11:
Expand All @@ -572,7 +580,7 @@ def p_produce(self, t):
#
def p_real_sprite(self, t):
"""real_sprite : LBRACKET expression_list RBRACKET
| ID COLON LBRACKET expression_list RBRACKET"""
| identifier COLON LBRACKET expression_list RBRACKET"""
if len(t) == 4:
t[0] = real_sprite.RealSprite(param_list=t[2], poslist=[t.lineno(1)])
else:
Expand All @@ -597,19 +605,19 @@ def p_recolour_assignment_3(self, t):

def p_recolour_sprite(self, t):
"""real_sprite : RECOLOUR_SPRITE LBRACE recolour_assignment_list RBRACE
| ID COLON RECOLOUR_SPRITE LBRACE recolour_assignment_list RBRACE"""
| identifier COLON RECOLOUR_SPRITE LBRACE recolour_assignment_list RBRACE"""
if len(t) == 5:
t[0] = real_sprite.RecolourSprite(mapping=t[3], poslist=[t.lineno(1)])
else:
t[0] = real_sprite.RecolourSprite(mapping=t[5], label=t[1], poslist=[t.lineno(1)])

def p_template_declaration(self, t):
"template_declaration : TEMPLATE ID LPAREN id_list RPAREN LBRACE spriteset_contents RBRACE"
"template_declaration : TEMPLATE identifier LPAREN id_list RPAREN LBRACE spriteset_contents RBRACE"
t[0] = spriteblock.TemplateDeclaration(t[2], t[4], t[7], t.lineno(1))

def p_template_usage(self, t):
"""template_usage : ID LPAREN expression_list RPAREN
| ID COLON ID LPAREN expression_list RPAREN"""
"""template_usage : identifier LPAREN expression_list RPAREN
| identifier COLON identifier LPAREN expression_list RPAREN"""
if len(t) == 5:
t[0] = real_sprite.TemplateUsage(t[1], t[3], None, t.lineno(1))
else:
Expand All @@ -627,31 +635,31 @@ def p_spriteset_contents(self, t):

def p_replace(self, t):
"""replace : REPLACESPRITE LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE
| REPLACESPRITE ID LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
| REPLACESPRITE identifier LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
if len(t) == 9:
t[0] = replace.ReplaceSprite(t[4], t[7], t[2], t.lineno(1))
else:
t[0] = replace.ReplaceSprite(t[3], t[6], None, t.lineno(1))

def p_replace_new(self, t):
"""replace_new : REPLACENEWSPRITE LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE
| REPLACENEWSPRITE ID LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
| REPLACENEWSPRITE identifier LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
if len(t) == 9:
t[0] = replace.ReplaceNewSprite(t[4], t[7], t[2], t.lineno(1))
else:
t[0] = replace.ReplaceNewSprite(t[3], t[6], None, t.lineno(1))

def p_base_graphics(self, t):
"""base_graphics : BASE_GRAPHICS LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE
| BASE_GRAPHICS ID LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
| BASE_GRAPHICS identifier LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
if len(t) == 9:
t[0] = base_graphics.BaseGraphics(t[4], t[7], t[2], t.lineno(1))
else:
t[0] = base_graphics.BaseGraphics(t[3], t[6], None, t.lineno(1))

def p_font_glyph(self, t):
"""font_glyph : FONTGLYPH LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE
| FONTGLYPH ID LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
| FONTGLYPH identifier LPAREN expression_list RPAREN LBRACE spriteset_contents RBRACE"""
if len(t) == 9:
t[0] = font.FontGlyphBlock(t[4], t[7], t[2], t.lineno(1))
else:
Expand All @@ -670,12 +678,12 @@ def p_spriteset(self, t):
t[0] = spriteblock.SpriteSet(t[3], t[6], t.lineno(1))

def p_spritegroup_normal(self, t):
"spritegroup : SPRITEGROUP ID LBRACE spriteview_list RBRACE"
"spritegroup : SPRITEGROUP identifier LBRACE spriteview_list RBRACE"
t[0] = spriteblock.SpriteGroup(t[2], t[4], t.lineno(1))

def p_spritelayout(self, t):
"""spritelayout : SPRITELAYOUT ID LBRACE layout_sprite_list RBRACE
| SPRITELAYOUT ID LPAREN id_list RPAREN LBRACE layout_sprite_list RBRACE"""
"""spritelayout : SPRITELAYOUT identifier LBRACE layout_sprite_list RBRACE
| SPRITELAYOUT identifier LPAREN id_list RPAREN LBRACE layout_sprite_list RBRACE"""
if len(t) == 6:
t[0] = spriteblock.SpriteLayout(t[2], [], t[4], t.lineno(1))
else:
Expand All @@ -690,8 +698,8 @@ def p_spriteview_list(self, t):
t[0] = t[1] + [t[2]]

def p_spriteview(self, t):
"""spriteview : ID COLON LBRACKET expression_list RBRACKET SEMICOLON
| ID COLON expression SEMICOLON"""
"""spriteview : identifier COLON LBRACKET expression_list RBRACKET SEMICOLON
| identifier COLON expression SEMICOLON"""
if len(t) == 7:
t[0] = spriteblock.SpriteView(t[1], t[4], t.lineno(1))
else:
Expand All @@ -706,7 +714,7 @@ def p_layout_sprite_list(self, t):
t[0] = t[1] + [t[2]]

def p_layout_sprite(self, t):
"layout_sprite : ID LBRACE layout_param_list RBRACE"
"layout_sprite : identifier LBRACE layout_param_list RBRACE"
t[0] = spriteblock.LayoutSprite(t[1], t[3], t.lineno(1))

def p_layout_param_list(self, t):
Expand Down Expand Up @@ -737,7 +745,7 @@ def p_town_names_param_list(self, t):
t[0] = t[1] + [t[2]]

def p_town_names_param(self, t):
"""town_names_param : ID COLON string SEMICOLON
"""town_names_param : identifier COLON string SEMICOLON
| LBRACE town_names_part_list RBRACE
| LBRACE town_names_part_list COMMA RBRACE"""
if t[1] != "{":
Expand All @@ -755,7 +763,7 @@ def p_town_names_part_list(self, t):

def p_town_names_part(self, t):
"""town_names_part : TOWN_NAMES LPAREN expression COMMA expression RPAREN
| ID LPAREN STRING_LITERAL COMMA expression RPAREN"""
| identifier LPAREN STRING_LITERAL COMMA expression RPAREN"""
if t[1] == "town_names":
t[0] = townnames.TownNamesEntryDefinition(t[3], t[5], t.lineno(1))
else:
Expand All @@ -765,7 +773,7 @@ def p_town_names_part(self, t):
# Snow line
#
def p_snowline(self, t):
"snowline : SNOWLINE LPAREN ID RPAREN LBRACE snowline_assignment_list RBRACE"
"snowline : SNOWLINE LPAREN identifier RPAREN LBRACE snowline_assignment_list RBRACE"
t[0] = snowline.Snowline(t[3], t[6], t.lineno(1))

#
Expand All @@ -789,9 +797,9 @@ def p_cargotable(self, t):
t[0] = cargotable.CargoTable(t[3], t.lineno(1))

def p_cargotable_list(self, t):
"""cargotable_list : ID
"""cargotable_list : identifier
| STRING_LITERAL
| cargotable_list COMMA ID
| cargotable_list COMMA identifier
| cargotable_list COMMA STRING_LITERAL"""
if len(t) == 2:
t[0] = [t[1]]
Expand Down Expand Up @@ -822,9 +830,9 @@ def p_tracktypetable_list(self, t):
t[0] = t[1] + [t[3]]

def p_tracktypetable_item(self, t):
"""tracktypetable_item : ID
"""tracktypetable_item : identifier
| STRING_LITERAL
| ID COLON LBRACKET expression_list RBRACKET"""
| identifier COLON LBRACKET expression_list RBRACKET"""
if len(t) == 2:
t[0] = t[1]
else:
Expand Down Expand Up @@ -855,7 +863,7 @@ def p_sort_vehicles(self, t):
t[0] = sort_vehicles.SortVehicles(t[3], t.lineno(1))

def p_tilelayout(self, t):
"tilelayout : TILELAYOUT ID LBRACE tilelayout_list RBRACE"
"tilelayout : TILELAYOUT identifier LBRACE tilelayout_list RBRACE"
t[0] = tilelayout.TileLayout(t[2], t[4], t.lineno(1))

def p_tilelayout_list(self, t):
Expand Down
2 changes: 2 additions & 0 deletions nml/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class NMLLexer:
"NUMBER",
"FLOAT",
"UNIT",
"DOT",
]

t_PLUS = r"\+"
Expand Down Expand Up @@ -157,6 +158,7 @@ class NMLLexer:
t_TERNARY_OPEN = r"\?"
t_COLON = r":"
t_SEMICOLON = r";"
t_DOT = r"\."

def t_FLOAT(self, t):
r"\d+\.\d+"
Expand Down
4 changes: 2 additions & 2 deletions regression/042_include.inc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
param[0] = param[0] + VALUE;
const NAME = VALUE;
param[0] = param[0] + NAME;
const _.NAME.x.y = VALUE;
param[0] = param[0] + _.NAME.x.y;

0 comments on commit 927b3b9

Please sign in to comment.