我目前正在尝试使用Parsec在Haskell中设计一个解析器。
声明类型的语法应该类似于这样:
Fruit is a Apple
类型也应该能够拥有参数:
Fruit a b is a Apple
在这里:
Fruit
的类型为Name
a b
的类型为[Parameter]
Apple
的类型为Value
问题在于,我的解析器目前不知道何时停止解析 parameters
并开始解析 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)
我已经尝试以我知道的两种方式(一次使用sepBy和一次使用manyTill)解析参数/值,但都失败了,几乎出现了parse-error:
*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"
typeAssigment3 :: Parser TypeAssignment typeAssigment3 = TypeAssignment <$> name <*> (space *> manyTill (parameter <* space) (P.try $ string "is a")) <*> (space *> value)
- Giftzwerg02try
。 - DDub