Commit cfff359b by Zachary Snow

isolate parse state abstraction

parent 499bd587
...@@ -6,13 +6,11 @@ module Language.SystemVerilog.Parser ...@@ -6,13 +6,11 @@ module Language.SystemVerilog.Parser
) where ) where
import Control.Monad.Except import Control.Monad.Except
import Control.Monad.State.Strict
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Language.SystemVerilog.AST (AST) import Language.SystemVerilog.AST (AST)
import Language.SystemVerilog.Parser.Lex (lexStr) import Language.SystemVerilog.Parser.Lex (lexStr)
import Language.SystemVerilog.Parser.Parse (parse) import Language.SystemVerilog.Parser.Parse (parse)
import Language.SystemVerilog.Parser.Preprocess (preprocess, annotate, Env) import Language.SystemVerilog.Parser.Preprocess (preprocess, annotate, Env)
import Language.SystemVerilog.Parser.Tokens (Position(..), tokenPosition)
-- parses a compilation unit given include search paths and predefined macros -- parses a compilation unit given include search paths and predefined macros
parseFiles :: [FilePath] -> [(String, String)] -> Bool -> Bool -> [FilePath] -> IO (Either String [AST]) parseFiles :: [FilePath] -> [(String, String)] -> Bool -> Bool -> [FilePath] -> IO (Either String [AST])
...@@ -37,9 +35,5 @@ parseFile' includePaths env skipPreprocessor path = do ...@@ -37,9 +35,5 @@ parseFile' includePaths env skipPreprocessor path = do
preResult <- liftIO $ runner includePaths env path preResult <- liftIO $ runner includePaths env path
(contents, env') <- liftEither preResult (contents, env') <- liftEither preResult
tokens <- liftEither $ uncurry lexStr $ unzip contents tokens <- liftEither $ uncurry lexStr $ unzip contents
let position = ast <- parse tokens
if null tokens
then Position path 1 1
else tokenPosition $ head tokens
ast <- evalStateT parse (position, tokens)
return (ast, env') return (ast, env')
...@@ -25,7 +25,7 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -25,7 +25,7 @@ import Language.SystemVerilog.Parser.Tokens
%monad { ParseState } %monad { ParseState }
%lexer { positionKeep } { TokenEOF } %lexer { positionKeep } { TokenEOF }
%name parse %name parseMain
%tokentype { Token } %tokentype { Token }
%error { parseError } %error { parseError }
...@@ -1385,7 +1385,7 @@ StmtTrace :: { Stmt } ...@@ -1385,7 +1385,7 @@ StmtTrace :: { Stmt }
Trace :: { String } Trace :: { String }
: position { "Trace: " ++ show $1 } : position { "Trace: " ++ show $1 }
position :: { Position } position :: { Position }
: {- empty -} {% gets fst } : {- empty -} {% gets pPosition }
end : "end" {} | error {% missingToken "end" } end : "end" {} | error {% missingToken "end" }
endclass : "endclass" {} | error {% missingToken "endclass" } endclass : "endclass" {} | error {% missingToken "endclass" }
...@@ -1399,26 +1399,39 @@ join : "join" {} | error {% missingToken "join" } ...@@ -1399,26 +1399,39 @@ join : "join" {} | error {% missingToken "join" }
{ {
type ParseState = StateT (Position, [Token]) (ExceptT String IO) data ParseData = ParseData
{ pPosition :: Position
, pTokens :: [Token]
}
type ParseState = StateT ParseData (ExceptT String IO)
parse :: [Token] -> ExceptT String IO AST
parse [] = return []
parse tokens =
evalStateT parseMain initialState
where
position = tokenPosition $ head tokens
initialState = ParseData position tokens
posInject :: (Position -> a) -> ParseState a posInject :: (Position -> a) -> ParseState a
posInject cont = do posInject cont = do
pos <- gets fst pos <- gets pPosition
return $ cont pos return $ cont pos
positionKeep :: (Token -> ParseState a) -> ParseState a positionKeep :: (Token -> ParseState a) -> ParseState a
positionKeep cont = do positionKeep cont = do
tokens <- gets snd tokens <- gets pTokens
case tokens of case tokens of
[] -> cont TokenEOF [] -> cont TokenEOF
tok : toks -> do tok : toks -> do
put (tokenPosition tok, toks) put $ ParseData (tokenPosition tok) toks
cont tok cont tok
parseError :: Token -> ParseState a parseError :: Token -> ParseState a
parseError a = case a of parseError a = case a of
TokenEOF -> do TokenEOF -> do
p <- gets fst p <- gets pPosition
throwError $ show p ++ ": Parse error: unexpected end of file." throwError $ show p ++ ": Parse error: unexpected end of file."
Token t s p -> throwError $ show p ++ ": Parse error: unexpected token '" Token t s p -> throwError $ show p ++ ": Parse error: unexpected token '"
++ s ++ "' (" ++ show t ++ ")." ++ s ++ "' (" ++ show t ++ ")."
...@@ -1487,7 +1500,7 @@ addMIAttr attr item = MIAttr attr item ...@@ -1487,7 +1500,7 @@ addMIAttr attr item = MIAttr attr item
missingToken :: String -> ParseState a missingToken :: String -> ParseState a
missingToken expected = do missingToken expected = do
p <- gets fst p <- gets pPosition
throwError $ show p ++ ": Parse error: missing expected `" ++ expected ++ "`" throwError $ show p ++ ": Parse error: missing expected `" ++ expected ++ "`"
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment