Last active
October 11, 2016 17:41
-
-
Save morgaine/7ab859f3429872419e0e4af57b97fba5 to your computer and use it in GitHub Desktop.
Brief example of expression parser in Haskell with Parsec
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
#! /usr/bin/runhaskell | |
-- | |
-- FutureLearn Haskell Course Sep-Oct 2016 | |
-- Lessons 4.6: Parsing Text Using Higher-Order Functions | |
-- Section: Expression parsers | |
-- | |
module Main where | |
import Text.Printf | |
import Text.ParserCombinators.Parsec | |
import Text.ParserCombinators.Parsec.Expr | |
import qualified Text.ParserCombinators.Parsec.Token as P | |
import Text.ParserCombinators.Parsec.Language | |
lexer = P.makeTokenParser emptyDef | |
parens = P.parens lexer | |
reservedOp = P.reservedOp lexer | |
natural = P.natural lexer | |
expr = buildExpressionParser optable term <?> "expression" | |
term = parens expr | |
<|> natural | |
<?> "simple expression" | |
optable = | |
[ [prefix "-" negate, prefix "+" id ] | |
, [postfix "++" (+1)] | |
, [binary "*" (*) AssocLeft, binary "/" (div) AssocLeft ] | |
, [binary "+" (+) AssocLeft, binary "-" (-) AssocLeft ] | |
] | |
binary name fun assoc = Infix (do{ reservedOp name; return fun }) assoc | |
prefix name fun = Prefix (do{ reservedOp name; return fun }) | |
postfix name fun = Postfix (do{ reservedOp name; return fun }) | |
someStrings = | |
[ "2" | |
, "(2)" | |
, "(2+3)" | |
, "(2+3)*4" | |
, "(2+3)/4" | |
, "(2 + 3) * 4" | |
, "2+3*4" | |
, "2.5" | |
] | |
parseStrings :: [String] -> IO () | |
parseStrings [] = do return () | |
parseStrings (x:xs) = do | |
printf "Parser {expr} parsing \"%-25s ---> " $ x ++ "\"" | |
parseTest expr x | |
putStrLn "" | |
parseStrings xs | |
main :: IO () | |
main = do | |
parseStrings someStrings |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output:
This "_ok" gist shows successful expr parsing. Failing parse input is easily added to the someStrings list. Note that the final parse is in practice an undetected failure.