Commit 6ee558b6 by Zachary Snow

initial pass improving decl parsing error messages

- all decl tokens are given an accurate starting position
- key grammar productions return token positions to facilitate the above
- helpers for standardized parse error generation
- replaced annoying pattern-matching type argument restrictions
- moving away from dumping raw decl tokens in error messages
parent ff0c7b02
...@@ -28,7 +28,7 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -28,7 +28,7 @@ import Language.SystemVerilog.Parser.Tokens
%lexer { positionKeep } { TokenEOF } %lexer { positionKeep } { TokenEOF }
%name parseMain %name parseMain
%tokentype { Token } %tokentype { Token }
%error { parseError } %error { parseErrorTok }
%expect 0 %expect 0
...@@ -462,58 +462,62 @@ TypeNonIdent :: { Type } ...@@ -462,58 +462,62 @@ TypeNonIdent :: { Type }
: PartialType OptSigning Dimensions { $1 $2 $3 } : PartialType OptSigning Dimensions { $1 $2 $3 }
| "type" "(" Expr ")" { TypeOf $3 } | "type" "(" Expr ")" { TypeOf $3 }
PartialType :: { Signing -> [Range] -> Type } PartialType :: { Signing -> [Range] -> Type }
: IntegerVectorType { IntegerVector $1 } : PartialTypeP { snd $1 }
| IntegerAtomType { \sg -> \[] -> IntegerAtom $1 sg } PartialTypeP :: { (Position, Signing -> [Range] -> Type) }
| NonIntegerType { \Unspecified -> \[] -> NonInteger $1 } : IntegerVectorTypeP { (fst $1, makeIntegerVector $1) }
| "enum" EnumBaseType "{" EnumItems "}" { \Unspecified -> Enum $2 $4 } | IntegerAtomTypeP { (fst $1, makeIntegerAtom $1) }
| "struct" Packing "{" StructItems "}" { \Unspecified -> Struct $2 $4 } | NonIntegerTypeP { (fst $1, makeNonInteger $1) }
| "union" Packing "{" StructItems "}" { \Unspecified -> Union $2 $4 } | "enum" EnumBaseType "{" EnumItems "}" { makeComplex $1 $ Enum $2 $4 }
| "struct" Packing "{" StructItems "}" { makeComplex $1 $ Struct $2 $4 }
| "union" Packing "{" StructItems "}" { makeComplex $1 $ Union $2 $4 }
CastingType :: { Type } CastingType :: { Type }
: IntegerVectorType { IntegerVector $1 Unspecified [] } : IntegerVectorTypeP { IntegerVector (snd $1) Unspecified [] }
| IntegerAtomType { IntegerAtom $1 Unspecified } | IntegerAtomTypeP { IntegerAtom (snd $1) Unspecified }
| NonIntegerType { NonInteger $1 } | NonIntegerTypeP { NonInteger (snd $1) }
| Signing { Implicit $1 [] } | SigningP { Implicit (snd $1) [] }
EnumBaseType :: { Type } EnumBaseType :: { Type }
: Type { $1 } : Type { $1 }
| Dimensions { Implicit Unspecified $1 } | Dimensions { Implicit Unspecified $1 }
Signing :: { Signing } Signing :: { Signing }
: "signed" { Signed } : SigningP { snd $1 }
| "unsigned" { Unsigned } SigningP :: { (Position, Signing) }
: "signed" { withPos $1 Signed }
| "unsigned" { withPos $1 Unsigned }
OptSigning :: { Signing } OptSigning :: { Signing }
: Signing { $1 } : Signing { $1 }
| {- empty -} { Unspecified } | {- empty -} { Unspecified }
NetType :: { NetType } NetTypeP :: { (Position, NetType) }
: "supply0" { TSupply0 } : "supply0" { withPos $1 TSupply0 }
| "supply1" { TSupply1 } | "supply1" { withPos $1 TSupply1 }
| "tri" { TTri } | "tri" { withPos $1 TTri }
| "triand" { TTriand } | "triand" { withPos $1 TTriand }
| "trior" { TTrior } | "trior" { withPos $1 TTrior }
| "trireg" { TTrireg } | "trireg" { withPos $1 TTrireg }
| "tri0" { TTri0 } | "tri0" { withPos $1 TTri0 }
| "tri1" { TTri1 } | "tri1" { withPos $1 TTri1 }
| "uwire" { TUwire } | "uwire" { withPos $1 TUwire }
| "wire" { TWire } | "wire" { withPos $1 TWire }
| "wand" { TWand } | "wand" { withPos $1 TWand }
| "wor" { TWor } | "wor" { withPos $1 TWor }
IntegerVectorType :: { IntegerVectorType } IntegerVectorTypeP :: { (Position, IntegerVectorType) }
: "bit" { TBit } : "bit" { withPos $1 TBit }
| "logic" { TLogic } | "logic" { withPos $1 TLogic }
| "reg" { TReg } | "reg" { withPos $1 TReg }
IntegerAtomType :: { IntegerAtomType } IntegerAtomTypeP :: { (Position, IntegerAtomType) }
: "byte" { TByte } : "byte" { withPos $1 TByte }
| "shortint" { TShortint } | "shortint" { withPos $1 TShortint }
| "int" { TInt } | "int" { withPos $1 TInt }
| "longint" { TLongint } | "longint" { withPos $1 TLongint }
| "integer" { TInteger } | "integer" { withPos $1 TInteger }
| "time" { TTime } | "time" { withPos $1 TTime }
NonIntegerType :: { NonIntegerType } NonIntegerTypeP :: { (Position, NonIntegerType) }
: "shortreal" { TShortreal } : "shortreal" { withPos $1 TShortreal }
| "real" { TReal } | "real" { withPos $1 TReal }
| "realtime" { TRealtime } | "realtime" { withPos $1 TRealtime }
| "string" { TString } | "string" { withPos $1 TString }
| "event" { TEvent } | "event" { withPos $1 TEvent }
EnumItems :: { [(Identifier, Expr)] } EnumItems :: { [(Identifier, Expr)] }
: VariablePortIdentifiers { $1 } : VariablePortIdentifiers { $1 }
...@@ -607,9 +611,11 @@ ModportSimplePort :: { (Identifier, Expr) } ...@@ -607,9 +611,11 @@ ModportSimplePort :: { (Identifier, Expr) }
| Identifier { ($1, Ident $1) } | Identifier { ($1, Ident $1) }
Identifier :: { Identifier } Identifier :: { Identifier }
: simpleIdentifier { tokenString $1 } : IdentifierP { snd $1 }
| escapedIdentifier { tokenString $1 } IdentifierP :: { (Position, Identifier) }
| systemIdentifier { tokenString $1 } : simpleIdentifier { withPos $1 $ tokenString $1 }
| escapedIdentifier { withPos $1 $ tokenString $1 }
| systemIdentifier { withPos $1 $ tokenString $1 }
Identifiers :: { [Identifier] } Identifiers :: { [Identifier] }
: Identifier { [$1] } : Identifier { [$1] }
...@@ -624,48 +630,48 @@ Strength :: { Strength } ...@@ -624,48 +630,48 @@ Strength :: { Strength }
DeclTokens(delim) :: { [DeclToken] } DeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(DeclTokens(delim), delim) { $1 } : DeclTokensBase(DeclTokens(delim), delim) { $1 }
DeclTokensBase(repeat, delim) :: { [DeclToken] } DeclTokensBase(repeat, delim) :: { [DeclToken] }
: DeclToken delim { [$1] } : DeclToken delim { [$1] }
| DeclToken repeat { [$1] ++ $2 } | DeclToken repeat { [$1] ++ $2 }
| Identifier ParamBindings repeat {% posInject \p -> [DTIdent p $1, DTParams p $2] ++ $3 } | IdentifierP ParamBindings repeat { [uncurry DTIdent $1, DTParams (fst $1) $2] ++ $3 }
| DeclTokenAsgn "," repeat {% posInject \p -> [$1, DTComma p] ++ $3 } | DeclTokenAsgn "," repeat { [$1, DTComma (tokenPosition $2)] ++ $3 }
| DeclTokenAsgn delim {% posInject \p -> [$1] } | DeclTokenAsgn delim { [$1] }
DeclToken :: { DeclToken } DeclToken :: { DeclToken }
: "," {% posInject \p -> DTComma p } : "," { DTComma $ tokenPosition $1 }
| "[" "]" {% posInject \p -> DTAutoDim p } | "[" "]" { DTAutoDim $ tokenPosition $1 }
| "const" {% posInject \p -> DTConst p } | "const" { DTConst $ tokenPosition $1 }
| "var" {% posInject \p -> DTVar p } | "var" { DTVar $ tokenPosition $1 }
| PartSelect {% posInject \p -> DTRange p $1 } | PartSelectP { uncurry DTRange $1 }
| Identifier {% posInject \p -> DTIdent p $1 } | IdentifierP { uncurry DTIdent $1 }
| Direction {% posInject \p -> DTDir p $1 } | DirectionP { uncurry DTDir $1 }
| "[" Expr "]" {% posInject \p -> DTBit p $2 } | LHSConcatP { uncurry DTConcat $1 }
| LHSConcat {% posInject \p -> DTConcat p $1 } | PartialTypeP { uncurry DTType $1 }
| PartialType {% posInject \p -> DTType p $1 } | NetTypeP Strength { uncurry DTNet $1 $2 }
| NetType Strength {% posInject \p -> DTNet p $1 $2 } | PortBindingsP { uncurry DTPorts $1 }
| "." Identifier {% posInject \p -> DTDot p $2 } | SigningP { uncurry DTSigning $1 }
| PortBindings {% posInject \p -> DTInstance p $1 } | "[" Expr "]" { DTBit (tokenPosition $1) $2 }
| Signing {% posInject \p -> DTSigning p $1 } | "." Identifier { DTDot (tokenPosition $1) $2 }
| "automatic" {% posInject \p -> DTLifetime p Automatic } | "automatic" { DTLifetime (tokenPosition $1) Automatic }
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) } | "{" StreamOp StreamSize Concat "}" { DTStream (tokenPosition $1) $2 $3 (map toLHS $4) }
| "{" StreamOp Concat "}" {% posInject \p -> DTStream p $2 (RawNum 1) (map toLHS $3) } | "{" StreamOp Concat "}" { DTStream (tokenPosition $1) $2 (RawNum 1) (map toLHS $3) }
| "type" "(" Expr ")" {% posInject \p -> DTType p (\Unspecified -> \[] -> TypeOf $3) } | "type" "(" Expr ")" { uncurry DTType $ makeTypeOf $1 $3 }
| IncOrDecOperator {% posInject \p -> DTAsgn p (AsgnOp $1) Nothing (RawNum 1) } | IncOrDecOperatorP { DTAsgn (fst $1) (AsgnOp $ snd $1) Nothing (RawNum 1) }
| "<=" opt(DelayOrEvent) Expr %prec Asgn {% posInject \p -> DTAsgn p AsgnOpNonBlocking $2 $3 } | "<=" opt(DelayOrEvent) Expr %prec Asgn { DTAsgn (tokenPosition $1) AsgnOpNonBlocking $2 $3 }
| Identifier "::" Identifier {% posInject \p -> DTPSIdent p $1 $3 } | IdentifierP "::" Identifier { uncurry DTPSIdent $1 $3 }
| Identifier ParamBindings "::" Identifier {% posInject \p -> DTCSIdent p $1 $2 $4 } | IdentifierP ParamBindings "::" Identifier { uncurry DTCSIdent $1 $2 $4 }
DeclTokenAsgn :: { DeclToken } DeclTokenAsgn :: { DeclToken }
: "=" opt(DelayOrEvent) Expr {% posInject \p -> DTAsgn p AsgnOpEq $2 $3 } : "=" opt(DelayOrEvent) Expr { DTAsgn (tokenPosition $1) AsgnOpEq $2 $3 }
| AsgnBinOp Expr {% posInject \p -> DTAsgn p $1 Nothing $2 } | AsgnBinOpP Expr { uncurry DTAsgn $1 Nothing $2 }
PortDeclTokens(delim) :: { [DeclToken] } PortDeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(PortDeclTokens(delim), delim) { $1 } : DeclTokensBase(PortDeclTokens(delim), delim) { $1 }
| GenericInterfaceDecl PortDeclTokens(delim) { $1 ++ $2} | GenericInterfaceDecl PortDeclTokens(delim) { $1 ++ $2}
| GenericInterfaceDecl delim { $1 } | GenericInterfaceDecl delim { $1 }
| AttributeInstance PortDeclTokens(delim) {% posInject \p -> DTAttr p $1 : $2 } | AttributeInstanceP PortDeclTokens(delim) { uncurry DTAttr $1 : $2 }
ModuleDeclTokens(delim) :: { [DeclToken] } ModuleDeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(ModuleDeclTokens(delim), delim) { $1 } : DeclTokensBase(ModuleDeclTokens(delim), delim) { $1 }
| GenericInterfaceDecl ModuleDeclTokens(delim) { $1 ++ $2} | GenericInterfaceDecl ModuleDeclTokens(delim) { $1 ++ $2}
| GenericInterfaceDecl delim { $1 } | GenericInterfaceDecl delim { $1 }
GenericInterfaceDecl :: { [DeclToken] } GenericInterfaceDecl :: { [DeclToken] }
: "interface" Identifier {% posInject \p -> [DTType p (\Unspecified -> InterfaceT "" ""), DTIdent p $2] } : "interface" IdentifierP { [DTType (tokenPosition $1) (\Unspecified -> InterfaceT "" ""), uncurry DTIdent $2] }
VariablePortIdentifiers :: { [(Identifier, Expr)] } VariablePortIdentifiers :: { [(Identifier, Expr)] }
: VariablePortIdentifier { [$1] } : VariablePortIdentifier { [$1] }
...@@ -674,9 +680,11 @@ VariablePortIdentifier :: { (Identifier, Expr) } ...@@ -674,9 +680,11 @@ VariablePortIdentifier :: { (Identifier, Expr) }
: Identifier OptAsgn { ($1,$2) } : Identifier OptAsgn { ($1,$2) }
Direction :: { Direction } Direction :: { Direction }
: "inout" { Inout } : DirectionP { snd $1 }
| "input" { Input } DirectionP :: { (Position, Direction) }
| "output" { Output } : "inout" { (tokenPosition $1, Inout ) }
| "input" { (tokenPosition $1, Input ) }
| "output" { (tokenPosition $1, Output) }
ModuleItems :: { [ModuleItem] } ModuleItems :: { [ModuleItem] }
: {- empty -} { [] } : {- empty -} { [] }
...@@ -778,7 +786,9 @@ AttributeInstances :: { [Attr] } ...@@ -778,7 +786,9 @@ AttributeInstances :: { [Attr] }
: {- empty -} { [] } : {- empty -} { [] }
| AttributeInstance AttributeInstances { $1 : $2 } | AttributeInstance AttributeInstances { $1 : $2 }
AttributeInstance :: { Attr } AttributeInstance :: { Attr }
: "(*" AttrSpecs "*)" { Attr $2 } : AttributeInstanceP { snd $1 }
AttributeInstanceP :: { (Position, Attr) }
: "(*" AttrSpecs "*)" { withPos $1 $ Attr $2 }
AttrSpecs :: { [AttrSpec] } AttrSpecs :: { [AttrSpec] }
: AttrSpec { [$1] } : AttrSpec { [$1] }
| AttrSpecs "," AttrSpec { $1 ++ [$3] } | AttrSpecs "," AttrSpec { $1 ++ [$3] }
...@@ -910,7 +920,7 @@ Drive :: { String } ...@@ -910,7 +920,7 @@ Drive :: { String }
: "pull0" { tokenString $1 } : "pull0" { tokenString $1 }
| "pull1" { tokenString $1 } | "pull1" { tokenString $1 }
DefaultNetType :: { String } DefaultNetType :: { String }
: NetType { show $1 } : NetTypeP { show $ snd $1 }
| Identifier { $1 } | Identifier { $1 }
PackageImportItems :: { [(Identifier, Identifier)] } PackageImportItems :: { [(Identifier, Identifier)] }
...@@ -969,28 +979,28 @@ DeclAsgn :: { (Identifier, Expr, [Range]) } ...@@ -969,28 +979,28 @@ DeclAsgn :: { (Identifier, Expr, [Range]) }
Range :: { Range } Range :: { Range }
: "[" Expr ":" Expr "]" { ($2, $4) } : "[" Expr ":" Expr "]" { ($2, $4) }
PartSelect :: { (PartSelectMode, Range) } PartSelectP :: { (Position, (PartSelectMode, Range)) }
: "[" Expr ":" Expr "]" { (NonIndexed , ($2, $4)) } : "[" Expr ":" Expr "]" { (tokenPosition $1, (NonIndexed , ($2, $4))) }
| "[" Expr "+:" Expr "]" { (IndexedPlus , ($2, $4)) } | "[" Expr "+:" Expr "]" { (tokenPosition $1, (IndexedPlus , ($2, $4))) }
| "[" Expr "-:" Expr "]" { (IndexedMinus, ($2, $4)) } | "[" Expr "-:" Expr "]" { (tokenPosition $1, (IndexedMinus, ($2, $4))) }
LHS :: { LHS } LHS :: { LHS }
: Identifier { LHSIdent $1 } : Identifier { LHSIdent $1 }
| LHS PartSelect { LHSRange $1 (fst $2) (snd $2) } | LHS PartSelectP { uncurry (LHSRange $1) (snd $2) }
| LHS "[" Expr "]" { LHSBit $1 $3 } | LHS "[" Expr "]" { LHSBit $1 $3 }
| LHS "." Identifier { LHSDot $1 $3 } | LHS "." Identifier { LHSDot $1 $3 }
| LHSConcat { LHSConcat $1 } | LHSConcatP { LHSConcat $ snd $1 }
| "{" StreamOp StreamSize Concat "}" { LHSStream $2 $3 (map toLHS $4) } | "{" StreamOp StreamSize Concat "}" { LHSStream $2 $3 (map toLHS $4) }
| "{" StreamOp Concat "}" { LHSStream $2 (RawNum 1) (map toLHS $3) } | "{" StreamOp Concat "}" { LHSStream $2 (RawNum 1) (map toLHS $3) }
LHSConcat :: { [LHS] } LHSConcatP :: { (Position, [LHS]) }
: "{" LHSs "}" { $2 } : "{" LHSs "}" { withPos $1 $2 }
LHSs :: { [LHS] } LHSs :: { [LHS] }
: LHS { [$1] } : LHS { [$1] }
| LHSs "," LHS { $1 ++ [$3] } | LHSs "," LHS { $1 ++ [$3] }
PortBindings :: { [PortBinding] } PortBindingsP:: { (Position, [PortBinding]) }
: "(" PortBindingsInside ")" {% checkPortBindings $2 } : "(" PortBindingsInside ")" {% checkPortBindings $2 >>= return . withPos $1 }
PortBindingsInside :: { [PortBinding] } PortBindingsInside :: { [PortBinding] }
: OptPortBinding { [$1] } : OptPortBinding { [$1] }
| OptPortBinding "," PortBindingsInside { $1 : $3} | OptPortBinding "," PortBindingsInside { $1 : $3}
...@@ -1246,7 +1256,7 @@ Expr :: { Expr } ...@@ -1246,7 +1256,7 @@ Expr :: { Expr }
| DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 } | DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 }
| DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (RawNum 1) } | DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (RawNum 1) }
| DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 } | DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 }
| Expr PartSelect { Range $1 (fst $2) (snd $2) } | Expr PartSelectP { uncurry (Range $1) (snd $2) }
| Expr "[" Expr "]" { Bit $1 $3 } | Expr "[" Expr "]" { Bit $1 $3 }
| "{" Expr Concat "}" { Repeat $2 $3 } | "{" Expr Concat "}" { Repeat $2 $3 }
| Concat { Concat $1 } | Concat { Concat $1 }
...@@ -1386,22 +1396,26 @@ AsgnOp :: { AsgnOp } ...@@ -1386,22 +1396,26 @@ AsgnOp :: { AsgnOp }
: "=" { AsgnOpEq } : "=" { AsgnOpEq }
| AsgnBinOp { $1 } | AsgnBinOp { $1 }
AsgnBinOp :: { AsgnOp } AsgnBinOp :: { AsgnOp }
: "+=" { AsgnOp Add } : AsgnBinOpP { snd $1 }
| "-=" { AsgnOp Sub } AsgnBinOpP :: { (Position, AsgnOp) }
| "*=" { AsgnOp Mul } : "+=" { withPos $1 $ AsgnOp Add }
| "/=" { AsgnOp Div } | "-=" { withPos $1 $ AsgnOp Sub }
| "%=" { AsgnOp Mod } | "*=" { withPos $1 $ AsgnOp Mul }
| "&=" { AsgnOp BitAnd } | "/=" { withPos $1 $ AsgnOp Div }
| "|=" { AsgnOp BitOr } | "%=" { withPos $1 $ AsgnOp Mod }
| "^=" { AsgnOp BitXor } | "&=" { withPos $1 $ AsgnOp BitAnd }
| "<<=" { AsgnOp ShiftL } | "|=" { withPos $1 $ AsgnOp BitOr }
| ">>=" { AsgnOp ShiftR } | "^=" { withPos $1 $ AsgnOp BitXor }
| "<<<=" { AsgnOp ShiftAL } | "<<=" { withPos $1 $ AsgnOp ShiftL }
| ">>>=" { AsgnOp ShiftAR } | ">>=" { withPos $1 $ AsgnOp ShiftR }
| "<<<=" { withPos $1 $ AsgnOp ShiftAL }
| ">>>=" { withPos $1 $ AsgnOp ShiftAR }
IncOrDecOperator :: { BinOp } IncOrDecOperator :: { BinOp }
: "++" { Add } : IncOrDecOperatorP { snd $1 }
| "--" { Sub } IncOrDecOperatorP :: { (Position, BinOp) }
: "++" { withPos $1 Add }
| "--" { withPos $1 Sub }
DimsFn :: { DimsFn } DimsFn :: { DimsFn }
: "$bits" { FnBits } : "$bits" { FnBits }
...@@ -1455,11 +1469,6 @@ parse tokens = ...@@ -1455,11 +1469,6 @@ parse tokens =
position = tokenPosition $ head tokens position = tokenPosition $ head tokens
initialState = ParseData position tokens initialState = ParseData position tokens
posInject :: (Position -> a) -> ParseState a
posInject cont = do
pos <- gets pPosition
return $ cont pos
positionKeep :: (Token -> ParseState a) -> ParseState a positionKeep :: (Token -> ParseState a) -> ParseState a
positionKeep cont = do positionKeep cont = do
tokens <- gets pTokens tokens <- gets pTokens
...@@ -1469,13 +1478,19 @@ positionKeep cont = do ...@@ -1469,13 +1478,19 @@ positionKeep cont = do
put $ ParseData (tokenPosition tok) toks put $ ParseData (tokenPosition tok) toks
cont tok cont tok
parseError :: Token -> ParseState a parseErrorTok :: Token -> ParseState a
parseError a = case a of parseErrorTok a = case a of
TokenEOF -> do TokenEOF -> do
p <- gets pPosition p <- gets pPosition
throwError $ show p ++ ": Parse error: unexpected end of file." parseErrorM p "unexpected end of file"
Token t s p -> throwError $ show p ++ ": Parse error: unexpected token '" Token t s p ->
++ s ++ "' (" ++ show t ++ ")." parseErrorM p $ "unexpected token '" ++ s ++ "' (" ++ show t ++ ")"
parseErrorM :: Position -> String -> ParseState a
parseErrorM pos msg = throwError $ show pos ++ ": Parse error: " ++ msg
parseError :: Position -> String -> a
parseError pos msg = error $ show pos ++ ": Parse error: " ++ msg
genItemsToGenItem :: [GenItem] -> GenItem genItemsToGenItem :: [GenItem] -> GenItem
genItemsToGenItem [x] = x genItemsToGenItem [x] = x
...@@ -1487,8 +1502,8 @@ combineDeclsAndStmts (a1, b1) (a2, b2) = ...@@ -1487,8 +1502,8 @@ combineDeclsAndStmts (a1, b1) (a2, b2) =
if not (null b1) && not (null a2) if not (null b1) && not (null a2)
then do then do
p <- gets pPosition p <- gets pPosition
throwError $ show p parseErrorM p
++ ": Parse error: procedural block contains a declaration after a statement" "procedural block contains a declaration after a statement"
else return (a1 ++ a2, b1 ++ b2) else return (a1 ++ a2, b1 ++ b2)
makeInput :: Decl -> Decl makeInput :: Decl -> Decl
...@@ -1502,13 +1517,13 @@ checkTag :: String -> String -> a -> ParseState a ...@@ -1502,13 +1517,13 @@ checkTag :: String -> String -> a -> ParseState a
checkTag _ "" x = return x checkTag _ "" x = return x
checkTag "" b _ = do checkTag "" b _ = do
p <- gets pPosition p <- gets pPosition
error $ show p ++ ": Parse error: block has only end label " ++ show b parseErrorM p $ "block has only end label " ++ show b
checkTag a b x = checkTag a b x =
if a == b if a == b
then return x then return x
else do else do
p <- gets pPosition p <- gets pPosition
error $ show p ++ ": Parse error: element " ++ show a parseErrorM p $ "element " ++ show a
++ " has mismatched end label " ++ show b ++ " has mismatched end label " ++ show b
toLHS :: Expr -> LHS toLHS :: Expr -> LHS
...@@ -1538,14 +1553,12 @@ validateCases :: Token -> [([Expr], a)] -> [([Expr], a)] ...@@ -1538,14 +1553,12 @@ validateCases :: Token -> [([Expr], a)] -> [([Expr], a)]
validateCases tok items = validateCases tok items =
if length (filter (null . fst) items) <= 1 if length (filter (null . fst) items) <= 1
then items then items
else error $ show (tokenPosition tok) else parseError (tokenPosition tok) "case has multiple defaults"
++ ": Parse error: case has multiple defaults"
caseInsideKW :: Token -> CaseKW -> CaseKW caseInsideKW :: Token -> CaseKW -> CaseKW
caseInsideKW _ CaseN = CaseInside caseInsideKW _ CaseN = CaseInside
caseInsideKW tok kw = caseInsideKW tok kw =
error $ show (tokenPosition tok) parseError (tokenPosition tok) $ "cannot use inside with " ++ show kw
++ ": Parse error: cannot use inside with " ++ show kw
addMIAttr :: Attr -> ModuleItem -> ModuleItem addMIAttr :: Attr -> ModuleItem -> ModuleItem
addMIAttr _ (item @ (MIPackageItem (Decl CommentDecl{}))) = item addMIAttr _ (item @ (MIPackageItem (Decl CommentDecl{}))) = item
...@@ -1554,7 +1567,7 @@ addMIAttr attr item = MIAttr attr item ...@@ -1554,7 +1567,7 @@ addMIAttr attr item = MIAttr attr item
missingToken :: String -> ParseState a missingToken :: String -> ParseState a
missingToken expected = do missingToken expected = do
p <- gets pPosition p <- gets pPosition
throwError $ show p ++ ": Parse error: missing expected `" ++ expected ++ "`" parseErrorM p $ "missing expected `" ++ expected ++ "`"
checkPortBindings :: [PortBinding] -> ParseState [PortBinding] checkPortBindings :: [PortBinding] -> ParseState [PortBinding]
checkPortBindings [] = return [] checkPortBindings [] = return []
...@@ -1573,7 +1586,46 @@ checkBindings kind bindings = ...@@ -1573,7 +1586,46 @@ checkBindings kind bindings =
return bindings return bindings
else do else do
p <- gets pPosition p <- gets pPosition
error $ show p ++ ": Parse error: illegal mix of ordered and named " ++ kind parseErrorM p $ "illegal mix of ordered and named " ++ kind
where bindingNames = map fst bindings where bindingNames = map fst bindings
withPos :: Token -> a -> (Position, a)
withPos tok = (tokenPosition tok, )
type PartialType = Signing -> [Range] -> Type
unexpectedPackedRanges :: Position -> String -> a
unexpectedPackedRanges pos typ =
parseError pos $ "unexpected packed range(s) applied to " ++ typ
unexpectedSigning :: Position -> Signing -> String -> a
unexpectedSigning pos sg typ =
parseError pos $ "unexpected " ++ show sg ++ " applied to " ++ typ
makeIntegerVector :: (Position, IntegerVectorType) -> PartialType
makeIntegerVector (_, typ) = IntegerVector typ
makeIntegerAtom :: (Position, IntegerAtomType) -> PartialType
makeIntegerAtom (_, typ) sg [] = IntegerAtom typ sg
makeIntegerAtom (pos, typ) _ _ = unexpectedPackedRanges pos (show typ)
makeNonInteger :: (Position, NonIntegerType) -> PartialType
makeNonInteger (_, typ) Unspecified [] = NonInteger typ
makeNonInteger (pos, typ) sg [] = unexpectedSigning pos sg (show typ)
makeNonInteger (pos, typ) Unspecified _ = unexpectedPackedRanges pos (show typ)
makeComplex :: Token -> ([Range] -> Type) -> (Position, PartialType)
makeComplex (Token _ str pos) tf = (pos, check)
where
check Unspecified = tf
check sg = unexpectedSigning pos sg str
makeTypeOf :: Token -> Expr -> (Position, PartialType)
makeTypeOf (Token _ _ pos) expr = (pos, check)
where
typ = TypeOf expr
check Unspecified [] = typ
check Unspecified _ = unexpectedPackedRanges pos (show typ)
check sg [] = unexpectedSigning pos sg (show typ)
} }
...@@ -45,7 +45,7 @@ module Language.SystemVerilog.Parser.ParseDecl ...@@ -45,7 +45,7 @@ module Language.SystemVerilog.Parser.ParseDecl
, parseDTsAsDeclsOrAsgns , parseDTsAsDeclsOrAsgns
) where ) where
import Data.List (findIndex, findIndices, partition) import Data.List (findIndex, findIndices, partition, uncons)
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
import Language.SystemVerilog.Parser.Tokens (Position(..)) import Language.SystemVerilog.Parser.Tokens (Position(..))
...@@ -65,7 +65,7 @@ data DeclToken ...@@ -65,7 +65,7 @@ data DeclToken
| DTType Position (Signing -> [Range] -> Type) | DTType Position (Signing -> [Range] -> Type)
| DTNet Position NetType Strength | DTNet Position NetType Strength
| DTParams Position [ParamBinding] | DTParams Position [ParamBinding]
| DTInstance Position [PortBinding] | DTPorts Position [PortBinding]
| DTBit Position Expr | DTBit Position Expr
| DTConcat Position [LHS] | DTConcat Position [LHS]
| DTStream Position StreamOp Expr [LHS] | DTStream Position StreamOp Expr [LHS]
...@@ -79,15 +79,17 @@ data DeclToken ...@@ -79,15 +79,17 @@ data DeclToken
-- a non-blocking operator, binary assignment operator, or a timing control -- a non-blocking operator, binary assignment operator, or a timing control
-- because we don't expect to see those assignment operators in declarations -- because we don't expect to see those assignment operators in declarations
forbidNonEqAsgn :: [DeclToken] -> a -> a forbidNonEqAsgn :: [DeclToken] -> a -> a
forbidNonEqAsgn tokens = forbidNonEqAsgn [] = id
if any isNonEqAsgn tokens forbidNonEqAsgn (tok @ (DTAsgn _ op mt _) : toks) =
then error $ "decl tokens contain bad assignment operator: " ++ show tokens if op /= AsgnOpEq then
else id parseError tok $ "unexpected " ++ opKind
where ++ " assignment operator in declaration"
isNonEqAsgn :: DeclToken -> Bool else if mt /= Nothing then
isNonEqAsgn (DTAsgn _ op mt _) = parseError tok "unexpected timing modifier in declaration"
op /= AsgnOpEq || mt /= Nothing else
isNonEqAsgn _ = False forbidNonEqAsgn toks
where opKind = if op == AsgnOpNonBlocking then "non-blocking" else "binary"
forbidNonEqAsgn (_ : toks) = forbidNonEqAsgn toks
-- [PUBLIC]: parser for module port declarations, including interface ports -- [PUBLIC]: parser for module port declarations, including interface ports
...@@ -102,7 +104,7 @@ parseDTsAsPortDecls pieces = ...@@ -102,7 +104,7 @@ parseDTsAsPortDecls pieces =
-- internal parseDTsAsPortDecls after the removal of an optional trailing comma -- internal parseDTsAsPortDecls after the removal of an optional trailing comma
parseDTsAsPortDecls' :: [DeclToken] -> ([Identifier], [ModuleItem]) parseDTsAsPortDecls' :: [DeclToken] -> ([Identifier], [ModuleItem])
parseDTsAsPortDecls' pieces = parseDTsAsPortDecls' pieces =
forbidNonEqAsgn pieces $ forbidNonEqAsgn pieces `seq`
if isSimpleList if isSimpleList
then (simpleIdents, []) then (simpleIdents, [])
else (portNames declarations, applyAttrs [] pieces declarations) else (portNames declarations, applyAttrs [] pieces declarations)
...@@ -173,10 +175,10 @@ parseDTsAsPortDecls' pieces = ...@@ -173,10 +175,10 @@ parseDTsAsPortDecls' pieces =
-- parameters) and module instantiations -- parameters) and module instantiations
parseDTsAsModuleItems :: [DeclToken] -> [ModuleItem] parseDTsAsModuleItems :: [DeclToken] -> [ModuleItem]
parseDTsAsModuleItems tokens = parseDTsAsModuleItems tokens =
forbidNonEqAsgn tokens $ forbidNonEqAsgn tokens `seq`
if isElabTask $ head tokens then if isElabTask $ head tokens then
asElabTask tokens asElabTask tokens
else if any isInstance tokens then else if any isPorts tokens then
parseDTsAsIntantiations tokens parseDTsAsIntantiations tokens
else else
map (MIPackageItem . Decl) $ parseDTsAsDecl tokens map (MIPackageItem . Decl) $ parseDTsAsDecl tokens
...@@ -185,80 +187,89 @@ parseDTsAsModuleItems tokens = ...@@ -185,80 +187,89 @@ parseDTsAsModuleItems tokens =
isElabTask (DTIdent _ x) = elem x elabTasks isElabTask (DTIdent _ x) = elem x elabTasks
where elabTasks = ["$fatal", "$error", "$warning", "$info"] where elabTasks = ["$fatal", "$error", "$warning", "$info"]
isElabTask _ = False isElabTask _ = False
isInstance :: DeclToken -> Bool
isInstance (DTInstance{}) = True
isInstance _ = False
-- internal; approximates the behavior of the elaboration system tasks -- internal; approximates the behavior of the elaboration system tasks
asElabTask :: [DeclToken] -> [ModuleItem] asElabTask :: [DeclToken] -> [ModuleItem]
asElabTask [DTIdent _ name, DTInstance _ args] = asElabTask [DTIdent _ name, DTPorts _ args] =
if name == "$info" if name == "$info"
then [] -- just drop them for simplicity then [] -- just drop them for simplicity
else [Instance "ThisModuleDoesNotExist" [] name' [] args] else [Instance "ThisModuleDoesNotExist" [] name' [] args]
where name' = "__sv2v_elab_" ++ tail name where name' = "__sv2v_elab_" ++ tail name
asElabTask [DTIdent pos name] = asElabTask [DTIdent pos name] =
asElabTask [DTIdent pos name, DTInstance pos []] asElabTask [DTIdent pos name, DTPorts pos []]
asElabTask tokens = asElabTask tokens =
error $ "could not parse elaboration system task: " ++ show tokens error $ "could not parse elaboration system task: " ++ show tokens
-- internal; parser for module instantiations -- internal; parser for module instantiations
parseDTsAsIntantiations :: [DeclToken] -> [ModuleItem] parseDTsAsIntantiations :: [DeclToken] -> [ModuleItem]
parseDTsAsIntantiations (DTIdent _ name : tokens) = parseDTsAsIntantiations (DTIdent _ name : DTParams _ params : tokens) =
if not (all isInstanceToken rest) step tokens
then error $ "instantiations mixed with other items: " ++ (show rest)
else step rest
where where
step :: [DeclToken] -> [ModuleItem] step :: [DeclToken] -> [ModuleItem]
step [] = error $ "unexpected end of instantiation list: " ++ (show tokens) step [] = parseError endTok "unexpected end of instantiation list"
step toks = step toks = inst : rest
case (init inst, last inst) of
(DTIdent _ x : ranges, DTInstance _ p) ->
Instance name params x rs p : follow
where rs = map asRange ranges
_ -> failure
where where
(inst, toks') = span (not . isComma) toks (delimTok, rest) =
follow = if null toks' then [] else step (tail toks') if null restToks
asRange :: DeclToken -> Range then (endTok, [])
asRange (DTRange _ (NonIndexed, s)) = s else (head restToks, step $ tail restToks)
asRange (DTBit _ s) = (RawNum 0, BinOp Sub s (RawNum 1)) inst = Instance name params x rs p
asRange _ = failure (x, rs, p) = parseDTsAsIntantiation instToks delimTok
failure = error $ "unrecognized instantiation of " ++ name (instToks, restToks) = break isComma toks
++ ": " ++ show inst -- TODO: all public interfaces should take the ending token
(params, rest) = endTok = last tokens
case head tokens of parseDTsAsIntantiations (DTIdent pos name : tokens) =
DTParams _ ps -> (ps, tail tokens) parseDTsAsIntantiations $ DTIdent pos name : DTParams pos [] : tokens
_ -> ([], tokens)
isInstanceToken :: DeclToken -> Bool
isInstanceToken (DTInstance{}) = True
isInstanceToken (DTRange{}) = True
isInstanceToken (DTBit{}) = True
isInstanceToken (DTIdent{}) = True
isInstanceToken (DTComma{}) = True
isInstanceToken _ = False
parseDTsAsIntantiations tokens = parseDTsAsIntantiations tokens =
error $ parseError (head tokens)
"DeclTokens contain instantiations, but start with non-ident: " "expected module or interface name at beginning of instantiation list"
++ (show tokens)
-- internal; parser for an individual instantiations
parseDTsAsIntantiation :: [DeclToken] -> DeclToken
-> (Identifier, [Range], [PortBinding])
parseDTsAsIntantiation l0 delimTok =
if null l0 then
parseError delimTok "expected instantiation before delimiter"
else if not (isIdent nameTok) then
parseError nameTok "expected instantiation name"
else if null l1 then
parseError delimTok "expected port connections before delimiter"
else if seq ranges not (isPorts portsTok) then
parseError portsTok "expected port connections"
else
(name, ranges, ports)
where
Just (nameTok, l1) = uncons l0
rangeToks = init l1
portsTok = last l1
DTIdent _ name = nameTok
DTPorts _ ports = portsTok
ranges = map asRange rangeToks
asRange :: DeclToken -> Range
asRange (DTRange _ (NonIndexed, s)) = s
asRange (DTBit _ s) = (RawNum 0, BinOp Sub s (RawNum 1))
asRange tok = parseError tok "expected instantiation dimensions"
-- [PUBLIC]: parser for generic, comma-separated declarations -- [PUBLIC]: parser for generic, comma-separated declarations
parseDTsAsDecls :: [DeclToken] -> [Decl] parseDTsAsDecls :: [DeclToken] -> [Decl]
parseDTsAsDecls tokens = parseDTsAsDecls tokens =
forbidNonEqAsgn tokens $ forbidNonEqAsgn tokens `seq`
concat $ map finalize $ parseDTsAsComponents tokens concat $ map finalize $ parseDTsAsComponents tokens
-- [PUBLIC]: used for "single" declarations, i.e., declarations appearing -- internal; used for "single" declarations, i.e., declarations appearing
-- outside of a port list -- outside of a port list
parseDTsAsDecl :: [DeclToken] -> [Decl] parseDTsAsDecl :: [DeclToken] -> [Decl]
parseDTsAsDecl tokens = parseDTsAsDecl tokens =
forbidNonEqAsgn tokens $
if length components /= 1 if length components /= 1
then error $ "too many declarations: " ++ (show tokens) then parseError tok $ "unexpected comma-separated declarations"
else finalize $ head components else finalize $ head components
where components = parseDTsAsComponents tokens where
components = parseDTsAsComponents tokens
_ : (pos, _, _) : _ = components
tok = DTComma pos
-- [PUBLIC]: parser for single block item declarations or assign or arg-less -- [PUBLIC]: parser for single block item declarations or assign or arg-less
...@@ -274,7 +285,7 @@ parseDTsAsDeclOrStmt tokens = ...@@ -274,7 +285,7 @@ parseDTsAsDeclOrStmt tokens =
pos = tokPos $ last tokens pos = tokPos $ last tokens
stmt = case last tokens of stmt = case last tokens of
DTAsgn _ op mt e -> Asgn op mt lhs e DTAsgn _ op mt e -> Asgn op mt lhs e
DTInstance _ args -> asSubroutine lhsToks (instanceToArgs args) DTPorts _ ports -> asSubroutine lhsToks (portsToArgs ports)
_ -> asSubroutine tokens (Args [] []) _ -> asSubroutine tokens (Args [] [])
lhsToks = init tokens lhsToks = init tokens
lhs = case takeLHS lhsToks of lhs = case takeLHS lhsToks of
...@@ -301,8 +312,8 @@ asSubroutine tokens = ...@@ -301,8 +312,8 @@ asSubroutine tokens =
Nothing -> error $ "invalid block item decl or stmt: " ++ show tokens Nothing -> error $ "invalid block item decl or stmt: " ++ show tokens
-- converts port bindings to call args -- converts port bindings to call args
instanceToArgs :: [PortBinding] -> Args portsToArgs :: [PortBinding] -> Args
instanceToArgs bindings = portsToArgs bindings =
Args pnArgs kwArgs Args pnArgs kwArgs
where where
(pnBindings, kwBindings) = partition (null . fst) bindings (pnBindings, kwBindings) = partition (null . fst) bindings
...@@ -313,7 +324,7 @@ instanceToArgs bindings = ...@@ -313,7 +324,7 @@ instanceToArgs bindings =
-- is only used for `for` loop initialization lists -- is only used for `for` loop initialization lists
parseDTsAsDeclsOrAsgns :: [DeclToken] -> Either [Decl] [(LHS, Expr)] parseDTsAsDeclsOrAsgns :: [DeclToken] -> Either [Decl] [(LHS, Expr)]
parseDTsAsDeclsOrAsgns tokens = parseDTsAsDeclsOrAsgns tokens =
forbidNonEqAsgn tokens $ forbidNonEqAsgn tokens `seq`
if hasLeadingAsgn || tripLookahead tokens if hasLeadingAsgn || tripLookahead tokens
then Right $ parseDTsAsAsgns tokens then Right $ parseDTsAsAsgns tokens
else Left $ map checkDecl $ parseDTsAsDecls tokens else Left $ map checkDecl $ parseDTsAsDecls tokens
...@@ -376,24 +387,23 @@ takeLHSStep _ _ = Nothing ...@@ -376,24 +387,23 @@ takeLHSStep _ _ = Nothing
-- batches together separate declaration lists -- batches together separate declaration lists
type DeclBase = Direction -> Identifier -> [Range] -> Expr -> Decl type DeclBase = Identifier -> [Range] -> Expr -> Decl
type Triplet = (Identifier, [Range], Expr) type Triplet = (Identifier, [Range], Expr)
type Component = (Direction, DeclBase, [Triplet]) type Component = (Position, DeclBase, [Triplet])
finalize :: (Position, Component) -> [Decl] finalize :: Component -> [Decl]
finalize (pos, (dir, base, trips)) = finalize (pos, base, trips) =
CommentDecl ("Trace: " ++ show pos) : CommentDecl ("Trace: " ++ show pos) :
map (\(x, a, e) -> base dir x a e) trips map (\(x, a, e) -> base x a e) trips
-- internal; entrypoint of the critical portion of our parser -- internal; entrypoint of the critical portion of our parser
parseDTsAsComponents :: [DeclToken] -> [(Position, Component)] parseDTsAsComponents :: [DeclToken] -> [Component]
parseDTsAsComponents [] = [] parseDTsAsComponents [] = []
parseDTsAsComponents tokens = parseDTsAsComponents tokens =
(position, component) : parseDTsAsComponents tokens' component : parseDTsAsComponents tokens'
where where (component, tokens') = parseDTsAsComponent tokens
(position, component, tokens') = parseDTsAsComponent tokens
parseDTsAsComponent :: [DeclToken] -> (Position, Component, [DeclToken]) parseDTsAsComponent :: [DeclToken] -> (Component, [DeclToken])
parseDTsAsComponent [] = error "parseDTsAsComponent unexpected end of tokens" parseDTsAsComponent [] = error "parseDTsAsComponent unexpected end of tokens"
parseDTsAsComponent l0 = parseDTsAsComponent l0 =
if l /= Nothing && l /= Just Automatic then if l /= Nothing && l /= Just Automatic then
...@@ -402,7 +412,7 @@ parseDTsAsComponent l0 = ...@@ -402,7 +412,7 @@ parseDTsAsComponent l0 =
error $ "declaration(s) missing type information: " error $ "declaration(s) missing type information: "
++ show (position, tps) ++ show (position, tps)
else else
(position, component, l6) (component, l6)
where where
(dir, l1) = takeDir l0 (dir, l1) = takeDir l0
(l , l2) = takeLifetime l1 (l , l2) = takeLifetime l1
...@@ -410,8 +420,9 @@ parseDTsAsComponent l0 = ...@@ -410,8 +420,9 @@ parseDTsAsComponent l0 =
(tf , l4) = takeType l3 (tf , l4) = takeType l3
(rs , l5) = takeRanges l4 (rs , l5) = takeRanges l4
(tps, l6) = takeTrips l5 True (tps, l6) = takeTrips l5 True
component = (dir, von $ tf rs, tps)
position = tokPos $ head l0 position = tokPos $ head l0
base = von dir $ tf rs
component = (position, base, tps)
takeTrips :: [DeclToken] -> Bool -> ([Triplet], [DeclToken]) takeTrips :: [DeclToken] -> Bool -> ([Triplet], [DeclToken])
takeTrips [] True = error "incomplete declaration" takeTrips [] True = error "incomplete declaration"
...@@ -461,12 +472,12 @@ takeLifetime :: [DeclToken] -> (Maybe Lifetime, [DeclToken]) ...@@ -461,12 +472,12 @@ takeLifetime :: [DeclToken] -> (Maybe Lifetime, [DeclToken])
takeLifetime (DTLifetime _ l : rest) = (Just l, rest) takeLifetime (DTLifetime _ l : rest) = (Just l, rest)
takeLifetime rest = (Nothing, rest) takeLifetime rest = (Nothing, rest)
takeVarOrNet :: [DeclToken] -> (Type -> DeclBase, [DeclToken]) takeVarOrNet :: [DeclToken] -> (Direction -> Type -> DeclBase, [DeclToken])
takeVarOrNet (DTConst _ : DTConst pos : _) = takeVarOrNet (DTConst{} : tok @ DTConst{} : _) =
error $ "unexpected const after const at " ++ show pos parseError tok "duplicate const modifier"
takeVarOrNet (DTConst _ : tokens) = takeVarOrNet tokens takeVarOrNet (DTConst _ : tokens) = takeVarOrNet tokens
takeVarOrNet (DTNet _ n s : tokens) = (\t d -> Net d n s t, tokens) takeVarOrNet (DTNet _ n s : tokens) = (\d -> Net d n s, tokens)
takeVarOrNet tokens = (flip Variable, tokens) takeVarOrNet tokens = (Variable, tokens)
takeType :: [DeclToken] -> ([Range] -> Type, [DeclToken]) takeType :: [DeclToken] -> ([Range] -> Type, [DeclToken])
takeType (DTIdent _ a : DTDot _ b : rest) = (InterfaceT a b , rest) takeType (DTIdent _ a : DTDot _ b : rest) = (InterfaceT a b , rest)
...@@ -488,8 +499,8 @@ takeType (DTIdent pos tn : rest) = ...@@ -488,8 +499,8 @@ takeType (DTIdent pos tn : rest) =
(_, Nothing) -> True (_, Nothing) -> True
-- if comma is first, then this ident is a declaration -- if comma is first, then this ident is a declaration
(Just a, Just b) -> a < b (Just a, Just b) -> a < b
takeType (DTVar _ : DTVar pos : _) = takeType (DTVar{} : tok @ DTVar{} : _) =
error $ "unexpected var after var at " ++ show pos parseError tok "duplicate var modifier"
takeType (DTVar _ : rest) = takeType (DTVar _ : rest) =
case tf [] of case tf [] of
Implicit sg [] -> (IntegerVector TLogic sg, rest') Implicit sg [] -> (IntegerVector TLogic sg, rest')
...@@ -549,6 +560,10 @@ isComma :: DeclToken -> Bool ...@@ -549,6 +560,10 @@ isComma :: DeclToken -> Bool
isComma (DTComma{}) = True isComma (DTComma{}) = True
isComma _ = False isComma _ = False
isPorts :: DeclToken -> Bool
isPorts DTPorts{} = True
isPorts _ = False
tokPos :: DeclToken -> Position tokPos :: DeclToken -> Position
tokPos (DTComma p) = p tokPos (DTComma p) = p
tokPos (DTAutoDim p) = p tokPos (DTAutoDim p) = p
...@@ -563,7 +578,7 @@ tokPos (DTDir p _) = p ...@@ -563,7 +578,7 @@ tokPos (DTDir p _) = p
tokPos (DTType p _) = p tokPos (DTType p _) = p
tokPos (DTNet p _ _) = p tokPos (DTNet p _ _) = p
tokPos (DTParams p _) = p tokPos (DTParams p _) = p
tokPos (DTInstance p _) = p tokPos (DTPorts p _) = p
tokPos (DTBit p _) = p tokPos (DTBit p _) = p
tokPos (DTConcat p _) = p tokPos (DTConcat p _) = p
tokPos (DTStream p _ _ _) = p tokPos (DTStream p _ _ _) = p
...@@ -571,3 +586,7 @@ tokPos (DTDot p _) = p ...@@ -571,3 +586,7 @@ tokPos (DTDot p _) = p
tokPos (DTSigning p _) = p tokPos (DTSigning p _) = p
tokPos (DTLifetime p _) = p tokPos (DTLifetime p _) = p
tokPos (DTAttr p _) = p tokPos (DTAttr p _) = p
parseError :: DeclToken -> String -> a
parseError tok msg = error $ show pos ++ ": Parse error: " ++ msg
where pos = tokPos tok
// pattern: unexpected packed range\(s\) applied to byte
module top;
byte [1:0] x;
endmodule
// pattern: const_const\.sv:3:11: Parse error: duplicate const modifier
module top;
const const logic x = 1'b1;
endmodule
// pattern: decl_binop_asgn\.sv:3:13: Parse error: unexpected binary assignment operator in declaration
module top;
logic x += 1;
endmodule
// pattern: decl_delay_asgn\.sv:3:13: Parse error: unexpected timing modifier in declaration
module top;
logic x = #1 1;
endmodule
// pattern: decl_delay_asgn_init\.sv:4:24: Parse error: unexpected timing modifier in declaration
module top;
initial
for (integer x = #1 1; 1; x++)
$display("Hi!");
endmodule
// pattern: decl_delay_asgn_package\.sv:3:13: Parse error: unexpected timing modifier in declaration
package P;
logic x = #1 1;
endpackage
module top;
import P::*;
endmodule
// pattern: decl_delay_asgn_port\.sv:3:14: Parse error: unexpected timing modifier in declaration
module top(
output x = #1 1
);
endmodule
// pattern: decl_non_blocking_asgn\.sv:3:13: Parse error: unexpected non-blocking assignment operator in declaration
module top;
logic x <= 1;
endmodule
// pattern: unexpected signed applied to enum
module top;
enum {
A, B
} signed x;
endmodule
// pattern: instantiation_extra_comma\.sv:3:18: Parse error: expected instantiation before delimiter
module top;
example a(), , b();
endmodule
// pattern: instantiation_missing_ports\.sv:3:14: Parse error: expected port connections before delimiter
module top;
example a, c();
endmodule
// pattern: instantiation_no_label\.sv:3:13: Parse error: expected instantiation name
module top;
example ();
endmodule
// pattern: instantiation_no_module\.sv:3:5: Parse error: expected module or interface name at beginning of instantiation list
module top;
, ();
endmodule
// pattern: instantiation_not_ports\.sv:3:15: Parse error: expected port connections
module top;
example a b, c();
endmodule
// pattern: instantiation_not_range\.sv:3:15: Parse error: expected instantiation dimensions
module top;
example a b();
endmodule
// pattern: instantiation_trailing_comma\.sv:3:16: Parse error: unexpected end of instantiation list
module top;
example a(), ;
endmodule
// pattern: run_on_decl_item.sv:3:16: Parse error: unexpected comma-separated declarations
module top;
integer x, byte y;
endmodule
// pattern: run_on_decl_stmt.sv:4:20: Parse error: unexpected comma-separated declarations
module top;
initial begin
integer x, byte y;
end
endmodule
// pattern: unexpected packed range\(s\) applied to string
module top;
string [1:0] x;
endmodule
// pattern: unexpected signed applied to string
module top;
string signed x;
endmodule
// pattern: unexpected packed range\(s\) applied to type\(y\)
module top;
logic y;
var type(y) [1:0] x;
endmodule
// pattern: unexpected signed applied to type\(y\)
module top;
logic y;
var type(y) signed x;
endmodule
// pattern: var_var\.sv:3:9: Parse error: duplicate var modifier
module top;
var var x = 1'b1;
endmodule
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