Skip to content

Commit 395b9ec

Browse files
ana-pantiliegithub-actionsrv-jenkins
authored
Allow parsing of multi-arg \\or with \\left-assoc (#2861)
* (R) Add test * (G) Parse \left-assoc for \or with two arguments * Format with fourmolu * (A) Remove commented-out code * (R) Add test for multiple arg \or * (G) Parse \or with arbitrary no. of arguments * Add equivalent tests for \right-assoc * (A) Factor out ParsedMultiOr type * Format with fourmolu * Update documentation * Add test for failing case * Format with fourmolu Co-authored-by: github-actions <[email protected]> Co-authored-by: rv-jenkins <[email protected]>
1 parent b7001f5 commit 395b9ec

File tree

3 files changed

+112
-9
lines changed

3 files changed

+112
-9
lines changed

docs/kore-syntax.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ A sort is either a _sort variable_ or a _sort constructor_ applied to a list of
181181
<application-pattern> ::=
182182
<symbol-identifier> "{" <sorts> "}" "(" <patterns> ")"
183183
184+
<multi-or> ::=
185+
"\or" "{" <sort> "}" "(" <patterns> ")"
186+
184187
<matching-logic-pattern>
185188
::=
186189
// Connectives
@@ -210,7 +213,9 @@ A sort is either a _sort variable_ or a _sort constructor_ applied to a list of
210213
| "\dv" "{" <sort> "}" "(" <string-literal> ")"
211214
// Syntax sugar
212215
| "\left-assoc" "{" "}" "(" <application-pattern> ")"
216+
| "\left-assoc" "{" "}" "(" <multi-or> ")"
213217
| "\right-assoc" "{" "}" "(" <application-pattern> ")"
218+
| "\right-assoc" "{" "}" "(" <multi-or> ")"
214219
```
215220

216221
### Attributes

kore/src/Kore/Parser/Parser.hs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ parseSymbolHead = parseSymbolOrAliasDeclarationHead Symbol
136136
-}
137137
parsePattern :: Parser ParsedPattern
138138
parsePattern =
139-
parseLiteral <|> (parseAnyId >>= parseRemainder)
139+
parseLiteral
140+
<|> (parseAnyId >>= parseRemainder)
140141
where
141142
parseRemainder identifier =
142143
parseVariableRemainder identifier
@@ -269,7 +270,7 @@ parseSymbolOrAliasRemainder symbolOrAliasConstructor = do
269270
@parseLeftAssoc@ assumes that the initial identifier has already been parsed.
270271
271272
@
272-
_ '{' '}' '(' <application-pattern> ')'
273+
_ '{' '}' '(' <application-pattern> | <multi-or> ')'
273274
@
274275
-}
275276
parseLeftAssoc :: Parser ParsedPattern
@@ -280,7 +281,7 @@ parseLeftAssoc = parseAssoc foldl1
280281
@parseRightAssoc@ assumes that the initial identifier has already been parsed.
281282
282283
@
283-
_ '{' '}' '(' <application-pattern> ')'
284+
_ '{' '}' '(' <application-pattern> | <multi-or> ')'
284285
@
285286
-}
286287
parseRightAssoc :: Parser ParsedPattern
@@ -300,12 +301,48 @@ parseAssoc ::
300301
Parser ParsedPattern
301302
parseAssoc foldAssoc = do
302303
braces $ pure ()
303-
application <- parens $ parseApplication parsePattern
304-
let mkApplication child1 child2 =
305-
from application{applicationChildren = [child1, child2]}
306-
case applicationChildren application of
307-
[] -> fail "expected one or more arguments"
308-
children -> pure (foldAssoc mkApplication children)
304+
Parse.try withOr <|> withApplication
305+
where
306+
withApplication = do
307+
application <- parens $ parseApplication parsePattern
308+
let mkApplication child1 child2 =
309+
from application{applicationChildren = [child1, child2]}
310+
case applicationChildren application of
311+
[] -> fail "expected one or more arguments"
312+
children -> pure (foldAssoc mkApplication children)
313+
withOr = do
314+
ParsedMultiOr{multiOrSort, multiOrChildren} <-
315+
parens $ parseMultiOr parsePattern
316+
let mkOr child1 child2 =
317+
from Or{orFirst = child1, orSecond = child2, orSort = multiOrSort}
318+
case multiOrChildren of
319+
[] -> fail "expected two or more arguments"
320+
[_] -> fail "expected two or more arguments"
321+
children -> return (foldAssoc mkOr children)
322+
323+
-- | Datatype for representing multi-argument Or.
324+
data ParsedMultiOr child = ParsedMultiOr
325+
{ multiOrSort :: Sort
326+
, multiOrChildren :: [child]
327+
}
328+
329+
{- | Parse an multi-argument Or occurring under an assoc syntatic sugar.
330+
331+
@
332+
<multi-or> ::= "\or" "{" <sort> "}" "(" <patterns> ")"
333+
@
334+
-}
335+
parseMultiOr :: Parser child -> Parser (ParsedMultiOr child)
336+
parseMultiOr parseChild = do
337+
parseAnyId >>= orLiteral
338+
multiOrSort <- braces parseSort
339+
multiOrChildren <- parens . list $ parseChild
340+
return ParsedMultiOr{multiOrSort, multiOrChildren}
341+
where
342+
orLiteral identifier =
343+
getSpecialId identifier >>= \case
344+
"or" -> return ()
345+
_ -> empty
309346

310347
{- | Parse a built-in Kore (matching logic) pattern.
311348
@@ -344,7 +381,9 @@ parseAssoc foldAssoc = do
344381
345382
// Syntax sugar
346383
| "\left-assoc" "{" "}" "(" <application-pattern> ")"
384+
| "\left-assoc" "{" "}" "(" <multi-or> ")"
347385
| "\right-assoc" "{" "}" "(" <application-pattern> ")"
386+
| "\right-assoc" "{" "}" "(" <multi-or> ")"
348387
@
349388
350389
Always starts with @\@.

kore/test/Test/Kore/Parser/Parser.hs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,35 @@ applicationPatternParserTests =
474474
]
475475
}
476476
)
477+
, success
478+
"\\left-assoc{}(\\or{s}(\"a\", \"b\"))"
479+
( embedParsedPattern $
480+
OrF
481+
Or
482+
{ orFirst = StringLiteral "a" & Const & StringLiteralF & embedParsedPattern
483+
, orSecond = StringLiteral "b" & Const & StringLiteralF & embedParsedPattern
484+
, orSort = sortVariableSort "s" :: Sort
485+
}
486+
)
487+
, success
488+
"\\left-assoc{}(\\or{s}(\"a\", \"b\", \"c\"))"
489+
( embedParsedPattern $
490+
OrF
491+
Or
492+
{ orFirst =
493+
embedParsedPattern $
494+
OrF
495+
Or
496+
{ orFirst =
497+
StringLiteral "a" & Const & StringLiteralF & embedParsedPattern
498+
, orSecond =
499+
StringLiteral "b" & Const & StringLiteralF & embedParsedPattern
500+
, orSort = sortVariableSort "s" :: Sort
501+
}
502+
, orSecond = StringLiteral "c" & Const & StringLiteralF & embedParsedPattern
503+
, orSort = sortVariableSort "s" :: Sort
504+
}
505+
)
477506
, success
478507
"\\right-assoc{}(c{}(\"a\"))"
479508
( StringLiteral "a"
@@ -530,6 +559,35 @@ applicationPatternParserTests =
530559
]
531560
}
532561
)
562+
, success
563+
"\\right-assoc{}(\\or{s}(\"a\", \"b\"))"
564+
( embedParsedPattern $
565+
OrF
566+
Or
567+
{ orFirst = StringLiteral "a" & Const & StringLiteralF & embedParsedPattern
568+
, orSecond = StringLiteral "b" & Const & StringLiteralF & embedParsedPattern
569+
, orSort = sortVariableSort "s" :: Sort
570+
}
571+
)
572+
, success
573+
"\\right-assoc{}(\\or{s}(\"a\", \"b\", \"c\"))"
574+
( embedParsedPattern $
575+
OrF
576+
Or
577+
{ orFirst = StringLiteral "a" & Const & StringLiteralF & embedParsedPattern
578+
, orSecond =
579+
embedParsedPattern $
580+
OrF
581+
Or
582+
{ orFirst =
583+
StringLiteral "b" & Const & StringLiteralF & embedParsedPattern
584+
, orSecond =
585+
StringLiteral "c" & Const & StringLiteralF & embedParsedPattern
586+
, orSort = sortVariableSort "s" :: Sort
587+
}
588+
, orSort = sortVariableSort "s" :: Sort
589+
}
590+
)
533591
, FailureWithoutMessage
534592
[ ""
535593
, "var"
@@ -539,6 +597,7 @@ applicationPatternParserTests =
539597
, "c{s}"
540598
, "\\left-assoc{}(c{}())"
541599
, "\\right-assoc{}(c{}())"
600+
, "\\or{s}(\"a\", \"b\", \"c\")"
542601
]
543602
]
544603
bottomPatternParserTests :: [TestTree]

0 commit comments

Comments
 (0)