Vin*_*sso 6 parsing haskell parsec
我正在尝试使用Parsec在Haskell中编写解析器.目前我有一个可以解析的程序
test x [1,2,3] end
Run Code Online (Sandbox Code Playgroud)
执行此操作的代码如下所示
testParser = do {
reserved "test";
v <- identifier;
symbol "[";
l <- sepBy natural commaSep;
symbol "]";
p <- pParser;
return $ Test v (List l) p
} <?> "end"
Run Code Online (Sandbox Code Playgroud)
其中commaSep定义为
commaSep = skipMany1 (space <|> char ',')
Run Code Online (Sandbox Code Playgroud)
现在有一些方法可以解析类似的声明,具体来说:
test x [1...3] end
Run Code Online (Sandbox Code Playgroud)
作为Haskell和Parsec的新手,我确信有一些非常简洁的方法可以做到这一点,我只是不知道.任何帮助,将不胜感激.
再次感谢.
dfl*_*str 14
我将使用Control.Applicative类似的一些功能(*>).如果你想避免Parsec的monadic接口并且更喜欢应用程序接口,这些函数很有用,因为在我看来解析器变得更容易阅读.
如果您不熟悉基本的应用功能,请发表评论,我会解释它们.如果您不确定,可以在Hoogle上查找它们.
正如我已经理解了你的问题,你需要一个解析器来实现这样的数据结构:
data Test = Test String Numbers
data Numbers = List [Int] | Range Int Int
Run Code Online (Sandbox Code Playgroud)
可以解析这样的数据结构的解析器看起来像这样(我没有编译代码,但它应该工作):
-- parses "test <identifier> [<numbers>] end"
testParser :: Parser Test
testParser =
Test <$> reserved "test" *> identifier
<*> symbol "[" *> numbersParser <* symbol "]"
<* reserved "end"
<?> "test"
numbersParser :: Parser Numbers
numbersParser = try listParser <|> rangeParser
-- parses "<natural>, <natural>, <natural>" etc
listParser :: Parser Numbers
listParser =
List <$> sepBy natural (symbol ",")
<?> "list"
-- parses "<natural> ... <natural>"
rangeParser :: Parser Numbers
rangeParser =
Range <$> natural <* symbol "..."
<*> natural
<?> "range"
Run Code Online (Sandbox Code Playgroud)