Я пытаюсь добавить парсер для инфиксных операторов в простой парсер выражений. Я уже посмотрел документацию и этот вопрос , но мне кажется, что я что-то упустил.
import qualified Text.Parsec.Expr as Expr
import qualified Text.Parsec.Token as Tokens
import Text.ParserCombinators.Parsec
import Text.Parsec
data Expr = Number Integer
| Op Expr Expr
| Boolean Bool
instance Show Expr where
show (Op l r) = "(+ " ++ (show l) ++ " " ++ (show r) ++ ")"
show (Number r) = show r
show (Boolean b) = show b
parens = Tokens.parens haskell
reserved = Tokens.reservedOp haskell
infix_ operator func =
Expr.Infix (spaces >> reserved operator >> spaces >> return func) Expr.AssocLeft
infixOp =
Expr.buildExpressionParser table parser
where
table = [[infix_ "+" Op]]
number :: Parser Expr
number =
do num <- many1 digit
return $ Number $ read num
bool :: Parser Expr
bool = (string "true" >> return (Boolean True)) <|> (string "false" >> return (Boolean False))
parser = parens infixOp <|> number <|> bool
run = Text.Parsec.runParser parser () ""
Этот синтаксический анализатор может анализировать выражения типа 1
, false
, (1 + 2)
, (1 + false)
, но не 1 + 2
(он анализируется как 1
). Если я попытаюсь изменить синтаксический анализатор на parens infixOp <|> infixOp <|> number <|> bool
, он застрянет.
Что я должен изменить, чтобы разобрать выражения вроде 1 + 2
без скобок?