{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE QuasiQuotes #-} module Algebra.Ring.Polynomial.Parser ( monomial, expression, variable, variableWithPower , number, integer, natural, parsePolyn) where import Algebra.Ring.Polynomial.Monomorphic import Control.Applicative hiding (many) import qualified Data.Map as M import Data.Ratio import qualified Numeric.Algebra as NA import Text.Peggy [peggy| expression :: Polynomial Rational = expr !. letter :: Char = [a-zA-Z] variable :: Variable = letter ('_' integer)? { Variable $1 (fromInteger <$> $2) } variableWithPower :: (Variable, Integer) = variable "^" natural { ($1, $2) } / variable { ($1, 1) } expr :: Polynomial Rational = expr "+" term { $1 + $2 } / expr "-" term { $1 - $2 } / term term :: Polynomial Rational = number space* monoms { injectCoeff $1 * $3 } / number { injectCoeff $1 } / monoms monoms :: Polynomial Rational = monoms space * fact { $1 * $3 } / fact fact :: Polynomial Rational = fact "^" natural { $1 ^ $2 } / "(" expr ")" / monomial { toPolyn [($1, 1)] } monomial :: Monomial = variableWithPower+ { M.fromListWith (+) $1 } number :: Rational = integer "/" integer { $1 % $2 } / integer '.' [0-9]+ { realToFrac (read (show $1 ++ '.' : $2) :: Double) } / integer { fromInteger $1 } integer :: Integer = "-" natural { negate $1 } / natural natural :: Integer = [1-9] [0-9]* { read ($1 : $2) } |] toPolyn :: [(Monomial, Ratio Integer)] -> Polynomial (Ratio Integer) toPolyn = normalize . Polynomial . M.fromList parsePolyn :: String -> Either ParseError (Polynomial Rational) parsePolyn = parseString expression "polynomial"