aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@ymhg.org>2019-03-31 21:54:20 +0100
committerYann Herklotz <git@ymhg.org>2019-03-31 21:54:20 +0100
commit1930e7686025601e22de49aa4d4dbeed8311caa0 (patch)
tree9266dc65ac55e3136c0893d2e9468bb260483262
parentc0be2c6fe39902af0cf61a14936547fc780d3f6c (diff)
downloadverismith-1930e7686025601e22de49aa4d4dbeed8311caa0.tar.gz
verismith-1930e7686025601e22de49aa4d4dbeed8311caa0.zip
Rewrite the parser with real lexer
-rw-r--r--src/VeriFuzz/AST.hs3
-rw-r--r--src/VeriFuzz/CodeGen.hs45
-rw-r--r--src/VeriFuzz/Lexer.hs321
-rw-r--r--src/VeriFuzz/Parser.hs239
-rw-r--r--src/VeriFuzz/Parser/Lex.x187
-rw-r--r--src/VeriFuzz/Parser/Parser.hs329
-rw-r--r--src/VeriFuzz/Parser/Preprocess.hs88
-rw-r--r--src/VeriFuzz/Parser/Token.hs337
-rw-r--r--verifuzz.cabal9
9 files changed, 977 insertions, 581 deletions
diff --git a/src/VeriFuzz/AST.hs b/src/VeriFuzz/AST.hs
index 15e8d0b..d8420d2 100644
--- a/src/VeriFuzz/AST.hs
+++ b/src/VeriFuzz/AST.hs
@@ -94,6 +94,9 @@ module VeriFuzz.AST
, stmntCA
, stmntTask
, stmntSysTask
+ , stmntCondExpr
+ , stmntCondTrue
+ , stmntCondFalse
-- * Module
, ModDecl(..)
, modId
diff --git a/src/VeriFuzz/CodeGen.hs b/src/VeriFuzz/CodeGen.hs
index 8f205f8..bd6372a 100644
--- a/src/VeriFuzz/CodeGen.hs
+++ b/src/VeriFuzz/CodeGen.hs
@@ -72,17 +72,17 @@ moduleDecl m =
-- | Conversts 'Port' to 'Text' for the module list, which means it only
-- generates a list of identifiers.
modPort :: Port -> Text
-modPort port = port ^. portName . getIdentifier
+modPort p = p ^. portName . getIdentifier
-- | Generate the 'Port' description.
port :: Port -> Text
-port port = t <> sign <> size <> name
+port p = t <> sign <> size <> name
where
- t = flip mappend " " . portType $ port ^. portType
- size | port ^. portSize > 1 = "[" <> showT (port ^. portSize - 1) <> ":0] "
+ t = flip mappend " " . pType $ p ^. portType
+ size | p ^. portSize > 1 = "[" <> showT (p ^. portSize - 1) <> ":0] "
| otherwise = ""
- name = port ^. portName . getIdentifier
- sign = signed $ port ^. portSigned
+ name = p ^. portName . getIdentifier
+ sign = signed $ p ^. portSigned
signed :: Bool -> Text
signed True = "signed "
@@ -98,23 +98,20 @@ portDir PortInOut = "inout"
moduleItem :: ModItem -> Text
moduleItem (ModCA ca) = contAssign ca
moduleItem (ModInst (Identifier i) (Identifier name) conn) =
- i <> " " <> name <> "(" <> comma (modConn <$> conn) <> ")" <> ";\n"
+ i <> " " <> name <> "(" <> comma (mConn <$> conn) <> ")" <> ";\n"
moduleItem (Initial stat ) = "initial " <> statement stat
moduleItem (Always stat ) = "always " <> statement stat
-moduleItem (Decl dir port) = maybe "" makePort dir <> port port <> ";\n"
+moduleItem (Decl dir p) = maybe "" makePort dir <> port p <> ";\n"
where makePort = (<> " ") . portDir
-modConn :: ModConn -> Text
-modConn (ModConn c) = expr c
-modConn (ModConnNamed n c) =
+mConn :: ModConn -> Text
+mConn (ModConn c) = expr c
+mConn (ModConnNamed n c) =
"." <> n ^. getIdentifier <> "(" <> expr c <> ")"
-- | Generate continuous assignment
contAssign :: ContAssign -> Text
-contAssign (ContAssign val e) = "assign " <> name <> " = " <> expr <> ";\n"
- where
- name = val ^. getIdentifier
- expr = expr e
+contAssign (ContAssign val e) = "assign " <> val ^. getIdentifier <> " = " <> expr e <> ";\n"
-- | Generate 'Function' to 'Text'
func :: Function -> Text
@@ -183,7 +180,7 @@ unaryOp UnNxorInv = "^~"
-- | Generate verilog code for an 'Event'.
event :: Event -> Text
event (EId i ) = "@(" <> i ^. getIdentifier <> ")"
-event (EExpr expr) = "@(" <> expr expr <> ")"
+event (EExpr e) = "@(" <> expr e <> ")"
event EAll = "@*"
event (EPosEdge i) = "@(posedge " <> i ^. getIdentifier <> ")"
event (ENegEdge i) = "@(negedge " <> i ^. getIdentifier <> ")"
@@ -195,7 +192,7 @@ delay (Delay i) = "#" <> showT i
-- | Generate the verilog code for an 'LVal'.
lVal :: LVal -> Text
lVal (RegId i ) = i ^. getIdentifier
-lVal (RegExpr i expr) = i ^. getIdentifier <> " [" <> expr expr <> "]"
+lVal (RegExpr i e) = i ^. getIdentifier <> " [" <> expr e <> "]"
lVal (RegSize i msb lsb) =
i
^. getIdentifier
@@ -209,9 +206,9 @@ lVal (RegConcat e) = "{" <> comma (expr <$> e) <> "}"
constExpr :: ConstExpr -> Text
constExpr (ConstExpr num) = showT num
-portType :: PortType -> Text
-portType Wire = "wire"
-portType Reg = "reg"
+pType :: PortType -> Text
+pType Wire = "wire"
+pType Reg = "reg"
genAssign :: Text -> Assign -> Text
genAssign op (Assign r d e) =
@@ -230,9 +227,9 @@ statement (CondStmnt e t Nothing) = "if(" <> expr e <> ")" <> defMap t
statement (CondStmnt e t f) = "if(" <> expr e <> ") " <> defMap t <> "else " <> defMap f
task :: Task -> Text
-task (Task name expr)
- | null expr = i
- | otherwise = i <> "(" <> comma (expr <$> expr) <> ")"
+task (Task name e)
+ | null e = i
+ | otherwise = i <> "(" <> comma (expr <$> e) <> ")"
where i = name ^. getIdentifier
-- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'.
@@ -251,7 +248,7 @@ instance Source Statement where
genSource = statement
instance Source PortType where
- genSource = portType
+ genSource = pType
instance Source ConstExpr where
genSource = constExpr
diff --git a/src/VeriFuzz/Lexer.hs b/src/VeriFuzz/Lexer.hs
deleted file mode 100644
index 02e1ebf..0000000
--- a/src/VeriFuzz/Lexer.hs
+++ /dev/null
@@ -1,321 +0,0 @@
-{-|
-Module : VeriFuzz.Lexer
-Description : Lexer for Verilog.
-Copyright : (c) 2019, Yann Herklotz
-License : GPL-3
-Maintainer : ymherklotz [at] gmail [dot] com
-Stability : experimental
-Portability : POSIX
-
-Lexer for Verilog.
--}
-
-module VeriFuzz.Lexer
- ( lexer
- , identifier
- , reserved
- , operator
- , reservedOp
- , charLiteral
- , stringLiteral
- , natural
- , integer
- , float
- , naturalOrFloat
- , decimal
- , hexadecimal
- , octal
- , symbol
- , lexeme
- , whiteSpace
- , parens
- , braces
- , angles
- , brackets
- , squares
- , comma
- , colon
- , dot
- , semiSep
- , semiSep1
- , commaSep
- , commaSep1
- )
-where
-
-import Data.Char (digitToInt)
-import Text.Parsec
-import qualified Text.Parsec.Token as P
-
-type VerilogDef = P.LanguageDef ()
-
-type Lexer = P.TokenParser ()
-
-type Parser = Parsec String ()
-
-verilogDef :: VerilogDef
-verilogDef = P.LanguageDef "/*"
- "*/"
- "//"
- False
- letter
- (alphaNum <|> char '_')
- (oneOf ":!#%&*+./<=>?@\\^|-~")
- (oneOf ":!#%&*+./<=>?@\\^|-~")
- reserved'
- reservedOp'
- True
-
-lexer :: Lexer
-lexer = P.makeTokenParser verilogDef
-
-identifier :: Parser String
-identifier = P.identifier lexer
-
-reserved :: String -> Parser ()
-reserved = P.reserved lexer
-
-operator :: Parser String
-operator = P.operator lexer
-
-reservedOp :: String -> Parser ()
-reservedOp = P.reservedOp lexer
-
-charLiteral :: Parser Char
-charLiteral = P.charLiteral lexer
-
-stringLiteral :: Parser String
-stringLiteral = P.stringLiteral lexer
-
-natural :: Parser Integer
-natural = P.natural lexer
-
-integer :: Parser Integer
-integer = P.integer lexer
-
-float :: Parser Double
-float = P.float lexer
-
-naturalOrFloat :: Parser (Either Integer Double)
-naturalOrFloat = P.naturalOrFloat lexer
-
-decimal :: Parser Integer
-decimal = P.decimal lexer
-
-number :: Integer -> Parser Char -> Parser Integer
-number base baseDigit = do
- digits <- many1 baseDigit
- let n = foldl (\x d -> base * x + toInteger (digitToInt d)) 0 digits
- seq n (return n)
-
-hexadecimal :: Parser Integer
-hexadecimal = number 16 hexDigit
-
-octal :: Parser Integer
-octal = number 8 octDigit
-
-symbol :: String -> Parser String
-symbol = P.symbol lexer
-
-lexeme :: Parser a -> Parser a
-lexeme = P.lexeme lexer
-
-whiteSpace :: Parser ()
-whiteSpace = P.whiteSpace lexer
-
-parens :: Parser a -> Parser a
-parens = P.parens lexer
-
-braces :: Parser a -> Parser a
-braces = P.braces lexer
-
-angles :: Parser a -> Parser a
-angles = P.angles lexer
-
-brackets :: Parser a -> Parser a
-brackets = P.brackets lexer
-
-squares :: Parser a -> Parser a
-squares = P.squares lexer
-
-comma :: Parser String
-comma = P.comma lexer
-
-colon :: Parser String
-colon = P.colon lexer
-
-dot :: Parser String
-dot = P.dot lexer
-
-semiSep :: Parser a -> Parser [a]
-semiSep = P.semiSep lexer
-
-semiSep1 :: Parser a -> Parser [a]
-semiSep1 = P.semiSep1 lexer
-
-commaSep :: Parser a -> Parser [a]
-commaSep = P.commaSep lexer
-
-commaSep1 :: Parser a -> Parser [a]
-commaSep1 = P.commaSep1 lexer
-
-reservedOp' :: [String]
-reservedOp' =
- [ "!"
- , "~"
- , "~&"
- , "~|"
- , "+"
- , "-"
- , "*"
- , "/"
- , "%"
- , "=="
- , "!="
- , "==="
- , "!=="
- , "&&"
- , "||"
- , "<"
- , "<="
- , ">"
- , ">="
- , "&"
- , "|"
- , "^"
- , "^~"
- , "~^"
- , "**"
- , "<<"
- , ">>"
- , "<<<"
- , ">>>"
- ]
-
-reserved' :: [String]
-reserved' =
- [ "always"
- , "and"
- , "assign"
- , "automatic"
- , "begin"
- , "buf"
- , "bufif0"
- , "bufif1"
- , "case"
- , "casex"
- , "casez"
- , "cell"
- , "cmos"
- , "config"
- , "deassign"
- , "default"
- , "defparam"
- , "design"
- , "disable"
- , "edge"
- , "else"
- , "end"
- , "endcase"
- , "endconfig"
- , "endfunction"
- , "endgenerate"
- , "endmodule"
- , "endprimitive"
- , "endspecify"
- , "endtable"
- , "endtask"
- , "event"
- , "for"
- , "force"
- , "forever"
- , "fork"
- , "function"
- , "generate"
- , "genvar"
- , "highz0"
- , "highz1"
- , "if"
- , "ifnone"
- , "incdir"
- , "include"
- , "initial"
- , "inout"
- , "input"
- , "instance"
- , "integer"
- , "join"
- , "large"
- , "liblist"
- , "library"
- , "localparam"
- , "macromodule"
- , "medium"
- , "module"
- , "nand"
- , "negedge"
- , "nmos"
- , "nor"
- , "noshowcancelled"
- , "not"
- , "notif0"
- , "notif1"
- , "or"
- , "output"
- , "parameter"
- , "pmos"
- , "posedge"
- , "primitive"
- , "pull0"
- , "pull1"
- , "pulldown"
- , "pullup"
- , "pulsestyle_onevent"
- , "pulsestyle_ondetect"
- , "remos"
- , "real"
- , "realtime"
- , "reg"
- , "release"
- , "repeat"
- , "rnmos"
- , "rpmos"
- , "rtran"
- , "rtranif0"
- , "rtranif1"
- , "scalared"
- , "showcancelled"
- , "signed"
- , "small"
- , "specify"
- , "specparam"
- , "strong0"
- , "strong1"
- , "supply0"
- , "supply1"
- , "table"
- , "task"
- , "time"
- , "tran"
- , "tranif0"
- , "tranif1"
- , "tri"
- , "tri0"
- , "tri1"
- , "triand"
- , "trior"
- , "trireg"
- , "unsigned"
- , "use"
- , "vectored"
- , "wait"
- , "wand"
- , "weak0"
- , "weak1"
- , "while"
- , "wire"
- , "wor"
- , "xnor"
- , "xor"
- ]
-
diff --git a/src/VeriFuzz/Parser.hs b/src/VeriFuzz/Parser.hs
index 2c26b56..66608f4 100644
--- a/src/VeriFuzz/Parser.hs
+++ b/src/VeriFuzz/Parser.hs
@@ -1,247 +1,18 @@
{-|
Module : VeriFuzz.Parser
-Description : Minimal Verilog parser to reconstruct the AST.
-Copyright : (c) 2019, Yann Herklotz
+Description : Parser module for Verilog.
+Copyright : (c) 2019, Yann Herklotz Grave
License : GPL-3
Maintainer : ymherklotz [at] gmail [dot] com
Stability : experimental
Portability : POSIX
-Minimal Verilog parser to reconstruct the AST. This parser does not support the
-whole Verilog syntax, as the AST does not support it either.
+Parser module for Verilog.
-}
module VeriFuzz.Parser
- ( -- * Parsers
- parseVerilog
- , parseVerilogSrc
- , parseDescription
- , parseModDecl
- , parseContAssign
- , parseExpr
+ ( module VeriFuzz.Parser.Parser
)
where
-import Control.Lens
-import Data.Functor (($>))
-import Data.Functor.Identity (Identity)
-import qualified Data.Text as T
-import Text.Parsec
-import Text.Parsec.Expr
-import VeriFuzz.AST
---import VeriFuzz.CodeGen
-import VeriFuzz.Internal
-import VeriFuzz.Lexer
-
-type Parser = Parsec String ()
-
-type ParseOperator = Operator String () Identity
-
-sBinOp :: BinaryOperator -> Expr -> Expr -> Expr
-sBinOp = sOp BinOp where sOp f b a = f a b
-
-parseExpr' :: Parser Expr
-parseExpr' = buildExpressionParser parseTable parseTerm <?> "expr"
-
-matchHex :: Char -> Bool
-matchHex c = c == 'h' || c == 'H'
-
---matchBin :: Char -> Bool
---matchBin c = c == 'b' || c == 'B'
-
-matchDec :: Char -> Bool
-matchDec c = c == 'd' || c == 'D'
-
-matchOct :: Char -> Bool
-matchOct c = c == 'o' || c == 'O'
-
--- | Parse a Number depending on if it is in a hex or decimal form. Octal and
--- binary are not supported yet.
-parseNum :: Parser Expr
-parseNum = do
- size <- fromIntegral <$> decimal
- _ <- string "'"
- matchNum size
- where
- matchNum size =
- (satisfy matchHex >> Number size <$> hexadecimal)
- <|> (satisfy matchDec >> Number size <$> decimal)
- <|> (satisfy matchOct >> Number size <$> octal)
-
-parseVar :: Parser Expr
-parseVar = Id <$> ident
-
-parseFunction :: Parser Function
-parseFunction =
- reserved "unsigned" $> UnSignedFunc <|> reserved "signed" $> SignedFunc
-
-parseFun :: Parser Expr
-parseFun = do
- f <- spaces *> reservedOp "$" *> parseFunction
- expr <- string "(" *> spaces *> parseExpr
- _ <- spaces *> string ")" *> spaces
- return $ Func f expr
-
-parseTerm :: Parser Expr
-parseTerm =
- parens parseExpr
- <|> (Concat <$> aroundList (string "{") (string "}") parseExpr)
- <|> parseFun
- <|> lexeme parseNum
- <|> parseVar
- <?> "simple expr"
-
--- | Parses the ternary conditional operator. It will behave in a right
--- associative way.
-parseCond :: Expr -> Parser Expr
-parseCond e = do
- _ <- spaces *> reservedOp "?"
- expr <- spaces *> parseExpr
- _ <- spaces *> reservedOp ":"
- Cond e expr <$> parseExpr
-
-parseExpr :: Parser Expr
-parseExpr = do
- e <- parseExpr'
- option e . try $ parseCond e
-
--- | Table of binary and unary operators that encode the right precedence for
--- each.
-parseTable :: [[ParseOperator Expr]]
-parseTable
- = [ [prefix "!" (UnOp UnLNot), prefix "~" (UnOp UnNot)]
- , [ prefix "&" (UnOp UnAnd)
- , prefix "|" (UnOp UnOr)
- , prefix "~&" (UnOp UnNand)
- , prefix "~|" (UnOp UnNor)
- , prefix "^" (UnOp UnXor)
- , prefix "~^" (UnOp UnNxor)
- , prefix "^~" (UnOp UnNxorInv)
- ]
- , [prefix "+" (UnOp UnPlus), prefix "-" (UnOp UnMinus)]
- , [binary "**" (sBinOp BinPower) AssocRight]
- , [ binary "*" (sBinOp BinTimes) AssocLeft
- , binary "/" (sBinOp BinDiv) AssocLeft
- , binary "%" (sBinOp BinMod) AssocLeft
- ]
- , [ binary "+" (sBinOp BinPlus) AssocLeft
- , binary "-" (sBinOp BinPlus) AssocLeft
- ]
- , [ binary "<<" (sBinOp BinLSL) AssocLeft
- , binary ">>" (sBinOp BinLSR) AssocLeft
- ]
- , [ binary "<<<" (sBinOp BinASL) AssocLeft
- , binary ">>>" (sBinOp BinASR) AssocLeft
- ]
- , [ binary "<" (sBinOp BinLT) AssocNone
- , binary ">" (sBinOp BinGT) AssocNone
- , binary "<=" (sBinOp BinLEq) AssocNone
- , binary ">=" (sBinOp BinLEq) AssocNone
- ]
- , [ binary "==" (sBinOp BinEq) AssocNone
- , binary "!=" (sBinOp BinNEq) AssocNone
- ]
- , [ binary "===" (sBinOp BinEq) AssocNone
- , binary "!==" (sBinOp BinNEq) AssocNone
- ]
- , [binary "&" (sBinOp BinAnd) AssocLeft]
- , [ binary "^" (sBinOp BinXor) AssocLeft
- , binary "^~" (sBinOp BinXNor) AssocLeft
- , binary "~^" (sBinOp BinXNorInv) AssocLeft
- ]
- , [binary "|" (sBinOp BinOr) AssocLeft]
- , [binary "&&" (sBinOp BinLAnd) AssocLeft]
- , [binary "||" (sBinOp BinLOr) AssocLeft]
- ]
-
-binary :: String -> (a -> a -> a) -> Assoc -> ParseOperator a
-binary name fun = Infix ((reservedOp name <?> "binary") >> return fun)
-
-prefix :: String -> (a -> a) -> ParseOperator a
-prefix name fun = Prefix ((reservedOp name <?> "prefix") >> return fun)
-
-aroundList :: Parser a -> Parser b -> Parser c -> Parser [c]
-aroundList a b c = lexeme $ do
- l <- a *> spaces *> commaSep c
- _ <- b
- return l
-
-parseContAssign :: Parser ContAssign
-parseContAssign = do
- var <- reserved "assign" *> ident
- expr <- reservedOp "=" *> parseExpr
- _ <- symbol ";"
- return $ ContAssign var expr
-
--- | Parse a range and return the total size. As it is inclusive, 1 has to be
--- added to the difference.
-parseRange :: Parser Int
-parseRange = do
- rangeH <- symbol "[" *> decimal
- rangeL <- symbol ":" *> decimal
- _ <- symbol "]"
- return . fromIntegral $ rangeH - rangeL + 1
-
-ident :: Parser Identifier
-ident = Identifier . T.pack <$> identifier
-
-parseNetDecl :: Maybe PortDir -> Parser ModItem
-parseNetDecl pd = do
- t <- option Wire type_
- sign <- option False (reserved "signed" $> True)
- range <- option 1 parseRange
- name <- ident
- _ <- symbol ";"
- return . Decl pd . Port t sign range $ name
- where type_ = reserved "wire" $> Wire <|> reserved "reg" $> Reg
-
-parsePortDir :: Parser PortDir
-parsePortDir =
- reserved "output"
- $> PortOut
- <|> reserved "input"
- $> PortIn
- <|> reserved "inout"
- $> PortInOut
-
-parseDecl :: Parser ModItem
-parseDecl = (Just <$> parsePortDir >>= parseNetDecl) <|> parseNetDecl Nothing
-
-parseModItem :: Parser ModItem
-parseModItem = (ModCA <$> parseContAssign) <|> parseDecl
-
-parseModList :: Parser [Identifier]
-parseModList = list <|> spaces $> []
- where list = aroundList (string "(") (string ")") ident
-
-filterDecl :: PortDir -> ModItem -> Bool
-filterDecl p (Decl (Just p') _) = p == p'
-filterDecl _ _ = False
-
-modPorts :: PortDir -> [ModItem] -> [Port]
-modPorts p mis = filter (filterDecl p) mis ^.. traverse . declPort
-
-parseModDecl :: Parser ModDecl
-parseModDecl = do
- name <- reserved "module" *> ident
- _ <- fmap defaultPort <$> parseModList
- _ <- symbol ";"
- modItem <- lexeme $ option [] . try $ many1 parseModItem
- _ <- reserved "endmodule"
- return $ ModDecl name
- (modPorts PortOut modItem)
- (modPorts PortIn modItem)
- modItem
-
-parseDescription :: Parser Description
-parseDescription = Description <$> lexeme parseModDecl
-
--- | Parses a 'String' into 'VerilogSrc' by skipping any beginning whitespace
--- and then parsing multiple Verilog source.
-parseVerilogSrc :: Parser VerilogSrc
-parseVerilogSrc = VerilogSrc <$> (whiteSpace *> many parseDescription)
-
--- | Parse a 'String' containing verilog code. The parser currently only supports
--- the subset of Verilog that is being generated randomly.
-parseVerilog :: String -> String -> Either ParseError VerilogSrc
-parseVerilog = parse parseVerilogSrc
+import VeriFuzz.Parser.Parser
diff --git a/src/VeriFuzz/Parser/Lex.x b/src/VeriFuzz/Parser/Lex.x
new file mode 100644
index 0000000..86c431e
--- /dev/null
+++ b/src/VeriFuzz/Parser/Lex.x
@@ -0,0 +1,187 @@
+{
+{-# OPTIONS_GHC -w #-}
+module VeriFuzz.Parser.Lex
+ ( alexScanTokens
+ ) where
+
+import VeriFuzz.Parser.Token
+
+}
+
+%wrapper "posn"
+
+-- Numbers
+
+$nonZeroDecimalDigit = [1-9]
+$decimalDigit = [0-9]
+@binaryDigit = [0-1]
+@octalDigit = [0-7]
+@hexDigit = [0-9a-fA-F]
+
+@decimalBase = "'" [dD]
+@binaryBase = "'" [bB]
+@octalBase = "'" [oO]
+@hexBase = "'" [hH]
+
+@binaryValue = @binaryDigit ("_" | @binaryDigit)*
+@octalValue = @octalDigit ("_" | @octalDigit)*
+@hexValue = @hexDigit ("_" | @hexDigit)*
+
+@unsignedNumber = $decimalDigit ("_" | $decimalDigit)*
+
+@size = @unsignedNumber
+
+@decimalNumber
+ = @unsignedNumber
+ | @size? @decimalBase @unsignedNumber
+
+@binaryNumber = @size? @binaryBase @binaryValue
+@octalNumber = @size? @octalBase @octalValue
+@hexNumber = @size? @hexBase @hexValue
+
+-- $exp = [eE]
+-- $sign = [\+\-]
+-- @realNumber = unsignedNumber "." unsignedNumber | unsignedNumber ( "." unsignedNumber)? exp sign? unsignedNumber
+@number = @decimalNumber | @octalNumber | @binaryNumber | @hexNumber
+
+-- Strings
+
+@string = \" [^\r\n]* \"
+
+-- Identifiers
+
+@escapedIdentifier = "\" ($printable # $white)+ $white
+@simpleIdentifier = [a-zA-Z_] [a-zA-Z0-9_\$]*
+@systemIdentifier = "$" [a-zA-Z0-9_\$]+
+
+
+tokens :-
+
+ "always" { tok KWAlways }
+ "assign" { tok KWAssign }
+ "begin" { tok KWBegin }
+ "case" { tok KWCase }
+ "default" { tok KWDefault }
+ "else" { tok KWElse }
+ "end" { tok KWEnd }
+ "endcase" { tok KWEndcase }
+ "endmodule" { tok KWEndmodule }
+ "for" { tok KWFor }
+ "if" { tok KWIf }
+ "initial" { tok KWInitial }
+ "inout" { tok KWInout }
+ "input" { tok KWInput }
+ "integer" { tok KWInteger }
+ "localparam" { tok KWLocalparam }
+ "module" { tok KWModule }
+ "negedge" { tok KWNegedge }
+ "or" { tok KWOr }
+ "output" { tok KWOutput }
+ "parameter" { tok KWParameter }
+ "posedge" { tok KWPosedge }
+ "reg" { tok KWReg }
+ "wire" { tok KWWire }
+ "signed" { tok KWSigned }
+
+ @simpleIdentifier { tok IdSimple }
+ @escapedIdentifier { tok IdEscaped }
+ @systemIdentifier { tok IdSystem }
+
+ @number { tok LitNumber }
+ @string { tok LitString }
+
+ "(" { tok SymParenL }
+ ")" { tok SymParenR }
+ "[" { tok SymBrackL }
+ "]" { tok SymBrackR }
+ "{" { tok SymBraceL }
+ "}" { tok SymBraceR }
+ "~" { tok SymTildy }
+ "!" { tok SymBang }
+ "@" { tok SymAt }
+ "#" { tok SymPound }
+ "%" { tok SymPercent }
+ "^" { tok SymHat }
+ "&" { tok SymAmp }
+ "|" { tok SymBar }
+ "*" { tok SymAster }
+ "." { tok SymDot }
+ "," { tok SymComma }
+ ":" { tok SymColon }
+ ";" { tok SymSemi }
+ "=" { tok SymEq }
+ "<" { tok SymLt }
+ ">" { tok SymGt }
+ "+" { tok SymPlus }
+ "-" { tok SymDash }
+ "?" { tok SymQuestion }
+ "/" { tok SymSlash }
+ "$" { tok SymDollar }
+ "'" { tok SymSQuote }
+
+ "~&" { tok SymTildyAmp }
+ "~|" { tok SymTildyBar }
+ "~^" { tok SymTildyHat }
+ "^~" { tok SymHatTildy }
+ "==" { tok SymEqEq }
+ "!=" { tok SymBangEq }
+ "&&" { tok SymAmpAmp }
+ "||" { tok SymBarBar }
+ "**" { tok SymAsterAster }
+ "<=" { tok SymLtEq }
+ ">=" { tok SymGtEq }
+ ">>" { tok SymGtGt }
+ "<<" { tok SymLtLt }
+ "++" { tok SymPlusPlus }
+ "--" { tok SymDashDash }
+ "+=" { tok SymPlusEq }
+ "-=" { tok SymDashEq }
+ "*=" { tok SymAsterEq }
+ "/=" { tok SymSlashEq }
+ "%=" { tok SymPercentEq }
+ "&=" { tok SymAmpEq }
+ "|=" { tok SymBarEq }
+ "^=" { tok SymHatEq }
+ "+:" { tok SymPlusColon }
+ "-:" { tok SymDashColon }
+ "::" { tok SymColonColon }
+ ".*" { tok SymDotAster }
+ "->" { tok SymDashGt }
+ ":=" { tok SymColonEq }
+ ":/" { tok SymColonSlash }
+ "##" { tok SymPoundPound }
+ "[*" { tok SymBrackLAster }
+ "[=" { tok SymBrackLEq }
+ "=>" { tok SymEqGt }
+ "@*" { tok SymAtAster }
+ "(*" { tok SymParenLAster }
+ "*)" { tok SymAsterParenR }
+ "*>" { tok SymAsterGt }
+
+ "===" { tok SymEqEqEq }
+ "!==" { tok SymBangEqEq }
+ "=?=" { tok SymEqQuestionEq }
+ "!?=" { tok SymBangQuestionEq }
+ ">>>" { tok SymGtGtGt }
+ "<<<" { tok SymLtLtLt }
+ "<<=" { tok SymLtLtEq }
+ ">>=" { tok SymGtGtEq }
+ "|->" { tok SymBarDashGt }
+ "|=>" { tok SymBarEqGt }
+ "[->" { tok SymBrackLDashGt }
+ "@@(" { tok SymAtAtParenL }
+ "(*)" { tok SymParenLAsterParenR }
+ "->>" { tok SymDashGtGt }
+ "&&&" { tok SymAmpAmpAmp }
+
+ "<<<=" { tok SymLtLtLtEq }
+ ">>>=" { tok SymGtGtGtEq }
+
+ $white ;
+
+ . { tok Unknown }
+
+{
+tok :: TokenName -> AlexPosn -> String -> Token
+tok t (AlexPn _ l c) s = Token t s $ Position "" l c
+}
diff --git a/src/VeriFuzz/Parser/Parser.hs b/src/VeriFuzz/Parser/Parser.hs
new file mode 100644
index 0000000..5a1d163
--- /dev/null
+++ b/src/VeriFuzz/Parser/Parser.hs
@@ -0,0 +1,329 @@
+{-|
+Module : VeriFuzz.Parser.Parser
+Description : Minimal Verilog parser to reconstruct the AST.
+Copyright : (c) 2019, Yann Herklotz
+License : GPL-3
+Maintainer : ymherklotz [at] gmail [dot] com
+Stability : experimental
+Portability : POSIX
+
+Minimal Verilog parser to reconstruct the AST. This parser does not support the
+whole Verilog syntax, as the AST does not support it either.
+-}
+
+module VeriFuzz.Parser.Parser
+ ( -- * Parsers
+ parseVerilog
+ , parseVerilogSrc
+ , parseDescription
+ , parseModDecl
+ , parseContAssign
+ , parseExpr
+ )
+where
+
+import Control.Lens
+import Data.Functor (($>))
+import Data.Functor.Identity (Identity)
+import qualified Data.Text as T
+import Text.Parsec hiding (satisfy)
+import Text.Parsec.Expr
+import VeriFuzz.AST
+--import VeriFuzz.CodeGen
+import Data.Bits
+import Data.List (isInfixOf, isPrefixOf)
+import VeriFuzz.Internal
+import VeriFuzz.Parser.Lex
+import VeriFuzz.Parser.Preprocess
+import VeriFuzz.Parser.Token
+
+
+type Parser = Parsec [Token] ()
+
+type ParseOperator = Operator [Token] () Identity
+
+data Decimal = Decimal { size :: Int
+ , num :: Integer
+ }
+
+instance Num Decimal where
+ (Decimal sa na) + (Decimal sb nb) = Decimal (max sa sb) (na + nb)
+ (Decimal sa na) - (Decimal sb nb) = Decimal (max sa sb) (na - nb)
+ (Decimal sa na) * (Decimal sb nb) = Decimal (max sa sb) (na * nb)
+ negate (Decimal s n) = Decimal s $ negate n
+ abs (Decimal s n) = Decimal s $ abs n
+ signum (Decimal s n) = Decimal s $ signum n
+ fromInteger = Decimal 32 . fromInteger
+
+-- | This parser succeeds whenever the given predicate returns true when called
+-- with parsed `Token`. Same as 'Text.Parsec.Char.satisfy'.
+satisfy :: (Token -> Bool) -> Parser TokenName
+satisfy f = tokenPrim show nextPos tokeq
+ where
+ tokeq :: Token -> Maybe TokenName
+ tokeq t@(Token t' _ _) = if f t then Just t' else Nothing
+
+satisfy' :: (Token -> Maybe a) -> Parser a
+satisfy' = tokenPrim show nextPos
+
+nextPos :: SourcePos -> Token -> [Token] -> SourcePos
+nextPos pos _ (Token _ _ (Position _ l c):_) = setSourceColumn (setSourceLine pos l) c
+nextPos pos _ [] = pos
+
+-- | Parses given `TokenName`.
+tok :: TokenName -> Parser TokenName
+tok t = satisfy (\(Token t' _ _) -> t' == t) <?> show t
+
+-- | Parse without returning the `TokenName`.
+tok' :: TokenName -> Parser ()
+tok' p = tok p >> return ()
+
+parens :: Parser a -> Parser a
+parens = between (tok SymParenL) (tok SymParenR)
+
+brackets :: Parser a -> Parser a
+brackets = between (tok SymBrackL) (tok SymBrackR)
+
+braces :: Parser a -> Parser a
+braces = between (tok SymBraceL) (tok SymBraceR)
+
+sBinOp :: BinaryOperator -> Expr -> Expr -> Expr
+sBinOp = sOp BinOp where sOp f b a = f a b
+
+parseExpr' :: Parser Expr
+parseExpr' = buildExpressionParser parseTable parseTerm <?> "expr"
+
+matchHex :: Char -> Bool
+matchHex c = c == 'h' || c == 'H'
+
+--matchBin :: Char -> Bool
+--matchBin c = c == 'b' || c == 'B'
+
+matchDec :: Char -> Bool
+matchDec c = c == 'd' || c == 'D'
+
+matchOct :: Char -> Bool
+matchOct c = c == 'o' || c == 'O'
+
+decToExpr :: Decimal -> Expr
+decToExpr (Decimal s n) = Number s n
+
+-- | Parse a Number depending on if it is in a hex or decimal form. Octal and
+-- binary are not supported yet.
+parseNum :: Parser Expr
+parseNum = decToExpr <$> number
+
+parseVar :: Parser Expr
+parseVar = Id <$> identifier
+
+systemFunc :: String -> Parser String
+systemFunc s = satisfy' matchId
+ where
+ matchId (Token IdSystem s' _) =
+ if s == s' then Just s else Nothing
+ matchId _ = Nothing
+
+parseFunction :: Parser Function
+parseFunction =
+ systemFunc "unsigned" $> UnSignedFunc <|> systemFunc "signed" $> SignedFunc
+
+parseFun :: Parser Expr
+parseFun = do
+ f <- parseFunction
+ expr <- parens parseExpr
+ return $ Func f expr
+
+parseTerm :: Parser Expr
+parseTerm =
+ parens parseExpr
+ <|> (Concat <$> braces (commaSep parseExpr))
+ <|> parseFun
+ <|> parseNum
+ <|> parseVar
+ <?> "simple expr"
+
+-- | Parses the ternary conditional operator. It will behave in a right
+-- associative way.
+parseCond :: Expr -> Parser Expr
+parseCond e = do
+ tok' SymQuestion
+ expr <- parseExpr
+ tok' SymColon
+ Cond e expr <$> parseExpr
+
+parseExpr :: Parser Expr
+parseExpr = do
+ e <- parseExpr'
+ option e . try $ parseCond e
+
+-- | Table of binary and unary operators that encode the right precedence for
+-- each.
+parseTable :: [[ParseOperator Expr]]
+parseTable
+ = [ [prefix SymBang (UnOp UnLNot), prefix SymTildy (UnOp UnNot)]
+ , [ prefix SymAmp (UnOp UnAnd)
+ , prefix SymBar (UnOp UnOr)
+ , prefix SymTildyAmp (UnOp UnNand)
+ , prefix SymTildyBar (UnOp UnNor)
+ , prefix SymHat (UnOp UnXor)
+ , prefix SymTildyHat (UnOp UnNxor)
+ , prefix SymHatTildy (UnOp UnNxorInv)
+ ]
+ , [prefix SymPlus (UnOp UnPlus), prefix SymDash (UnOp UnMinus)]
+ , [binary SymAsterAster (sBinOp BinPower) AssocRight]
+ , [ binary SymAster (sBinOp BinTimes) AssocLeft
+ , binary SymSlash (sBinOp BinDiv) AssocLeft
+ , binary SymPercent (sBinOp BinMod) AssocLeft
+ ]
+ , [ binary SymPlus (sBinOp BinPlus) AssocLeft
+ , binary SymDash (sBinOp BinPlus) AssocLeft
+ ]
+ , [ binary SymLtLt (sBinOp BinLSL) AssocLeft
+ , binary SymGtGt (sBinOp BinLSR) AssocLeft
+ ]
+ , [ binary SymLtLtLt (sBinOp BinASL) AssocLeft
+ , binary SymGtGtGt (sBinOp BinASR) AssocLeft
+ ]
+ , [ binary SymLt (sBinOp BinLT) AssocNone
+ , binary SymGt (sBinOp BinGT) AssocNone
+ , binary SymLtEq (sBinOp BinLEq) AssocNone
+ , binary SymGtEq (sBinOp BinLEq) AssocNone
+ ]
+ , [ binary SymEqEq (sBinOp BinEq) AssocNone
+ , binary SymBangEq (sBinOp BinNEq) AssocNone
+ ]
+ , [ binary SymEqEqEq (sBinOp BinEq) AssocNone
+ , binary SymBangEqEq (sBinOp BinNEq) AssocNone
+ ]
+ , [binary SymAmp (sBinOp BinAnd) AssocLeft]
+ , [ binary SymHat (sBinOp BinXor) AssocLeft
+ , binary SymHatTildy (sBinOp BinXNor) AssocLeft
+ , binary SymTildyHat (sBinOp BinXNorInv) AssocLeft
+ ]
+ , [binary SymBar (sBinOp BinOr) AssocLeft]
+ , [binary SymAmpAmp (sBinOp BinLAnd) AssocLeft]
+ , [binary SymBarBar (sBinOp BinLOr) AssocLeft]
+ ]
+
+binary :: TokenName -> (a -> a -> a) -> Assoc -> ParseOperator a
+binary name fun = Infix ((tok name <?> "binary") >> return fun)
+
+prefix :: TokenName -> (a -> a) -> ParseOperator a
+prefix name fun = Prefix ((tok name <?> "prefix") >> return fun)
+
+commaSep :: Parser a -> Parser [a]
+commaSep = flip sepBy $ tok SymComma
+
+parseContAssign :: Parser ContAssign
+parseContAssign = do
+ var <- tok KWAssign *> identifier
+ expr <- tok SymEq *> parseExpr
+ tok SymSemi
+ return $ ContAssign var expr
+
+numLit :: Parser String
+numLit = satisfy' matchId
+ where
+ matchId (Token LitNumber s _) = Just s
+ matchId _ = Nothing
+
+number :: Parser Decimal
+number = number' <$> numLit
+ where
+ number' :: String -> Decimal
+ number' a
+ | all (flip elem ['0' .. '9']) a = fromInteger $ read a
+ | head a == '\'' = fromInteger $ f a
+ | isInfixOf "'" a = Decimal (read w) (f b)
+ | otherwise = error $ "Invalid number format: " ++ a
+ where
+ w = takeWhile (/= '\'') a
+ b = dropWhile (/= '\'') a
+ f a
+ | isPrefixOf "'d" a = read $ drop 2 a
+ | isPrefixOf "'h" a = read $ "0x" ++ drop 2 a
+ | isPrefixOf "'b" a = foldl (\ n b -> shiftL n 1 .|. (if b == '1' then 1 else 0)) 0 (drop 2 a)
+ | otherwise = error $ "Invalid number format: " ++ a
+
+toInteger' :: Decimal -> Integer
+toInteger' (Decimal _ n) = n
+
+-- | Parse a range and return the total size. As it is inclusive, 1 has to be
+-- added to the difference.
+parseRange :: Parser Int
+parseRange = do
+ rangeH <- tok SymBrackL *> number
+ rangeL <- tok SymColon *> number
+ tok' SymBrackR
+ return . fromInteger . toInteger' $ rangeH - rangeL + 1
+
+strId :: Parser String
+strId = satisfy' matchId
+ where
+ matchId (Token IdSimple s _) = Just s
+ matchId (Token IdEscaped s _) = Just s
+ matchId _ = Nothing
+
+identifier :: Parser Identifier
+identifier = Identifier . T.pack <$> strId
+
+parseNetDecl :: Maybe PortDir -> Parser ModItem
+parseNetDecl pd = do
+ t <- option Wire type_
+ sign <- option False (tok KWSigned $> True)
+ range <- option 1 parseRange
+ name <- identifier
+ tok' SymSemi
+ return . Decl pd . Port t sign range $ name
+ where type_ = tok KWWire $> Wire <|> tok KWReg $> Reg
+
+parsePortDir :: Parser PortDir
+parsePortDir =
+ tok KWOutput
+ $> PortOut
+ <|> tok KWInput
+ $> PortIn
+ <|> tok KWInout
+ $> PortInOut
+
+parseDecl :: Parser ModItem
+parseDecl = (Just <$> parsePortDir >>= parseNetDecl) <|> parseNetDecl Nothing
+
+parseModItem :: Parser ModItem
+parseModItem = (ModCA <$> parseContAssign) <|> parseDecl
+
+parseModList :: Parser [Identifier]
+parseModList = list <|> return []
+ where list = parens $ commaSep identifier
+
+filterDecl :: PortDir -> ModItem -> Bool
+filterDecl p (Decl (Just p') _) = p == p'
+filterDecl _ _ = False
+
+modPorts :: PortDir -> [ModItem] -> [Port]
+modPorts p mis = filter (filterDecl p) mis ^.. traverse . declPort
+
+parseModDecl :: Parser ModDecl
+parseModDecl = do
+ name <- tok KWModule *> identifier
+ _ <- fmap defaultPort <$> parseModList
+ tok' SymSemi
+ modItem <- option [] . try $ many1 parseModItem
+ tok' KWEndmodule
+ return $ ModDecl name
+ (modPorts PortOut modItem)
+ (modPorts PortIn modItem)
+ modItem
+
+parseDescription :: Parser Description
+parseDescription = Description <$> parseModDecl
+
+-- | Parses a 'String' into 'VerilogSrc' by skipping any beginning whitespace
+-- and then parsing multiple Verilog source.
+parseVerilogSrc :: Parser VerilogSrc
+parseVerilogSrc = VerilogSrc <$> many parseDescription
+
+-- | Parse a 'String' containing verilog code. The parser currently only supports
+-- the subset of Verilog that is being generated randomly.
+parseVerilog :: String -> String -> Either ParseError VerilogSrc
+parseVerilog s = parse parseVerilogSrc s . alexScanTokens . preprocess [] s
diff --git a/src/VeriFuzz/Parser/Preprocess.hs b/src/VeriFuzz/Parser/Preprocess.hs
new file mode 100644
index 0000000..c0a4246
--- /dev/null
+++ b/src/VeriFuzz/Parser/Preprocess.hs
@@ -0,0 +1,88 @@
+{-|
+Module : VeriFuzz.Parser.Preprocess
+Description : Simple preprocessor for `define and comments.
+Copyright : (c) 2011-2015 Tom Hawkins, 2019 Yann Herklotz
+License : GPL-3
+Maintainer : ymherklotz [at] gmail [dot] com
+Stability : experimental
+Portability : POSIX
+
+Simple preprocessor for `define and comments.
+
+The code is from https://github.com/tomahawkins/verilog.
+
+Edits to the original code are warning fixes and formatting changes.
+-}
+
+module VeriFuzz.Parser.Preprocess
+ ( uncomment
+ , preprocess
+ ) where
+
+-- | Remove comments from code.
+uncomment :: FilePath -> String -> String
+uncomment file = uncomment'
+ where
+ uncomment' a = case a of
+ "" -> ""
+ '/' : '/' : rest -> " " ++ removeEOL rest
+ '/' : '*' : rest -> " " ++ remove rest
+ '"' : rest -> '"' : ignoreString rest
+ b : rest -> b : uncomment' rest
+
+ removeEOL a = case a of
+ "" -> ""
+ '\n' : rest -> '\n' : uncomment' rest
+ '\t' : rest -> '\t' : removeEOL rest
+ _ : rest -> ' ' : removeEOL rest
+
+ remove a = case a of
+ "" -> error $ "File ended without closing comment (*/): " ++ file
+ '"' : rest -> removeString rest
+ '\n' : rest -> '\n' : remove rest
+ '\t' : rest -> '\t' : remove rest
+ '*' : '/' : rest -> " " ++ uncomment' rest
+ _ : rest -> " " ++ remove rest
+
+ removeString a = case a of
+ "" -> error $ "File ended without closing string: " ++ file
+ '"' : rest -> " " ++ remove rest
+ '\\' : '"' : rest -> " " ++ removeString rest
+ '\n' : rest -> '\n' : removeString rest
+ '\t' : rest -> '\t' : removeString rest
+ _ : rest -> ' ' : removeString rest
+
+ ignoreString a = case a of
+ "" -> error $ "File ended without closing string: " ++ file
+ '"' : rest -> '"' : uncomment' rest
+ '\\' : '"' : rest -> "\\\"" ++ ignoreString rest
+ b : rest -> b : ignoreString rest
+
+-- | A simple `define preprocessor.
+preprocess :: [(String, String)] -> FilePath -> String -> String
+preprocess env file content = unlines $ pp True [] env $ lines $ uncomment file content
+ where
+ pp :: Bool -> [Bool] -> [(String, String)] -> [String] -> [String]
+ pp _ _ _ [] = []
+ pp on stack env_ (a : rest) = case words a of
+ "`define" : name : value -> "" : pp on stack (if on then (name, ppLine env_ $ unwords value) : env_ else env_) rest
+ "`ifdef" : name : _ -> "" : pp (on && elem name (map fst env_)) (on : stack) env_ rest
+ "`ifndef" : name : _ -> "" : pp (on && notElem name (map fst env_)) (on : stack) env_ rest
+ "`else" : _
+ | not $ null stack -> "" : pp (head stack && not on) stack env_ rest
+ | otherwise -> error $ "`else without associated `ifdef/`ifndef: " ++ file
+ "`endif" : _
+ | not $ null stack -> "" : pp (head stack) (tail stack) env_ rest
+ | otherwise -> error $ "`endif without associated `ifdef/`ifndef: " ++ file
+ _ -> (if on then ppLine env_ a else "") : pp on stack env_ rest
+
+ppLine :: [(String, String)] -> String -> String
+ppLine _ "" = ""
+ppLine env ('`' : a) = case lookup name env of
+ Just value -> value ++ ppLine env rest
+ Nothing -> error $ "Undefined macro: `" ++ name ++ " Env: " ++ show env
+ where
+ name = takeWhile (flip elem $ ['A' .. 'Z'] ++ ['a' .. 'z'] ++ ['0' .. '9'] ++ ['_']) a
+ rest = drop (length name) a
+ppLine env (a : b) = a : ppLine env b
+
diff --git a/src/VeriFuzz/Parser/Token.hs b/src/VeriFuzz/Parser/Token.hs
new file mode 100644
index 0000000..f776dd8
--- /dev/null
+++ b/src/VeriFuzz/Parser/Token.hs
@@ -0,0 +1,337 @@
+module VeriFuzz.Parser.Token
+ ( Token (..)
+ , TokenName (..)
+ , Position (..)
+ , tokenString
+ ) where
+
+import Text.Printf
+
+tokenString :: Token -> String
+tokenString (Token _ s _) = s
+
+data Position = Position String Int Int deriving Eq
+
+instance Show Position where
+ show (Position f l c) = printf "%s:%d:%d" f l c
+
+data Token = Token TokenName String Position deriving (Show, Eq)
+
+data TokenName
+ = KWAlias
+ | KWAlways
+ | KWAlwaysComb
+ | KWAlwaysFf
+ | KWAlwaysLatch
+ | KWAnd
+ | KWAssert
+ | KWAssign
+ | KWAssume
+ | KWAutomatic
+ | KWBefore
+ | KWBegin
+ | KWBind
+ | KWBins
+ | KWBinsof
+ | KWBit
+ | KWBreak
+ | KWBuf
+ | KWBufif0
+ | KWBufif1
+ | KWByte
+ | KWCase
+ | KWCasex
+ | KWCasez
+ | KWCell
+ | KWChandle
+ | KWClass
+ | KWClocking
+ | KWCmos
+ | KWConfig
+ | KWConst
+ | KWConstraint
+ | KWContext
+ | KWContinue
+ | KWCover
+ | KWCovergroup
+ | KWCoverpoint
+ | KWCross
+ | KWDeassign
+ | KWDefault
+ | KWDefparam
+ | KWDesign
+ | KWDisable
+ | KWDist
+ | KWDo
+ | KWEdge
+ | KWElse
+ | KWEnd
+ | KWEndcase
+ | KWEndclass
+ | KWEndclocking
+ | KWEndconfig
+ | KWEndfunction
+ | KWEndgenerate
+ | KWEndgroup
+ | KWEndinterface
+ | KWEndmodule
+ | KWEndpackage
+ | KWEndprimitive
+ | KWEndprogram
+ | KWEndproperty
+ | KWEndspecify
+ | KWEndsequence
+ | KWEndtable
+ | KWEndtask
+ | KWEnum
+ | KWEvent
+ | KWExpect
+ | KWExport
+ | KWExtends
+ | KWExtern
+ | KWFinal
+ | KWFirstMatch
+ | KWFor
+ | KWForce
+ | KWForeach
+ | KWForever
+ | KWFork
+ | KWForkjoin
+ | KWFunction
+ | KWFunctionPrototype
+ | KWGenerate
+ | KWGenvar
+ | KWHighz0
+ | KWHighz1
+ | KWIf
+ | KWIff
+ | KWIfnone
+ | KWIgnoreBins
+ | KWIllegalBins
+ | KWImport
+ | KWIncdir
+ | KWInclude
+ | KWInitial
+ | KWInout
+ | KWInput
+ | KWInside
+ | KWInstance
+ | KWInt
+ | KWInteger
+ | KWInterface
+ | KWIntersect
+ | KWJoin
+ | KWJoinAny
+ | KWJoinNone
+ | KWLarge
+ | KWLiblist
+ | KWLibrary
+ | KWLocal
+ | KWLocalparam
+ | KWLogic
+ | KWLongint
+ | KWMacromodule
+ | KWMatches
+ | KWMedium
+ | KWModport
+ | KWModule
+ | KWNand
+ | KWNegedge
+ | KWNew
+ | KWNmos
+ | KWNor
+ | KWNoshowcancelled
+ | KWNot
+ | KWNotif0
+ | KWNotif1
+ | KWNull
+ | KWOption
+ | KWOr
+ | KWOutput
+ | KWPackage
+ | KWPacked
+ | KWParameter
+ | KWPathpulseDollar
+ | KWPmos
+ | KWPosedge
+ | KWPrimitive
+ | KWPriority
+ | KWProgram
+ | KWProperty
+ | KWProtected
+ | KWPull0
+ | KWPull1
+ | KWPulldown
+ | KWPullup
+ | KWPulsestyleOnevent
+ | KWPulsestyleOndetect
+ | KWPure
+ | KWRand
+ | KWRandc
+ | KWRandcase
+ | KWRandsequence
+ | KWRcmos
+ | KWReal
+ | KWRealtime
+ | KWRef
+ | KWReg
+ | KWRelease
+ | KWRepeat
+ | KWReturn
+ | KWRnmos
+ | KWRpmos
+ | KWRtran
+ | KWRtranif0
+ | KWRtranif1
+ | KWScalared
+ | KWSequence
+ | KWShortint
+ | KWShortreal
+ | KWShowcancelled
+ | KWSigned
+ | KWSmall
+ | KWSolve
+ | KWSpecify
+ | KWSpecparam
+ | KWStatic
+ | KWStrength0
+ | KWStrength1
+ | KWString
+ | KWStrong0
+ | KWStrong1
+ | KWStruct
+ | KWSuper
+ | KWSupply0
+ | KWSupply1
+ | KWTable
+ | KWTagged
+ | KWTask
+ | KWThis
+ | KWThroughout
+ | KWTime
+ | KWTimeprecision
+ | KWTimeunit
+ | KWTran
+ | KWTranif0
+ | KWTranif1
+ | KWTri
+ | KWTri0
+ | KWTri1
+ | KWTriand
+ | KWTrior
+ | KWTrireg
+ | KWType
+ | KWTypedef
+ | KWTypeOption
+ | KWUnion
+ | KWUnique
+ | KWUnsigned
+ | KWUse
+ | KWVar
+ | KWVectored
+ | KWVirtual
+ | KWVoid
+ | KWWait
+ | KWWaitOrder
+ | KWWand
+ | KWWeak0
+ | KWWeak1
+ | KWWhile
+ | KWWildcard
+ | KWWire
+ | KWWith
+ | KWWithin
+ | KWWor
+ | KWXnor
+ | KWXor
+ | IdSimple
+ | IdEscaped
+ | IdSystem
+ | LitNumberUnsigned
+ | LitNumber
+ | LitString
+ | SymParenL
+ | SymParenR
+ | SymBrackL
+ | SymBrackR
+ | SymBraceL
+ | SymBraceR
+ | SymTildy
+ | SymBang
+ | SymAt
+ | SymPound
+ | SymPercent
+ | SymHat
+ | SymAmp
+ | SymBar
+ | SymAster
+ | SymDot
+ | SymComma
+ | SymColon
+ | SymSemi
+ | SymEq
+ | SymLt
+ | SymGt
+ | SymPlus
+ | SymDash
+ | SymQuestion
+ | SymSlash
+ | SymDollar
+ | SymSQuote
+ | SymTildyAmp
+ | SymTildyBar
+ | SymTildyHat
+ | SymHatTildy
+ | SymEqEq
+ | SymBangEq
+ | SymAmpAmp
+ | SymBarBar
+ | SymAsterAster
+ | SymLtEq
+ | SymGtEq
+ | SymGtGt
+ | SymLtLt
+ | SymPlusPlus
+ | SymDashDash
+ | SymPlusEq
+ | SymDashEq
+ | SymAsterEq
+ | SymSlashEq
+ | SymPercentEq
+ | SymAmpEq
+ | SymBarEq
+ | SymHatEq
+ | SymPlusColon
+ | SymDashColon
+ | SymColonColon
+ | SymDotAster
+ | SymDashGt
+ | SymColonEq
+ | SymColonSlash
+ | SymPoundPound
+ | SymBrackLAster
+ | SymBrackLEq
+ | SymEqGt
+ | SymAtAster
+ | SymParenLAster
+ | SymAsterParenR
+ | SymAsterGt
+ | SymEqEqEq
+ | SymBangEqEq
+ | SymEqQuestionEq
+ | SymBangQuestionEq
+ | SymGtGtGt
+ | SymLtLtLt
+ | SymLtLtEq
+ | SymGtGtEq
+ | SymBarDashGt
+ | SymBarEqGt
+ | SymBrackLDashGt
+ | SymAtAtParenL
+ | SymParenLAsterParenR
+ | SymDashGtGt
+ | SymAmpAmpAmp
+ | SymLtLtLtEq
+ | SymGtGtGtEq
+ | Unknown
+ deriving (Show, Eq)
diff --git a/verifuzz.cabal b/verifuzz.cabal
index 81b71e3..267dffe 100644
--- a/verifuzz.cabal
+++ b/verifuzz.cabal
@@ -19,7 +19,8 @@ extra-source-files: README.md
library
hs-source-dirs: src
default-language: Haskell2010
- ghc-options: -Wall -Werror
+ ghc-options: -Wall
+ build-tools: alex >=3 && <4
exposed-modules: VeriFuzz
, VeriFuzz.AST
, VeriFuzz.Config
@@ -34,9 +35,12 @@ library
, VeriFuzz.Env
, VeriFuzz.Gen
, VeriFuzz.Icarus
- , VeriFuzz.Lexer
, VeriFuzz.Mutate
, VeriFuzz.Parser
+ , VeriFuzz.Parser.Parser
+ , VeriFuzz.Parser.Preprocess
+ , VeriFuzz.Parser.Token
+ , VeriFuzz.Parser.Lex
, VeriFuzz.Random
, VeriFuzz.RandomAlt
, VeriFuzz.Reduce
@@ -61,6 +65,7 @@ library
, parsec >=3.1 && <3.2
, transformers >=0.5 && <0.6
, tomland >=0.5 && <0.6
+ , array >=0.5 && <0.6
default-extensions: OverloadedStrings
executable verifuzz