myrho / elm-parser-extras / Parser.Expression

Tools for building parsers for prefix, postfix or infix operator expressions.

Types


type Operator a
    = Infix (Parser (a -> a -> a)) Assoc
    | Prefix (Parser (a -> a))
    | Postfix (Parser (a -> a))

The representation for an operator parser. An operator can either be binary infix and require an associativity, or it can be unary prefix or postfix.


type alias OperatorTable a =
List (List (Operator a))

This is just a List of Lists of Operators. The first inner list has the highest precedence and the last has the lowest. If two operators are on the same inner list, they have the same precedence.


type Assoc
    = AssocNone
    | AssocLeft
    | AssocRight

The associativity of an operator.

Operators

prefixOperator : (a -> a) -> Parser () -> Operator a

Create a prefix operator parser from a unary function and a parser for the operator symbol.

infixOperator : (a -> a -> a) -> Parser () -> Assoc -> Operator a

Create an infix operator parser from a binary function, a parser for the operator symbol and an associativity.

postfixOperator : (a -> a) -> Parser () -> Operator a

Create a postfix operator parser from a unary function and a parser for the operator symbol.

Builder

buildExpressionParser : OperatorTable a -> Parser a -> Parser a

Build an expression parser for terms from a table of operators, taking into account precedence and associativity.

The following would define a simple arithmetic parser.

operators : OperatorTable number
operators =
    [ [ prefixOperator negate (symbol "-"), prefixOperator identity (symbol "+") ]
    , [ postfixOperator (\x -> x + 1) (symbol "++") ]
    , [ infixOperator (*) (symbol "*") AssocLeft ]
    , [ infixOperator (+) (symbol "+") AssocLeft, infixOperator (-) (symbol "-") AssocLeft ]
    ]

term : Parser Int
term =
    oneOf
        [ parens (lazy (\_ -> expr))
            |. spaces
        , int
            |. spaces
        ]

expr : Parser Int
expr =
    buildExpressionParser operators (lazy <| \_ -> term)