view exercises/src/AdditionParser2.hs @ 30:8bf7ca2663d2

Advanced AdditionParser
author Markus Kaiser <markus.kaiser@in.tum.de>
date Sat, 12 Jan 2013 14:36:43 +0000
parents
children
line wrap: on
line source

module AdditionParser2 where

import Data.Char
import Parser

data Token = Num Int | Plus | Times | LeftPar | RightPar deriving (Show, Eq)

-- Scanner (Lexer)
digitS :: Parser Char Int
digitS = one isDigit >>> digitToInt

numberS :: Parser Char Int
numberS = list1 (one isDigit) >>> (\n -> read n :: Int)

additionS :: Parser Char [Token]
additionS = list (spaces *** token >>> snd) *** spaces >>> fst
    where
        spaces = list $ item ' '
        token = item '(' >>> const LeftPar |||
                item ')' >>> const RightPar |||
                item '+' >>> const Plus |||
                item '*' >>> const Times |||
                numberS >>> Num

-- Parser
additionP :: Parser Token Int
additionP = additionP1 *** optional (item Plus *** additionP >>> snd) >>> ints
    where
        ints (x, Just y) = x + y
        ints (x, _) = x

additionP1 :: Parser Token Int
additionP1 = additionP2 *** optional (item Times *** additionP1 >>> snd) >>> ints
    where
        ints (x, Just y) = x * y
        ints (x, _) = x

additionP2 :: Parser Token Int
additionP2 =
    one isNum >>> int |||
    enclose LeftPar RightPar additionP
    where
        isNum (Num _) = True
        isNum (_) = False
        int (Num n) = n

-- Composition
additionSP :: String -> Maybe (Int, [Token])
additionSP xs = case additionS xs of
                    Just (ys, []) -> additionP ys
                    _ -> Nothing

test = additionSP "2*4+10+(2+2)*2"