用 Elm 解析骰子符号
Parsing dice notation with Elm
我正在尝试编写一个小骰子符号(例如“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
并且我希望解析器在成功解析时 return 一个 Roll
,但我不确定如何继续。
我猜我需要使用 oneOf
,但我不确定如何使用。
不幸的是,我找不到任何使用这个库的好例子。
您可以先编写一个可选地解析 int 的解析器,如果没有消耗任何内容,则 return 默认值:
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
感谢@Chad 的回答 (),我得到了它:
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
使您失望,因为它回溯了。您可以使用原始 Parser.token
并摆脱它。 (example on Ellie)
dice : Parser (Int, Int)
dice =
succeed Tuple.pair
|= int
|. Parser.token "d"
|= int
我正在尝试编写一个小骰子符号(例如“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
并且我希望解析器在成功解析时 return 一个 Roll
,但我不确定如何继续。
我猜我需要使用 oneOf
,但我不确定如何使用。
不幸的是,我找不到任何使用这个库的好例子。
您可以先编写一个可选地解析 int 的解析器,如果没有消耗任何内容,则 return 默认值:
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
感谢@Chad 的回答 (
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
使您失望,因为它回溯了。您可以使用原始 Parser.token
并摆脱它。 (example on Ellie)
dice : Parser (Int, Int)
dice =
succeed Tuple.pair
|= int
|. Parser.token "d"
|= int