Skip to content

Instantly share code, notes, and snippets.

@osa1
Last active November 4, 2017 01:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save osa1/9414577 to your computer and use it in GitHub Desktop.
Save osa1/9414577 to your computer and use it in GitHub Desktop.
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module Main where
import Control.Applicative ((<*))
import qualified Data.Set as S
import Prelude hiding (exp)
import Text.Parsec
import Debug.Trace
type MarksSeen = S.Set Int
type RecParser s m a = ParsecT s MarksSeen m a
putMark i = do
is <- getState
if S.member i is
then fail "recursion"
else putState $ S.insert i is
resetMarks = putState S.empty
plus = char '+' >> spaces
int = fmap (Int . read) $ many1 digit <* spaces
data Exp = Add Exp Exp
| App Exp Exp
| Int Int
deriving (Show)
add = do
putMark 1
e1 <- exp
resetMarks
plus
e2 <- exp
return $ Add e1 e2
app = do
putMark 2
fn <- exp
resetMarks
putMark 2
as <- many1 exp
resetMarks
return $ foldl App fn as
exp = choice [try add, try app, int] <* spaces
pgm = exp <* eof
rec = putMark 0 >> rec >> resetMarks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment