diff -r 9d155da5b417 -r 671d66ba3af6 tools/PascalParser.hs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/PascalParser.hs Wed Nov 17 16:19:28 2010 +0300 @@ -0,0 +1,98 @@ +module PascalParser where + +import Text.ParserCombinators.Parsec +import Control.Monad + +data PascalUnit = + Program Identificator Implementation FunctionBody + | Unit Identificator Interface Implementation (Maybe Initialize) (Maybe Finalize) + deriving Show + +data Interface = Interface Uses TypesAndVars + deriving Show +data Implementation = Implementation Uses TypesAndVars Functions + deriving Show +data Functions = Functions [Function] + deriving Show +data Function = Function String + deriving Show +data Identificator = Identificator String + deriving Show +data FunctionBody = FunctionBody String + deriving Show +data TypesAndVars = TypesAndVars String + deriving Show +data Initialize = Initialize Functions + deriving Show +data Finalize = Finalize Functions + deriving Show +data Uses = Uses [Identificator] + deriving Show + +parsePascalUnit :: String -> Either ParseError PascalUnit +parsePascalUnit = parse pascalUnit "unit" + where + comments = skipMany (comment >> spaces) + identificator = do + spaces + l <- letter <|> oneOf "_" + ls <- many (alphaNum <|> oneOf "_") + spaces + return $ Identificator (l:ls) + + pascalUnit = do + spaces + comments + u <- choice [program, unit] + comments + spaces + return u + + comment = choice [ + char '{' >> manyTill anyChar (try $ char '}') + , string "(*" >> manyTill anyChar (try $ string "*)") + , string "//" >> manyTill anyChar (try newline) + ] + + unit = do + name <- unitName + spaces + comments + int <- string "interface" >> interface + manyTill anyChar (try $ string "implementation") + spaces + comments + impl <- implementation + return $ Unit name int impl Nothing Nothing + where + unitName = between (string "unit") (char ';') identificator + + interface = do + spaces + comments + u <- uses + return $ Interface u (TypesAndVars "") + + program = do + name <- programName + spaces + comments + impl <- implementation + return $ Program name impl (FunctionBody "") + where + programName = between (string "program") (char ';') identificator + + implementation = do + u <- uses + manyTill anyChar (try $ string "end.") + return $ Implementation u (TypesAndVars "") (Functions []) + + uses = liftM Uses (option [] u) + where + u = do + string "uses" + spaces + u <- (identificator >>= \i -> spaces >> return i) `sepBy1` (char ',' >> spaces) + char ';' + spaces + return u