Haskell-Parsec::解析空间直到字符串文本

Haskell-Parsec::解析空间直到字符串文本,haskell,parsec,Haskell,Parsec,我目前正在尝试使用Parsec在Haskell中设计一个解析器。 声明类型的语法应如下所示: Fruit is a Apple 类型还应具有以下参数: Fruit a b is a Apple 在哪里 水果具有类型名称 ab具有类型[参数] Apple具有类型Value 这里的问题是,我的解析器目前不知道何时停止解析参数并开始解析值 代码如下: newtype Name = Name String deriving (Show) newtype Parameter = Parameter

我目前正在尝试使用Parsec在Haskell中设计一个解析器。 声明类型的语法应如下所示:

Fruit is a Apple
类型还应具有以下参数:

Fruit a b is a Apple
在哪里

  • 水果
    具有类型
    名称
  • ab
    具有类型
    [参数]
  • Apple
    具有类型
    Value
这里的问题是,我的解析器目前不知道何时停止解析
参数
并开始解析

代码如下:

newtype Name = Name String deriving (Show)
newtype Parameter = Parameter String deriving (Show)
newtype Value = Value String deriving (Show)

data TypeAssignment = TypeAssignment Name [Parameter] Value deriving (Show)

-- first variant using `sepBy`
typeAssigment :: Parser TypeAssignment
typeAssigment =
    TypeAssignment
    <$> name
    <*> (space *> parameter `sepBy` space)
    <*> (string "is a" *> value)

-- second variant using manyTill
typeAssigment2 :: Parser TypeAssignment
typeAssigment2 =
    TypeAssignment 
    <$> name
    <*> (space *> manyTill parameter (string "is a"))
    <*> value

name :: Parser Name
name = Name <$> word

parameter :: Parser Parameter
parameter = Parameter <$> word

value :: Parser Value
value = Value <$> word

word :: Parser String
word = (:) <$> letter <*> many (letter <|> digit)

typeAssignment1
的问题是
“is”
“a”
是完全有效的
参数。因此,参数解析会吞噬整个输入,直到什么都没有留下,然后您会得到一个错误。事实上,如果仔细观察该错误,您会发现这是正确的:解析器期望一个空格(用于更多参数)或“is a”(整个解析器的终端)

另一方面,
typeAssignment2
非常接近,但您似乎没有正确处理空格。为了解析多个
参数
s,您需要解析这些参数之间的所有
空格
s,而不仅仅是第一个

我认为下面的替代方案应该可以做到这一点:

TypeAssignment 3::解析器类型分配
类型分配3=
类型分配
名称
manyTill(空格*>参数)(try$string“is a”)
(空格*>值)

谢谢,这帮了大忙!需要稍加修改,然后它就可以完美地为我工作:
TypeAssignment 3::Parser TypeAssignment TypeAssignment 3=TypeAssignment name(空格*>manyTill(参数值)
噢,是的,谢谢你指出这一点(这就是我没有亲自测试代码的结果).我更新了答案,使其包含
try
*EParser> parseTest typeAssigment "Fruit a b is a Apple"
parse error at (line 1, column 21):
unexpected end of input
expecting space or "is a"

*EParser> parseTest typeAssigment2 "Fruit a b is a Apple"
parse error at (line 1, column 8):
unexpected " "
expecting letter, digit or "is a"