mirror of https://github.com/zachjs/sv2v.git
isolate parse state abstraction
This commit is contained in:
parent
499bd5873e
commit
cfff359b51
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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 ++ "`"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue