📄 parse.y
字号:
/* YACC parser for C++ syntax. Copyright (C) 1988, 1989, 1993, 1994, 1995 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com)This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. *//* This grammar is based on the GNU CC grammar. *//* Note: Bison automatically applies a default action of "$$ = $1" for all derivations; this is applied before the explicit action, if one is given. Keep this in mind when reading the actions. */%{/* Cause the `yydebug' variable to be defined. */#define YYDEBUG 1#include "config.h"#include <stdio.h>#include <errno.h>#include "tree.h"#include "input.h"#include "flags.h"#include "lex.h"#include "cp-tree.h"#include "output.h"/* Since parsers are distinct for each language, put the language string definition here. (fnf) */char *language_string = "GNU C++";extern tree void_list_node;extern struct obstack permanent_obstack;#ifndef errnoextern int errno;#endifextern int end_of_file;extern int current_class_depth;/* FSF LOCAL dje prefix attributes */extern tree strip_attrs PROTO((tree));/* END FSF LOCAL */void yyerror ();/* Like YYERROR but do call yyerror. */#define YYERROR1 { yyerror ("syntax error"); YYERROR; }#define OP0(NODE) (TREE_OPERAND (NODE, 0))#define OP1(NODE) (TREE_OPERAND (NODE, 1))/* Contains the statement keyword (if/while/do) to include in an error message if the user supplies an empty conditional expression. */static char *cond_stmt_keyword;/* Nonzero if we have an `extern "C"' acting as an extern specifier. */int have_extern_spec;int used_extern_spec;void yyhook ();/* Cons up an empty parameter list. */#ifdef __GNUC____inline#endifstatic treeempty_parms (){ tree parms; if (strict_prototype) parms = void_list_node; else parms = NULL_TREE; return parms;}%}%start program%union {long itype; tree ttype; char *strtype; enum tree_code code; }/* All identifiers that are not reserved words and are not declared typedefs in the current block */%token IDENTIFIER/* All identifiers that are declared typedefs in the current block. In some contexts, they are treated just like IDENTIFIER, but they can also serve as typespecs in declarations. */%token TYPENAME/* Reserved words that specify storage class. yylval contains an IDENTIFIER_NODE which indicates which one. */%token SCSPEC/* Reserved words that specify type. yylval contains an IDENTIFIER_NODE which indicates which one. */%token TYPESPEC/* Reserved words that qualify type: "const" or "volatile". yylval contains an IDENTIFIER_NODE which indicates which one. */%token TYPE_QUAL/* Character or numeric constants. yylval is the node for the constant. */%token CONSTANT/* String constants in raw form. yylval is a STRING_CST node. */%token STRING/* "...", used for functions with variable arglists. */%token ELLIPSIS/* the reserved words *//* SCO include files test "ASM", so use something else. */%token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF%token SIGOF%token ATTRIBUTE EXTENSION LABEL/* the reserved words... C++ extensions */%token <ttype> AGGR%token <itype> VISSPEC%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE%token NAMESPACE TYPENAME_KEYWORD USING%token LEFT_RIGHT TEMPLATE%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST%token <itype> SCOPE/* Define the operator tokens and their precedences. The value is an integer because, if used, it is the tree code to use in the expression made from the operator. */%left EMPTY /* used to resolve s/r with epsilon */%left error/* Add precedence rules to solve dangling else s/r conflict */%nonassoc IF%nonassoc ELSE%left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD%left '{' ',' ';'%nonassoc THROW%right <code> ':'%right <code> ASSIGN '='%right <code> '?'%left <code> OROR%left <code> ANDAND%left <code> '|'%left <code> '^'%left <code> '&'%left <code> MIN_MAX%left <code> EQCOMPARE%left <code> ARITHCOMPARE '<' '>'%left <code> LSHIFT RSHIFT%left <code> '+' '-'%left <code> '*' '/' '%'%left <code> POINTSAT_STAR DOT_STAR%right <code> UNARY PLUSPLUS MINUSMINUS '~'%left HYPERUNARY%left <ttype> PAREN_STAR_PAREN LEFT_RIGHT%left <code> POINTSAT '.' '(' '['%right SCOPE /* C++ extension */%nonassoc NEW DELETE TRY CATCH%type <code> unop%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist%type <ttype> paren_expr_or_null nontrivial_exprlist%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING%type <ttype> typed_declspecs reserved_declspecs boolean.literal%type <ttype> typed_typespecs reserved_typespecquals%type <ttype> declmods typespec typespecqual_reserved%type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual%type <itype> initdecls notype_initdecls initdcl /* C++ modification */%type <ttype> init initlist maybeasm maybe_init%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers%type <ttype> maybe_attribute attributes attribute attribute_list attrib%type <ttype> any_word%type <ttype> compstmt implicitly_scoped_stmt%type <ttype> declarator notype_declarator after_type_declarator%type <ttype> direct_notype_declarator direct_after_type_declarator%type <ttype> structsp opt.component_decl_list component_decl_list%type <ttype> component_decl component_decl_1 components notype_components%type <ttype> component_declarator component_declarator0%type <ttype> notype_component_declarator notype_component_declarator0%type <ttype> after_type_component_declarator after_type_component_declarator0%type <ttype> enumlist enumerator%type <ttype> type_id absdcl type_quals%type <ttype> direct_abstract_declarator conversion_declarator%type <ttype> new_type_id new_declarator direct_new_declarator%type <ttype> xexpr parmlist parms parm bad_parm full_parm%type <ttype> identifiers_or_typenames%type <ttype> fcast_or_absdcl regcast_or_absdcl%type <ttype> expr_or_declarator complex_notype_declarator%type <ttype> notype_unqualified_id unqualified_id qualified_id%type <ttype> overqualified_id notype_qualified_id any_id%type <ttype> complex_direct_notype_declarator functional_cast%type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma/* C++ extensions */%token <ttype> TYPENAME_ELLIPSIS PTYPENAME%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL%token <ttype> PRE_PARSED_CLASS_DECL%type <ttype> fn.def1 /* Not really! */%type <ttype> fn.def2 return_id%type <itype> ctor_initializer_opt%type <ttype> named_class_head named_class_head_sans_basetype%type <ttype> named_complex_class_head_sans_basetype%type <ttype> unnamed_class_head%type <ttype> class_head base_class_list%type <itype> base_class_access_list%type <ttype> base_class maybe_base_class_list base_class.1%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers%type <ttype> operator_name%type <ttype> object aggr%type <itype> new delete/* %type <ttype> primary_no_id */%type <ttype> nonmomentary_expr maybe_parmlist%type <itype> initdcl0 notype_initdcl0 member_init_list%type <ttype> template_header template_parm_list template_parm%type <ttype> template_type_parm%type <ttype> template_type template_arg_list template_arg%type <ttype> template_instantiation template_type_name tmpl.2%type <ttype> template_instantiate_once template_instantiate_some%type <itype> fn_tmpl_end/* %type <itype> try_for_typename */%type <ttype> condition xcond paren_cond_or_null%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem%type <ttype> qualified_type_name complete_type_name notype_identifier%type <ttype> complex_type_name nested_name_specifier_1%type <itype> nomods_initdecls nomods_initdcl0%type <ttype> new_initializer new_placement specialization type_specifier_seq%type <ttype> using_decl .poplevel/* in order to recognize aggr tags as defining and thus shadowing. */%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN%type <ttype> named_class_head_sans_basetype_defn %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN%token NSNAME%type <ttype> NSNAME/* Used in lex.c for parsing pragmas. */%token END_OF_LINE/* lex.c and pt.c depends on this being the last token. Define any new tokens before this one! */%token END_OF_SAVED_INPUT%{/* List of types and structure classes of the current declaration. */static tree current_declspecs;/* List of prefix attributes in effect. Prefix attributes are parsed by the reserved_declspecs and declmods rules. They create a list that contains *both* declspecs and attrs. *//* ??? It is not clear yet that all cases where an attribute can now appear in a declspec list have been updated. */static tree prefix_attributes;/* When defining an aggregate, this is the most recent one being defined. */static tree current_aggr;/* Tell yyparse how to print a token's value, if yydebug is set. */#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)extern void yyprint ();extern tree combine_strings PROTO((tree));%}%%program: /* empty */ | extdefs { /* In case there were missing closebraces, get us back to the global binding level. */ while (! global_bindings_p ()) poplevel (0, 0, 0); finish_file (); } ;/* the reason for the strange actions in this rule is so that notype_initdecls when reached via datadef can find a valid list of type and sc specs in $0. */extdefs: { $<ttype>$ = NULL_TREE; } lang_extdef { $<ttype>$ = NULL_TREE; } | extdefs lang_extdef { $<ttype>$ = NULL_TREE; } ;extdefs_opt: extdefs | /* empty */ ;.hush_warning: { have_extern_spec = 1; used_extern_spec = 0; $<ttype>$ = NULL_TREE; } ;.warning_ok: { have_extern_spec = 0; } ;asm_keyword: ASM_KEYWORD | GCC_ASM_KEYWORD ;lang_extdef: { if (pending_lang_change) do_pending_lang_change(); } extdef { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) pop_everything (); } ;extdef: fndef { if (pending_inlines) do_pending_inlines (); } | datadef { if (pending_inlines) do_pending_inlines (); } | template_def { if (pending_inlines) do_pending_inlines (); } | overloaddef | asm_keyword '(' string ')' ';' { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); assemble_asm ($3); } | extern_lang_string '{' extdefs_opt '}' { pop_lang_context (); } | extern_lang_string .hush_warning fndef .warning_ok { if (pending_inlines) do_pending_inlines (); pop_lang_context (); } | extern_lang_string .hush_warning datadef .warning_ok { if (pending_inlines) do_pending_inlines (); pop_lang_context (); } | NAMESPACE identifier '{' { push_namespace ($2); } extdefs_opt '}' { pop_namespace (); } | NAMESPACE '{' { push_namespace (NULL_TREE); } extdefs_opt '}' { pop_namespace (); } | NAMESPACE identifier '=' any_id ';' { do_namespace_alias ($2, $4); } | using_decl ';' { do_toplevel_using_decl ($1); } | USING NAMESPACE any_id ';' { do_using_directive ($3); } ;using_decl: USING qualified_id { $$ = $2; } | USING global_scope qualified_id { $$ = $3; } | USING global_scope unqualified_id { $$ = $3; } ;any_id: unqualified_id | qualified_id | global_scope qualified_id { $$ = $2; } | global_scope unqualified_id { $$ = $2; } ;extern_lang_string: EXTERN_LANG_STRING { push_lang_context ($1); } | extern_lang_string EXTERN_LANG_STRING { if (current_lang_name != $2) cp_error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name); pop_lang_context (); push_lang_context ($2); } ;template_header: TEMPLATE '<' { begin_template_parm_list (); } template_parm_list '>' { $$ = end_template_parm_list ($4); } ;template_parm_list: template_parm { $$ = process_template_parm (NULL_TREE, $1); } | template_parm_list ',' template_parm { $$ = process_template_parm ($1, $3); } ;template_type_parm: aggr { $$ = build_tree_list ($1, NULL_TREE); ttpa: if (TREE_PURPOSE ($$) == signature_type_node) sorry ("signature as template type parameter"); else if (TREE_PURPOSE ($$) != class_type_node) pedwarn ("template type parameters must use the keyword `class'"); } | aggr identifier { $$ = build_tree_list ($1, $2); goto ttpa; } | TYPENAME_KEYWORD { $$ = build_tree_list (class_type_node, NULL_TREE); } | TYPENAME_KEYWORD identifier { $$ = build_tree_list (class_type_node, $2); } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -