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