Trying to build a parser

I’m trying to learn parser library and stuck. It’s not working for single number (for example “3”), but I think it should because of

expression : Parser Expression
expression =
        [ addExpr
        , intExpr

after addExpr failed it should run intExpr. What do I do wrong? Here is whole code

module TokenParser exposing (..)

import Parser exposing (..)


type AST
    = Statement Expression

type Expression
    = IntValue Int
    | AddExpr Expression Expression

newLines =
    chompWhile (\c -> c == '\n')

addExpr : Parser Expression
addExpr =
        |= intExpr
        |. symbol "+"
        |= intExpr

intExpr =
    succeed IntValue
        |= int

expression : Parser Expression
expression =
        [ addExpr
        , intExpr

statement : Parser AST
statement =
    map Statement expression

statements : Parser (List AST)
statements =
    loop [] statementsHelp

statementsHelp : List AST -> Parser (Step (List AST) (List AST))
statementsHelp revStmts =
        [ succeed (\stmt -> Loop (stmt :: revStmts))
            |= statement
            |. newLines
        , succeed ()
            |. end
            |> map (\_ -> Done (List.reverse revStmts))

parse : String -> Result (List DeadEnd) (List AST)
parse string =
    run statements string

1 Like

I’m pretty sure that it’s because oneOf “commits” to the first path that looks like it will succeed (where at least the first character succeeds).

So because addExpr successfully parses the int part (and then later fails), oneOf will not evaluate the rest of the oneOf parsers. This is done for performance reasons so that the parser doesn’t have to backtrack and re-try parsing the same source code again.

The docs for oneOf link to this document that explain how to work around this behavior.

We’ve also talked about this in an Elm Radio episode about elm/parser, which you may find useful.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.