mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
syntax: introducing %gprec for precedence groups
It is now possible to introduce precedence groups, with precedence
relationships inside the group, but not with the outside tokens. Ex:
%gprec arith {
%left '+' '-'
%left '*' '/'
%right '^'
}
%gprec {
%left OR
%left AND
}
%left OTHER
%precedence OTHER2
Here, the arithmetical operators (in the "arith" group) can be compared, the
boolean operators can be compared, but OTHER can only be compared to OTHER2.
* src/gram.c, src/gram.h, src/scan-gram.l, src/parse-gram.y: {} blocks after
%gprec are understood by the lexer
* src/parse-gram.y: New syntax
* tests/input.at, tests/regression.at: Fix due to lexer change
This commit is contained in:
@@ -44,6 +44,8 @@ int nvars = 0;
|
|||||||
|
|
||||||
symbol_number *token_translations = NULL;
|
symbol_number *token_translations = NULL;
|
||||||
|
|
||||||
|
enum braces_state prec_braces = 0;
|
||||||
|
|
||||||
int max_user_token_number = 256;
|
int max_user_token_number = 256;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
11
src/gram.h
11
src/gram.h
@@ -117,6 +117,17 @@ typedef int item_number;
|
|||||||
extern item_number *ritem;
|
extern item_number *ritem;
|
||||||
extern unsigned int nritems;
|
extern unsigned int nritems;
|
||||||
|
|
||||||
|
enum braces_state
|
||||||
|
{
|
||||||
|
default_braces_state,
|
||||||
|
gprec_seen,
|
||||||
|
group_name_seen,
|
||||||
|
braces_seen
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Marker for the lexer and parser, to correctly interpret braces. */
|
||||||
|
extern enum braces_state prec_braces;
|
||||||
|
|
||||||
/* There is weird relationship between OT1H item_number and OTOH
|
/* There is weird relationship between OT1H item_number and OTOH
|
||||||
symbol_number and rule_number: we store the latter in
|
symbol_number and rule_number: we store the latter in
|
||||||
item_number. symbol_number values are stored as-is, while
|
item_number. symbol_number values are stored as-is, while
|
||||||
|
|||||||
@@ -130,6 +130,7 @@
|
|||||||
|
|
||||||
%token PERCENT_PREC "%prec"
|
%token PERCENT_PREC "%prec"
|
||||||
%token PERCENT_DPREC "%dprec"
|
%token PERCENT_DPREC "%dprec"
|
||||||
|
%token PERCENT_GPREC "%gprec"
|
||||||
%token PERCENT_MERGE "%merge"
|
%token PERCENT_MERGE "%merge"
|
||||||
|
|
||||||
/*----------------------.
|
/*----------------------.
|
||||||
@@ -178,6 +179,8 @@
|
|||||||
%token TAG "<tag>"
|
%token TAG "<tag>"
|
||||||
%token TAG_ANY "<*>"
|
%token TAG_ANY "<*>"
|
||||||
%token TAG_NONE "<>"
|
%token TAG_NONE "<>"
|
||||||
|
%token LBRACE "{"
|
||||||
|
%token RBRACE "}"
|
||||||
|
|
||||||
%union {unsigned char character;}
|
%union {unsigned char character;}
|
||||||
%type <character> CHAR
|
%type <character> CHAR
|
||||||
@@ -214,6 +217,7 @@
|
|||||||
%union {named_ref *named_ref;}
|
%union {named_ref *named_ref;}
|
||||||
%type <named_ref> named_ref.opt
|
%type <named_ref> named_ref.opt
|
||||||
|
|
||||||
|
%type <uniqstr> prec_group_name.opt
|
||||||
/*---------.
|
/*---------.
|
||||||
| %param. |
|
| %param. |
|
||||||
`---------*/
|
`---------*/
|
||||||
@@ -365,6 +369,7 @@ params:
|
|||||||
|
|
||||||
grammar_declaration:
|
grammar_declaration:
|
||||||
precedence_declaration
|
precedence_declaration
|
||||||
|
| precedence_group_declaration
|
||||||
| symbol_declaration
|
| symbol_declaration
|
||||||
| "%start" symbol
|
| "%start" symbol
|
||||||
{
|
{
|
||||||
@@ -457,6 +462,30 @@ symbol_declaration:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* A group of symbols for precedence declaration */
|
||||||
|
precedence_group_declaration:
|
||||||
|
"%gprec" prec_group_name.opt
|
||||||
|
{
|
||||||
|
set_current_group ($2, &@2);
|
||||||
|
}
|
||||||
|
"{" precedence_declarations "}"
|
||||||
|
{
|
||||||
|
set_current_group (DEFAULT_GROUP_NAME, NULL);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Name for the precedence group. If none is present a new unique one is
|
||||||
|
generated. */
|
||||||
|
prec_group_name.opt:
|
||||||
|
%empty { $$ = new_anonymous_group_name (); }
|
||||||
|
| variable /* Just a string, maybe there's a better way? */
|
||||||
|
;
|
||||||
|
|
||||||
|
precedence_declarations:
|
||||||
|
precedence_declaration
|
||||||
|
| precedence_declarations precedence_declaration
|
||||||
|
;
|
||||||
|
|
||||||
precedence_declaration:
|
precedence_declaration:
|
||||||
precedence_declarator tag.opt symbols.prec
|
precedence_declarator tag.opt symbols.prec
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -223,6 +223,10 @@ eqopt ([[:space:]]*=)?
|
|||||||
"%fixed-output-files" return PERCENT_YACC;
|
"%fixed-output-files" return PERCENT_YACC;
|
||||||
"%initial-action" return PERCENT_INITIAL_ACTION;
|
"%initial-action" return PERCENT_INITIAL_ACTION;
|
||||||
"%glr-parser" return PERCENT_GLR_PARSER;
|
"%glr-parser" return PERCENT_GLR_PARSER;
|
||||||
|
"%gprec" {
|
||||||
|
prec_braces = gprec_seen;
|
||||||
|
return PERCENT_GPREC;
|
||||||
|
}
|
||||||
"%language" return PERCENT_LANGUAGE;
|
"%language" return PERCENT_LANGUAGE;
|
||||||
"%left" return PERCENT_LEFT;
|
"%left" return PERCENT_LEFT;
|
||||||
"%lex-param" RETURN_PERCENT_PARAM(lex);
|
"%lex-param" RETURN_PERCENT_PARAM(lex);
|
||||||
@@ -273,10 +277,16 @@ eqopt ([[:space:]]*=)?
|
|||||||
"=" return EQUAL;
|
"=" return EQUAL;
|
||||||
"|" return PIPE;
|
"|" return PIPE;
|
||||||
";" return SEMICOLON;
|
";" return SEMICOLON;
|
||||||
|
"}" return RBRACE;
|
||||||
|
|
||||||
{id} {
|
{id} {
|
||||||
val->uniqstr = uniqstr_new (yytext);
|
val->uniqstr = uniqstr_new (yytext);
|
||||||
id_loc = *loc;
|
id_loc = *loc;
|
||||||
|
if (prec_braces == gprec_seen)
|
||||||
|
{
|
||||||
|
prec_braces = group_name_seen;
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
bracketed_id_str = NULL;
|
bracketed_id_str = NULL;
|
||||||
BEGIN SC_AFTER_IDENTIFIER;
|
BEGIN SC_AFTER_IDENTIFIER;
|
||||||
}
|
}
|
||||||
@@ -307,6 +317,11 @@ eqopt ([[:space:]]*=)?
|
|||||||
|
|
||||||
/* Code in between braces. */
|
/* Code in between braces. */
|
||||||
"{" {
|
"{" {
|
||||||
|
if (prec_braces == gprec_seen || prec_braces == group_name_seen)
|
||||||
|
{
|
||||||
|
prec_braces = braces_seen;
|
||||||
|
return LBRACE;
|
||||||
|
}
|
||||||
STRING_GROW;
|
STRING_GROW;
|
||||||
nesting = 0;
|
nesting = 0;
|
||||||
code_start = loc->start;
|
code_start = loc->start;
|
||||||
|
|||||||
@@ -64,14 +64,13 @@ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
|
|||||||
AT_BISON_CHECK([input.y], [1], [],
|
AT_BISON_CHECK([input.y], [1], [],
|
||||||
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
||||||
input.y:3.1: error: invalid character: '?'
|
input.y:3.1: error: invalid character: '?'
|
||||||
input.y:4.14: error: invalid character: '}'
|
input.y:4.14: error: syntax error, unexpected }
|
||||||
input.y:5.1: error: invalid character: '%'
|
input.y:5.1: error: invalid character: '%'
|
||||||
input.y:5.2: error: invalid character: '&'
|
input.y:5.2: error: invalid character: '&'
|
||||||
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
|
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
|
||||||
input.y:7.1: error: invalid character: '%'
|
input.y:7.1: error: invalid character: '%'
|
||||||
input.y:7.2: error: invalid character: '-'
|
input.y:7.2: error: invalid character: '-'
|
||||||
input.y:8.1-9.0: error: missing '%}' at end of file
|
input.y:8.1-9.0: error: missing '%}' at end of file
|
||||||
input.y:8.1-9.0: error: syntax error, unexpected %{...%}
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|||||||
@@ -405,14 +405,13 @@ default: 'a' }
|
|||||||
|
|
||||||
AT_BISON_CHECK([input.y], [1], [],
|
AT_BISON_CHECK([input.y], [1], [],
|
||||||
[[input.y:2.1: error: invalid character: '?'
|
[[input.y:2.1: error: invalid character: '?'
|
||||||
input.y:3.14: error: invalid character: '}'
|
input.y:3.14: error: syntax error, unexpected }
|
||||||
input.y:4.1: error: invalid character: '%'
|
input.y:4.1: error: invalid character: '%'
|
||||||
input.y:4.2: error: invalid character: '&'
|
input.y:4.2: error: invalid character: '&'
|
||||||
input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
|
input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
|
||||||
input.y:6.1: error: invalid character: '%'
|
input.y:6.1: error: invalid character: '%'
|
||||||
input.y:6.2: error: invalid character: '-'
|
input.y:6.2: error: invalid character: '-'
|
||||||
input.y:7.1-8.0: error: missing '%}' at end of file
|
input.y:7.1-8.0: error: missing '%}' at end of file
|
||||||
input.y:7.1-8.0: error: syntax error, unexpected %{...%}
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user