Skip to content

Instantly share code, notes, and snippets.

@alogic0
Last active October 12, 2016 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alogic0/cab6646e7b5c115735d62f7ad86c752c to your computer and use it in GitHub Desktop.
Save alogic0/cab6646e7b5c115735d62f7ad86c752c to your computer and use it in GitHub Desktop.
FutureLearn Haskell 2016, Parsing Text, Expression parsers
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import qualified Text.ParserCombinators.Parsec.Token as P
import Text.ParserCombinators.Parsec.Language
import Control.Monad (liftM)
lexer = P.makeTokenParser emptyDef
parens = P.parens lexer
natural = P.natural lexer
reservedOp = P.reservedOp lexer
data Expr =
MkConst Integer
| MkOpExpr String Expr Expr
| MkPrefixOpExpr String Expr
deriving Show
expr_parser :: Parser Expr
expr_parser = buildExpressionParser optable term <?> "expression"
optable =
let
op name assoc =
Infix ( do { reservedOp name;
return (MkOpExpr name) } ) assoc
prefix name =
Prefix (
reservedOp name >>
return (MkPrefixOpExpr name) )
in
[ [ op "*" AssocLeft, op "/" AssocLeft, op "%" AssocLeft ]
, [ op "+" AssocLeft, op "-" AssocLeft ], [ prefix "-" ] ]
term = parens expr_parser
<|> liftM MkConst natural
@alogic0
Copy link
Author

alogic0 commented Oct 12, 2016

Example of running:

~/prog> ghci parseExpr.hs
*Main> parse expr_parser  "" "3+5-9*2"
Right (MkOpExpr "-" (MkOpExpr "+" (MkConst 3) (MkConst 5)) (MkOpExpr "*" (MkConst 9) (MkConst 2)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment