mirror of https://github.com/zachjs/sv2v.git
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
This commit is contained in:
parent
ff0c7b026c
commit
6ee558b6b9
|
|
@ -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 }
|
||||||
: 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) }
|
||||||
| 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 }
|
||||||
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) }
|
||||||
: 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] }
|
||||||
: {- 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 }
|
||||||
: "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]) }
|
||||||
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 }
|
||||||
| 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 }
|
||||||
: "=" { 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 =
|
||||||
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
|
||||||
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) =
|
||||||
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
|
||||||
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)]
|
||||||
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
|
||||||
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 =
|
||||||
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
|
||||||
, 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
|
||||||
| 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
|
||||||
-- 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 =
|
||||||
-- 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 =
|
||||||
-- 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 =
|
||||||
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 =
|
||||||
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 =
|
||||||
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 =
|
||||||
-- 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
|
||||||
|
|
||||||
|
|
||||||
-- 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 =
|
||||||
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 =
|
||||||
(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])
|
||||||
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) =
|
||||||
(_, 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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: unexpected packed range\(s\) applied to byte
|
||||||
|
module top;
|
||||||
|
byte [1:0] x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: const_const\.sv:3:11: Parse error: duplicate const modifier
|
||||||
|
module top;
|
||||||
|
const const logic x = 1'b1;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: decl_binop_asgn\.sv:3:13: Parse error: unexpected binary assignment operator in declaration
|
||||||
|
module top;
|
||||||
|
logic x += 1;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: decl_delay_asgn\.sv:3:13: Parse error: unexpected timing modifier in declaration
|
||||||
|
module top;
|
||||||
|
logic x = #1 1;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// 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
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
// 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
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
// pattern: decl_delay_asgn_port\.sv:3:14: Parse error: unexpected timing modifier in declaration
|
||||||
|
module top(
|
||||||
|
output x = #1 1
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: decl_non_blocking_asgn\.sv:3:13: Parse error: unexpected non-blocking assignment operator in declaration
|
||||||
|
module top;
|
||||||
|
logic x <= 1;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// pattern: unexpected signed applied to enum
|
||||||
|
module top;
|
||||||
|
enum {
|
||||||
|
A, B
|
||||||
|
} signed x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_extra_comma\.sv:3:18: Parse error: expected instantiation before delimiter
|
||||||
|
module top;
|
||||||
|
example a(), , b();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_missing_ports\.sv:3:14: Parse error: expected port connections before delimiter
|
||||||
|
module top;
|
||||||
|
example a, c();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_no_label\.sv:3:13: Parse error: expected instantiation name
|
||||||
|
module top;
|
||||||
|
example ();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_no_module\.sv:3:5: Parse error: expected module or interface name at beginning of instantiation list
|
||||||
|
module top;
|
||||||
|
, ();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_not_ports\.sv:3:15: Parse error: expected port connections
|
||||||
|
module top;
|
||||||
|
example a b, c();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_not_range\.sv:3:15: Parse error: expected instantiation dimensions
|
||||||
|
module top;
|
||||||
|
example a b();
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: instantiation_trailing_comma\.sv:3:16: Parse error: unexpected end of instantiation list
|
||||||
|
module top;
|
||||||
|
example a(), ;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: run_on_decl_item.sv:3:16: Parse error: unexpected comma-separated declarations
|
||||||
|
module top;
|
||||||
|
integer x, byte y;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// pattern: run_on_decl_stmt.sv:4:20: Parse error: unexpected comma-separated declarations
|
||||||
|
module top;
|
||||||
|
initial begin
|
||||||
|
integer x, byte y;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: unexpected packed range\(s\) applied to string
|
||||||
|
module top;
|
||||||
|
string [1:0] x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: unexpected signed applied to string
|
||||||
|
module top;
|
||||||
|
string signed x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
// pattern: unexpected packed range\(s\) applied to type\(y\)
|
||||||
|
module top;
|
||||||
|
logic y;
|
||||||
|
var type(y) [1:0] x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
// pattern: unexpected signed applied to type\(y\)
|
||||||
|
module top;
|
||||||
|
logic y;
|
||||||
|
var type(y) signed x;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// pattern: var_var\.sv:3:9: Parse error: duplicate var modifier
|
||||||
|
module top;
|
||||||
|
var var x = 1'b1;
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue