diff --git a/src/parse-gram.y b/src/parse-gram.y index 6a19e571..9fcf8195 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -106,6 +106,7 @@ /* Handle a %yacc directive. */ static void handle_yacc (location const *loc); + /* Implementation of yyerror. */ static void gram_error (location const *, char const *); /* A string that describes a char (e.g., 'a' -> "'a'"). */ @@ -196,7 +197,7 @@ %token BRACED_CODE "{...}" %token BRACED_PREDICATE "%?{...}" %token BRACKETED_ID "[identifier]" -%token CHAR "char" +%token CHAR "character literal" %token COLON ":" %token EPILOGUE "epilogue" %token EQUAL "=" @@ -732,12 +733,24 @@ id: { $$ = symbol_from_uniqstr ($1, @1); } | CHAR { + const char *var = "api.token.raw"; if (current_class == nterm_sym) { - gram_error (&@1, - _("character literals cannot be nonterminals")); + complain (&@1, complaint, + _("character literals cannot be nonterminals")); YYERROR; } + if (muscle_percent_define_ifdef (var)) + { + unsigned indent = 0; + complain_indent (&@1, complaint, &indent, + _("character literals cannot be used together" + " with %s"), var); + indent += SUB_INDENT; + location loc = muscle_percent_define_get_loc (var); + complain_indent (&loc, complaint, &indent, + _("definition of %s"), var); + } $$ = symbol_get (char_name ($1), @1); symbol_class_set ($$, token_sym, @1, false); symbol_user_token_number_set ($$, $1, @1); diff --git a/tests/diagnostics.at b/tests/diagnostics.at index a4496952..8caef178 100644 --- a/tests/diagnostics.at +++ b/tests/diagnostics.at @@ -277,7 +277,7 @@ AT_TEST([[Carriage return]], [[input.y:10.8-11.0: error: missing '"' at end of line 10 | %token " | ^ -input.y:10.8-11.0: error: syntax error, unexpected string, expecting char or identifier or +input.y:10.8-11.0: error: syntax error, unexpected string, expecting character literal or identifier or 10 | %token " | ^ ]]) diff --git a/tests/input.at b/tests/input.at index 64711222..8a265c42 100644 --- a/tests/input.at +++ b/tests/input.at @@ -232,10 +232,10 @@ input.y:3.17-24: error: nonterminals cannot be given a string alias input.y:4.8-10: error: character literals cannot be nonterminals 4 | %nterm '+' '*'; | ^~~ -input.y:5.8-15: error: syntax error, unexpected string, expecting char or identifier or +input.y:5.8-15: error: syntax error, unexpected string, expecting character literal or identifier or 5 | %nterm "number"; | ^~~~~~~~ -input.y:6.8-13: error: syntax error, unexpected string, expecting char or identifier or +input.y:6.8-13: error: syntax error, unexpected string, expecting character literal or identifier or 6 | %token "tok1" 1; | ^~~~~~ input.y:7.14: error: syntax error, unexpected integer @@ -2760,3 +2760,37 @@ AT_BISON_CHECK([[-fcaret input.y]], [[0]], [[]], AT_BISON_OPTION_POPDEFS AT_CLEANUP + + + +## -------------------------------------- ## +## Character literals and api.token.raw. ## +## -------------------------------------- ## + +AT_SETUP([[Character literals and api.token.raw]]) + +AT_BISON_OPTION_PUSHDEFS +AT_DATA_GRAMMAR([[input.y]], +[[%define api.token.raw +%token 'a' +%% +exp: 'b' "c" {} +]]) + +AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]], +[[input.y:10.8-10: error: character literals cannot be used together with api.token.raw + 10 | %token 'a' + | ^~~ +input.y:9.1-21: definition of api.token.raw + 9 | %define api.token.raw + | ^~~~~~~~~~~~~~~~~~~~~ +input.y:12.6-8: error: character literals cannot be used together with api.token.raw + 12 | exp: 'b' "c" {} + | ^~~ +input.y:9.1-21: definition of api.token.raw + 9 | %define api.token.raw + | ^~~~~~~~~~~~~~~~~~~~~ +]]) + +AT_BISON_OPTION_POPDEFS +AT_CLEANUP