我正在尝试使用该库编写一个小骰子符号(例如“2d6”,其中2
是count
而6
是骰子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
,但我不确定如何。
不幸的是,我找不到使用这个库的任何好例子。
答案 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