Hello bison team.

I would like to submit a patch adding some kind of named symbol references
in input grammar. It looks like this:

tchk_definition
  : SETUP(kw) '(' timing_check_event(dat) ',' timing_check_event(ref) ','
timing_check_limit(lmt)
    notify_register_arg(reg) ')'
    {
      vcLinkTchk(accSetup, $ref, $dat, $lmt, $reg, vsc_scopeG, vsc_specifyG,
$kw.lineNum, $kw.srcInfo);
    }

@name (location info) is also supported.

This functionality has been already tested and used in my company for many
(5+) years, the original change was
done on 1.75 version. There are some big scale parsers (Verilog, Verilog
2001, VHDL) implemented using this syntax.

I understand that at least, documentaion and tests are missing. This is my
first time I am trying to contribute to bison,
so please provide me additional info about the process.

I attached the git generated patch mail.

-- 
Best regards,
Alex Rozenman ([email protected]).
From 32ec1a1f9d691c678be90b8af0111734764dbd5b Mon Sep 17 00:00:00 2001
From: Alex Rozenman <[email protected]>
Date: Thu, 22 Jan 2009 19:18:47 +0200
Subject: [PATCH] named symbol references implemented

---
 src/parse-gram.y |    6 +++-
 src/reader.c     |   14 +++++--
 src/reader.h     |    2 +-
 src/scan-code.l  |   97 ++++++++++++++++++++++++++++++++++++++++++------------
 src/scan-gram.l  |    2 +
 src/symlist.c    |    5 +++
 src/symlist.h    |    3 ++
 7 files changed, 102 insertions(+), 27 deletions(-)

diff --git a/src/parse-gram.y b/src/parse-gram.y
index cada04f..8e3f0de 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -170,6 +170,8 @@ static int current_prec = 0;
 %token TAG             "<tag>"
 %token TAG_ANY         "<*>"
 %token TAG_NONE        "<>"
+%token LEFT_PAREN      "("
+%token RIGHT_PAREN     ")"
 
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
@@ -531,7 +533,9 @@ rhs:
   /* Nothing.  */
     { grammar_current_rule_begin (current_lhs, current_lhs_location); }
 | rhs symbol
-    { grammar_current_rule_symbol_append ($2, @2); }
+    { grammar_current_rule_symbol_append ($2, @2, 0); }
+| rhs symbol "(" ID ")"
+    { grammar_current_rule_symbol_append ($2, @2, $4); }
 | rhs "{...}"
     { grammar_current_rule_action_append ($2, @2); }
 | rhs "%prec" symbol
diff --git a/src/reader.c b/src/reader.c
index 7758c77..a70fe06 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -169,7 +169,7 @@ free_merger_functions (void)
 static symbol_list *grammar_end = NULL;
 
 /* Append SYM to the grammar.  */
-static void
+static symbol_list *
 grammar_symbol_append (symbol *sym, location loc)
 {
   symbol_list *p = symbol_list_sym_new (sym, loc);
@@ -185,6 +185,8 @@ grammar_symbol_append (symbol *sym, location loc)
      part of it.  */
   if (sym)
     ++nritems;
+
+  return p;
 }
 
 /* The rule currently being defined, and the previous rule.
@@ -353,7 +355,7 @@ grammar_midrule_action (void)
 
   /* Insert the dummy nonterminal replacing the midrule action into
      the current rule.  Bind it to its dedicated rule.  */
-  grammar_current_rule_symbol_append (dummy, dummy_location);
+  grammar_current_rule_symbol_append (dummy, dummy_location, 0);
   grammar_end->midrule = midrule;
   midrule->midrule_parent_rule = current_rule;
   midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
@@ -402,11 +404,15 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
    action as a mid-rule action.  */
 
 void
-grammar_current_rule_symbol_append (symbol *sym, location loc)
+grammar_current_rule_symbol_append (symbol *sym, location loc, uniqstr accessor)
 {
+  symbol_list *p;
   if (current_rule->action_props.code)
     grammar_midrule_action ();
-  grammar_symbol_append (sym, loc);
+  p = grammar_symbol_append (sym, loc);
+  if (accessor) {
+    p->accessor = accessor;
+  }
 }
 
 /* Attach an ACTION to the current rule.  */
diff --git a/src/reader.h b/src/reader.h
index 2d73ab3..7334622 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -48,7 +48,7 @@ void grammar_midrule_action (void);
 void grammar_current_rule_prec_set (symbol *precsym, location loc);
 void grammar_current_rule_dprec_set (int dprec, location loc);
 void grammar_current_rule_merge_set (uniqstr name, location loc);
-void grammar_current_rule_symbol_append (symbol *sym, location loc);
+void grammar_current_rule_symbol_append (symbol *sym, location loc, uniqstr accessor);
 void grammar_current_rule_action_append (const char *action, location loc);
 void reader (void);
 void free_merger_functions (void);
diff --git a/src/scan-code.l b/src/scan-code.l
index 7a655fb..82f6f76 100644
--- a/src/scan-code.l
+++ b/src/scan-code.l
@@ -167,11 +167,11 @@ splice	 (\\[ \f\t\v]*\n)*
 
 <SC_RULE_ACTION>
 {
-  "$"("<"{tag}">")?(-?[0-9]+|"$")  {
+  "$"("<"{tag}">")?(-?[0-9A-Za-z_]+|"$")  {
     handle_action_dollar (self->rule, yytext, *loc);
     need_semicolon = true;
   }
-  "@"(-?[0-9]+|"$") {
+  "@"(-?[0-9A-Za-z_]+|"$") {
     handle_action_at (self->rule, yytext, *loc);
     need_semicolon = true;
   }
@@ -267,6 +267,60 @@ splice	 (\\[ \f\t\v]*\n)*
 
 %%
 
+static bool
+parse_symbol_reference(char *cp, symbol_list *rule, int rule_length, 
+                       char *text, location loc, int *result)
+{
+  if (('0' <= *cp && *cp <= '9') || *cp == '-')
+    {
+      long int num = strtol (cp, &cp, 10);
+      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
+        {
+          *result = num;
+          return true;
+        }
+      else
+        {
+          complain_at (loc, _("integer out of range: %s"), quote (text));
+          return false;
+        }
+    }
+  else 
+    {
+      long int ind;
+      symbol_list* l;
+      bool found = false;
+      uniqstr accessor = uniqstr_new(cp);
+
+      for (ind = 0, l = rule; 
+           l && !(l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL);
+           l = l->next, ind++)
+        {
+          if (l->accessor == accessor) {
+            found = true;
+            break;
+          }
+
+          if (l->content_type == SYMLIST_SYMBOL && 
+              l->content.sym->tag == accessor) {
+            found = true;
+            break;
+          }
+        }
+      
+      if (found)
+        {
+          *result = ind;
+          return true;
+        }
+      else
+        {
+          complain_at (loc, _("reference not found: %s"), quote (text));
+          return false;
+        }
+    }
+}
+
 /* Keeps track of the maximum number of semantic values to the left of
    a handle (those referenced by $0, $-1, etc.) are required by the
    semantic actions of this grammar. */
@@ -343,12 +397,10 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
     }
   else
     {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + effective_rule_length <= num
-	  && num <= effective_rule_length)
+      int n;
+      if (parse_symbol_reference (cp, effective_rule, effective_rule_length, 
+                                  text, dollar_loc, &n))
 	{
-	  int n = num;
 	  if (max_left_semantic_context < 1 - n)
 	    max_left_semantic_context = 1 - n;
 	  if (!type_name && 0 < n)
@@ -363,7 +415,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
 		untyped_var_seen = true;
 	      type_name = "";
 	    }
-
+          
 	  obstack_fgrow3 (&obstack_for_string,
 			  "]b4_rhs_value(%d, %d, [%s])[",
 			  effective_rule_length, n, type_name);
@@ -371,8 +423,6 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
             symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
               true;
 	}
-      else
-	complain_at (dollar_loc, _("integer out of range: %s"), quote (text));
     }
 }
 
@@ -386,10 +436,19 @@ static void
 handle_action_at (symbol_list *rule, char *text, location at_loc)
 {
   char *cp = text + 1;
-  int effective_rule_length =
-    (rule->midrule_parent_rule
-     ? rule->midrule_parent_rhs_index - 1
-     : symbol_list_length (rule->next));
+  symbol_list *effective_rule;
+  int effective_rule_length;
+
+  if (rule->midrule_parent_rule)
+    {
+      effective_rule = rule->midrule_parent_rule;
+      effective_rule_length = rule->midrule_parent_rhs_index - 1;
+    }
+  else
+    {
+      effective_rule = rule;
+      effective_rule_length = symbol_list_length (rule->next);
+    }
 
   locations_flag = true;
 
@@ -397,17 +456,13 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
     obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
   else
     {
-      long int num = strtol (cp, NULL, 10);
-
-      if (1 - INT_MAX + effective_rule_length <= num
-	  && num <= effective_rule_length)
+      int n;
+      if (parse_symbol_reference (cp, effective_rule, effective_rule_length, 
+                                  text, at_loc, &n))
 	{
-	  int n = num;
 	  obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
 			  effective_rule_length, n);
 	}
-      else
-	complain_at (at_loc, _("integer out of range: %s"), quote (text));
     }
 }
 
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 9a733bc..ca3e5a7 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -217,6 +217,8 @@ splice	 (\\[ \f\t\v]*\n)*
   "="                     return EQUAL;
   "|"                     return PIPE;
   ";"                     return SEMICOLON;
+  "("                     return LEFT_PAREN;
+  ")"                     return RIGHT_PAREN;
 
   {id} {
     val->uniqstr = uniqstr_new (yytext);
diff --git a/src/symlist.c b/src/symlist.c
index 6c6b57d..e856880 100644
--- a/src/symlist.c
+++ b/src/symlist.c
@@ -47,6 +47,8 @@ symbol_list_sym_new (symbol *sym, location loc)
   res->dprec = 0;
   res->merger = 0;
 
+  res->accessor = NULL;
+
   res->next = NULL;
 
   return res;
@@ -65,6 +67,7 @@ symbol_list_type_new (uniqstr type_name, location loc)
   res->content_type = SYMLIST_TYPE;
   res->content.type_name = type_name;
   res->location = loc;
+  res->accessor = NULL;
   res->next = NULL;
 
   return res;
@@ -82,6 +85,7 @@ symbol_list_default_tagged_new (location loc)
 
   res->content_type = SYMLIST_DEFAULT_TAGGED;
   res->location = loc;
+  res->accessor = NULL;
   res->next = NULL;
 
   return res;
@@ -99,6 +103,7 @@ symbol_list_default_tagless_new (location loc)
 
   res->content_type = SYMLIST_DEFAULT_TAGLESS;
   res->location = loc;
+  res->accessor = NULL;
   res->next = NULL;
 
   return res;
diff --git a/src/symlist.h b/src/symlist.h
index 992fd4e..db2ea42 100644
--- a/src/symlist.h
+++ b/src/symlist.h
@@ -69,6 +69,9 @@ typedef struct symbol_list
   int merger;
   location merger_declaration_location;
 
+  /* Symbolic accessor. */
+  uniqstr accessor;
+
   /* The list.  */
   struct symbol_list *next;
 } symbol_list;
-- 
1.5.3.4

Reply via email to