Skip to content

Commit

Permalink
(System)Verilog: escaped identifiers (LRM 5.6.1)
Browse files Browse the repository at this point in the history
Add support for escaped identifiers in Verilog and SystemVerilog:
`\` + zero or more non-whitespace characters + whitespace.

Note that the `\` itself isn't part of the identifier, and that `\foo`
is the same as just `foo` (unlike in VHDL), but that identifiers
identical to keywords such as `\begin` are also allowed.

This definition also theoretically allows an empty identifier, `\`,
which ctags doesn't support.
In that case, leave the `\` as part of the name.
Since this would create ambiguity with an identifier declared as `\\`,
leave the `\` if the name starts with `\\` as well
(so `\foo` becomes `foo` but `\\foo` stays as `\\foo`).

Escaped identifiers are defined in the standard in section
3.7.1 (Verilog) / 5.6.1 (SystemVerilog).
  • Loading branch information
cousteaulecommandant committed Dec 1, 2024
1 parent 45735bd commit 5dc2b1f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 7 deletions.
1 change: 1 addition & 0 deletions Units/parser-verilog.r/verilog-escaped-id.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sort=no
12 changes: 12 additions & 0 deletions Units/parser-verilog.r/verilog-escaped-id.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
themodule#(x=42) input.v /^module \\themodule#(x=42) ($/;" m
clk,rst, input.v /^ input wire \\clk,rst, , \\d ,$/;" p module:themodule#(x=42)
d input.v /^ input wire \\clk,rst, , \\d ,$/;" p module:themodule#(x=42)
1+1=2 input.v /^ output reg \\1+1=2$/;" p module:themodule#(x=42)
\\ input.v /^localparam \\ = 1;$/;" c module:themodule#(x=42)
\\\\ input.v /^localparam \\\\ = \\ ;$/;" c module:themodule#(x=42)
\\\\\\ input.v /^localparam \\\\\\ = \\\\ ;$/;" c module:themodule#(x=42)
r\\n input.v /^localparam \\r\\n = \\\\\\ ;$/;" c module:themodule#(x=42)
\\\\r\\n input.v /^localparam \\\\r\\n = \\r\\n ;$/;" c module:themodule#(x=42)
\\\\\\r\\n input.v /^localparam \\\\\\r\\n = \\\\r\\n ;$/;" c module:themodule#(x=42)
end input.v /^always @(posedge \\clk,rst, ) begin : \\end$/;" b module:themodule#(x=42)
\\\\end input.v /^ if (\\\\\\r\\n ) begin : \\\\end$/;" b block:themodule#(x=42).end
19 changes: 19 additions & 0 deletions Units/parser-verilog.r/verilog-escaped-id.d/input.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module \themodule#(x=42) (
input wire \clk,rst, , \d ,
output reg \1+1=2
);

localparam \ = 1;
localparam \\ = \ ;
localparam \\\ = \\ ;
localparam \r\n = \\\ ;
localparam \\r\n = \r\n ;
localparam \\\r\n = \\r\n ;

always @(posedge \clk,rst, ) begin : \end
if (\\\r\n ) begin : \\end
\1+1=2 <= d;
end
end

endmodule
32 changes: 25 additions & 7 deletions parsers/verilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,10 +705,10 @@ static int vGetc (void)
return _vGetc (false);
}

// Is the first charactor in an identifier? [a-zA-Z_`]
// Is the first character in an identifier? [a-zA-Z_`\\]
static bool isWordToken (const int c)
{
return (isalpha (c) || c == '_' || c == '`');
return (isalpha (c) || c == '_' || c == '`' || c == '\\');
}

// Is a charactor in an identifier? [a-zA-Z0-9_`$]
Expand Down Expand Up @@ -873,12 +873,30 @@ static int _readWordToken (tokenInfo *const token, int c, bool skip)
Assert (isWordToken (c));

clearToken (token);
do
if (c == '\\')
{
vStringPut (token->name, c);
c = vGetc ();
} while (isIdentifierCharacter (c));
_updateKind (token);
// Escaped identifier
c = vGetc (); // skip leading '\'
// A single `\` would result in an empty identifier, which is unsupported.
// Add the initial `\` in that case, and also in case it starts with `\\`.
if (!isgraph (c) || c == '\\')
vStringPut (token->name, '\\');
while (isgraph (c))
{
vStringPut (token->name, c);
c = vGetc ();
}
token->kind = K_IDENTIFIER;
}
else
{
do
{
vStringPut (token->name, c);
c = vGetc ();
} while (isIdentifierCharacter (c));
_updateKind (token);
}

if (skip)
return skipWhite (c);
Expand Down

0 comments on commit 5dc2b1f

Please sign in to comment.