bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/7] syntax: introducing %gprec for precedence groups


From: Valentin Tolmer
Subject: [PATCH 3/7] syntax: introducing %gprec for precedence groups
Date: Thu, 1 Aug 2013 16:04:51 +0200

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
---
 src/gram.c          |    2 ++
 src/gram.h          |   11 +++++++++++
 src/parse-gram.y    |   29 +++++++++++++++++++++++++++++
 src/scan-gram.l     |   15 +++++++++++++++
 tests/input.at      |    3 +--
 tests/regression.at |    3 +--
 6 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/gram.c b/src/gram.c
index 66f550c..7a58cec 100644
--- a/src/gram.c
+++ b/src/gram.c
@@ -44,6 +44,8 @@ int nvars = 0;
 
 symbol_number *token_translations = NULL;
 
+enum braces_state prec_braces = 0;
+
 int max_user_token_number = 256;
 
 bool
diff --git a/src/gram.h b/src/gram.h
index 52de2de..50e442d 100644
--- a/src/gram.h
+++ b/src/gram.h
@@ -117,6 +117,17 @@ typedef int item_number;
 extern item_number *ritem;
 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
    symbol_number and rule_number: we store the latter in
    item_number.  symbol_number values are stored as-is, while
diff --git a/src/parse-gram.y b/src/parse-gram.y
index 1ec4b4d..89af756 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -130,6 +130,7 @@
 
 %token PERCENT_PREC          "%prec"
 %token PERCENT_DPREC         "%dprec"
+%token PERCENT_GPREC         "%gprec"
 %token PERCENT_MERGE         "%merge"
 
 /*----------------------.
@@ -178,6 +179,8 @@
 %token TAG             "<tag>"
 %token TAG_ANY         "<*>"
 %token TAG_NONE        "<>"
+%token LBRACE          "{"
+%token RBRACE          "}"
 
 %union {unsigned char character;}
 %type <character> CHAR
@@ -214,6 +217,7 @@
 %union {named_ref *named_ref;}
 %type <named_ref> named_ref.opt
 
+%type <uniqstr> prec_group_name.opt
 /*---------.
 | %param.  |
 `---------*/
@@ -365,6 +369,7 @@ params:
 
 grammar_declaration:
   precedence_declaration
+| precedence_group_declaration
 | symbol_declaration
 | "%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_declarator tag.opt symbols.prec
     {
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 665e80d..f5157c9 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -223,6 +223,10 @@ eqopt    ([[:space:]]*=)?
   "%fixed-output-files"             return PERCENT_YACC;
   "%initial-action"                 return PERCENT_INITIAL_ACTION;
   "%glr-parser"                     return PERCENT_GLR_PARSER;
+  "%gprec"                          {
+                                      prec_braces = gprec_seen;
+                                      return PERCENT_GPREC;
+                                    }
   "%language"                       return PERCENT_LANGUAGE;
   "%left"                           return PERCENT_LEFT;
   "%lex-param"                      RETURN_PERCENT_PARAM(lex);
@@ -273,10 +277,16 @@ eqopt    ([[:space:]]*=)?
   "="                     return EQUAL;
   "|"                     return PIPE;
   ";"                     return SEMICOLON;
+  "}"                     return RBRACE;
 
   {id} {
     val->uniqstr = uniqstr_new (yytext);
     id_loc = *loc;
+    if (prec_braces == gprec_seen)
+    {
+      prec_braces = group_name_seen;
+      return ID;
+    }
     bracketed_id_str = NULL;
     BEGIN SC_AFTER_IDENTIFIER;
   }
@@ -307,6 +317,11 @@ eqopt    ([[:space:]]*=)?
 
   /* Code in between braces.  */
   "{" {
+    if (prec_braces == gprec_seen || prec_braces == group_name_seen)
+    {
+      prec_braces = braces_seen;
+      return LBRACE;
+    }
     STRING_GROW;
     nesting = 0;
     code_start = loc->start;
diff --git a/tests/input.at b/tests/input.at
index 1548f14..f05a989 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -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], [],
 [[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
 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.2: error: invalid character: '&'
 input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
 input.y:7.1: 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: syntax error, unexpected %{...%}
 ]])
 
 AT_CLEANUP
diff --git a/tests/regression.at b/tests/regression.at
index b9ca94c..f2edccc 100644
--- a/tests/regression.at
+++ b/tests/regression.at
@@ -405,14 +405,13 @@ default: 'a' }
 
 AT_BISON_CHECK([input.y], [1], [],
 [[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.2: error: invalid character: '&'
 input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
 input.y:6.1: 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: syntax error, unexpected %{...%}
 ]])
 
 AT_CLEANUP
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]