Skip to content
Snippets Groups Projects
Commit 535fdcd9 authored by Hugo Hörnquist's avatar Hugo Hörnquist
Browse files

Fix parsing of nested if statements.

parent 89401a65
No related branches found
No related tags found
No related merge requests found
...@@ -186,7 +186,7 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -186,7 +186,7 @@ class ParserFormatter(Serializer[ParseDirective]):
ensure => present, ensure => present,
} }
""" """
return (ws & param.k & return (ws & tag('qn', param.k) &
ws & param.arrow & ws & param.arrow &
ws & self.s(param.v) & ws & self.s(param.v) &
# Technically only optional for final entry # Technically only optional for final entry
...@@ -214,7 +214,7 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -214,7 +214,7 @@ class ParserFormatter(Serializer[ParseDirective]):
for item in xs: for item in xs:
parser &= ws & ',' & self.declaration_parameter(item) parser &= ws & ',' & self.declaration_parameter(item)
parser &= ws & optional(s(',')) & ws & delim[1] parser &= ws & optional(s(',')) & ws & delim[1]
return name('declaration-parameters', parser) return tag('declaration-parameters', parser)
def known_array(self, delim: str, in_items: list[Puppet]) -> ParseDirective: def known_array(self, delim: str, in_items: list[Puppet]) -> ParseDirective:
""" """
...@@ -257,8 +257,6 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -257,8 +257,6 @@ class ParserFormatter(Serializer[ParseDirective]):
raise ValueError(f'Unexpected extra forms after else: {rest!r}') raise ValueError(f'Unexpected extra forms after else: {rest!r}')
case [(test, body), *rest]: case [(test, body), *rest]:
# logger.warning("elsif clause, test: %s, body: %s", test, body)
# Recursive calls wrapped in lambdas, since they NEED # Recursive calls wrapped in lambdas, since they NEED
# to be lazily evaluated, since they are only valid in # to be lazily evaluated, since they are only valid in
# their branch ('else'/'elsif') # their branch ('else'/'elsif')
...@@ -268,12 +266,12 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -268,12 +266,12 @@ class ParserFormatter(Serializer[ParseDirective]):
ws & self.s(body) & ws & self.s(body) &
ws & '}') & (lambda: self.if_chain(rest)) ws & '}') & (lambda: self.if_chain(rest))
inner = PuppetIfChain([(test, body), *rest])
else_parser = (ws & tag('keyword', 'else') & else_parser = (ws & tag('keyword', 'else') &
ws & '{' & ws & '{' &
ws & (lambda: self.s(PuppetIfChain(rest))) & ws & (lambda: self.s(inner)) &
ws & '}') ws & '}')
# return elsif_parser | else_parser
return else_parser | elsif_parser return else_parser | elsif_parser
raise ValueError(f"Bad if-chain: {chain!r}") raise ValueError(f"Bad if-chain: {chain!r}")
...@@ -323,7 +321,7 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -323,7 +321,7 @@ class ParserFormatter(Serializer[ParseDirective]):
def _puppet_case(self, it: PuppetCase) -> ParseDirective: def _puppet_case(self, it: PuppetCase) -> ParseDirective:
parser = ws & tag('keyword', 'case') & ws & self.s(it.test) & ws & '{' parser = ws & tag('keyword', 'case') & ws & self.s(it.test) & ws & '{'
for ((x, *xs), body) in it.cases: for ([x, *xs], body) in it.cases:
parser &= ws & self.s(x) parser &= ws & self.s(x)
for x in xs: for x in xs:
parser &= ws & ',' & ws & self.s(x) parser &= ws & ',' & ws & self.s(x)
...@@ -333,11 +331,10 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -333,11 +331,10 @@ class ParserFormatter(Serializer[ParseDirective]):
@override @override
def _puppet_class(self, it: PuppetClass) -> ParseDirective: def _puppet_class(self, it: PuppetClass) -> ParseDirective:
parser = (ws & tag('keyword', 'class') & ws & it.name & parser = (ws & tag('keyword', 'class') & ws & tag('name', it.name) &
optional(ws & self.declaration_parameters('()', it.params))) optional(ws & self.declaration_parameters('()', it.params)))
parser &= optional(ws & 'inherits' & ws & tag('inherits', it.parent)) parser &= optional(ws & 'inherits' & ws & tag('inherits', it.parent))
parser &= ws & '{' & ws & self.s(it.body) & ws & '}' parser &= ws & '{' & ws & self.s(it.body) & ws & '}'
# logger.warning(parser)
return parser return parser
@override @override
...@@ -355,13 +352,14 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -355,13 +352,14 @@ class ParserFormatter(Serializer[ParseDirective]):
& optional(s('{')) & optional(s('{'))
& ws & ws
& optional(s('$')) & optional(s('$'))
& x & tag('var', x)
& ws & ws
& optional(s('}'))) & optional(s('}')))
parser &= f parser &= f
case PuppetString(st): case PuppetString(st):
try: try:
parser &= st for c in st:
parser &= rich_char(c)
except ParseError: except ParseError:
for c in st: for c in st:
parser &= rich_char(c) parser &= rich_char(c)
...@@ -373,6 +371,7 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -373,6 +371,7 @@ class ParserFormatter(Serializer[ParseDirective]):
@override @override
def _puppet_declaration(self, it: PuppetDeclaration) -> ParseDirective: def _puppet_declaration(self, it: PuppetDeclaration) -> ParseDirective:
# TODO tag with declaration
return ws & self.s(it.k) & ws & '=' & ws & self.s(it.v) return ws & self.s(it.k) & ws & '=' & ws & self.s(it.v)
@override @override
...@@ -410,7 +409,8 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -410,7 +409,8 @@ class ParserFormatter(Serializer[ParseDirective]):
# logger.warning("clauses: %s", it.clauses) # logger.warning("clauses: %s", it.clauses)
(test1, body1), *rest = it.clauses (test1, body1), *rest = it.clauses
assert test1 != 'else', f"Unexpected else clause: {it.clauses}" assert test1 != 'else', f"Unexpected else clause: {it.clauses}"
parser = (ws & 'if' # assert test1 != 'elsif', f"Unexpected elsif clause: {it.clauses}"
parser = (ws & tag('keyword', 'if')
& ws & self.s(test1) & ws & self.s(test1)
& ws & '{' & ws & '{'
& ws & self.s(body1) & ws & self.s(body1)
...@@ -444,7 +444,7 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -444,7 +444,7 @@ class ParserFormatter(Serializer[ParseDirective]):
def _puppet_lambda(self, it: PuppetLambda) -> ParseDirective: def _puppet_lambda(self, it: PuppetLambda) -> ParseDirective:
return tag('lambda', return tag('lambda',
self.declaration_parameters('||', it.params) & self.declaration_parameters('||', it.params) &
'{' & self.s(it.body) & '}') ws & '{' & self.s(it.body) & ws & '}')
@override @override
def _puppet_literal(self, it: PuppetLiteral) -> ParseDirective: def _puppet_literal(self, it: PuppetLiteral) -> ParseDirective:
...@@ -574,6 +574,9 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -574,6 +574,9 @@ class ParserFormatter(Serializer[ParseDirective]):
# A string with " as delimiter # A string with " as delimiter
double_quoted = s('"') & [rich_char(c) for c in it.s] & '"' double_quoted = s('"') & [rich_char(c) for c in it.s] & '"'
if it.s == '':
parser = ws & (single_quoted | double_quoted)
else:
parser = ws & (raw_string | single_quoted | double_quoted) parser = ws & (raw_string | single_quoted | double_quoted)
return tag('string', parser) return tag('string', parser)
...@@ -588,7 +591,9 @@ class ParserFormatter(Serializer[ParseDirective]): ...@@ -588,7 +591,9 @@ class ParserFormatter(Serializer[ParseDirective]):
@override @override
def _puppet_var(self, it: PuppetVar) -> ParseDirective: def _puppet_var(self, it: PuppetVar) -> ParseDirective:
return name(f'${it.name}', ws & '$' & it.name) # TODO highlight entire decalaration
# TODO hyperlink?
return name(f'${it.name}', ws & '$' & tag('var', it.name))
@override @override
def _puppet_virtual_query(self, it: PuppetVirtualQuery) -> ParseDirective: def _puppet_virtual_query(self, it: PuppetVirtualQuery) -> ParseDirective:
......
...@@ -53,6 +53,8 @@ class DocStringTag(Deserializable): ...@@ -53,6 +53,8 @@ class DocStringTag(Deserializable):
:param text: :param text:
Freeform text content of the tag. Freeform text content of the tag.
TODO types
""" """
tag_name: str tag_name: str
......
# Muppet's built in output # Muppet's built in output
comment: comment:
- comment - comment
- line-comment
error: error:
- parse-error - parse-error
interpolate: interpolate:
...@@ -23,3 +24,4 @@ string: ...@@ -23,3 +24,4 @@ string:
variable: variable:
- qn - qn
- var - var
- name
...@@ -182,7 +182,7 @@ def test_complement(): ...@@ -182,7 +182,7 @@ def test_complement():
def test_stringifiers(): def test_stringifiers():
assert "'a'" == str(s("a")) assert "'a'" == str(s("a"))
assert "~ 'a'" == repr(~ s("a")) assert "~ 'a'" == repr(~ s("a"))
assert "x" == str(name("x", space & space)) assert "[x]" == str(name("x", space & space))
assert "('a' & 'b')" == str(s('a') & s('b')) assert "('a' & 'b')" == str(s('a') & s('b'))
assert "('a' | 'b')" == str(s('a') | s('b')) assert "('a' | 'b')" == str(s('a') | s('b'))
assert "char" == str(char) assert "char" == str(char)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment