lukewilliamboswell / roc-parser

A simple Parser for Roc
https://lukewilliamboswell.github.io/roc-parser/
Universal Permissive License v1.0
27 stars 8 forks source link

lazy not working for recursive parser #11

Open megakilo opened 8 months ago

megakilo commented 8 months ago

I have this mini parser for add expression. But compiler overflows due to the recursive structure. I saw lazy seems to be the solution for this but can't figure out why it doesn't work.

term : Parser Utf8 U64
term = alt digits (lazy (\_ -> expr) |> between (codeunit '(') (codeunit ')'))

expr : Parser Utf8 U64
expr = const (\x -> \y -> x + y) |> apply (lazy \_ -> term) |> skip (codeunit '+') |> apply (lazy \_ -> term)

expect parseStr expr "1+2" == Ok 3u64
expect parseStr expr "1+(1+2)" == Ok 4u64
megakilo commented 8 months ago

The Elm equivalent works fine

parens = Parser.succeed (\v -> v) |. Parser.symbol "(" |= expr |. Parser.symbol ")"

term = Parser.oneOf
        [ Parser.int
        , parens
        ]

expr = Parser.succeed  (\x y -> x + y) |= Parser.lazy (\_ -> term) |. Parser.symbol "+" |= Parser.lazy (\_ -> term)

main =
    "1+(2+3)"
        |> Parser.run expr
        |> Debug.toString
        |> text
megakilo commented 8 months ago

I think it's related to the compiler bug here https://github.com/roc-lang/roc/issues/4288