📄 c-parse.in
字号:
$$ = 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); } | objcprotocolexpr { $$ = build_protocol_expr ($1); } | objcencodeexpr { $$ = build_encode_expr ($1); } | objc_string { $$ = build_objc_string_object ($1); }end ifobjc ;/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */string: STRING | string STRING { $$ = chainon ($1, $2); } ;ifobjc/* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained onto it. */objc_string: OBJC_STRING | objc_string OBJC_STRING { $$ = chainon ($1, $2); } ;end ifobjcold_style_parm_decls: /* 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 ;/* We don't allow prefix attributes here because they cause reduce/reduce conflicts: we can't know whether we're parsing a function decl with attribute suffix, or function defn with attribute prefix on first old style parm. */datadecl: typed_declspecs_no_prefix_attr setspecs initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods_no_prefix_attr setspecs notype_initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs_no_prefix_attr ';' { shadow_tag_warned ($1, 1); pedwarn ("empty declaration"); } | declmods_no_prefix_attr ';' { 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 (prefix_attributes, current_declspecs, declspec_stack); split_specs_attrs ($<ttype>0, ¤t_declspecs, &prefix_attributes); } ;/* ??? Yuck. See after_type_declarator. */setattrs: /* empty */ { prefix_attributes = chainon (prefix_attributes, $<ttype>0); } ;decl: typed_declspecs setspecs initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods setspecs notype_initdecls ';' { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs setspecs nested_function { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | declmods setspecs notype_nested_function { current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } | typed_declspecs ';' { shadow_tag ($1); } | declmods ';' { pedwarn ("empty declaration"); } | extension decl { pedantic = $<itype>1; } ;/* 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. Declspecs have a non-NULL TREE_VALUE, attributes do not. */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); } | reserved_declspecs attributes { $$ = tree_cons ($2, NULL_TREE, $1); } ;typed_declspecs_no_prefix_attr: typespec reserved_declspecs_no_prefix_attr { $$ = tree_cons (NULL_TREE, $1, $2); } | declmods_no_prefix_attr typespec reserved_declspecs_no_prefix_attr { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ;reserved_declspecs_no_prefix_attr: /* empty */ { $$ = NULL_TREE; } | reserved_declspecs_no_prefix_attr typespecqual_reserved { $$ = tree_cons (NULL_TREE, $2, $1); } | reserved_declspecs_no_prefix_attr 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, type modifiers, and prefix attributes. A declaration can start with just this, but then it cannot be used to redeclare a typedef-name. Declspecs have a non-NULL TREE_VALUE, attributes do not. */declmods: declmods_no_prefix_attr { $$ = $1; } | attributes { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); } | declmods declmods_no_prefix_attr { $$ = chainon ($2, $1); } | declmods attributes { $$ = tree_cons ($2, NULL_TREE, $1); } ;declmods_no_prefix_attr: TYPE_QUAL { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); TREE_STATIC ($$) = 1; } | SCSPEC { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } | declmods_no_prefix_attr TYPE_QUAL { $$ = tree_cons (NULL_TREE, $2, $1); TREE_STATIC ($$) = 1; } | declmods_no_prefix_attr 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 protocolrefs { $$ = get_static_reference ($1, $2); } | OBJECTNAME protocolrefs { $$ = get_object_reference ($2); }/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" - nisse@lysator.liu.se */ | non_empty_protocolrefs { $$ = get_object_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, $3, prefix_attributes); start_init ($<ttype>$, $2, global_bindings_p ()); } init/* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); finish_decl ($<ttype>5, $6, $2); } | declarator maybeasm maybe_attribute { tree d = start_decl ($1, current_declspecs, 0, $3, prefix_attributes); finish_decl (d, NULL_TREE, $2); } ;notype_initdcl: notype_declarator maybeasm maybe_attribute '=' { $<ttype>$ = start_decl ($1, current_declspecs, 1, $3, prefix_attributes); start_init ($<ttype>$, $2, global_bindings_p ()); } init/* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); decl_attributes ($<ttype>5, $3, prefix_attributes); finish_decl ($<ttype>5, $6, $2); } | notype_declarator maybeasm maybe_attribute { tree d = start_decl ($1, current_declspecs, 0, $3, prefix_attributes); finish_decl (d, NULL_TREE, $2); } ;/* the * rules are dummies to accept the Apollo extended syntax so that the header files compile. */maybe_attribute: /* empty */ { $$ = NULL_TREE; } | attributes { $$ = $1; } ; attributes: attribute { $$ = $1; } | attributes attribute { $$ = chainon ($1, $2); } ;attribute: ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; } ;attribute_list: attrib { $$ = $1; } | attribute_list ',' attrib { $$ = chainon ($1, $3); } ; attrib: /* empty */ { $$ = NULL_TREE; } | any_word { $$ = build_tree_list ($1, NULL_TREE); } | any_word '(' IDENTIFIER ')' { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } | any_word '(' exprlist ')' { $$ = build_tree_list ($1, $3); } ;/* This still leaves out most reserved keywords, shouldn't we include them? */any_word: identifier | SCSPEC | TYPESPEC | TYPE_QUAL ;/* Initializers. `init' is the entry point. */init: expr_no_commas | '{' { really_start_incremental_init (NULL_TREE); /* Note that the call to clear_momentary is in process_init_element. */ push_momentary (); } initlist_maybe_comma '}' { $$ = pop_init_level (0); if ($$ == error_mark_node && ! (yychar == STRING || yychar == CONSTANT)) pop_momentary (); else pop_momentary_nofree (); } | error { $$ = error_mark_node; } ;/* `initlist_maybe_comma' is the guts of an initializer in braces. */initlist_maybe_comma: /* empty */ { if (pedantic) pedwarn ("ANSI C forbids empty initializer braces"); } | initlist1 maybecomma ;initlist1: initelt | initlist1 ',' initelt ;/* `initelt' is a single element of an initializer. It may use braces. */initelt: expr_no_commas { process_init_element ($1); } | '{' { push_init_level (0); } initlist_maybe_comma '}' { process_init_element (pop_init_level (0)); } | error /* These are for labeled elements. The syntax for an array element initializer conflicts with the syntax for an Objective-C message, so don't include these productions in the Objective-C grammar. */ifc | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '=' { set_init_index ($2, $4); } initelt | '[' expr_no_commas ']' '=' { set_init_index ($2, NULL_TREE); } initelt | '[' expr_no_commas ']' { set_init_index ($2, NULL_TREE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -