[WIP] Verible standalone preprocessor#1360
[WIP] Verible standalone preprocessor#1360karimtera wants to merge 13 commits intochipsalliance:masterfrom
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1360 +/- ##
==========================================
- Coverage 92.90% 91.91% -1.00%
==========================================
Files 340 344 +4
Lines 23832 24125 +293
==========================================
+ Hits 22141 22174 +33
- Misses 1691 1951 +260
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
…o generate all variants with the new mode generate-variants
fa4aa99 to
392c605
Compare
|
Hello @hzeller , Wish you had a good vacation! Here is a quick overview about what's going on here:
|
"verible::CmdPositionalArguments" class only supports these types so far: SV files, +define+<name>[=<value>], and +incdir+<dir>.
|
Note:
TODO:
|
- Added a feature to VerilogPreprocess which allows to store paths, That can be used later to find the SV file to include. - The preprocessor tool takes these paths from the user, as a +incdir+<path>[+<another_path>] and set then in VerilogPreprocess. - The included files macros and conditionals can be expanded and evaluated. - Some limitations exists and were written as TODOs in place, need to open issues for these.
|
Include directives supported usage:
Limitations:
|
- The preprocessor tool preserves the white-spaces in the SV files. - Changed the output of the -generate_variants and -multipecu from tokens (enum,text) into normal text.
|
To solve the white-spaces problem I have added TokenStreamView::const_iterator VerilogPreprocess::GenerateBypassWhiteSpaces(
const StreamIteratorGenerator& generator) {
auto iterator =
generator(); // iterator should be pointing to a non-whitespace token;
while (verilog::VerilogLexer::KeepSyntaxTreeTokens(**iterator) == 0) {
iterator = generator();
}
return iterator;
}Then replaced each Example: Example input file: `include "file.sv"
module m();
wire x = 1;
`ifdef KARIM
real is_defined = 1;
`else
real is_defined = 0;
`endif
// pre-blank line
// post-blank line
endmoduleExample output: module included_module();
wire x=1;
endmodule
module m();
wire x = 1;
real is_defined = 0;
// pre-blank line
// post-blank line
endmoduleNote: if added TODO:
|
mglb
left a comment
There was a problem hiding this comment.
Hi! I've played a bit with the tool and checked part of the code - more comments to come.
So far:
Maybe add a flag to disable blank lines.
Suggestion: this could include a comment following `endif/`else in the same line.
Question mostly out of curiosity: do SystemVerilog allows any tokens other than comments in the same line as `else and `endif? Because this works:
module m();
wire x = `ifdef KARIM
1`else/* no KARIM */0`endif; // endif KARIM
endmoduleFailing use cases:
input:
`ifndef KARIM
// not defined: define
`define KARIM
`endif
module m();
`ifdef KARIM
// defined
`else
// NOT defined
`endif
endmoduleoutput:
// not defined: define
module m();
// NOT defined
endmoduleExpected // defined.
file: file.sv:
module included_module();
wire x=1;
endmodulefile: test.m01.inc.sv:
// begin: test.m01.inc.sv
`include "file.sv"
// end: test.m01.inc.svfile: test.m01.sv (input):
// begin: test.m01.sv
`include "test.m01.inc.sv"
module m();
wire x = 1;
endmodule
// end: test.m01.svoutput:
// begin: test.m01.sv
// begin: test.m01.inc.sv
module m();
wire x = 1;
endmodule
// end: test.m01.svExpected inclusion of nested `include or error.
Cosmetic "issues"
More informative error reporting would be nice. At this moment it looks like:
$ ./bazel-bin/verilog/tools/preprocessor/verible-verilog-preprocessor - <<< $'// before\n`include "no-such-file.sv"\n// after\n'
// before
no such file found.
It is even more confusing when there's no comment before the include.
Example error from verible-verilog-syntax:
$ ./bazel-bin/verilog/tools/syntax/verible-verilog-syntax --printtokens - <<< "module 4"
-:1:8: syntax error at token "4"
I would rename --strip_comments to --erase_comments or something. I think "strip" suggests that they will be removed (replaced with empty strings).
Instead of Variant number 1: it would be nice to print something like //////// variant: 1 //////// for easier parsing (also for human eyes).
mglb
left a comment
There was a problem hiding this comment.
To solve the white-spaces problem I have added
VerilogPreprocess::GenerateBypassWhiteSpacesfunction which skips white-spaces tokens, and returns an iterator to a non-whitespace token.
It looks good generally, and seems to work here.
| std::vector<absl::string_view> GetIncludeDirs(); | ||
|
|
||
| // Gets macro defines arguments. | ||
| std::vector<std::pair<absl::string_view, absl::string_view>> GetDefines(); | ||
|
|
||
| // Gets SV files arguments. | ||
| std::vector<absl::string_view> GetFiles(); |
There was a problem hiding this comment.
const std::vector<...>& GetX() const; and auto& in assignments in verilog_preprocessor.cc
There was a problem hiding this comment.
The first const is giving me a warning with clang-tidy:
Clang-Tidy: Return type 'const TYPE' (aka 'const TYPE') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness
I think it means that it leads the reader to think the caller can't change the returned value, which is not true in general.
There was a problem hiding this comment.
I guess you forgot & after const std::vector<...>. This warnings appears only when returning const values/objects (which makes sense, because such const does nothing), not references to const value (which is used a lot to avoid forced copy).
| absl::Status DepthFirstSearch( | ||
| int index); // travese the tree in a depth first manner. | ||
| std::vector<verible::TokenSequence> | ||
| variants_; // a memory for all variants generated. | ||
|
|
||
| private: | ||
| std::vector<int> | ||
| ifs_; // vector of all `ifdef/`ifndef indexes in source_sequence_. | ||
| std::map<int, std::vector<int>> elses_; // indexes of `elsif/`else indexes in | ||
| // source_sequence_ of each if block. | ||
| std::map<int, std::vector<int>> | ||
| edges_; // the tree edges which defines the possible next childs of each | ||
| // token in source_sequence_. | ||
| verible::TokenSequence | ||
| source_sequence_; // the original source code lexed token seqouence. | ||
| verible::TokenSequence | ||
| current_sequence_; // the variant's token sequence currrently being built | ||
| // by DepthFirstSearch. |
There was a problem hiding this comment.
Put comments above code to avoid excessive wrapping. Also in other places.
| // karimtera(TODO): how to differentiate between <file> and "file"?? both are | ||
| // the same token, need to edit the lexer. |
There was a problem hiding this comment.
AFAIK `include <file> is not yet supported in Verible at all.
There was a problem hiding this comment.
That should be enabled from the lexer's side to begin with, right?
|
@kbieganski : here are some bits and pieces for the preprocessor, that have been addressed in various sub-pull request. Can you have a look through these to make sure everything actually made it to the final preprocessor or if there are pieces missing that we should reformulate in a new PR ? |
Description:
This PR introduces takes another step to enhance the standalone preprocessor tool by implementing
multiple-cumode.Please refer to issue #1358 for more information about the proposed design.
Goal:
Flags description
Using the Abseil flags library allows an easy access to flags and their arguments.
Positional arguments
Those mainly are the SV files to preprocess, defines and search-directory paths for includes.
Any of the following positional argument can be passed one or more times.
`define foo text`include "file_name"TODO:
constqualifier incmd_positional_arguments.h.+define+macro+="a=b"issue.absl/flags.