解析parsec之前的空白或-parsec
问题描述:
我正在使用Haskell中的Parsec
模块解析文件。这些文件的组件之一是颜色。我创建了一个类型的颜色是这样的:解析parsec之前的空白或-parsec
data Color = Yellow | Red | Blue | Green deriving (Show)
我在解析颜色最初尝试是这样的:
symbol :: String -> Parsec String() String
symbol s = spaces >> string s
colorP :: Parsec String() Color
colorP =
liftM mkColor $ symbol "Yellow" <|> symbol "Red" <|> symbol "Blue" <|> symbol "Green"
where
mkColor :: String -> Color
mkColor "Yellow" = Yellow
mkColor "Red" = Red
mkColor "Blue" = Blue
mkColor "Green" = Green
我创建了symbol
解析器基本上吃掉尽可能多的空白地,然后吃给定的字符串s
。但是,这似乎并不奏效。我测试此代码与以下电话:
parse colorP "" " Red"
这给了我以下错误:
unexpected "R"
expecting space or "Yellow"
然而,我去寻找关于Hoogle为与<|>
运营商进入的文件和在那里我发现以下内容:
This combinator implements choice. The parser p <|> q first applies p. If it succeeds, the value of p is returned. If p fails without consuming any input, parser q is tried.
所以,我觉得上面的示例的问题是,解析器p
(在这种情况下symbol "Yellow"
)alrea dy确实消耗了一些输入,即空白!所以,我重构了我的colorP
像这样:
colorP =
liftM mkColor $ spaces >> (string "Yellow" <|> string "Red" <|> string "Blue" <|> string "Green")
where
-- mkColor same as before
它给出我想要的结果。
现在,我想知道是否没有像我编写的解析器symbol
这样的解析器,但是在发生故障时会放回输入。或者是第二次实现的是大多数Haskell-ish的第一个实现?
答
你可以使用try
symbol s = try (spaces >> string s)
The parser try p behaves like parser p, except that it pretends that it hasn't consumed any input when an error occurs.