Skip to content

Commit

Permalink
reduce backtracking in parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
janmasrovira committed Jul 15, 2024
1 parent 6d1447c commit b9d4b2f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
39 changes: 31 additions & 8 deletions src/Juvix/Compiler/Concrete/Translation/FromSource.hs
Original file line number Diff line number Diff line change
Expand Up @@ -995,14 +995,38 @@ pnamedArgumentItemPun = do
_namedArgumentReferencedSymbol = ()
}

namedArgumentNew ::
-- | Parses zero or more named arguments. This function is necessary to avoid
-- using excessive backtracking.
manyNamedArgumentNewRBrace ::
forall r.
(Members '[ParserResultBuilder, PragmasStash, JudocStash] r) =>
ParsecS r (NamedArgumentNew 'Parsed)
namedArgumentNew =
-- TODO this Try should be removed somehow
P.try (NamedArgumentNewFunction <$> pnamedArgumentFunctionDef)
<|> NamedArgumentItemPun <$> pnamedArgumentItemPun
ParsecS r [NamedArgumentNew 'Parsed]
manyNamedArgumentNewRBrace = reverse <$> go []
where
go :: [NamedArgumentNew 'Parsed] -> ParsecS r [NamedArgumentNew 'Parsed]
go acc =
rbrace $> acc
<|> itemHelper (P.try (withIsLast (NamedArgumentItemPun <$> pnamedArgumentItemPun)))
<|> itemHelper (withIsLast (NamedArgumentNewFunction <$> pnamedArgumentFunctionDef))
where
itemHelper :: ParsecS r (Bool, NamedArgumentNew 'Parsed) -> ParsecS r [NamedArgumentNew 'Parsed]
itemHelper p = do
(isLast, item) <- p
let acc' = item : acc
if
| isLast -> return acc'
| otherwise -> go acc'

pIsLast :: ParsecS r Bool
pIsLast =
rbrace $> True
<|> semicolon $> False

withIsLast :: ParsecS r a -> ParsecS r (Bool, a)
withIsLast p = do
res <- p
isLast <- pIsLast
return (isLast, res)

pisExhaustive ::
forall r.
Expand All @@ -1028,8 +1052,7 @@ namedApplicationNew = P.label "<named application>" $ do
exhaustive <- pisExhaustive
lbrace
return (n, exhaustive)
_namedApplicationNewArguments <- P.sepEndBy namedArgumentNew semicolon
rbrace
_namedApplicationNewArguments <- manyNamedArgumentNewRBrace
let _namedApplicationNewExtra = Irrelevant ()
return NamedApplicationNew {..}

Expand Down
12 changes: 9 additions & 3 deletions tests/positive/Puns.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ type S :=
mkS {
fieldA : A;
fieldB : B;
fieldC : A
fieldC : A;
fieldD : B;
fieldE : B
};

f (fieldA : A) (fieldB : B) : S :=
mkS@{
let
fieldD := b;
in mkS@{
fieldC := fieldA;
fieldA;
fieldB
fieldB;
fieldE := b;
fieldD;
};

0 comments on commit b9d4b2f

Please sign in to comment.