tools/PascalPreprocessor.hs
author unc0rr
Tue, 22 Nov 2011 22:48:02 +0300
changeset 6413 6714531e7bd2
parent 6412 4b9a59116535
child 6414 8474b7fa84d6
permissions -rw-r--r--
Preprocessor strips comments

module PascalPreprocessor where

import Text.Parsec
import Control.Monad.IO.Class
import System.IO
import qualified Data.Map as Map


-- comments are removed
comment = choice [
        char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}') >> return ""
        , (try $ string "(*") >> manyTill anyChar (try $ string "*)") >> return ""
        , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n"
        ]

preprocess :: String -> IO String
preprocess fn = do
    r <- runParserT (preprocessFile fn) Map.empty "" ""
    case r of
         (Left a) -> do
             hPutStrLn stderr (show a)
             return ""
         (Right a) -> return a
    
    where
    preprocessFile :: String -> ParsecT String (Map.Map String String) IO String
    preprocessFile fn = do
        f <- liftIO (readFile fn)
        setInput f
        preprocessor
        
    preprocessor, codeBlock, switch :: ParsecT String (Map.Map String String) IO String
    
    preprocessor = chainl codeBlock (return (++)) ""
    
    codeBlock = choice [
            switch
            , comment
            , char '\'' >> many (noneOf "'") >>= \s -> char '\'' >> return ('\'' : s ++ "'")
            , many1 $ noneOf "{'/("
            , char '/' >> notFollowedBy (char '/') >> return "/"
            , char '(' >> notFollowedBy (char '*') >> return "("
            ]
            
    switch = do
        try $ string "{$"
        s <- choice [
            include
            , unknown
            ]
        return s
        
    include = do
        try $ string "INCLUDE"
        spaces
        (char '"')
        fn <- many1 $ noneOf "\"\n"
        char '"'
        spaces
        char '}'
        f <- liftIO (readFile fn)
        c <- getInput
        setInput $ f ++ c
        return ""

    unknown = do
        fn <- many1 $ noneOf "}\n"
        char '}'
        return ""