我正在尝试用Parsec解析一个简单的语言。可以有“x = y”赋值或“前缀测试”之类的前缀。但是,分配的解析规则是贪婪的,如果没有“=”则不会失败。例如,
parse tp "" "prefix foo"
导致解析错误。相应的代码:
module Test where
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Language
import Text.ParserCombinators.Parsec.Expr
import qualified Text.ParserCombinators.Parsec.Token as P
lexer = haskell
reserved = P.reserved lexer
reservedOp = P.reservedOp lexer
data Term = Term String
deriving (Show)
term :: Parser Term
term = do { x <- many alphaNum
; reservedOp "="
; y <- many alphaNum
; return (Term (x++y))
}
<|> do { reserved "prefix"
; x <- many alphaNum
; return (Term x)
}
tp = do { e<-term; return e }
我错过了什么?我的方法是否可行,还是我误解了Parsec?
答案 0 :(得分:1)
正如评论中的user2407038所指出的那样,问题是x <- many alphaNum
消耗了prefix
,因此无法应用第二条规则。解决方案是将try
放在块的前面,这会回收消耗的部分流。