From 32ec1a1f9d691c678be90b8af0111734764dbd5b Mon Sep 17 00:00:00 2001
From: Alex Rozenman
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 ""
%token TAG_ANY "<*>"
%token TAG_NONE "<>"
+%token LEFT_PAREN "("
+%token RIGHT_PAREN ")"
%type 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)*
{
- "$"("<"{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