Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parsing of 'with' inside streaming operator. #1504

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions verilog/formatting/formatter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,10 @@ static constexpr FormatterTestCase kFormatterTestCases[] = {
" parameter int b={ << 4 {{ << 2 { a } }} } ;",
"parameter int b = {<<4{{<<2{a}}}};\n",
},
{
" parameter int b={ << {foo with [ 1 +: 4 ] } } ;",
"parameter int b = {<<{foo with [1+:4]}};\n",
},

// basic module test cases
{"module foo;endmodule:foo\n",
Expand Down
3 changes: 3 additions & 0 deletions verilog/formatting/token_annotator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ static WithReason<int> SpacesRequiredBetween(
if (right_context.IsInsideFirst({NodeEnum::kStreamingConcatenation}, {})) {
if (left.TokenEnum() == TK_LS || left.TokenEnum() == TK_RS) {
return {0, "No space around streaming operators"};
} else if (left.TokenEnum() == TK_with__followed_by_bracket ||
right.TokenEnum() == TK_with__followed_by_bracket) {
return {1, "Space around 'with' keyword in streaming concatenation."};
} else if (left.format_token_enum == FormatTokenType::numeric_literal ||
left.format_token_enum == FormatTokenType::identifier ||
left.format_token_enum == FormatTokenType::keyword) {
Expand Down
1 change: 1 addition & 0 deletions verilog/formatting/verilog_token.cc
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ static const absl::node_hash_map<verilog_tokentype, FTT>& FormatTokenTypeMap() {
{verilog_tokentype::TK_wildcard, FTT::keyword},
{verilog_tokentype::TK_with, FTT::keyword},
{verilog_tokentype::TK_with__covergroup, FTT::keyword},
{verilog_tokentype::TK_with__followed_by_bracket, FTT::keyword},
{verilog_tokentype::TK_within, FTT::keyword},
{verilog_tokentype::TK_timeprecision_check, FTT::keyword},
{verilog_tokentype::TK_timeunit_check, FTT::keyword},
Expand Down
5 changes: 5 additions & 0 deletions verilog/parser/verilog.lex
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ wait_order { UpdateLocation(); return TK_wait_order; }
wildcard { UpdateLocation(); return TK_wildcard; }
<COVERGROUP>with { UpdateLocation(); return TK_with__covergroup; }
with { UpdateLocation(); return TK_with; }
"with"({TraditionalCommentOrSpace}|{EndOfLineComment})*"[" {
yyless(4); // only consume 'with', push rest back to input
UpdateLocation();
return TK_with__followed_by_bracket;
}
within { UpdateLocation(); return TK_within; }
timeprecision_check { UpdateLocation(); return TK_timeprecision_check; }
timeunit_check { UpdateLocation(); return TK_timeunit_check; }
Expand Down
7 changes: 4 additions & 3 deletions verilog/parser/verilog.y
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ is not locally defined, so the grammar here uses only generic identifiers.
%token TK_wait_order "wait_order"
%token TK_wildcard "wildcard"
%token TK_with "with"
%token TK_with__followed_by_bracket "with ["
%token TK_with__covergroup "with(covergroup)"
%token TK_within "within"
/* Fake tokens that are passed once we have an initial token. */
Expand Down Expand Up @@ -3159,12 +3160,12 @@ block_item_or_statement_or_null_list_opt
| /* empty */
{ $$ = MakeTaggedNode(N::kBlockItemStatementList); }
;

stream_expression
: expression
{ $$ = move($1); }
/* TODO(fangism):
| expression TK_with select_variable_dimension
*/
| expression TK_with__followed_by_bracket select_variable_dimension
{ $$ = ExtendNode($1, $2, $3); }
;
stream_expression_list
: stream_expression_list ',' stream_expression
Expand Down
3 changes: 3 additions & 0 deletions verilog/parser/verilog_lexer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,9 @@ static std::initializer_list<LexerTestData> kSequenceTests = {

static std::initializer_list<LexerTestData> kContextKeywordTests = {
{{SymbolIdentifier, "option"}},
{{TK_with__followed_by_bracket, "with"},
" // hello\n"
" /* this bracket is the context we're looking for -> */["},
{{TK_covergroup, "covergroup"},
" ",
{SymbolIdentifier, "blah1"},
Expand Down
11 changes: 11 additions & 0 deletions verilog/parser/verilog_parser_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,17 @@ static const ParserTestCaseArray kFunctionTests = {
"function void unpack_id(utils_pkg::bytestream_t bytes);\n"
"{<< byte {this.reserved, this.id}} = bytes;\n"
"endfunction",
"function void unpack_id_with(int nums);\n"
"{>>8 {foo, bar with \t [ a +: b]}} = nums;\n"
"endfunction",
"function void unpack_id_with(int nums);\n"
"{>>8 {foo, bar with /* some comment */ /* another one */ // more\n"
"[ a +: b]}} = nums;\n"
"endfunction",
"function void unpack_id_with(int nums);\n"
"{>>8 {foo, bar with // eol comment\n"
" [ a +: b]}} = nums;\n"
"endfunction",
// concatenation lvalue
"module foo;\n"
" initial begin\n"
Expand Down