diff --git a/Units/parser-verilog.r/verilog-escaped-id.d/args.ctags b/Units/parser-verilog.r/verilog-escaped-id.d/args.ctags new file mode 100644 index 0000000000..5ee5f79f70 --- /dev/null +++ b/Units/parser-verilog.r/verilog-escaped-id.d/args.ctags @@ -0,0 +1 @@ +--sort=no diff --git a/Units/parser-verilog.r/verilog-escaped-id.d/expected.tags b/Units/parser-verilog.r/verilog-escaped-id.d/expected.tags new file mode 100644 index 0000000000..d3514b9334 --- /dev/null +++ b/Units/parser-verilog.r/verilog-escaped-id.d/expected.tags @@ -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 diff --git a/Units/parser-verilog.r/verilog-escaped-id.d/input.v b/Units/parser-verilog.r/verilog-escaped-id.d/input.v new file mode 100644 index 0000000000..89fb752294 --- /dev/null +++ b/Units/parser-verilog.r/verilog-escaped-id.d/input.v @@ -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 diff --git a/parsers/verilog.c b/parsers/verilog.c index f2e5a10296..3269b9af42 100644 --- a/parsers/verilog.c +++ b/parsers/verilog.c @@ -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_`$] @@ -873,12 +873,35 @@ 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 '\' + while (isgraph (c)) + { + vStringPut (token->name, c); + c = vGetc (); + } + // A single `\` would result in an empty identifier, which is unsupported. + // Keep the `\` in that case, and also in case it starts with `\`. + if (vStringIsEmpty (token->name) || vStringChar (token->name, 0) == '\\') + { + vString *tempName = vStringNewInit ("\\"); + vStringCat (tempName, token->name); + vStringCopy (token->name, tempName); + vStringDelete (tempName); + } + token->kind = K_IDENTIFIER; + } + else + { + do + { + vStringPut (token->name, c); + c = vGetc (); + } while (isIdentifierCharacter (c)); + _updateKind (token); + } if (skip) return skipWhite (c);