⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-parse.y

📁 使用yacc和lex编写的cmm语言的词法分析和语法分析程序.
💻 Y
📖 第 1 页 / 共 4 页
字号:
		{ $$ = 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); }	| expr_no_commas ASSIGN expr_no_commas		{ $$ = build_modify_expr ($1, $2, $3); }	;primary:	IDENTIFIER		{		  tree context;		  $$ = lastiddecl;		  if (!$$ || $$ == error_mark_node)		    {		      if (yychar == YYEMPTY)			yychar = YYLEX;		      if (yychar == '(')			{			  $$ = 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			{			  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 (! TREE_USED ($$))		    {		      if (TREE_EXTERNAL ($$))			assemble_external ($$);		      TREE_USED ($$) = 1;		    }		  if (TREE_CODE ($$) == CONST_DECL)		    $$ = DECL_INITIAL ($$);		}	| 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);		}	| primary '(' exprlist ')'   %prec '.'		{ $$ = build_function_call ($1, $3); }	| primary '[' expr ']'   %prec '.'		{ $$ = build_array_ref ($1, $3); }	| primary '.' identifier		{ $$ = build_component_ref ($1, $3); }	| primary POINTSAT identifier		{ $$ = build_component_ref (build_indirect_ref ($1, "->"), $3); }	| primary PLUSPLUS		{ $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }	| primary MINUSMINUS		{ $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }	;/* 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 ($1); }	| 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 (0, 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		{ $$ = 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); }	| SCSPEC		{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }	| declmods TYPE_QUAL		{ $$ = tree_cons (NULL_TREE, $2, $1); }	| declmods SCSPEC		{ $$ = tree_cons (NULL_TREE, $2, $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); }	| TYPEOF '(' expr ')'		{ $$ = TREE_TYPE ($3);		  if (pedantic)		    pedwarn ("ANSI C forbids `typeof'"); }	| TYPEOF '(' typename ')'		{ $$ = groktypename ($3);		  if (pedantic)		    pedwarn ("ANSI C forbids `typeof'"); }	;/* 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 '(' 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); }	| declarator maybeasm maybe_attribute		{ tree d = start_decl ($1, current_declspecs, 0);		  decl_attributes (d, $3);		  finish_decl (d, NULL_TREE, $2); }	;notype_initdcl:	  notype_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); }	| notype_declarator maybeasm maybe_attribute		{ tree d = start_decl ($1, current_declspecs, 0);		  decl_attributes (d, $3);		  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; }    | ATTRIBUTE '(' '(' attribute_list ')' ')'		{ $$ = $4; }    ;attribute_list    : attrib	{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }    | attribute_list ',' attrib	{ $$ = tree_cons (NULL_TREE, $3, $1); }    ;attrib    : IDENTIFIER	{ if (strcmp (IDENTIFIER_POINTER ($1), "packed"))	    warning ("`%s' attribute directive ignored",		     IDENTIFIER_POINTER ($1));	  $$ = $1; }    | IDENTIFIER '(' CONSTANT ')'	{ /* if not "aligned(n)", then issue warning */	  if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0	      || TREE_CODE ($3) != INTEGER_CST)	    {	      warning ("`%s' attribute directive ignored",		       IDENTIFIER_POINTER ($1));	      $$ = $1;	    }	  else	    $$ = tree_cons ($1, $3); }    | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'	{ /* if not "format(...)", then issue warning */	  if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0	      || TREE_CODE ($5) != INTEGER_CST	      || TREE_CODE ($7) != INTEGER_CST)	    {	      warning ("`%s' attribute directive ignored",		       IDENTIFIER_POINTER ($1));	      $$ = $1;	    }	  else	    $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7))); }    ;init:	expr_no_commas	| '{' '}'		{ $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);		  if (pedantic)		    pedwarn ("ANSI C forbids empty initializer braces"); }	| '{' initlist '}'		{ $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }	| '{' initlist ',' '}'		{ $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }	| error		{ $$ = NULL_TREE; }	;/* This chain is built in reverse order,   and put in forward order where initlist is used.  */initlist:	  init		{ $$ = build_tree_list (NULL_TREE, $1); }	| initlist ',' init		{ $$ = tree_cons (NULL_TREE, $3, $1); }	/* These are for labeled elements.  */	| '[' expr_no_commas ']' init		{ $$ = build_tree_list ($2, $4); }	| initlist ',' '[' expr_no_commas ']' init

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -