ParseProofScript.hs revision 3c786cf5be934d8c0136269f27fcc9e64babb8a6
{- |
Module : $Header$
Description : parse a heterogeneous proof script and return it as pgip-xml
Copyright : (c) Christian Maeder, DFKI GmbH 2009
License : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
Maintainer : Christian.Maeder@dfki.de
Stability : provisional
Portability : portable
-}
module PGIP.ParseProofScript where
import Interfaces.Command
import PGIP.XMLstate (genErrorResponse)
import CMDL.DataTypes
import CMDL.Commands
import Text.ParserCombinators.Parsec.Pos (initialPos)
import Text.XML.Light as XML
import Common.Utils
import Data.Char
import Data.Either
import Data.List
data WhiteWord = WhiteWord
{ leading :: String -- ^ leading white space
, word :: String }
data LitCommand = LitCommand
{ commandWW :: WhiteWord
, argumentWW :: Maybe WhiteWord
, trailing :: String -- ^ trailing white space
, command :: CmdlCmdDescription }
parseLine :: [CmdlCmdDescription] -> FilePath -> Int -> Parser LitCommand
parseLine cl fp i = do
setPosition $ setSourceLine (initialPos fp) i
s1 <- many space
(eof >> return LitCommand
{ commandWW = WhiteWord "" ""
, argumentWW = Nothing
, trailing = s1
, command = cmdlIgnoreFunc "" }) <|> do
(cs, cm) <- choice (map (\ (c, sl) -> do
s <- try $ parseCommand sl
return (s, c)) $ (proveAll, ["prove-all"])
: map (\ c -> (c, words $ cmdNameStr $ cmdDescription c)) cl)
<|> do
h <- char '#'
r <- many anyChar
return (h : r, cmdlIgnoreFunc r)
s2 <- many space
(eof >> return LitCommand
{ commandWW = WhiteWord s1 cs
, argumentWW = Nothing
, trailing = s2
, command = cm }) <|> do
(arg, s3) <- parseArgument
return LitCommand
{ commandWW = WhiteWord s1 cs
, argumentWW = Just $ WhiteWord s2 arg
, trailing = s3
, command = cm
{ cmdDescription = setInputStr arg $ cmdDescription cm } }
parseArgument :: Parser (String, String)
parseArgument = do
arg <- many1 (satisfy $ not . isSpace)
sp <- many space
(eof >> return (arg, sp)) <|> do
(rargs, s) <- parseArgument
return (arg ++ sp ++ rargs, s)
parseCommand :: [String] -> Parser String
parseCommand cmd = case cmd of
[] -> fail ""
[c] -> string c
c : r -> do
string c
s <- many1 space
t <- parseCommand r
return $ c ++ s ++ t
parseSingleLine :: FilePath -> Int -> String -> Either String LitCommand
parseSingleLine fp i str =
case parse (parseLine getCommands fp i) fp str of
Left e -> Left $ show e
Right r -> Right r
parseContent :: FilePath -> String -> Either String [LitCommand]
parseContent fp str = let
l = number $ lines str
(es, rs) = partitionEithers $ map
(\ (s, i) -> parseSingleLine fp i s) l
in if null es then Right rs else
Left $ unlines es
whiteSpaceElems :: String -> [Element]
whiteSpaceElems str = if null str then [] else [unode "whitespace" str]
litString :: LitCommand -> String
litString c = word (commandWW c)
++ maybe "" (\ a -> leading a ++ word a) (argumentWW c)
closeTheory :: Bool -> [Element]
closeTheory isOpen = [unode "closetheory" () | isOpen]
xmlLitCmds :: String -> Bool -> [LitCommand] -> [Element]
xmlLitCmds trailer isOpen ls = case ls of
[] -> closeTheory isOpen ++ whiteSpaceElems trailer
h : r ->
let wsp = trailer ++ leading (commandWW h)
wspes = whiteSpaceElems wsp
in case cmdDescription $ command h of
SelectCmd LibFile _ ->
wspes ++ closeTheory isOpen ++
[unode "opentheory" $ litString h]
++ xmlLitCmds (trailing h ++ "\n") True r
GroupCmd _ -> xmlLitCmds (wsp ++ "\n") isOpen r
CommentCmd _ -> xmlLitCmds (wsp ++ litString h ++ "\n") isOpen r
_ -> wspes ++ [unode "proofstep" $ litString h]
++ xmlLitCmds (trailing h ++ "\n") isOpen r
parseHPF :: FilePath -> IO ()
parseHPF fp = do
str <- readFile fp
case parseContent fp str of
Left err -> putStrLn $ showElement $ genErrorResponse True err
Right rs -> putStrLn $ unlines $ map
(showElement . unode "pgip") $ xmlLitCmds "" False rs