用榆树解析骰子符号

时间:2017-08-10 17:43:19

标签: elm parser-combinators

我正在尝试使用该库编写一个小骰子符号(例如“2d6”,其中2count6是骰子size)解析器在elm-tools/parser

表达式应采用

形式
[int] "d" int

但我无法解析可选的前导int(如果缺少,则会默认为1。)

到目前为止,我已经想出了这个:

import Parser exposing (..)


type alias Roll =
    { count : Int
    , size : Int
    }


die : Parser Int
die =
    succeed identity
        |. keyword "d"
        |= int

我希望解析器在成功解析时返回Roll,但我不确定如何继续。

我猜我需要使用oneOf,但我不确定如何。

不幸的是,我找不到使用这个库的任何好例子。

3 个答案:

答案 0 :(得分:2)

您可以先编写一个解析器,可选择解析一个int,如果没有消耗任何内容,则返回一个默认值:

optionalInt : Int -> Parser Int
optionalInt default =
    keep zeroOrMore Char.isDigit
        |> andThen
            (\str ->
                case str of
                    "" ->
                        succeed default

                    digits ->
                        case String.toInt digits of
                            Ok val ->
                                succeed val

                            Err err ->
                                fail err
            )

现在您可以使用该解析器为Roll创建解析器:

roll : Parser Roll
roll =
    succeed Roll
        |= optionalInt 1
        |. keyword "d"
        |= int

答案 1 :(得分:0)

感谢@ Chad的回答(https://stackoverflow.com/a/45620875/96233),我得到了它的工作:

type alias Dice =
    { count : Int
    , size : Int
    }


dice : Parser Dice
dice =
    succeed Dice
        |= count
        |. spaces
        |. keyword "d"
        |. spaces
        |= integer


count : Parser Int
count =
    oneOf
        [ integer |> andThen succeed
        , succeed 1
        ]


integer : Parser Int
integer =
    keep oneOrMore isDigit
        |> andThen
            (\s ->
                case String.toInt s of
                    Ok value ->
                        succeed value

                    Err err ->
                        fail err
            )


spaces : Parser ()
spaces =
    ignore zeroOrMore (\c -> c == ' ')

答案 2 :(得分:0)

Parser.keyword使您失败,因为它回溯了。您可以使用原始的Parser.token并摆脱它。 (example on Ellie

dice : Parser (Int, Int)
dice =
    succeed Tuple.pair
        |= int
        |. Parser.token "d"
        |= int