tools/PascalParser.hs
changeset 4353 671d66ba3af6
child 6270 0a99f73dd8dd
--- /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