diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-03-09 16:05:14 +0100 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-03-09 16:05:14 +0100 |
| commit | c27e85f27b8db206da23b813358ea44e302f2419 (patch) | |
| tree | 9264644e625630777e9950882ead930f6e49902b | |
| parent | 39dbada85b32a8775e3cba7a3676f99cfc482829 (diff) | |
| download | computorv1-c27e85f27b8db206da23b813358ea44e302f2419.tar.gz computorv1-c27e85f27b8db206da23b813358ea44e302f2419.tar.bz2 computorv1-c27e85f27b8db206da23b813358ea44e302f2419.zip | |
Parser combinator actually working (kinda)
| -rw-r--r-- | parser.hs | 68 |
1 files changed, 49 insertions, 19 deletions
@@ -1,48 +1,78 @@ module Parser where import Control.Applicative +import Control.Monad +import Data.Char +import Numeric.Natural -newtype Parser a = Parser { runParser :: String -> Maybe (a, String) } +newtype Parser a = Parser (String -> Maybe (a, String)) + +parse :: Parser a -> String -> Maybe (a, String) +parse (Parser p) input = p input instance Functor Parser where + -- fmap :: (a -> b) -> Parser a -> Parser b fmap f (Parser p) = Parser new_p where new_p s = do (x, s') <- p s return (f x, s') instance Applicative Parser where + -- pure :: a -> Parser a pure x = Parser (\s -> Just (x, s)) + -- (<*>) :: Parser (a -> b) -> Parser a -> Parser b (Parser p1) <*> (Parser p2) = Parser new_p where new_p s = do (f, s') <- p1 s (x, s'') <- p2 s' return (f x, s'') - -- (Parser p1) *> (Parser p2) = Parser new_p - -- (Parser p1) <* (Parser p2) = Parser new_p instance Alternative Parser where + -- empty :: Parser a empty = Parser (\_ -> Nothing) + -- (<|>) :: Parser a -> Parser a -> Parser a (Parser p1) <|> (Parser p2) = Parser new_p where new_p s = p1 s <|> p2 s -data Equation - = EquationAdd - | EquationSub - | EquationMul - -- | EquationDiv ? - | EquationExp - | EquationEqu - | EquationNum Float - charP :: Char -> Parser Char -charP c = Parser f - where f "" = Nothing - f (c:cs) = Just (c, cs) +charP x = Parser p + where p "" = Nothing + p (c:cs) = if c == x then Just (c, cs) + else Nothing + +digitsP :: Parser String +digitsP = Parser (\s -> Just $ span isDigit s) + +sepBy :: Parser a -> Parser b -> Parser [a] +sepBy x sep = ((:) <$> x <*> many (sep *> x)) <|> pure [] + + +-- 1 * X^0 + 2 * X^1 + 1 * 3 * X^2 = 0 +data Equation = Equation { left :: Polynomial, right :: Polynomial } deriving (Show) +type Polynomial = [Term] +data Term = Term { coefficient :: Float, exponent :: Natural } deriving (Show) + +coefficientP :: Parser Float +coefficientP = read <$> (floatP <|> digitsP) + where floatP = (\i _ f -> (i ++ "." ++ f)) + <$> digitsP <*> charP '.' <*> digitsP + +exponentP :: Parser Natural +exponentP = read <$> digitsP + +termP :: Parser Term +termP = (\coef _ exp -> Term coef exp) + <$> coefficientP + <*> (charP '*' *> charP 'X' *> charP '^') + <*> exponentP --- equationAddP :: Parser Equation --- equationAddP = charP '+' *> EquationAdd +polynomialP :: Parser Polynomial +polynomialP = sepBy termP (charP '+') --- equationP :: Parser Equation --- equationP = +equationP :: Parser Equation +equationP = (\l _ r -> Equation l r) + <$> polynomialP + <*> charP '=' + <*> polynomialP |
