105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Bison Action Scanner                             -*- C -*-
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 2006-2012 Free Software Foundation, Inc.
405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This file is part of Bison, the GNU Compiler Compiler.
605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software: you can redistribute it and/or modify
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   it under the terms of the GNU General Public License as published by
905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the Free Software Foundation, either version 3 of the License, or
1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (at your option) any later version.
1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is distributed in the hope that it will be useful,
1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   but WITHOUT ANY WARRANTY; without even the implied warranty of
1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   GNU General Public License for more details.
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   You should have received a copy of the GNU General Public License
1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang%option debug nodefault noinput nounput noyywrap never-interactive
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang%option prefix="code_" outfile="lex.yy.c"
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang%{
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Work around a bug in flex 2.5.31.  See Debian bug 333231
2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#undef code_wrap
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define code_wrap() 1
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define FLEX_PREFIX(Id) code_ ## Id
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "flex-scanner.h"
3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "complain.h"
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "reader.h"
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "getargs.h"
3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "scan-code.h"
3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "symlist.h"
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <c-ctype.h>
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <get-errno.h>
4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <quote.h>
4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The current calling start condition: SC_RULE_ACTION or
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   SC_SYMBOL_ACTION. */
4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define YY_DECL static char *code_lex (code_props *self, int sc_context)
4505436638acc7c010349a69c3395f1a57c642dc62Ying WangYY_DECL;
4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define YY_USER_ACTION  location_compute (loc, &loc->end, yytext, yyleng);
4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *fetch_type_name (char *cp, char const **type_name,
5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                              location dollar_loc);
5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void handle_action_dollar (symbol_list *rule, char *cp,
5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang				  location dollar_loc);
5405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void handle_action_at (symbol_list *rule, char *cp, location at_loc);
5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A string to be pushed to obstack after dollar/at has been handled. */
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *ref_tail_fields;
5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic location the_location;
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic location *loc = &the_location;
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A string representing the most recent translation.  */
6305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *last_string;
6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* True if an untyped $$ or $n was seen.  */
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic bool untyped_var_seen;
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang%}
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* C and C++ comments in code. */
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang%x SC_COMMENT SC_LINE_COMMENT
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Strings and characters in code. */
7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang%x SC_STRING SC_CHARACTER
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Whether in a rule or symbol action.  Specifies the translation
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    of $ and @.  */
7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang%x SC_RULE_ACTION SC_SYMBOL_ACTION
7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* POSIX says that a tag must be both an id and a C union member, but
7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   historically almost any character is allowed in a tag.  We disallow
8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   NUL and newline, as this simplifies our implementation.  */
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtag	 [^\0\n>]+
8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Zero or more instances of backslash-newline.  Following GCC, allow
8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   white space between the backslash and the newline.  */
8505436638acc7c010349a69c3395f1a57c642dc62Ying Wangsplice	 (\\[ \f\t\v]*\n)*
8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* C style identifier. Must start with letter. Will be used for
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   named symbol references. Shall be kept synchronized with
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   scan-gram.l "letter" and "id". */
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wangletter	  [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wangid	  {letter}({letter}|[-0-9])*
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wangref      -?[0-9]+|{id}|"["{id}"]"|"$"
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang%%
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang%{
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Nesting level of the current code in braces.  */
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int braces_level = 0;
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Whether a semicolon is probably needed.
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     The heuristic is that a semicolon is not needed after '{', '}',
10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ';', or a C preprocessor directive, and that whitespaces and
10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     comments do not affect this flag.  Note that '{' does not need a
10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     semicolon because of '{}'.  A semicolon may be needed before a
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     cpp directive, but don't bother.
10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     While it is maintained in several start-conditions (factoring
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     opportunities), it is meaningful only for SC_RULE_ACTION. */
11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  bool need_semicolon = false;
11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Whether in a C preprocessor directive.  Don't use a start condition
11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     for this because, at the end of strings and comments, we still need
11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     to know whether we're in a directive.  */
11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  bool in_cpp = false;
11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* This scanner is special: it is invoked only once, henceforth
11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     is expected to return only once.  This initialization is
11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     therefore done once per action to translate. */
12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  aver (sc_context == SC_SYMBOL_ACTION
12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	|| sc_context == SC_RULE_ACTION
12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	|| sc_context == INITIAL);
12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  BEGIN sc_context;
12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang%}
12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /*------------------------------------------------------------.
12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  | Scanning a C comment.  The initial '/ *' is already eaten.  |
12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  `------------------------------------------------------------*/
12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_COMMENT>
13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "*"{splice}"/"  STRING_GROW; BEGIN sc_context;
13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /*--------------------------------------------------------------.
13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  | Scanning a line comment.  The initial '//' is already eaten.  |
13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  `--------------------------------------------------------------*/
13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_LINE_COMMENT>
14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "\n"		 STRING_GROW; BEGIN sc_context;
14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {splice}	 STRING_GROW;
14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /*--------------------------------------------.
14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  | Scanning user-code characters and strings.  |
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  `--------------------------------------------*/
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_CHARACTER,SC_STRING>
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {splice}|\\{splice}.	STRING_GROW;
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_CHARACTER>
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "'"		STRING_GROW; BEGIN sc_context;
15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_STRING>
16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "\""		STRING_GROW; BEGIN sc_context;
16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_RULE_ACTION,SC_SYMBOL_ACTION>
16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "'" {
17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW;
17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BEGIN SC_CHARACTER;
17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "\"" {
17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW;
17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BEGIN SC_STRING;
17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "/"{splice}"*" {
18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW;
18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BEGIN SC_COMMENT;
18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "/"{splice}"/" {
18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW;
18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    BEGIN SC_LINE_COMMENT;
18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [$@]  {
18805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    warn_at (*loc, _("stray '%s'"), yytext);
18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_escape (&obstack_for_string, yytext);
19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [\[\]]  {
19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_escape (&obstack_for_string, yytext);
19405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
19605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
19705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_RULE_ACTION>
19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "$"("<"{tag}">")?{ref}  {
20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    ref_tail_fields = NULL;
20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    handle_action_dollar (self->rule, yytext, *loc);
20305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (ref_tail_fields)
20405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, ref_tail_fields);
20505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "@"{ref} {
20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    ref_tail_fields = NULL;
20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    handle_action_at (self->rule, yytext, *loc);
21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (ref_tail_fields)
21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, ref_tail_fields);
21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = true;
21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  ";"  STRING_GROW;                 need_semicolon = false;
21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "{"  STRING_GROW; ++braces_level; need_semicolon = false;
21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "}"  {
21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    bool outer_brace = --braces_level == 0;
21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* As an undocumented Bison extension, append ';' before the last
22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang       brace in braced code, so that the user code can omit trailing
22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang       ';'.  But do not append ';' if emulating Yacc, since Yacc does
22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang       not append one.  This is deprecated since release 2.4.1.  */
22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (outer_brace && !yacc_flag && language_prio == default_prio
22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        && skeleton_prio == default_prio && need_semicolon && ! in_cpp)
22605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
22705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        unsigned int indent = 0;
22805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        warn_at_indent (*loc, &indent,
22905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       _("a ';' might be needed at the end of action code"));
23005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        indent += SUB_INDENT;
23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        warn_at_indent (*loc, &indent,
23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       _("future versions of Bison will not add the ';'"));
23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        obstack_1grow (&obstack_for_string, ';');
23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW;
23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    need_semicolon = false;
23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Preprocessing directives should only be recognized at the beginning
24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     of lines, allowing whitespace including comments, but in C/C++,
24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     '#' can only be the start of preprocessor directives or within
24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     '#define' directives anyway, so don't bother with begin of line.  */
24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "#"       STRING_GROW; in_cpp = true;
24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {splice}  STRING_GROW;
24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [\n\r]    STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [ \t\f]   STRING_GROW;
24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* YYFAIL is undocumented and was formally deprecated in Bison
25105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     2.4.2.  */
25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  YYFAIL {
25305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STRING_GROW; need_semicolon = true;
25405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    warn_at (*loc, _("use of YYFAIL, which is deprecated and will be"
25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                     " removed"));
25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* The sole purpose of this is to make sure identifiers that merely
25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     contain YYFAIL don't produce the above warning.  */
26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [A-Za-z_][0-9A-Za-z_]* STRING_GROW; need_semicolon = true;
26105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  . STRING_GROW; need_semicolon = true;
26305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
26405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26505436638acc7c010349a69c3395f1a57c642dc62Ying Wang<SC_SYMBOL_ACTION>
26605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
26705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "$"("<"{tag}">")?"$" {
26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    const char *type_name = NULL;
26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    fetch_type_name (yytext + 1, &type_name, *loc)[-1] = 0;
27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_quote (&obstack_for_string, type_name);
27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_sgrow (&obstack_for_string, ")[");
27305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    self->is_value_used = true;
27405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
27505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "@$" {
27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    locations_flag = true;
27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
27905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
28005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
28105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
28205436638acc7c010349a69c3395f1a57c642dc62Ying Wang<*>
28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Escape M4 quoting characters in C code.  */
28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  [$@\[\]]    obstack_escape (&obstack_for_string, yytext);
28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
28705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* By default, grow the string obstack with the input.  */
28805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  .|\n        STRING_GROW;
28905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* End of processing. */
29105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  <<EOF>>     STRING_FINISH; return last_string;
29205436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
29305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29405436638acc7c010349a69c3395f1a57c642dc62Ying Wang%%
29505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline bool
29705436638acc7c010349a69c3395f1a57c642dc62Ying Wangis_dot_or_dash (char ch)
29805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
29905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return ch == '.' || ch == '-';
30005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
30105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
30205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline bool
30305436638acc7c010349a69c3395f1a57c642dc62Ying Wangcontains_dot_or_dash (const char* p)
30405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (; *p; ++p)
30605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (is_dot_or_dash (*p))
30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      return true;
30805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return false;
30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Defines a variant of a symbolic name resolution. */
31205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
31405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Index in symbol list. */
31505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned symbol_index;
31605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
31705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Matched symbol id and loc. */
31805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  uniqstr id;
31905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  location loc;
32005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Hiding named reference. */
32205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  named_ref* hidden_by;
32305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Error flags. May contain zero (no errors) or
32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     a combination of VARIANT_* values. */
32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned err;
32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} variant;
32805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Set when the variant refers to a symbol hidden
33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   by an explicit symbol reference. */
33105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define VARIANT_HIDDEN (1 << 0)
33205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
33305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Set when the variant refers to a symbol containing
33405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   dots or dashes. Will require explicit bracketing. */
33505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define VARIANT_BAD_BRACKETING (1 << 1)
33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
33705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Set when the variant refers to a symbol which is
33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   not visible from current midrule. */
33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2)
34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
34105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic variant *variant_table = NULL;
34205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic unsigned variant_table_size = 0;
34305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic unsigned variant_count = 0;
34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
34505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic variant *
34605436638acc7c010349a69c3395f1a57c642dc62Ying Wangvariant_table_grow (void)
34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
34805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  ++variant_count;
34905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (variant_count > variant_table_size)
35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      while (variant_count > variant_table_size)
35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	variant_table_size = 2 * variant_table_size + 3;
35305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      variant_table = xnrealloc (variant_table, variant_table_size,
35405436638acc7c010349a69c3395f1a57c642dc62Ying Wang				 sizeof *variant_table);
35505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
35605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return &variant_table[variant_count - 1];
35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
35905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
36005436638acc7c010349a69c3395f1a57c642dc62Ying Wangvariant_table_free (void)
36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
36205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  free (variant_table);
36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  variant_table = NULL;
36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  variant_table_size = variant_count = 0;
36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
36605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
36705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *
36805436638acc7c010349a69c3395f1a57c642dc62Ying Wangfind_prefix_end (const char *prefix, char *begin, char *end)
36905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *ptr = begin;
37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (; *prefix && ptr != end; ++prefix, ++ptr)
37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (*prefix != *ptr)
37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      return 0;
37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (*prefix)
37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return 0;
37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return ptr;
38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic variant *
38305436638acc7c010349a69c3395f1a57c642dc62Ying Wangvariant_add (uniqstr id, location id_loc, unsigned symbol_index,
38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	     char *cp, char *cp_end, bool explicit_bracketing)
38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
38605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *prefix_end;
38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  prefix_end = find_prefix_end (id, cp, cp_end);
38905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (prefix_end &&
39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (prefix_end == cp_end ||
39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang       (!explicit_bracketing && is_dot_or_dash (*prefix_end))))
39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      variant *r = variant_table_grow ();
39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      r->symbol_index = symbol_index;
39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      r->id = id;
39605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      r->loc = id_loc;
39705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      r->hidden_by = NULL;
39805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      r->err = 0;
39905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      return r;
40005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
40105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
40205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return NULL;
40305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
40405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
40505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic const char *
40605436638acc7c010349a69c3395f1a57c642dc62Ying Wangget_at_spec (unsigned symbol_index)
40705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
40805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  static char at_buf[20];
40905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (symbol_index == 0)
41005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    strcpy (at_buf, "$$");
41105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
41205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    snprintf (at_buf, sizeof at_buf, "$%u", symbol_index);
41305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return at_buf;
41405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
41505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
41605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
41705436638acc7c010349a69c3395f1a57c642dc62Ying Wangshow_sub_messages (const char* cp, bool explicit_bracketing,
41805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   int midrule_rhs_index, char dollar_or_at,
41905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   bool is_warning, unsigned indent)
42005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
42105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned i;
42205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
42305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (i = 0; i < variant_count; ++i)
42405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
42505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      const variant *var = &variant_table[i];
42605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      const char *at_spec = get_at_spec (var->symbol_index);
42705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
42805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (var->err == 0)
42905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
43005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (is_warning)
43105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
43205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            dollar_or_at, var->id, at_spec);
43305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else
43405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"),
43505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                dollar_or_at, var->id, at_spec);
43605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
43705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      else
43805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	{
43905436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  static struct obstack msg_buf;
44005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  const char *tail = explicit_bracketing ? "" :
44105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    cp + strlen (var->id);
44205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  const char *id = var->hidden_by ? var->hidden_by->id :
44305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    var->id;
44405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  location id_loc = var->hidden_by ? var->hidden_by->loc :
44505436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    var->loc;
44605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
44705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  /* Create the explanation message. */
44805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_init (&msg_buf);
44905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
45005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at);
45105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  if (contains_dot_or_dash (id))
45205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    obstack_printf (&msg_buf, "[%s]", id);
45305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  else
45405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    obstack_sgrow (&msg_buf, id);
45505436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_sgrow (&msg_buf, tail);
45605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
45705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  if (var->err & VARIANT_HIDDEN)
45805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    {
45905436638acc7c010349a69c3395f1a57c642dc62Ying Wang	      obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at);
46005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	      if (contains_dot_or_dash (var->id))
46105436638acc7c010349a69c3395f1a57c642dc62Ying Wang		obstack_printf (&msg_buf, "[%s]", var->id);
46205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	      else
46305436638acc7c010349a69c3395f1a57c642dc62Ying Wang		obstack_sgrow (&msg_buf, var->id);
46405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	      obstack_sgrow (&msg_buf, tail);
46505436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    }
46605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
46705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_printf (&msg_buf, _(" at %s"), at_spec);
46805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
46905436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE)
47005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
47105436638acc7c010349a69c3395f1a57c642dc62Ying Wang              const char *format =
47205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                _(", cannot be accessed from mid-rule action at $%d");
47305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              obstack_printf (&msg_buf, format, midrule_rhs_index);
47405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
47505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
47605436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_1grow (&msg_buf, '\0');
47705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (is_warning)
47805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            warn_at_indent (id_loc, &indent, "%s",
47905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            (char *) obstack_finish (&msg_buf));
48005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else
48105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at_indent (id_loc, &indent, "%s",
48205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                (char *) obstack_finish (&msg_buf));
48305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  obstack_free (&msg_buf, 0);
48405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	}
48505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
48605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
48705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Returned from "parse_ref" when the reference
48905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   is inappropriate. */
49005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define INVALID_REF (INT_MIN)
49105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
49205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Returned from "parse_ref" when the reference
49305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   points to LHS ($$) of the current rule or midrule. */
49405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define LHS_REF (INT_MIN + 1)
49505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
49605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Parse named or positional reference. In case of positional
49705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   references, can return negative values for $-n "deep" stack
49805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   accesses. */
49905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic long int
50005436638acc7c010349a69c3395f1a57c642dc62Ying Wangparse_ref (char *cp, symbol_list *rule, int rule_length,
50105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	   int midrule_rhs_index, char *text, location text_loc,
50205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	   char dollar_or_at)
50305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
50405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  symbol_list *l;
50505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *cp_end;
50605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  bool explicit_bracketing;
50705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned i;
50805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned valid_variants = 0;
50905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned valid_variant_index = 0;
51005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if ('$' == *cp)
51205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return LHS_REF;
51305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (c_isdigit (*cp) || (*cp == '-' && c_isdigit (* (cp + 1))))
51505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
51605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      long int num = strtol (cp, &cp, 10);
51705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (1 - INT_MAX + rule_length <= num && num <= rule_length)
51805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	return num;
51905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      else
52005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	{
52105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  complain_at (text_loc, _("integer out of range: %s"),
52205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       quote (text));
52305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  return INVALID_REF;
52405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	}
52505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
52605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if ('[' == *cp)
52805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
52905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Ignore the brackets. */
53005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      char *p;
53105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (p = ++cp; *p != ']'; ++p)
53205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	continue;
53305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      cp_end = p;
53405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
53505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      explicit_bracketing = true;
53605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
53705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
53805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
53905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Take all characters of the name. */
54005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      char* p;
54105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (p = cp; *p; ++p)
54205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	if (is_dot_or_dash (*p))
54305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  {
54405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    ref_tail_fields = p;
54505436638acc7c010349a69c3395f1a57c642dc62Ying Wang	    break;
54605436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  }
54705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (p = cp; *p; ++p)
54805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	continue;
54905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      cp_end = p;
55005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
55105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      explicit_bracketing = false;
55205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
55305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
55405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Add all relevant variants. */
55505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {
55605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    unsigned symbol_index;
55705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    variant_count = 0;
55805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    for (symbol_index = 0, l = rule; !symbol_list_null (l);
55905436638acc7c010349a69c3395f1a57c642dc62Ying Wang         ++symbol_index, l = l->next)
56005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
56105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	variant *var;
56205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	if (l->content_type != SYMLIST_SYMBOL)
56305436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  continue;
56405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
56505436638acc7c010349a69c3395f1a57c642dc62Ying Wang	var = variant_add (l->content.sym->tag, l->sym_loc,
56605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                           symbol_index, cp, cp_end, explicit_bracketing);
56705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	if (var && l->named_ref)
56805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  var->hidden_by = l->named_ref;
56905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
57005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	if (l->named_ref)
57105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  variant_add (l->named_ref->id, l->named_ref->loc,
57205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       symbol_index, cp, cp_end, explicit_bracketing);
57305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
57405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  }
57505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
57605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Check errors. */
57705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (i = 0; i < variant_count; ++i)
57805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
57905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      variant *var = &variant_table[i];
58005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      unsigned symbol_index = var->symbol_index;
58105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
58205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Check visibility from mid-rule actions. */
58305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (midrule_rhs_index != 0
58405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  && (symbol_index == 0 || midrule_rhs_index < symbol_index))
58505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        var->err |= VARIANT_NOT_VISIBLE_FROM_MIDRULE;
58605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
58705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Check correct bracketing. */
58805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!explicit_bracketing && contains_dot_or_dash (var->id))
58905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        var->err |= VARIANT_BAD_BRACKETING;
59005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
59105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Check using of hidden symbols. */
59205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (var->hidden_by)
59305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        var->err |= VARIANT_HIDDEN;
59405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
59505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!var->err)
59605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
59705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          valid_variant_index = i;
59805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          ++valid_variants;
59905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
60005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
60105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
60205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  switch (valid_variants)
60305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
60405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case 0:
60505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
60605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        unsigned len = (explicit_bracketing || !ref_tail_fields) ?
60705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          cp_end - cp : ref_tail_fields - cp;
60805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        unsigned indent = 0;
60905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        complain_at_indent (text_loc, &indent, _("invalid reference: %s"),
61105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            quote (text));
61205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        indent += SUB_INDENT;
61305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (len == 0)
61405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
61505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            location sym_loc = text_loc;
61605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            sym_loc.start.column += 1;
61705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            sym_loc.end = sym_loc.start;
61805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            const char *format =
61905436638acc7c010349a69c3395f1a57c642dc62Ying Wang              _("syntax error after '%c', expecting integer, letter,"
62005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                " '_', '[', or '$'");
62105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at_indent (sym_loc, &indent, format, dollar_or_at);
62205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
62305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        else if (midrule_rhs_index)
62405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
62505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            const char *format =
62605436638acc7c010349a69c3395f1a57c642dc62Ying Wang              _("symbol not found in production before $%d: %.*s");
62705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at_indent (rule->location, &indent, format,
62805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                midrule_rhs_index, len, cp);
62905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
63005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        else
63105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
63205436638acc7c010349a69c3395f1a57c642dc62Ying Wang            const char *format =
63305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              _("symbol not found in production: %.*s");
63405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at_indent (rule->location, &indent, format,
63505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                len, cp);
63605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
63705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
63805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (variant_count > 0)
63905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
64005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             dollar_or_at, false, indent);
64105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        return INVALID_REF;
64205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
64305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case 1:
64405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
64505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        unsigned indent = 0;
64605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (variant_count > 1)
64705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
64805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            warn_at_indent (text_loc, &indent, _("misleading reference: %s"),
64905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            quote (text));
65005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
65105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                               dollar_or_at, true, indent + SUB_INDENT);
65205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
65305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
65405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned symbol_index =
65505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            variant_table[valid_variant_index].symbol_index;
65605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          return (symbol_index == midrule_rhs_index) ? LHS_REF : symbol_index;
65705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
65805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
65905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case 2:
66005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    default:
66105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
66205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        unsigned indent = 0;
66305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"),
66405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            quote (text));
66505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        show_sub_messages (cp, explicit_bracketing, midrule_rhs_index,
66605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                           dollar_or_at, false, indent + SUB_INDENT);
66705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        return INVALID_REF;
66805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
66905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
67005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
67105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Not reachable. */
67205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return INVALID_REF;
67305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
67405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
67505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Keeps track of the maximum number of semantic values to the left of
67605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   a handle (those referenced by $0, $-1, etc.) are required by the
67705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   semantic actions of this grammar. */
67805436638acc7c010349a69c3395f1a57c642dc62Ying Wangint max_left_semantic_context = 0;
67905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
68005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
68105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* If CP points to a typename (i.e., <.*?>), set TYPE_NAME to its
68205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   beginning (i.e., after the opening "<", and return the pointer
68305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   immediately after it.  */
68405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
68505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic
68605436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
68705436638acc7c010349a69c3395f1a57c642dc62Ying Wangfetch_type_name (char *cp, char const **type_name,
68805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 location dollar_loc)
68905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
69005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (*cp == '<')
69105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
69205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      *type_name = ++cp;
69305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      while (*cp != '>')
69405436638acc7c010349a69c3395f1a57c642dc62Ying Wang	++cp;
69505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
69605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* The '>' symbol will be later replaced by '\0'. Original
69705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	 'text' is needed for error messages. */
69805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      ++cp;
69905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (untyped_var_seen)
70005436638acc7c010349a69c3395f1a57c642dc62Ying Wang	complain_at (dollar_loc, _("explicit type given in untyped grammar"));
70105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      tag_seen = true;
70205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
70305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return cp;
70405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
70505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
70605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------------.
70705436638acc7c010349a69c3395f1a57c642dc62Ying Wang| TEXT is pointing to a wannabee semantic value (i.e., a '$').      |
70805436638acc7c010349a69c3395f1a57c642dc62Ying Wang|                                                                   |
70905436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Possible inputs: $[<TYPENAME>]($|integer)                         |
71005436638acc7c010349a69c3395f1a57c642dc62Ying Wang|                                                                   |
71105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
71205436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------------*/
71305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
71405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
71505436638acc7c010349a69c3395f1a57c642dc62Ying Wanghandle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
71605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
71705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char const *type_name = NULL;
71805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *cp = text + 1;
71905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  symbol_list *effective_rule;
72005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int effective_rule_length;
72105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int n;
72205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
72305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (rule->midrule_parent_rule)
72405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
72505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule = rule->midrule_parent_rule;
72605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule_length = rule->midrule_parent_rhs_index - 1;
72705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
72805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
72905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
73005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule = rule;
73105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule_length = symbol_list_length (rule->next);
73205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
73305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
73405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Get the type name if explicit. */
73505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  cp = fetch_type_name (cp, &type_name, dollar_loc);
73605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
73705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  n = parse_ref (cp, effective_rule, effective_rule_length,
73805436638acc7c010349a69c3395f1a57c642dc62Ying Wang		 rule->midrule_parent_rhs_index, text, dollar_loc, '$');
73905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
74005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* End type_name. */
74105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (type_name)
74205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    cp[-1] = '\0';
74305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
74405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  switch (n)
74505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
74605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case INVALID_REF:
74705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
74805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
74905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case LHS_REF:
75005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!type_name)
75105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
75205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
75305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!type_name)
75405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
75505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (union_seen | tag_seen)
75605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
75705436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (rule->midrule_parent_rule)
75805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                complain_at (dollar_loc,
75905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             _("$$ for the midrule at $%d of %s"
76005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                               " has no declared type"),
76105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             rule->midrule_parent_rhs_index,
76205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             quote (effective_rule->content.sym->tag));
76305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              else
76405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                complain_at (dollar_loc, _("$$ of %s has no declared type"),
76505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             quote (rule->content.sym->tag));
76605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
76705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else
76805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            untyped_var_seen = true;
76905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
77005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
77105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, "]b4_lhs_value(");
77205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_quote (&obstack_for_string, type_name);
77305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, ")[");
77405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      rule->action_props.is_value_used = true;
77505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
77605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
77705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    default:
77805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (max_left_semantic_context < 1 - n)
77905436638acc7c010349a69c3395f1a57c642dc62Ying Wang	max_left_semantic_context = 1 - n;
78005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!type_name && 0 < n)
78105436638acc7c010349a69c3395f1a57c642dc62Ying Wang	type_name =
78205436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
78305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!type_name)
78405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
78505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (union_seen | tag_seen)
78605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            complain_at (dollar_loc, _("$%s of %s has no declared type"),
78705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                         cp, quote (effective_rule->content.sym->tag));
78805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else
78905436638acc7c010349a69c3395f1a57c642dc62Ying Wang            untyped_var_seen = true;
79005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
79105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
79205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_printf (&obstack_for_string,
79305436638acc7c010349a69c3395f1a57c642dc62Ying Wang		      "]b4_rhs_value(%d, %d, ", effective_rule_length, n);
79405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_quote (&obstack_for_string, type_name);
79505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, ")[");
79605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (n > 0)
79705436638acc7c010349a69c3395f1a57c642dc62Ying Wang	symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
79805436638acc7c010349a69c3395f1a57c642dc62Ying Wang	  true;
79905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
80005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
80105436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
80205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------.
80505436638acc7c010349a69c3395f1a57c642dc62Ying Wang| TEXT is a location token (i.e., a '@...').  Output to |
80605436638acc7c010349a69c3395f1a57c642dc62Ying Wang| OBSTACK_FOR_STRING a reference to this location.      |
80705436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------*/
80805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
81005436638acc7c010349a69c3395f1a57c642dc62Ying Wanghandle_action_at (symbol_list *rule, char *text, location at_loc)
81105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
81205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *cp = text + 1;
81305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  symbol_list *effective_rule;
81405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int effective_rule_length;
81505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int n;
81605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
81705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (rule->midrule_parent_rule)
81805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
81905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule = rule->midrule_parent_rule;
82005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule_length = rule->midrule_parent_rhs_index - 1;
82105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
82205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
82305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
82405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule = rule;
82505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      effective_rule_length = symbol_list_length (rule->next);
82605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
82705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
82805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  locations_flag = true;
82905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
83005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  n = parse_ref (cp, effective_rule, effective_rule_length,
83105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 rule->midrule_parent_rhs_index, text, at_loc, '@');
83205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  switch (n)
83305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
83405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case INVALID_REF:
83505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
83605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
83705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case LHS_REF:
83805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
83905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
84005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
84105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    default:
84205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
84305436638acc7c010349a69c3395f1a57c642dc62Ying Wang		      effective_rule_length, n);
84405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      break;
84505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
84605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
84705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
84805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
84905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*-------------------------.
85005436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Initialize the scanner.  |
85105436638acc7c010349a69c3395f1a57c642dc62Ying Wang`-------------------------*/
85205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
85305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Translate the dollars and ats in \a self, in the context \a sc_context
85405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
85505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
85605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char const *
85705436638acc7c010349a69c3395f1a57c642dc62Ying Wangtranslate_action (code_props *self, int sc_context)
85805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
85905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *res;
86005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  static bool initialized = false;
86105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!initialized)
86205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
86305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      obstack_init (&obstack_for_string);
86405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      yy_flex_debug = 0;
86505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      initialized = true;
86605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
86705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
86805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  loc->start = loc->end = self->location.start;
86905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  yy_switch_to_buffer (yy_scan_string (self->code));
87005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  res = code_lex (self, sc_context);
87105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  yy_delete_buffer (YY_CURRENT_BUFFER);
87205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
87305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return res;
87405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
87505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
87605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------------------.
87705436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Implementation of the public interface as documented in "scan-code.h".  |
87805436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------------------*/
87905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88005436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
88105436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props_none_init (code_props *self)
88205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
88305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  *self = code_props_none;
88405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
88505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88605436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props const code_props_none = CODE_PROPS_NONE_INIT;
88705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88805436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
88905436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props_plain_init (code_props *self, char const *code,
89005436638acc7c010349a69c3395f1a57c642dc62Ying Wang		       location code_loc)
89105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
89205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->kind = CODE_PROPS_PLAIN;
89305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->code = code;
89405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->location = code_loc;
89505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->is_value_used = false;
89605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->rule = NULL;
89705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->named_ref = NULL;
89805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
89905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
90005436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
90105436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props_symbol_action_init (code_props *self, char const *code,
90205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                               location code_loc)
90305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
90405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->kind = CODE_PROPS_SYMBOL_ACTION;
90505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->code = code;
90605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->location = code_loc;
90705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->is_value_used = false;
90805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->rule = NULL;
90905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->named_ref = NULL;
91005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
91105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
91205436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
91305436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props_rule_action_init (code_props *self, char const *code,
91405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             location code_loc, symbol_list *rule,
91505436638acc7c010349a69c3395f1a57c642dc62Ying Wang			     named_ref *name)
91605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
91705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->kind = CODE_PROPS_RULE_ACTION;
91805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->code = code;
91905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->location = code_loc;
92005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->is_value_used = false;
92105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->rule = rule;
92205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  self->named_ref = name;
92305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
92405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
92505436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
92605436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_props_translate_code (code_props *self)
92705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
92805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  switch (self->kind)
92905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
93005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      case CODE_PROPS_NONE:
93105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        break;
93205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      case CODE_PROPS_PLAIN:
93305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        self->code = translate_action (self, INITIAL);
93405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        break;
93505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      case CODE_PROPS_SYMBOL_ACTION:
93605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        self->code = translate_action (self, SC_SYMBOL_ACTION);
93705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        break;
93805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      case CODE_PROPS_RULE_ACTION:
93905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        self->code = translate_action (self, SC_RULE_ACTION);
94005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        break;
94105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
94205436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
94305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
94405436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
94505436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_scanner_last_string_free (void)
94605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
94705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  STRING_FREE;
94805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
94905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
95005436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
95105436638acc7c010349a69c3395f1a57c642dc62Ying Wangcode_scanner_free (void)
95205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
95305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  obstack_free (&obstack_for_string, 0);
95405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  variant_table_free ();
95505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
95605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Reclaim Flex's buffers.  */
95705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  yylex_destroy ();
95805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
959