Fix for GitHub issue #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.
This commit is contained in:
parent
45fbf55806
commit
332170d36b
|
|
@ -1,7 +1,7 @@
|
|||
%option prefix="yy"
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -148,18 +148,38 @@ static void ifdef_leave(void)
|
|||
free(cur);
|
||||
}
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) do { \
|
||||
if (istack->file) { \
|
||||
size_t rc = fread(buf, 1, max_size, istack->file); \
|
||||
result = (rc == 0) ? YY_NULL : rc; \
|
||||
} else { \
|
||||
if (*istack->str == 0) \
|
||||
result = YY_NULL; \
|
||||
else { \
|
||||
buf[0] = *istack->str++; \
|
||||
result = 1; \
|
||||
} \
|
||||
} \
|
||||
#define YY_INPUT(buf,result,max_size) do { \
|
||||
if (istack->file) { \
|
||||
size_t rc = fread(buf, 1, max_size, istack->file); \
|
||||
result = (rc == 0) ? YY_NULL : rc; \
|
||||
} else { \
|
||||
/* We are expanding a macro. Handle the SV macro escape \
|
||||
sequences. There doesn't seem to be any good reason \
|
||||
not to allow them in traditional Verilog as well. */ \
|
||||
while ((istack->str[0] == '`') && \
|
||||
(istack->str[1] == '`')) { \
|
||||
istack->str += 2; \
|
||||
} \
|
||||
if (*istack->str == 0) { \
|
||||
result = YY_NULL; \
|
||||
} else if ((istack->str[0] == '`') && \
|
||||
(istack->str[1] == '"')) { \
|
||||
istack->str += 2; \
|
||||
buf[0] = '"'; \
|
||||
result = 1; \
|
||||
} else if ((istack->str[0] == '`') && \
|
||||
(istack->str[1] == '\\')&& \
|
||||
(istack->str[2] == '`') && \
|
||||
(istack->str[3] == '"')) { \
|
||||
istack->str += 4; \
|
||||
buf[0] = '\\'; \
|
||||
buf[1] = '"'; \
|
||||
result = 2; \
|
||||
} else { \
|
||||
buf[0] = *istack->str++; \
|
||||
result = 1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int comment_enter = 0;
|
||||
|
|
@ -242,12 +262,6 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
|||
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
|
||||
}
|
||||
|
||||
/* `" overrides the usual lexical meaning of " and `\`" indicates
|
||||
that the expansion should include the escape sequence \".
|
||||
*/
|
||||
`\" { fputc('"', yyout); }
|
||||
`\\`\" { fprintf(yyout, "\\\""); }
|
||||
|
||||
/* Strings do not contain preprocessor directives, but can expand
|
||||
* macros. If that happens, they get expanded in the context of the
|
||||
* string.
|
||||
|
|
@ -514,29 +528,19 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
|
|||
do_expand(0);
|
||||
}
|
||||
|
||||
/* Stringified version of macro expansion. If the sequence `` is
|
||||
* encountered inside a macro definition, we use the SystemVerilog
|
||||
* handling of ignoring it so that identifiers can be constructed
|
||||
* from arguments. If istack->file is NULL, we are reading text
|
||||
* produced from a macro, so use SystemVerilog's handling;
|
||||
* otherwise, use the special Icarus handling.
|
||||
*/
|
||||
/* Stringified version of macro expansion. This is an Icarus extension.
|
||||
When expanding macro text, the SV usage of `` takes precedence. */
|
||||
``[a-zA-Z_][a-zA-Z0-9_$]* {
|
||||
if (istack->file == NULL)
|
||||
fprintf(yyout, "%s", yytext+2);
|
||||
else {
|
||||
assert(do_expand_stringify_flag == 0);
|
||||
do_expand_stringify_flag = 1;
|
||||
fputc('"', yyout);
|
||||
if (macro_needs_args(yytext+2))
|
||||
yy_push_state(MA_START);
|
||||
else
|
||||
do_expand(0);
|
||||
}
|
||||
assert(istack->file);
|
||||
assert(do_expand_stringify_flag == 0);
|
||||
do_expand_stringify_flag = 1;
|
||||
fputc('"', yyout);
|
||||
if (macro_needs_args(yytext+2))
|
||||
yy_push_state(MA_START);
|
||||
else
|
||||
do_expand(0);
|
||||
}
|
||||
|
||||
`` { if (istack->file != NULL) ECHO; }
|
||||
|
||||
<MA_START>\( { BEGIN(MA_ADD); macro_start_args(); }
|
||||
|
||||
<MA_START>{W} {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue