用Elm解析骰子符号

用Elm解析骰子符号,elm,parser-combinators,Elm,Parser Combinators,我正在尝试使用elm工具/parser中的库编写一个小骰子符号(例如,“2d6”,其中2是count,而6是diesize)解析器 表达式的格式应为 [int] "d" int 但是我无法解析可选的前导int(如果缺少它,它将默认为1) 到目前为止,我已经想到了这个: import Parser exposing (..) type alias Roll = { count : Int , size : Int } die : Parser Int die =

我正在尝试使用
elm工具/parser
中的库编写一个小骰子符号(例如,“2d6”,其中
2
count
,而
6
是die
size
)解析器

表达式的格式应为

[int] "d" int
但是我无法解析可选的前导
int
(如果缺少它,它将默认为
1

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

import Parser exposing (..)


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


die : Parser Int
die =
    succeed identity
        |. keyword "d"
        |= int
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 == ' ')
我希望解析器在成功解析时返回
Roll
,但我不确定如何继续

我猜我将需要使用其中一个,但我不确定如何使用


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

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

optionant:Int->Parser Int
期权违约=
保留零个或更多字符
|>然后
(\str->
病例str
"" ->
成功违约
数字->
大小写字符串.toInt位
Ok val->
接替瓦尔
Err Err->
失败错误
)
现在,您可以使用该解析器为
Roll
创建解析器:

roll:Parser roll
滚=
成功滚动
|=选项1
|.关键字“d”
|=整数
多亏了@Chad的答案(),我才得以解决这个问题:

import Parser exposing (..)


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


die : Parser Int
die =
    succeed identity
        |. keyword "d"
        |= int
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 == ' ')

Parser.keyword
使您失败,因为它会回溯。您可以使用原始的
解析器.token
并将其删除。()


计数
大小
进行校正。我将更新我的问题以澄清。谢谢,我已经删除了我关于这个答案的含糊不清的陈述,因为
int
如果遇到字母数字字符就会失败。但是,如果在
2
后面有空格,则会成功。您是否更改了要求?没有。我现在使用“private”
integer
解析器而不是
int
修复代码。似乎
int
会对
d
感到困惑,因为它是一个合法的十六进制数字。如果Chad的答案对你有帮助,你应该投票表决,也许会接受它作为最有帮助的答案。