Skip to content

Commit

Permalink
Fix issues #48 and #98 using Lark's interactive parser.
Browse files Browse the repository at this point in the history
  • Loading branch information
erezsh committed Dec 3, 2022
1 parent a7350ac commit 7f1c625
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 11 deletions.
5 changes: 2 additions & 3 deletions mappyfile/mapfile.lark
Expand Up @@ -49,9 +49,8 @@ _composite_item: (composite|attr|points|projection|pattern|values|config)
!validation: "VALIDATION"i string_pair* _END
!connectionoptions: "CONNECTIONOPTIONS"i string_pair* _END

attr: (UNQUOTED_STRING | composite_type) (value | UNQUOTED_STRING)
//attr: (UNQUOTED_STRING | SYMBOL) (value | UNQUOTED_STRING)
// SYMBOL is listed in composite_type but is also an attribute name
attr: (UNQUOTED_STRING | composite_type) (value | UNQUOTED_STRING | UNQUOTED_STRING_VALUE)
%declare UNQUOTED_STRING_VALUE // generated using the interactive parser. See issues #48, #98

?value: string | int | float | expression | not_expression | attr_bind | path
| regexp | runtime_var | list | NULL | true | false | extent | rgb | hexcolor
Expand Down
14 changes: 13 additions & 1 deletion mappyfile/parser.py
Expand Up @@ -41,6 +41,7 @@

log = logging.getLogger("mappyfile")

SYMBOL_ATTRIBUTES = {'ANCHORPOINT', 'ANTIALIAS', 'FILLED', 'FONT', 'IMAGE', 'NAME', 'COLOR', 'TYPE', 'FONT', 'CHARACTER', 'POINTS', 'TRANSPARENT'}

class Parser(object):

Expand Down Expand Up @@ -221,7 +222,18 @@ def parse(self, text, fn=None):

try:
self._comments[:] = [] # clear any comments from a previous parse
tree = self.lalr.parse(text)
ip = self.lalr.parse_interactive(text)
for t in ip.iter_parse():
if t.type == 'UNQUOTED_STRING':
# Unquoted strings after SYMBOL can only be values, not attributes
if ip.parser_state.value_stack[-1] == 'SYMBOL' and t.value.upper() not in SYMBOL_ATTRIBUTES:
t.type = 'UNQUOTED_STRING_VALUE'
elif t.type == 'GRID':
# Unquoted 'GRID' coming after NAME is always a value, not a composite type
if ip.parser_state.value_stack[-1] == 'NAME':
t.type = 'UNQUOTED_STRING_VALUE'

tree = ip.resume_parse()
if self.include_comments:
self.assign_comments(tree, self._comments)
return tree
Expand Down
2 changes: 1 addition & 1 deletion mappyfile/transformer.py
Expand Up @@ -281,7 +281,7 @@ def attr(self, tokens):

if isinstance(key_token, (list, tuple)):
key_token = key_token[0]
assert self.key_name(key_token) in ("style", "symbol")
assert self.key_name(key_token) in ("style", "symbol"), self.key_name(key_token)

key_name = self.key_name(key_token)
value_tokens = tokens[1:]
Expand Down
9 changes: 3 additions & 6 deletions tests/test_snippets.py
Expand Up @@ -687,7 +687,6 @@ def test_symbol_style():
assert(output(s, schema_name="style") == exp)


@pytest.mark.xfail
def test_symbol_style2():
"""
barb_warm is not in quotes
Expand All @@ -700,8 +699,9 @@ def test_symbol_style2():
SIZE 8
END
"""
exp = "STYLE SYMBOL 'barb_warm' END"
assert(output(s, schema_name="style") == exp)
exp = "STYLE SYMBOL 'barb_warm' GAP -45 SIZE 8 END"
res = output(s, schema_name="style")
assert(res == exp)


def test_extent():
Expand Down Expand Up @@ -981,9 +981,7 @@ def test_cluster2():
assert(output(s, schema_name="layer") == exp)


@pytest.mark.xfail
def test_outputformat_unquoted_keyword():

s = u"""
MAP
OUTPUTFORMAT
Expand All @@ -993,7 +991,6 @@ def test_outputformat_unquoted_keyword():
END
"""

print(output(s, schema_name="map"))
exp = u"MAP OUTPUTFORMAT NAME 'grid' IMAGEMODE INT16 END END"
assert(output(s, schema_name="map") == exp)

Expand Down

0 comments on commit 7f1c625

Please sign in to comment.