【发布时间】:2016-05-09 17:49:36
【问题描述】:
我想解析这样的语言
foo = (bar, bar1 = (bar2 = bar4), bar5)
我写了一个简单的解析器
module SimpleParser where
import Text.Parsec.String (Parser)
import Text.Parsec.Language (emptyDef)
import Text.Parsec
import qualified Text.Parsec.Token as Tok
import Text.Parsec.Char
import Prelude
lexer :: Tok.TokenParser ()
lexer = Tok.makeTokenParser style
where
style = emptyDef {
Tok.identLetter = alphaNum
}
parens :: Parser a -> Parser a
parens = Tok.parens lexer
commaSep :: Parser a -> Parser [a]
commaSep = Tok.commaSep lexer
identifier :: Parser String
identifier = Tok.identifier lexer
reservedOp :: String -> Parser ()
reservedOp = Tok.reservedOp lexer
data Expr = Ident String | Label String Expr | ExprList [Expr] deriving (Eq, Ord, Show)
parseExpr :: String -> Either ParseError Expr
parseExpr s = parse expr "" s
expr :: Parser Expr
expr = parens expr
<|> try exprList
<|> ident
ident :: Parser Expr
ident = do
var <- identifier
return $ Ident var
exprLabel :: Parser Expr
exprLabel = do
var <- identifier
reservedOp "="
body <- expr
return $ Label var body
exprList :: Parser Expr
exprList = do
list <- commaSep (try exprLabel <|> expr)
return $ ExprList list
但即使使用以下简单输入,它也有一个无限循环:
test = parseExpr "foo = bar"
有人可以解释为什么它不起作用以及如何解决它吗?
【问题讨论】:
-
这种讨厌的行为通常与语法上的左递归有关。我没有足够的时间检查,但我相信使用
chainl或chainr会有所帮助。稍后,我会检查您的代码并尝试修复。
标签: parsing haskell text-parsing parsec