better parse errors when missing endif preprocessor directive
#385 opened on Jul 25, 2021
Description
The following example is simplified from a real-life example, that had a large if-else tree at the top of the file to determine the parameters to be used in the rest of the file. It was missing an `` endif directive -- which can easily happen with multiple levels of nesting. The result is that all of the rest of the code in the file was assumed to be part of the final else-clause, and BSC gave parse errors that were not helpful in identifying the problem.
package PP;
// ================================================================
`ifdef M1
`ifdef M2
typedef 3 Num;
`else
typedef 2 Num;
`endif
`else
`ifdef M2
typedef 2 Num;
`else
typedef 1 Num;
`endif
// XXX An endif is missing here
typedef Bit #(TLog #(Num)) NumPtr;
// ================================================================
(* synthesize *)
module mkPP ();
Reg#(NumPtr) rg <- mkRegU;
endmodule
// ================================================================
endpackage
When compiled with -D M1 -D M2, BSC gives this message:
Error: "PP.bsv", line 8, column 15: (P0005)
Unexpected end of file; expected attributes or SV 3.1a keyword `endpackage'
The position and message here at least make a little sense: If you assume that the end of file implicitly closes any open if-else clauses, then all of the remaining code in the file is enclosed in that last clause; and if you select the first block (via -D flags), then the end of the file (after preprocessing) is indeed where the error position is pointing. (That is, if you write an explicit `endif at the end of the file, you will get this same error message from BSC.) However, BSC knows that the end of the file was reached without an explicit `endif directive, so BSC should have at least warned about that.
When compiled with no -D flags, we get an odd message and position:
Error: "PP.bsv", line 36, column 1: (P0052)
Unassigned expressions forbidden in toplevel context
If you put an explicit `endif directive at the end of the file and compile with no -D flag, you do not get an error. I have no idea offhand why the parser gives this message (with a position pointing to endpackage). It might be best for BSC to error if there are missing `endif directives. (Presumably other mismatches are errors, but worth testing that too.) Preprocessor tests are in testsuite/bsc.preprocessor/ (which maybe should be moved unto bsc.syntax/bsv05/?).