X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/c2724603c9d87e816dbdf1a9bfd7d70ffc1bd137..ba60c39547a445dee3e07920931b4d7a81843868:/src/scan-gram.l?ds=sidebyside diff --git a/src/scan-gram.l b/src/scan-gram.l index 4ed30c6f..15b6b31d 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,7 +1,6 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002-2011 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -56,10 +55,16 @@ static boundary scanner_cursor; static size_t no_cr_read (FILE *, char *, size_t); #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size)) -#define RETURN_PERCENT_FLAG(Value) \ +#define RETURN_PERCENT_PARAM(Value) \ + RETURN_VALUE(PERCENT_PARAM, param, param_ ## Value) + +#define RETURN_PERCENT_FLAG(Value) \ + RETURN_VALUE(PERCENT_FLAG, uniqstr, uniqstr_new (Value)) + +#define RETURN_VALUE(Token, Field, Value) \ do { \ - val->uniqstr = uniqstr_new (Value); \ - return PERCENT_FLAG; \ + val->Field = Value; \ + return Token; \ } while (0) #define ROLLBACK_CURRENT_TOKEN \ @@ -100,11 +105,12 @@ static void unexpected_newline (boundary, char const *); /* A complex tag, with nested angles brackets. */ %x SC_TAG - /* Three types of user code: + /* Four types of user code: - prologue (code between `%{' `%}' in the first section, before %%); - actions, printers, union, etc, (between braced in the middle section); - - epilogue (everything after the second %%). */ -%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE + - epilogue (everything after the second %%). + - predicate (code between `%?{' and `{' in middle section); */ +%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE SC_PREDICATE /* C and C++ comments in code. */ %x SC_COMMENT SC_LINE_COMMENT /* Strings and characters in code. */ @@ -112,8 +118,8 @@ static void unexpected_newline (boundary, char const *); /* Bracketed identifiers support. */ %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID -letter [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] -id {letter}({letter}|[0-9])* +letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +id {letter}({letter}|[-0-9])* directive %{id} int [0-9]+ @@ -204,7 +210,7 @@ splice (\\[ \f\t\v]*\n)* "%glr-parser" return PERCENT_GLR_PARSER; "%language" return PERCENT_LANGUAGE; "%left" return PERCENT_LEFT; - "%lex-param" return PERCENT_LEX_PARAM; + "%lex-param" RETURN_PERCENT_PARAM(lex); "%locations" RETURN_PERCENT_FLAG("locations"); "%merge" return PERCENT_MERGE; "%name"[-_]"prefix" return PERCENT_NAME_PREFIX; @@ -214,7 +220,8 @@ splice (\\[ \f\t\v]*\n)* "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER; "%nterm" return PERCENT_NTERM; "%output" return PERCENT_OUTPUT; - "%parse-param" return PERCENT_PARSE_PARAM; + "%param" RETURN_PERCENT_PARAM(both); + "%parse-param" RETURN_PERCENT_PARAM(parse); "%prec" return PERCENT_PREC; "%precedence" return PERCENT_PRECEDENCE; "%printer" return PERCENT_PRINTER; @@ -278,6 +285,13 @@ splice (\\[ \f\t\v]*\n)* BEGIN SC_BRACED_CODE; } + /* Semantic predicate. */ + "%?"[ \f\n\t\v]*"{" { + nesting = 0; + code_start = loc->start; + BEGIN SC_PREDICATE; + } + /* A type. */ "<*>" return TAG_ANY; "<>" return TAG_NONE; @@ -617,12 +631,9 @@ splice (\\[ \f\t\v]*\n)* } \\(.|\n) { char const *p = yytext + 1; - char quoted_ws[] = "` '"; - if (isspace (*p) && isprint (*p)) - { - quoted_ws[1] = *p; - p = quoted_ws; - } + /* Quote only if escaping won't make the character visible. */ + if (isspace ((unsigned char) *p) && isprint ((unsigned char) *p)) + p = quote (p); else p = quotearg_style_mem (escape_quoting_style, p, 1); complain_at (*loc, _("invalid character after \\-escape: %s"), p); @@ -657,7 +668,7 @@ splice (\\[ \f\t\v]*\n)* | Strings, comments etc. can be found in user code. | `---------------------------------------------------*/ - + { "'" { STRING_GROW; @@ -687,14 +698,32 @@ splice (\\[ \f\t\v]*\n)* /*-----------------------------------------------------------. - | Scanning some code in braces (actions). The initial "{" is | - | already eaten. | + | Scanning some code in braces (actions, predicates). The | + | initial "{" is already eaten. | `-----------------------------------------------------------*/ - + { "{"|"<"{splice}"%" STRING_GROW; nesting++; "%"{splice}">" STRING_GROW; nesting--; + + /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly + (as `<' `<%'). */ + "<"{splice}"<" STRING_GROW; + + <> { + int token = (YY_START == SC_BRACED_CODE) ? BRACED_CODE : BRACED_PREDICATE; + unexpected_eof (code_start, "}"); + STRING_FINISH; + loc->start = code_start; + val->code = last_string; + BEGIN INITIAL; + return token; + } +} + + +{ "}" { obstack_1grow (&obstack_for_string, '}'); @@ -708,22 +737,25 @@ splice (\\[ \f\t\v]*\n)* return BRACED_CODE; } } +} - /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly - (as `<' `<%'). */ - "<"{splice}"<" STRING_GROW; - - <> { - unexpected_eof (code_start, "}"); - STRING_FINISH; - loc->start = code_start; - val->code = last_string; - BEGIN INITIAL; - return BRACED_CODE; + +{ + "}" { + --nesting; + if (nesting < 0) + { + STRING_FINISH; + loc->start = code_start; + val->code = last_string; + BEGIN INITIAL; + return BRACED_PREDICATE; + } + else + obstack_1grow (&obstack_for_string, '}'); } } - /*--------------------------------------------------------------. | Scanning some prologue: from "%{" (already scanned) to "%}". | `--------------------------------------------------------------*/ @@ -770,8 +802,8 @@ splice (\\[ \f\t\v]*\n)* | By default, grow the string obstack with the input. | `-----------------------------------------------------*/ -. | -\n STRING_GROW; +. | + \n STRING_GROW; %% @@ -909,8 +941,8 @@ handle_syncline (char *args, location loc) { char *after_num; unsigned long int lineno = strtoul (args, &after_num, 10); - char *file = strchr (after_num, '"') + 1; - *strchr (file, '"') = '\0'; + char *file = mbschr (after_num, '"') + 1; + *mbschr (file, '"') = '\0'; if (INT_MAX <= lineno) { warn_at (loc, _("line number overflow"));