Skip to content

Instantly share code, notes, and snippets.

@frasertweedale
Created May 24, 2019 00:08
Show Gist options
  • Save frasertweedale/b968fb53ff4d2ba0a1403ecb6f281557 to your computer and use it in GitHub Desktop.
Save frasertweedale/b968fb53ff4d2ba0a1403ecb6f281557 to your computer and use it in GitHub Desktop.
Arithmetic expression operator precedence parsing
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Data.Char (isAlpha)
import Data.Attoparsec.ByteString.Char8
data Expr = Mul Expr Expr | Add Expr Expr | Lit Char | Var Char deriving Show
expr = (add <|> mul <|> (Var <$> satisfy isAlpha) <|> (Lit <$> satisfy isDigit)) <* endOfInput
where
add = Add <$> ((takeTill (=='+') <* char8 '+') >>= either fail pure . parseOnly expr) <*> expr
mul = Mul <$> ((takeTill (=='*') <* char8 '*') >>= either fail pure . parseOnly expr) <*> expr
main = do
print $ parseOnly expr "1+2+3*4+5+6*7+8"
print $ parseOnly expr "1*3+4+5+6*7*8"
print $ parseOnly expr "1+?+3*4+5+6*7+8"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment