Created
October 16, 2016 23:10
-
-
Save tiqwab/de848250850126d4f04c68e17216f94a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import System.Environment | |
import Text.Parsec | |
import Text.Parsec.Expr | |
import qualified Text.Parsec.Language as L | |
import qualified Text.Parsec.Token as T | |
import Text.ParserCombinators.Parsec hiding (try) | |
{- | |
Implement calculator with `Text.Parsec.Expr`. | |
Use `Text.Parsec.Token` to make parsing simple. | |
-} | |
-- Make simple language definition | |
langCalc = L.emptyDef { T.opLetter = char '+' <|> char '-' <|> char '*' <|> char '/' } | |
-- Create parser with language definition | |
calcTokenParser = T.makeTokenParser langCalc | |
-- Create parser for calculator | |
expr = buildExpressionParser table term | |
<?> "expression" | |
term = T.parens calcTokenParser expr | |
<|> T.natural calcTokenParser | |
<?> "simple expression" | |
-- Table of operators. The list is ordered in descending precedence. | |
table = [ [prefix "-" negate, prefix "+" id ] | |
, [postfix "++" (+1)] | |
, [binary "*" (*) AssocLeft, binary "/" (div) AssocLeft ] | |
, [binary "+" (+) AssocLeft, binary "-" (-) AssocLeft ] | |
] | |
binary name fun assoc = Infix (do{ T.reservedOp calcTokenParser name; return fun }) assoc | |
prefix name fun = Prefix (do{ T.reservedOp calcTokenParser name; return fun }) | |
postfix name fun = Postfix (do{ T.reservedOp calcTokenParser name; return fun }) | |
-- :main "(1+2)*(-5+1)++" | |
-- -> -9 | |
main = do args <- getArgs | |
parseTest (expr :: CharParser () Integer) (head args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment