Commit c0cb401a by Zachary Snow

fix handling of end labels

- disallow using end label alone on blocks
- improved parse error for mismatches
- add label checking for non-block constructs
- allow generate block to have label before begin
parent a87ee7c1
...@@ -542,11 +542,12 @@ Packing :: { Packing } ...@@ -542,11 +542,12 @@ Packing :: { Packing }
| {- empty -} { Unpacked } | {- empty -} { Unpacked }
Part(begin, end) :: { Description } Part(begin, end) :: { Description }
: AttributeInstances begin PartHeader ModuleItems end opt(Tag) { $3 $1 False $2 $4 } : AttributeInstances begin PartHeader ModuleItems end StrTag {% $3 $1 False $2 $4 $6 }
| AttributeInstances "extern" begin PartHeader { $4 $1 True $3 [] } | AttributeInstances "extern" begin PartHeader {% $4 $1 True $3 [] "" }
PartHeader :: { [Attr] -> Bool -> PartKW -> [ModuleItem] -> Description } PartHeader :: { [Attr] -> Bool -> PartKW -> [ModuleItem] -> Identifier -> ParseState Description }
: Lifetime Identifier PackageImportDeclarations Params PortDecls ";" { \attrs extern kw items -> Part attrs extern kw $1 $2 (fst $5) ($3 ++ $4 ++ (snd $5) ++ items) } : Lifetime Identifier PackageImportDeclarations Params PortDecls ";"
{ \attrs extern kw items label -> checkTag $2 label $ Part attrs extern kw $1 $2 (fst $5) ($3 ++ $4 ++ (snd $5) ++ items) }
ModuleKW :: { PartKW } ModuleKW :: { PartKW }
: "module" { Module } : "module" { Module }
...@@ -555,11 +556,8 @@ InterfaceKW :: { PartKW } ...@@ -555,11 +556,8 @@ InterfaceKW :: { PartKW }
: "interface" { Interface } : "interface" { Interface }
PackageDeclaration :: { Description } PackageDeclaration :: { Description }
: "package" Lifetime Identifier ";" PackageItems endpackage opt(Tag) { Package $2 $3 $5 } : "package" Lifetime Identifier ";" PackageItems endpackage StrTag {% checkTag $3 $7 $ Package $2 $3 $5 }
| "class" Lifetime Identifier PIParams ";" PackageItems endclass opt(Tag) { Class $2 $3 $4 $6 } | "class" Lifetime Identifier PIParams ";" PackageItems endclass StrTag {% checkTag $3 $8 $ Class $2 $3 $4 $6 }
Tag :: { Identifier }
: ":" Identifier { $2 }
StrTag :: { Identifier } StrTag :: { Identifier }
: {- empty -} { "" } : {- empty -} { "" }
...@@ -852,9 +850,9 @@ NonDeclPackageItem :: { [PackageItem] } ...@@ -852,9 +850,9 @@ NonDeclPackageItem :: { [PackageItem] }
: "typedef" Type Identifier ";" { [Decl $ ParamType Localparam $3 $2] } : "typedef" Type Identifier ";" { [Decl $ ParamType Localparam $3 $2] }
| "typedef" Type Identifier DimensionsNonEmpty ";" { [Decl $ ParamType Localparam $3 (UnpackedType $2 $4)] } | "typedef" Type Identifier DimensionsNonEmpty ";" { [Decl $ ParamType Localparam $3 (UnpackedType $2 $4)] }
| "typedef" TypedefRef Identifier ";" { [Decl $ ParamType Localparam $3 $2] } | "typedef" TypedefRef Identifier ";" { [Decl $ ParamType Localparam $3 $2] }
| "function" Lifetime FuncRetAndName TFItems DeclsAndStmts endfunction opt(Tag) { [Function $2 (fst $3) (snd $3) (map makeInput $4 ++ fst $5) (snd $5)] } | "function" Lifetime FuncRetAndName TFItems DeclsAndStmts endfunction StrTag {% checkTag (snd $3) $7 [Function $2 (fst $3) (snd $3) (map makeInput $4 ++ fst $5) (snd $5)] }
| "function" Lifetime "void" Identifier TFItems DeclsAndStmts endfunction opt(Tag) { [Task $2 $4 ($5 ++ fst $6) (snd $6)] } | "function" Lifetime "void" Identifier TFItems DeclsAndStmts endfunction StrTag {% checkTag $4 $8 [Task $2 $4 ($5 ++ fst $6) (snd $6)] }
| "task" Lifetime Identifier TFItems DeclsAndStmts endtask opt(Tag) { [Task $2 $3 ($4 ++ fst $5) (snd $5)] } | "task" Lifetime Identifier TFItems DeclsAndStmts endtask StrTag {% checkTag $3 $7 [Task $2 $3 ($4 ++ fst $5) (snd $5)] }
| "import" PackageImportItems ";" { map (uncurry Import) $2 } | "import" PackageImportItems ";" { map (uncurry Import) $2 }
| "export" PackageImportItems ";" { map (uncurry Export) $2 } | "export" PackageImportItems ";" { map (uncurry Export) $2 }
| "export" "*" "::" "*" ";" { [Export "" ""] } | "export" "*" "::" "*" ";" { [Export "" ""] }
...@@ -1016,8 +1014,8 @@ StmtNonAsgn :: { Stmt } ...@@ -1016,8 +1014,8 @@ StmtNonAsgn :: { Stmt }
| StmtNonBlock { $1 } | StmtNonBlock { $1 }
| Identifier ":" StmtNonBlock { Block Seq $1 [] [$3] } | Identifier ":" StmtNonBlock { Block Seq $1 [] [$3] }
StmtBlock(begin, end) :: { Stmt } StmtBlock(begin, end) :: { Stmt }
: begin StrTag DeclsAndStmts end StrTag { uncurry (Block $1 $ combineTags $2 $5) $3 } : begin StrTag DeclsAndStmts end StrTag {% checkTag $2 $5 $ uncurry (Block $1 $2) $3 }
| Identifier ":" begin DeclsAndStmts end StrTag { uncurry (Block $3 $ combineTags $1 $6) $4 } | Identifier ":" begin DeclsAndStmts end StrTag {% checkTag $1 $6 $ uncurry (Block $3 $1) $4 }
StmtNonBlock :: { Stmt } StmtNonBlock :: { Stmt }
: ";" { Null } : ";" { Null }
| Unique "if" "(" Expr ")" Stmt "else" Stmt { If $1 $4 $6 $8 } | Unique "if" "(" Expr ")" Stmt "else" Stmt { If $1 $4 $6 $8 }
...@@ -1333,7 +1331,10 @@ LoopGenerateConstruct :: { GenItem } ...@@ -1333,7 +1331,10 @@ LoopGenerateConstruct :: { GenItem }
: "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenItem { $3 $5 $7 $9 } : "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenItem { $3 $5 $7 $9 }
GenBlock :: { (Identifier, [GenItem]) } GenBlock :: { (Identifier, [GenItem]) }
: "begin" StrTag GenItems end StrTag { (combineTags $2 $5, $3) } : GenBlockBegin GenItems end StrTag {% checkTag $1 $4 ($1, $2) }
GenBlockBegin :: { Identifier }
: "begin" StrTag { $2 }
| Identifier ":" "begin" { $1 }
GenCases :: { [GenCase] } GenCases :: { [GenCase] }
: GenCase { [$1] } : GenCase { [$1] }
...@@ -1465,13 +1466,18 @@ makeInput (CommentDecl c) = CommentDecl c ...@@ -1465,13 +1466,18 @@ makeInput (CommentDecl c) = CommentDecl c
makeInput other = makeInput other =
error $ "unexpected non-var or non-input decl: " ++ (show other) error $ "unexpected non-var or non-input decl: " ++ (show other)
combineTags :: Identifier -> Identifier -> Identifier checkTag :: String -> String -> a -> ParseState a
combineTags a "" = a checkTag _ "" x = return x
combineTags "" b = b checkTag "" b _ = do
combineTags a b = p <- gets pPosition
error $ show p ++ ": Parse error: block has only end label " ++ show b
checkTag a b x =
if a == b if a == b
then a then return x
else error $ "tag mismatch: " ++ show (a, b) else do
p <- gets pPosition
error $ show p ++ ": Parse error: element " ++ show a
++ " has mismatched end label " ++ show b
toLHS :: Expr -> LHS toLHS :: Expr -> LHS
toLHS expr = toLHS expr =
......
class C #(
parameter X
);
localparam Y = X * 2;
endclass : C
package P;
localparam Z = 3;
endpackage : P
`define DUMP(expr) initial $display(`"expr = %0d`", expr);
interface intf;
initial $display("intf");
endinterface : intf
module top;
intf i();
function automatic integer f;
input integer inp;
return inp * 8;
endfunction : f
task t;
$display("t()");
endtask : t
localparam W = 4;
`DUMP(W)
`DUMP(C#(3)::X)
`DUMP(C#(3)::Y)
`DUMP(P::Z)
`DUMP(f(3))
initial t();
initial begin : blkA
$display("Hello!");
end : blkA
if (1) begin : blkB
initial $display("Bye!");
end : blkB
initial blkC : begin
$display("No!");
end : blkC
if (1) blkD : begin
initial $display("Way!");
end : blkD
endmodule : top
`define DUMP(expr, value) initial $display(`"expr = %0d`", value);
module top;
`DUMP(W, 4)
`DUMP(C#(3)::X, 3)
`DUMP(C#(3)::Y, 6)
`DUMP(P::Z, 3)
`DUMP(f(3), 24)
if (1) initial begin
$display("intf");
$display("Bye!");
$display("Way!");
end
initial begin
$display("t()");
$display("Hello!");
$display("No!");
end
endmodule
// pattern: block has only end label "no"
module top;
initial begin
$display("Hi!");
end : no
endmodule
// pattern: element "yes" has mismatched end label "no"
module top;
initial begin : yes
$display("Hi!");
end : no
endmodule
// pattern: element "yes" has mismatched end label "no"
class yes;
endclass : no
// pattern: element "yes" has mismatched end label "no"
module top;
function yes;
yes = 0;
endfunction : no
endmodule
// pattern: block has only end label "no"
module top;
if (1) begin
wire x;
end : no
endmodule
// pattern: element "yes" has mismatched end label "no"
module top;
if (1) begin : yes
wire x;
end : no
endmodule
// pattern: element "yes" has mismatched end label "no"
interface yes;
endinterface : no
// pattern: element "yes" has mismatched end label "no"
module yes;
endmodule : no
// pattern: element "yes" has mismatched end label "no"
package yes;
endpackage : no
// pattern: element "yes" has mismatched end label "no"
module top;
task yes;
endtask : no
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