79 lines
2.3 KiB
Haskell
79 lines
2.3 KiB
Haskell
|
{-# 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
|
||
|
-- <line> ::= <insurer-id> ":" <percent> <optional-exprs>
|
||
|
-- <optional-exprs> ::= "" | "if" <exprs>
|
||
|
line :: Parser INASTLine
|
||
|
line = do
|
||
|
id <- insurerId
|
||
|
": "
|
||
|
pc <- percent
|
||
|
oe <- option [] (" if " *> exprs)
|
||
|
endOfLine
|
||
|
pure $ INASTLine id pc oe
|
||
|
-- <exprs> ::= <expr> | <expr> "and" <exprs>
|
||
|
exprs :: Parser [ INASTExpr ]
|
||
|
exprs = expr `sepBy` " and "
|
||
|
-- <expr> ::= <lesser-than> | <greater-than> | <equals> | <insurer-id>
|
||
|
expr :: Parser INASTExpr
|
||
|
expr = choice [ INASTExprLt <$> lt
|
||
|
, INASTExprGt <$> gt
|
||
|
, INASTExprEq <$> eq
|
||
|
, INASTExprInsurerId <$> insurerId ]
|
||
|
-- <lesser-than> ::= "<" <integer>
|
||
|
lt :: Parser INASTLt
|
||
|
lt = "<" *> integer
|
||
|
-- <greater-than> ::= ">" <integer>
|
||
|
gt :: Parser INASTGt
|
||
|
gt = ">" *> integer
|
||
|
-- <equals> ::= "=" <integer>
|
||
|
eq :: Parser INASTEq
|
||
|
eq = "=" *> integer
|
||
|
-- <insurer-id> ::= "I" <integer>
|
||
|
insurerId :: Parser INASTInsurerId
|
||
|
insurerId = "I" *> integer
|
||
|
-- <percent> ::= <integer> "%"
|
||
|
percent :: Parser INASTPercent
|
||
|
percent = integer <* "%"
|
||
|
-- <integer> ::= <digit> | <non-zero-digit> <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)
|
||
|
|
||
|
|