📄 c-parse.in
字号:
{ $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas '&' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas '|' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas '^' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas ANDAND expr_no_commas { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); } | expr_no_commas OROR expr_no_commas { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); } | expr_no_commas '?' xexpr ':' expr_no_commas { $$ = build_conditional_expr ($1, $3, $5); } | expr_no_commas '=' expr_no_commas { $$ = build_modify_expr ($1, NOP_EXPR, $3); C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } | expr_no_commas ASSIGN expr_no_commas { $$ = build_modify_expr ($1, $2, $3); C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } ;primary: IDENTIFIER { tree context; $$ = lastiddecl; if (!$$ || $$ == error_mark_node) { if (yychar == YYEMPTY) yychar = YYLEX; if (yychar == '(') {ifobjc if (objc_receiver_context && ! (objc_receiver_context && strcmp (IDENTIFIER_POINTER ($1), "super"))) /* we have a message to super */ $$ = get_super_receiver (); else if (objc_method_context && is_ivar (objc_ivar_chain, $1)) $$ = build_ivar_reference ($1); elseend ifobjc { /* Ordinary implicit function declaration. */ $$ = implicitly_declare ($1); assemble_external ($$); TREE_USED ($$) = 1; } } else if (current_function_decl == 0) { error ("`%s' undeclared, outside of functions", IDENTIFIER_POINTER ($1)); $$ = error_mark_node; } else {ifobjc if (objc_receiver_context && ! strcmp (IDENTIFIER_POINTER ($1), "super")) /* we have a message to super */ $$ = get_super_receiver (); else if (objc_method_context && is_ivar (objc_ivar_chain, $1)) $$ = build_ivar_reference ($1); elseend ifobjc { if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl) { error ("`%s' undeclared (first use this function)", IDENTIFIER_POINTER ($1)); if (! undeclared_variable_notice) { error ("(Each undeclared identifier is reported only once"); error ("for each function it appears in.)"); undeclared_variable_notice = 1; } } $$ = error_mark_node; /* Prevent repeated error messages. */ IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node; IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl; } } } else if (TREE_TYPE ($$) == error_mark_node) $$ = error_mark_node; else if (C_DECL_ANTICIPATED ($$)) { /* The first time we see a build-in function used, if it has not been declared. */ C_DECL_ANTICIPATED ($$) = 0; if (yychar == YYEMPTY) yychar = YYLEX; if (yychar == '(') { /* Omit the implicit declaration we would ordinarily do, so we don't lose the actual built in type. But print a diagnostic for the mismatch. */ifobjc if (objc_method_context && is_ivar (objc_ivar_chain, $1)) error ("Instance variable `%s' implicitly declared as function", IDENTIFIER_POINTER (DECL_NAME ($$))); elseend ifobjc if (TREE_CODE ($$) != FUNCTION_DECL) error ("`%s' implicitly declared as function", IDENTIFIER_POINTER (DECL_NAME ($$))); else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$))) != TYPE_MODE (integer_type_node)) && (TREE_TYPE (TREE_TYPE ($$)) != void_type_node)) pedwarn ("type mismatch in implicit declaration for built-in function `%s'", IDENTIFIER_POINTER (DECL_NAME ($$))); /* If it really returns void, change that to int. */ if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node) TREE_TYPE ($$) = build_function_type (integer_type_node, TYPE_ARG_TYPES (TREE_TYPE ($$))); } else pedwarn ("built-in function `%s' used without declaration", IDENTIFIER_POINTER (DECL_NAME ($$))); /* Do what we would ordinarily do when a fn is used. */ assemble_external ($$); TREE_USED ($$) = 1; } else { assemble_external ($$); TREE_USED ($$) = 1;ifobjc /* we have a definition - still check if iVariable */ if (!objc_receiver_context || (objc_receiver_context && strcmp (IDENTIFIER_POINTER ($1), "super"))) { if (objc_method_context && is_ivar (objc_ivar_chain, $1)) { if (IDENTIFIER_LOCAL_VALUE ($1)) warning ("local declaration of `%s' hides instance variable", IDENTIFIER_POINTER ($1)); else $$ = build_ivar_reference ($1); } } else /* we have a message to super */ $$ = get_super_receiver ();end ifobjc } if (TREE_CODE ($$) == CONST_DECL) { $$ = DECL_INITIAL ($$); /* This is to prevent an enum whose value is 0 from being considered a null pointer constant. */ $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$); TREE_CONSTANT ($$) = 1; } } | CONSTANT | string { $$ = combine_strings ($1); } | '(' expr ')' { char class = TREE_CODE_CLASS (TREE_CODE ($2)); if (class == 'e' || class == '1' || class == '2' || class == '<') C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); $$ = $2; } | '(' error ')' { $$ = error_mark_node; } | '(' { if (current_function_decl == 0) { error ("braced-group within expression allowed only inside a function"); YYERROR; } /* We must force a BLOCK for this level so that, if it is not expanded later, there is a way to turn off the entire subtree of blocks that are contained in it. */ keep_next_level (); push_label_level (); $<ttype>$ = expand_start_stmt_expr (); } compstmt ')' { tree rtl_exp; if (pedantic) pedwarn ("ANSI C forbids braced-groups within expressions"); pop_label_level (); rtl_exp = expand_end_stmt_expr ($<ttype>2); /* The statements have side effects, so the group does. */ TREE_SIDE_EFFECTS (rtl_exp) = 1; /* Make a BIND_EXPR for the BLOCK already made. */ $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), NULL_TREE, rtl_exp, $3); /* Remove the block from the tree at this point. It gets put back at the proper place when the BIND_EXPR is expanded. */ delete_block ($3); } | primary '(' exprlist ')' %prec '.' { $$ = build_function_call ($1, $3); } | primary '[' expr ']' %prec '.' { $$ = build_array_ref ($1, $3); } | primary '.' identifier {ifobjc if (doing_objc_thang) { if (is_public ($1, $3)) $$ = build_component_ref ($1, $3); else $$ = error_mark_node; } elseend ifobjc $$ = build_component_ref ($1, $3); } | primary POINTSAT identifier { tree expr = build_indirect_ref ($1, "->");ifobjc if (doing_objc_thang) { if (is_public (expr, $3)) $$ = build_component_ref (expr, $3); else $$ = error_mark_node; } elseend ifobjc $$ = build_component_ref (expr, $3); } | primary PLUSPLUS { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); } | primary MINUSMINUS { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }ifobjc | objcmessageexpr { $$ = build_message_expr ($1); } | objcselectorexpr { $$ = build_selector_expr ($1); } | objcencodeexpr { $$ = build_encode_expr ($1); }end ifobjc ;/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */string: STRING | string STRING { $$ = chainon ($1, $2); } ;xdecls: /* empty */ | datadecls | datadecls ELLIPSIS /* ... is used here to indicate a varargs function. */ { c_mark_varargs (); if (pedantic) pedwarn ("ANSI C does not permit use of `varargs.h'"); } ;/* The following are analogous to lineno_decl, decls and decl except that they do not allow nested functions. They are used for old-style parm decls. */lineno_datadecl: save_filename save_lineno datadecl { } ;datadecls: lineno_datadecl | errstmt | datadecls lineno_datadecl | lineno_datadecl errstmt ;datadecl: typed_declspecs setspecs initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods setspecs notype_initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs ';' { shadow_tag_warned ($1, 1); pedwarn ("empty declaration"); } | declmods ';' { pedwarn ("empty declaration"); } ;/* This combination which saves a lineno before a decl is the normal thing to use, rather than decl itself. This is to avoid shift/reduce conflicts in contexts where statement labels are allowed. */lineno_decl: save_filename save_lineno decl { } ;decls: lineno_decl | errstmt | decls lineno_decl | lineno_decl errstmt ;/* records the type and storage class specs to use for processing the declarators that follow. Maintains a stack of outer-level values of current_declspecs, for the sake of parm declarations nested in function declarators. */setspecs: /* empty */ { $$ = suspend_momentary (); pending_xref_error (); declspec_stack = tree_cons (NULL_TREE, current_declspecs, declspec_stack); current_declspecs = $<ttype>0; } ;decl: typed_declspecs setspecs initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods setspecs notype_initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs setspecs nested_function { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods setspecs notype_nested_function { current_declspecs = TREE_VALUE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs ';' { shadow_tag ($1); } | declmods ';' { pedwarn ("empty declaration"); } ;/* Declspecs which contain at least one type specifier or typedef name. (Just `const' or `volatile' is not enough.) A typedef'd name following these is taken as a name to be declared. */typed_declspecs: typespec reserved_declspecs { $$ = tree_cons (NULL_TREE, $1, $2); } | declmods typespec reserved_declspecs { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ;reserved_declspecs: /* empty */ { $$ = NULL_TREE; } | reserved_declspecs typespecqual_reserved { $$ = tree_cons (NULL_TREE, $2, $1); } | reserved_declspecs SCSPEC { if (extra_warnings) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = tree_cons (NULL_TREE, $2, $1); } ;/* List of just storage classes and type modifiers. A declaration can start with just this, but then it cannot be used to redeclare a typedef-name. */declmods: TYPE_QUAL { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); TREE_STATIC ($$) = 1; } | SCSPEC { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } | declmods TYPE_QUAL { $$ = tree_cons (NULL_TREE, $2, $1); TREE_STATIC ($$) = 1; } | declmods SCSPEC { if (extra_warnings && TREE_STATIC ($1)) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = tree_cons (NULL_TREE, $2, $1); TREE_STATIC ($$) = TREE_STATIC ($1); } ;/* Used instead of declspecs where storage classes are not allowed (that is, for typenames and structure components). Don't accept a typedef-name if anything but a modifier precedes it. */typed_typespecs: typespec reserved_typespecquals { $$ = tree_cons (NULL_TREE, $1, $2); } | nonempty_type_quals typespec reserved_typespecquals { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ;reserved_typespecquals: /* empty */ { $$ = NULL_TREE; } | reserved_typespecquals typespecqual_reserved { $$ = tree_cons (NULL_TREE, $2, $1); } ;/* A typespec (but not a type qualifier). Once we have seen one of these in a declaration, if a typedef name appears then it is being redeclared. */typespec: TYPESPEC | structsp | TYPENAME { /* For a typedef name, record the meaning, not the name. In case of `foo foo, bar;'. */ $$ = lookup_name ($1); }ifobjc | CLASSNAME { $$ = get_static_reference ($1); }end ifobjc | TYPEOF '(' expr ')' { $$ = TREE_TYPE ($3); } | TYPEOF '(' typename ')' { $$ = groktypename ($3); } ;/* A typespec that is a reserved word, or a type qualifier. */typespecqual_reserved: TYPESPEC | TYPE_QUAL | structsp ;initdecls: initdcl | initdecls ',' initdcl ;notype_initdecls: notype_initdcl | notype_initdecls ',' initdcl ;maybeasm: /* empty */ { $$ = NULL_TREE; } | ASM_KEYWORD '(' string ')' { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } ;initdcl: declarator maybeasm maybe_attribute '=' { $<ttype>$ = start_decl ($1, current_declspecs, 1); } init/* Note how the declaration of the variable is in effect while its init is parsed! */ { decl_attributes ($<ttype>5, $3); finish_decl ($<ttype>5, $6, $2); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -