mirror of https://github.com/zachjs/sv2v.git
support for begin_keywords directive
This commit is contained in:
parent
3d3359d35a
commit
d86f8535a0
|
|
@ -0,0 +1,84 @@
|
|||
{- sv2v
|
||||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
-
|
||||
- To implement the `begin_keywords` directive, this module defines which IEEE
|
||||
- 1800-2017 keywords are not keywords in preceding specifications.
|
||||
-}
|
||||
module Language.SystemVerilog.Parser.Keywords
|
||||
( specMap
|
||||
) where
|
||||
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
||||
import Language.SystemVerilog.Parser.Tokens
|
||||
|
||||
newKeywords :: [(String, [TokenName])]
|
||||
newKeywords = [
|
||||
|
||||
("1364-1995", [KW_always, KW_and, KW_assign, KW_begin, KW_buf, KW_bufif0,
|
||||
KW_bufif1, KW_case, KW_casex, KW_casez, KW_cmos, KW_deassign, KW_default,
|
||||
KW_defparam, KW_disable, KW_edge, KW_else, KW_end, KW_endcase,
|
||||
KW_endfunction, KW_endmodule, KW_endprimitive, KW_endspecify, KW_endtable,
|
||||
KW_endtask, KW_event, KW_for, KW_force, KW_forever, KW_fork, KW_function,
|
||||
KW_highz0, KW_highz1, KW_if, KW_ifnone, KW_initial, KW_inout, KW_input,
|
||||
KW_integer, KW_join, KW_large, KW_macromodule, KW_medium, KW_module,
|
||||
KW_nand, KW_negedge, KW_nmos, KW_nor, KW_not, KW_notif0, KW_notif1, KW_or,
|
||||
KW_output, KW_parameter, KW_pmos, KW_posedge, KW_primitive, KW_pull0,
|
||||
KW_pull1, KW_pulldown, KW_pullup, KW_rcmos, KW_real, KW_realtime, KW_reg,
|
||||
KW_release, KW_repeat, KW_rnmos, KW_rpmos, KW_rtran, KW_rtranif0,
|
||||
KW_rtranif1, KW_scalared, KW_small, KW_specify, KW_specparam, KW_strong0,
|
||||
KW_strong1, KW_supply0, KW_supply1, KW_table, KW_task, KW_time, KW_tran,
|
||||
KW_tranif0, KW_tranif1, KW_tri, KW_tri0, KW_tri1, KW_triand, KW_trior,
|
||||
KW_trireg, KW_vectored, KW_wait, KW_wand, KW_weak0, KW_weak1, KW_while,
|
||||
KW_wire, KW_wor, KW_xnor, KW_xor]),
|
||||
|
||||
("1364-2001-noconfig", [KW_cell, KW_config, KW_design, KW_endconfig,
|
||||
KW_incdir, KW_include, KW_instance, KW_liblist, KW_library, KW_use]),
|
||||
|
||||
("1364-2001", [KW_automatic, KW_endgenerate, KW_generate, KW_genvar,
|
||||
KW_localparam, KW_noshowcancelled, KW_pulsestyle_ondetect,
|
||||
KW_pulsestyle_onevent, KW_showcancelled, KW_signed, KW_unsigned]),
|
||||
|
||||
("1364-2005", [KW_uwire]),
|
||||
|
||||
("1800-2005", [KW_alias, KW_always_comb, KW_always_ff, KW_always_latch,
|
||||
KW_assert, KW_assume, KW_before, KW_bind, KW_bins, KW_binsof, KW_bit,
|
||||
KW_break, KW_byte, KW_chandle, KW_class, KW_clocking, KW_const,
|
||||
KW_constraint, KW_context, KW_continue, KW_cover, KW_covergroup,
|
||||
KW_coverpoint, KW_cross, KW_dist, KW_do, KW_endclass, KW_endclocking,
|
||||
KW_endgroup, KW_endinterface, KW_endpackage, KW_endprogram, KW_endproperty,
|
||||
KW_endsequence, KW_enum, KW_expect, KW_export, KW_extends, KW_extern,
|
||||
KW_final, KW_first_match, KW_foreach, KW_forkjoin, KW_iff, KW_ignore_bins,
|
||||
KW_illegal_bins, KW_import, KW_inside, KW_int, KW_interface, KW_intersect,
|
||||
KW_join_any, KW_join_none, KW_local, KW_logic, KW_longint, KW_matches,
|
||||
KW_modport, KW_new, KW_null, KW_package, KW_packed, KW_priority, KW_program,
|
||||
KW_property, KW_protected, KW_pure, KW_rand, KW_randc, KW_randcase,
|
||||
KW_randsequence, KW_ref, KW_return, KW_sequence, KW_shortint, KW_shortreal,
|
||||
KW_solve, KW_static, KW_string, KW_struct, KW_super, KW_tagged, KW_this,
|
||||
KW_throughout, KW_timeprecision, KW_timeunit, KW_type, KW_typedef, KW_union,
|
||||
KW_unique, KW_var, KW_virtual, KW_void, KW_wait_order, KW_wildcard, KW_with,
|
||||
KW_within]),
|
||||
|
||||
("1800-2009", [KW_accept_on, KW_checker, KW_endchecker, KW_eventually,
|
||||
KW_global, KW_implies, KW_let, KW_nexttime, KW_reject_on, KW_restrict,
|
||||
KW_s_always, KW_s_eventually, KW_s_nexttime, KW_s_until, KW_s_until_with,
|
||||
KW_strong, KW_sync_accept_on, KW_sync_reject_on, KW_unique0, KW_until,
|
||||
KW_until_with, KW_untyped, KW_weak]),
|
||||
|
||||
("1800-2012", [KW_implements, KW_nettype, KW_interconnect, KW_soft]),
|
||||
|
||||
("1800-2017", [])
|
||||
|
||||
]
|
||||
|
||||
specMap :: Map.Map String (Set.Set TokenName)
|
||||
specMap =
|
||||
Map.fromList $ zip keys vals
|
||||
where
|
||||
keys = map fst newKeywords
|
||||
sets = map (Set.fromList . snd) newKeywords
|
||||
allKeywords = Set.unions sets
|
||||
vals =
|
||||
map (Set.difference allKeywords) $
|
||||
scanl1 Set.union sets
|
||||
|
|
@ -33,9 +33,11 @@ import System.FilePath (dropFileName)
|
|||
import System.Directory (findFile)
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
import Data.List (span, elemIndex, dropWhileEnd)
|
||||
import Data.Maybe (isJust, fromJust)
|
||||
|
||||
import Language.SystemVerilog.Parser.Keywords (specMap)
|
||||
import Language.SystemVerilog.Parser.Tokens
|
||||
}
|
||||
|
||||
|
|
@ -513,13 +515,14 @@ data AlexUserState = LS
|
|||
, lsEnv :: Env -- active macro definitions
|
||||
, lsCondStack :: [Cond] -- if-else cascade state
|
||||
, lsIncludePaths :: [FilePath] -- folders to search for includes
|
||||
, lsSpecStack :: [Set.Set TokenName] -- stack of non-keyword token names
|
||||
} deriving (Eq, Show)
|
||||
|
||||
-- this initial user state does not contain the initial filename, environment,
|
||||
-- or include paths; alex requires that this be defined; we override it before
|
||||
-- we begin the actual lexing procedure
|
||||
alexInitUserState :: AlexUserState
|
||||
alexInitUserState = LS [] "" Map.empty [] []
|
||||
alexInitUserState = LS [] "" Map.empty [] [] []
|
||||
|
||||
-- public-facing lexer entrypoint
|
||||
lexFile :: [String] -> Env -> FilePath -> IO (Either String ([Token], Env))
|
||||
|
|
@ -529,10 +532,14 @@ lexFile includePaths env path = do
|
|||
return $ case result of
|
||||
Left msg -> Left msg
|
||||
Right finalState ->
|
||||
if null $ lsCondStack finalState
|
||||
then Right (finalToks, lsEnv finalState)
|
||||
else Left $ path ++ ": unfinished conditional directives: " ++
|
||||
(show $ length $ lsCondStack finalState)
|
||||
if not $ null $ lsCondStack finalState then
|
||||
Left $ path ++ ": unfinished conditional directives: " ++
|
||||
(show $ length $ lsCondStack finalState)
|
||||
else if not $ null $ lsSpecStack finalState then
|
||||
Left $ path ++ ": unterminated begin_keywords blocks: " ++
|
||||
(show $ length $ lsSpecStack finalState)
|
||||
else
|
||||
Right (finalToks, lsEnv finalState)
|
||||
where finalToks = coalesce $ reverse $ lsToks finalState
|
||||
where
|
||||
setEnv = do
|
||||
|
|
@ -910,6 +917,27 @@ handleDirective (posOrig, _, _, strOrig) len = do
|
|||
"pragma" -> passThrough
|
||||
"resetall" -> passThrough
|
||||
|
||||
"begin_keywords" -> do
|
||||
quotedSpec <- takeQuotedString
|
||||
let spec = tail $ init quotedSpec
|
||||
case Map.lookup spec specMap of
|
||||
Nothing ->
|
||||
lexicalError $ "invalid keyword set name: " ++ show spec
|
||||
Just set -> do
|
||||
specStack <- gets lsSpecStack
|
||||
modify $ \s -> s { lsSpecStack = set : specStack }
|
||||
dropWhitespace
|
||||
alexMonadScan
|
||||
"end_keywords" -> do
|
||||
specStack <- gets lsSpecStack
|
||||
if null specStack
|
||||
then
|
||||
lexicalError "unexpected end_keywords before begin_keywords"
|
||||
else do
|
||||
modify $ \s -> s { lsSpecStack = tail specStack }
|
||||
dropWhitespace
|
||||
alexMonadScan
|
||||
|
||||
"__FILE__" -> do
|
||||
tokPos <- toTokPos posOrig
|
||||
currFile <- gets lsCurrFile
|
||||
|
|
@ -1070,7 +1098,11 @@ tok tokId (pos, _, _, input) len = do
|
|||
tokPos <- toTokPos pos
|
||||
condStack <- gets lsCondStack
|
||||
() <- if any (/= CurrentlyTrue) condStack
|
||||
then modify id
|
||||
else modify (push $ Token tokId tokStr tokPos)
|
||||
then return ()
|
||||
else do
|
||||
specStack <- gets lsSpecStack
|
||||
if null specStack || Set.notMember tokId (head specStack)
|
||||
then modify (push $ Token tokId tokStr tokPos)
|
||||
else modify (push $ Token Id_simple ('_' : tokStr) tokPos)
|
||||
alexMonadScan
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,4 +381,4 @@ data TokenName
|
|||
| Spe_Directive
|
||||
| Unknown
|
||||
| MacroBoundary
|
||||
deriving (Show, Eq)
|
||||
deriving (Show, Eq, Ord)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ executable sv2v
|
|||
Language.SystemVerilog.AST.Stmt
|
||||
Language.SystemVerilog.AST.Type
|
||||
Language.SystemVerilog.Parser
|
||||
Language.SystemVerilog.Parser.Keywords
|
||||
Language.SystemVerilog.Parser.Lex
|
||||
Language.SystemVerilog.Parser.Parse
|
||||
Language.SystemVerilog.Parser.ParseDecl
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
`begin_keywords "1364-2001-noconfig"
|
||||
task foo;
|
||||
integer automatic = 2;
|
||||
$display(automatic * automatic);
|
||||
endtask
|
||||
`begin_keywords "1364-2005"
|
||||
task automatic bar;
|
||||
integer logic = 3;
|
||||
$display(logic * logic);
|
||||
endtask
|
||||
`end_keywords
|
||||
`end_keywords
|
||||
module top;
|
||||
initial foo;
|
||||
initial bar;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
module top;
|
||||
task foo;
|
||||
integer x;
|
||||
begin
|
||||
x = 2;
|
||||
$display(x * x);
|
||||
end
|
||||
endtask
|
||||
task bar;
|
||||
integer y;
|
||||
begin
|
||||
y = 3;
|
||||
$display(y * y);
|
||||
end
|
||||
endtask
|
||||
initial foo;
|
||||
initial bar;
|
||||
endmodule
|
||||
Loading…
Reference in New Issue