Parsec 中无前缀的解析操作
Parsing operation without prefix in Parsec
我正在尝试使用 Parsec 解析一种简单的语言。可以有赋值 "x=y" 或像 "prefix test" 这样的前缀。但是,赋值的解析规则是贪心的,如果没有“=”也不会失败。例如,
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?
正如 user2407038 在评论中指出的那样,问题是 x <- many alphaNum
消耗了 prefix
,因此无法应用第二条规则。解决方案是将 try
放在块的前面,这会倒带消耗的部分流。
我正在尝试使用 Parsec 解析一种简单的语言。可以有赋值 "x=y" 或像 "prefix test" 这样的前缀。但是,赋值的解析规则是贪心的,如果没有“=”也不会失败。例如,
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?
正如 user2407038 在评论中指出的那样,问题是 x <- many alphaNum
消耗了 prefix
,因此无法应用第二条规则。解决方案是将 try
放在块的前面,这会倒带消耗的部分流。