
Hi, I just want to add a new parser for variables but this doesn't seem to work can anybody tell me what I'm doing wrong? module ExprSyn where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr runExpr :: String -> IO () runExpr str = case runParser expr () " " str of Left err -> putStrLn "Error:" >> print err Right val -> print val demo1 = runExpr "2+5" data Expr = Mul Expr Expr | Div Expr Expr | Add Expr Expr | Sub Expr Expr | Val Float |Let String Expr Expr | Var String deriving (Eq,Show) expr :: Parser Expr expr = variable <|> buildExpressionParser table factor <?> "expression" table :: [[Operator Char st Expr]] table = [[op "*" Mul AssocLeft, op "/" Div AssocLeft] ,[op "+" Add AssocLeft, op "-" Sub AssocLeft] ] where op s f assoc = Infix (do{ string s; return f}) assoc factor :: Parser Expr factor = do{ char '(' ; x <- expr ; char ')' ; return x } <|> number <|> variable <?> "simple expression" variable :: Parser Expr variable = do { b <- letter ; do { cs <- word ;return (c:cs) <|> return [c] <|> number } number :: Parser Expr number = do{ ds <- many1 digit ; return (Val $ read ds) } John

Am Samstag 09 Januar 2010 18:45:23 schrieb John Moore:
Hi, I just want to add a new parser for variables but this doesn't seem to work can anybody tell me what I'm doing wrong?
module ExprSyn where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr runExpr :: String -> IO () runExpr str = case runParser expr () " " str of Left err -> putStrLn "Error:" >> print err Right val -> print val demo1 = runExpr "2+5" data Expr = Mul Expr Expr
| Div Expr Expr | Add Expr Expr | Sub Expr Expr | Val Float | |Let String Expr Expr | Var String
deriving (Eq,Show) expr :: Parser Expr expr = variable <|> buildExpressionParser table factor > "expression"
variable succeeds on the start of the input "2". Then the second parser isn't tried at all. Try reversing the alternatives: expr = buildExpressionParser table factor <|> variable <?> "expression" Perhaps even better and less surprising, don't let variable parse numbers, so expr = buildExpressionParser table factor <|> variable <|> number <?> "expression"
table :: [[Operator Char st Expr]] table = [[op "*" Mul AssocLeft, op "/" Div AssocLeft] ,[op "+" Add AssocLeft, op "-" Sub AssocLeft] ] where op s f assoc = Infix (do{ string s; return f}) assoc factor :: Parser Expr factor = do{ char '(' ; x <- expr ; char ')' ; return x } <|> number <|> variable > "simple expression" variable :: Parser Expr variable = do { b <- letter ; do { cs <- word ;return (c:cs)
Wrong type, should be return (Var (c:cs)) resp. return (Var c])
<|> return [c] <|> number }
number :: Parser Expr number = do{ ds <- many1 digit ; return (Val $ read ds) }
John
participants (2)
-
Daniel Fischer
-
John Moore