Skip to content

Commit 332170d

Browse files
Fix for GitHub issue steveicarus#105 - fully support SV macro escape sequences.
The existing support for ``, `", and `\`" did not work in nested macro definitions. Note that the new implementation only detects and replaces these sequences inside the macro text (as required by the IEEE standard), whereas the old implementation would detect and replace them anywhere in the source files.
1 parent 45fbf55 commit 332170d

File tree

1 file changed

+43
-39
lines changed

1 file changed

+43
-39
lines changed

ivlpp/lexor.lex

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%option prefix="yy"
22
%{
33
/*
4-
* Copyright (c) 1999-2015 Stephen Williams ([email protected])
4+
* Copyright (c) 1999-2016 Stephen Williams ([email protected])
55
*
66
* This source code is free software; you can redistribute it
77
* and/or modify it in source code form under the terms of the GNU
@@ -148,18 +148,38 @@ static void ifdef_leave(void)
148148
free(cur);
149149
}
150150

151-
#define YY_INPUT(buf,result,max_size) do { \
152-
if (istack->file) { \
153-
size_t rc = fread(buf, 1, max_size, istack->file); \
154-
result = (rc == 0) ? YY_NULL : rc; \
155-
} else { \
156-
if (*istack->str == 0) \
157-
result = YY_NULL; \
158-
else { \
159-
buf[0] = *istack->str++; \
160-
result = 1; \
161-
} \
162-
} \
151+
#define YY_INPUT(buf,result,max_size) do { \
152+
if (istack->file) { \
153+
size_t rc = fread(buf, 1, max_size, istack->file); \
154+
result = (rc == 0) ? YY_NULL : rc; \
155+
} else { \
156+
/* We are expanding a macro. Handle the SV macro escape \
157+
sequences. There doesn't seem to be any good reason \
158+
not to allow them in traditional Verilog as well. */ \
159+
while ((istack->str[0] == '`') && \
160+
(istack->str[1] == '`')) { \
161+
istack->str += 2; \
162+
} \
163+
if (*istack->str == 0) { \
164+
result = YY_NULL; \
165+
} else if ((istack->str[0] == '`') && \
166+
(istack->str[1] == '"')) { \
167+
istack->str += 2; \
168+
buf[0] = '"'; \
169+
result = 1; \
170+
} else if ((istack->str[0] == '`') && \
171+
(istack->str[1] == '\\')&& \
172+
(istack->str[2] == '`') && \
173+
(istack->str[3] == '"')) { \
174+
istack->str += 4; \
175+
buf[0] = '\\'; \
176+
buf[1] = '"'; \
177+
result = 2; \
178+
} else { \
179+
buf[0] = *istack->str++; \
180+
result = 1; \
181+
} \
182+
} \
163183
} while (0)
164184

165185
static int comment_enter = 0;
@@ -242,12 +262,6 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
242262
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
243263
}
244264

245-
/* `" overrides the usual lexical meaning of " and `\`" indicates
246-
that the expansion should include the escape sequence \".
247-
*/
248-
`\" { fputc('"', yyout); }
249-
`\\`\" { fprintf(yyout, "\\\""); }
250-
251265
/* Strings do not contain preprocessor directives, but can expand
252266
* macros. If that happens, they get expanded in the context of the
253267
* string.
@@ -514,29 +528,19 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
514528
do_expand(0);
515529
}
516530

517-
/* Stringified version of macro expansion. If the sequence `` is
518-
* encountered inside a macro definition, we use the SystemVerilog
519-
* handling of ignoring it so that identifiers can be constructed
520-
* from arguments. If istack->file is NULL, we are reading text
521-
* produced from a macro, so use SystemVerilog's handling;
522-
* otherwise, use the special Icarus handling.
523-
*/
531+
/* Stringified version of macro expansion. This is an Icarus extension.
532+
When expanding macro text, the SV usage of `` takes precedence. */
524533
``[a-zA-Z_][a-zA-Z0-9_$]* {
525-
if (istack->file == NULL)
526-
fprintf(yyout, "%s", yytext+2);
527-
else {
528-
assert(do_expand_stringify_flag == 0);
529-
do_expand_stringify_flag = 1;
530-
fputc('"', yyout);
531-
if (macro_needs_args(yytext+2))
532-
yy_push_state(MA_START);
533-
else
534-
do_expand(0);
535-
}
534+
assert(istack->file);
535+
assert(do_expand_stringify_flag == 0);
536+
do_expand_stringify_flag = 1;
537+
fputc('"', yyout);
538+
if (macro_needs_args(yytext+2))
539+
yy_push_state(MA_START);
540+
else
541+
do_expand(0);
536542
}
537543

538-
`` { if (istack->file != NULL) ECHO; }
539-
540544
<MA_START>\( { BEGIN(MA_ADD); macro_start_args(); }
541545

542546
<MA_START>{W} {}

0 commit comments

Comments
 (0)