Haskell Parsec遇到的解析器[...] [英] Haskell Parsec Parser for Encountering [...]

查看:122
本文介绍了Haskell Parsec遇到的解析器[...]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Parsec在Haskell中编写解析器。目前我有一个程序可以解析

  test x [1,2,3] end 


$

这样做的代码如下所示:

  testParser = do {
保留test;
v < - 标识符;
符号[;
l < - sepBy natural commaSep;
符号];
p < - pParser;
return $ Test v(List l)p
}<?> end

其中commaSep被定义为

  commaSep = skipMany1(space< |> char',')

现在有什么方法可以解析类似的语句,具体如下:

  test x [1 .. .3] end 

对于Haskell和Parsec而言,我确信有一些我只是不知道这样做的简洁方式。任何帮助将不胜感激。



再次感谢。 将使用 Control.Applicative中的一些函数 (* GT) 。如果您想要避免Parsec的monadic接口并偏好应用接口,这些函数非常有用,因为在我看来解析器变得更容易阅读。



如果你不熟悉基本的应用功能,留下评论,我会解释它们。如果您不确定,您可以在 Hoogle 上查看它们。






正如我已经理解你的问题,你需要一个解析器为这样的一些数据结构:

  data Test =测试字符串数字
数据Numbers = List [Int] |范围Int Int

解析这种数据结构的解析器看起来像这样(我没有编译代码,但应该可以):

   - 解析test< identifier> [< numbers>] end 
testParser :: Parser测试
testParser =
测试< $>保留测试*>标识符
< *>符号[*> numbersParser< * symbol]
< *保留end
<> test

numbersParser :: Parser Numbers
numbersParser = try listParser< |> rangeParser

- parses< natural>,< natural>,< natural> etc
listParser :: Parser Numbers
listParser =
List< $> sepBy natural(符号,)
<> list

- parses< natural> ...< natural>
rangeParser :: Parser Numbers
rangeParser =
Range< $>自然的< *符号...
< *>自然
<> 范围


I'm attempting to write a parser in Haskell using Parsec. Currently I have a program that can parse

test x [1,2,3] end

The code that does this is given as follows

testParser = do { 
  reserved "test"; 
  v <- identifier; 
  symbol "["; 
  l <- sepBy natural commaSep;
  symbol "]";
  p <- pParser;
  return $ Test v (List l) p
 } <?> "end"

where commaSep is defined as

commaSep        = skipMany1 (space <|> char ',')

Now is there some way for me to parse a similar statement, specifically:

test x [1...3] end

Being new to Haskell, and Parsec for that matter, I'm sure there's some nice concise way of doing this that I'm just not aware of. Any help would be appreciated.

Thanks again.

解决方案

I'll be using some functions from Control.Applicative like (*>). These functions are useful if you want to avoid the monadic interface of Parsec and prefer the applicative interface, because the parsers become easier to read that way in my opinion.

If you aren't familiar with the basic applicative functions, leave a comment and I'll explain them. You can look them up on Hoogle if you are unsure.


As I've understood your problem, you want a parser for some data structure like this:

data Test = Test String Numbers
data Numbers = List [Int] | Range Int Int

A parser that can parse such a data structure would look like this (I've not compiled the code, but it should work):

-- 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"

这篇关于Haskell Parsec遇到的解析器[...]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆