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