isolate parse state abstraction

This commit is contained in:
Zachary Snow 2021-04-20 19:47:55 -04:00
parent 499bd5873e
commit cfff359b51
2 changed files with 22 additions and 15 deletions

View File

@ -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
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')

View File

@ -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 }
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" }
{ {
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
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 ++ "`"
} }