{- Like Expr, but using only elementary parser combinators. -} module SimpleExpr where import ParseDecorate import ParseTree import ExprLexer hiding (Num) import qualified ExprLexer as E import Token ((>&)) data Expr = Add Expr Expr | Mul Expr Expr | Num Int deriving (Eq, Show, Read) type ExprParser = Parser E.Token Expr Expr infixl 5 <$$> (<$$>) = unit pExpr :: ExprParser pExpr = pSum pSum :: ExprParser pSum = pMul <|> id <$$> (\x _ y -> Add x y) <$> pMul <*> symbol Plus <*> pSum pMul :: ExprParser pMul = pUnit <|> id <$$> (\x _ y -> Mul x y) <$> pUnit <*> symbol Star <*> pMul pUnit :: ExprParser pUnit = pNum <|> id <$$> (\_ x _ -> x) <$> symbol POpen <*> pExpr <*> symbol PClose pNum :: ExprParser pNum = id <$$> (\(E.Num n) -> Num n) <$> satisfy isNum oneOf :: Eq s => [s] -> Parser s s w oneOf = foldl1 (<|>) . map symbol testRanges :: (Show s, Show w, Symbol s) => ParseTree s w -> IO () testRanges tree = putStr $ unlines $ source : (map visualise allRanges) where syn = compute 0 tree source = ' ' : show (source_Syn_ParseTree syn) (_, len) = outerRange_Syn_ParseTree syn allRanges = [ (t0, t1) | t0 <- [0..len - 1], t1 <- [t0 + 1..len] ] visualise t@(t0, t1) = "|" ++ sp t0 ++ replicate (t1 - t0) '-' ++ sp (len - t1) ++ "| " ++ (show . map (unUnit . fst)) (select_Syn_ParseTree syn t) sp n = replicate n ' ' unUnit (Unit x _) = x unUnit _ = undefined demo :: String -> IO () demo = testRanges . (pTokens >& pExpr)