{-# LANGUAGE OverloadedStrings #-} module Main where import Control.Applicative ((<|>),empty) import Data.Attoparsec.Text (Parser, parseOnly, decimal, choice, option, sepBy, endOfLine, endOfInput, many1) import qualified Data.Maybe as M import qualified Data.Text as T import qualified Data.Text.IO as T insuranceNetworkParser :: Parser InsuranceNetworkAST insuranceNetworkParser = many1 line where -- ::= ":" -- ::= "" | "if" line :: Parser INASTLine line = do id <- insurerId ": " pc <- percent oe <- option [] (" if " *> exprs) endOfLine pure $ INASTLine id pc oe -- ::= | "and" exprs :: Parser [ INASTExpr ] exprs = expr `sepBy` " and " -- ::= | | | expr :: Parser INASTExpr expr = choice [ INASTExprLt <$> lt , INASTExprGt <$> gt , INASTExprEq <$> eq , INASTExprInsurerId <$> insurerId ] -- ::= "<" lt :: Parser INASTLt lt = "<" *> integer -- ::= ">" gt :: Parser INASTGt gt = ">" *> integer -- ::= "=" eq :: Parser INASTEq eq = "=" *> integer -- ::= "I" insurerId :: Parser INASTInsurerId insurerId = "I" *> integer -- ::= "%" percent :: Parser INASTPercent percent = integer <* "%" -- ::= | -- Overapproximation of the grammar integer :: Parser Int integer = decimal type InsuranceNetworkAST = [INASTLine] data INASTLine = INASTLine INASTInsurerId INASTPercent [INASTExpr] deriving (Show) data INASTExpr = INASTExprLt INASTLt | INASTExprGt INASTGt | INASTExprEq INASTEq | INASTExprInsurerId INASTInsurerId deriving (Show) type INASTLt = Int type INASTGt = Int type INASTEq = Int type INASTInsurerId = Int type INASTPercent = Int main :: IO () main = do inputNetwork <- T.readFile "./input.network" T.putStrLn "Using the following input network:" T.putStrLn inputNetwork T.putStrLn "Parsed AST:" print (parseOnly insuranceNetworkParser inputNetwork)