From 5b1d97fac7caa617b7252e75879d786d11f9242a Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Fri, 9 Oct 2020 11:38:16 +0100 Subject: [PATCH] Support escaped identifiers as macro names. (cherry picked from commit 359b2b65c2f015191ec05109d82e91ec22569a9b) --- ivlpp/lexor.lex | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index b43584436..e80960bd4 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -186,9 +186,11 @@ static int ma_parenthesis_level = 0; %x PPINCLUDE %x DEF_NAME +%x DEF_ESC %x DEF_ARG %x DEF_SEP %x DEF_TXT +%x MN_ESC %x MA_START %x MA_ADD %x CCOMMENT @@ -338,6 +340,11 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) [a-zA-Z_][a-zA-Z0-9_$]*"("{W}? { BEGIN(DEF_ARG); def_start(); } [a-zA-Z_][a-zA-Z0-9_$]*{W}? { BEGIN(DEF_TXT); def_start(); } +\\ { BEGIN(DEF_ESC); } + +[^ \t\b\f\n\r]+{W}"("{W}? { BEGIN(DEF_ARG); def_start(); } +[^ \t\b\f\n\r]+{W} { BEGIN(DEF_TXT); def_start(); } + /* define arg: = */ [a-zA-Z_][a-zA-Z0-9_$]*{W}*"="[^,\)]*{W}? { BEGIN(DEF_SEP); def_add_arg(); } /* define arg: */ @@ -352,7 +359,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) (\n|"\r\n"|"\n\r"|\r){W}? { istack->lineno += 1; fputc('\n', yyout); } -. { +. { emit_pathline(istack); fprintf(stderr, "error: malformed `define directive.\n"); error_count += 1; @@ -535,6 +542,24 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) do_expand(0); } +`\\ { yy_push_state(MN_ESC); } + +[^ \t\b\f\n\r]+ { + yy_pop_state(); + if (macro_needs_args(yytext)) + yy_push_state(MA_START); + else + do_expand(0); +} + +. { + yy_pop_state(); + unput(yytext[0]); + emit_pathline(istack); + fprintf(stderr, "error: malformed macro name.\n"); + error_count += 1; +} + /* 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_$]* { @@ -825,8 +850,13 @@ static void def_add_arg(void) /* This can happen because we are also processing "argv[0]", the macro name, as a pseudo-argument. The lexor will match that - as name(, so chop off the ( here. */ - if (yytext[length - 1] == '(') length--; + as name(, so chop off the ( here. If we have an escaped name, + we also need to strip off the white space that terminates the + name. */ + if (yytext[length - 1] == '(') { + length--; + while (isspace((int)yytext[length - 1])) length--; + } yytext[length] = 0;