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

📄 c-exp.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 3 页
字号:
			    error ("No function \"%s\" in specified context.",				   copy_name ($3));			  $$ = SYMBOL_BLOCK_VALUE (tem); }	;variable:	block COLONCOLON name			{ struct symbol *sym;			  sym = lookup_symbol (copy_name ($3), $1,					       VAR_NAMESPACE, 0, NULL);			  if (sym == 0)			    error ("No symbol \"%s\" in specified context.",				   copy_name ($3));			  write_exp_elt_opcode (OP_VAR_VALUE);			  write_exp_elt_sym (sym);			  write_exp_elt_opcode (OP_VAR_VALUE); }	;qualified_name:	typebase COLONCOLON name			{			  struct type *type = $1;			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT			      && TYPE_CODE (type) != TYPE_CODE_UNION)			    error ("`%s' is not defined as an aggregate type.",				   TYPE_NAME (type));			  write_exp_elt_opcode (OP_SCOPE);			  write_exp_elt_type (type);			  write_exp_string ($3);			  write_exp_elt_opcode (OP_SCOPE);			}	|	typebase COLONCOLON '~' name			{			  struct type *type = $1;			  struct stoken tmp_token;			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT			      && TYPE_CODE (type) != TYPE_CODE_UNION)			    error ("`%s' is not defined as an aggregate type.",				   TYPE_NAME (type));			  if (strcmp (type_name_no_tag (type), $4.ptr))			    error ("invalid destructor `%s::~%s'",				   type_name_no_tag (type), $4.ptr);			  tmp_token.ptr = (char*) alloca ($4.length + 2);			  tmp_token.length = $4.length + 1;			  tmp_token.ptr[0] = '~';			  memcpy (tmp_token.ptr+1, $4.ptr, $4.length);			  tmp_token.ptr[tmp_token.length] = 0;			  write_exp_elt_opcode (OP_SCOPE);			  write_exp_elt_type (type);			  write_exp_string (tmp_token);			  write_exp_elt_opcode (OP_SCOPE);			}	;variable:	qualified_name	|	COLONCOLON name			{			  char *name = copy_name ($2);			  struct symbol *sym;			  struct minimal_symbol *msymbol;			  sym =			    lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);			  if (sym)			    {			      write_exp_elt_opcode (OP_VAR_VALUE);			      write_exp_elt_sym (sym);			      write_exp_elt_opcode (OP_VAR_VALUE);			      break;			    }			  msymbol = lookup_minimal_symbol (name,				      (struct objfile *) NULL);			  if (msymbol != NULL)			    {			      write_exp_elt_opcode (OP_LONG);			      write_exp_elt_type (builtin_type_int);			      write_exp_elt_longcst ((LONGEST) msymbol -> address);			      write_exp_elt_opcode (OP_LONG);			      write_exp_elt_opcode (UNOP_MEMVAL);			      if (msymbol -> type == mst_data ||				  msymbol -> type == mst_bss)				write_exp_elt_type (builtin_type_int);			      else if (msymbol -> type == mst_text)				write_exp_elt_type (lookup_function_type (builtin_type_int));			      else				write_exp_elt_type (builtin_type_char);			      write_exp_elt_opcode (UNOP_MEMVAL);			    }			  else			    if (!have_full_symbols () && !have_partial_symbols ())			      error ("No symbol table is loaded.  Use the \"file\" command.");			    else			      error ("No symbol \"%s\" in current context.", name);			}	;variable:	name_not_typename			{ struct symbol *sym = $1.sym;			  if (sym)			    {			      switch (SYMBOL_CLASS (sym))				{				case LOC_REGISTER:				case LOC_ARG:				case LOC_REF_ARG:				case LOC_REGPARM:				case LOC_LOCAL:				case LOC_LOCAL_ARG:				  if (innermost_block == 0 ||				      contained_in (block_found, 						    innermost_block))				    innermost_block = block_found;				case LOC_UNDEF:				case LOC_CONST:				case LOC_STATIC:				case LOC_TYPEDEF:				case LOC_LABEL:				case LOC_BLOCK:				case LOC_CONST_BYTES:				  /* In this case the expression can				     be evaluated regardless of what				     frame we are in, so there is no				     need to check for the				     innermost_block.  These cases are				     listed so that gcc -Wall will				     report types that may not have				     been considered.  */				  break;				}			      write_exp_elt_opcode (OP_VAR_VALUE);			      write_exp_elt_sym (sym);			      write_exp_elt_opcode (OP_VAR_VALUE);			    }			  else if ($1.is_a_field_of_this)			    {			      /* C++: it hangs off of `this'.  Must			         not inadvertently convert from a method call				 to data ref.  */			      if (innermost_block == 0 || 				  contained_in (block_found, innermost_block))				innermost_block = block_found;			      write_exp_elt_opcode (OP_THIS);			      write_exp_elt_opcode (OP_THIS);			      write_exp_elt_opcode (STRUCTOP_PTR);			      write_exp_string ($1.stoken);			      write_exp_elt_opcode (STRUCTOP_PTR);			    }			  else			    {			      struct minimal_symbol *msymbol;			      register char *arg = copy_name ($1.stoken);			      msymbol = lookup_minimal_symbol (arg,					  (struct objfile *) NULL);			      if (msymbol != NULL)				{				  write_exp_elt_opcode (OP_LONG);				  write_exp_elt_type (builtin_type_int);				  write_exp_elt_longcst ((LONGEST) msymbol -> address);				  write_exp_elt_opcode (OP_LONG);				  write_exp_elt_opcode (UNOP_MEMVAL);				  if (msymbol -> type == mst_data ||				      msymbol -> type == mst_bss)				    write_exp_elt_type (builtin_type_int);				  else if (msymbol -> type == mst_text)				    write_exp_elt_type (lookup_function_type (builtin_type_int));				  else				    write_exp_elt_type (builtin_type_char);				  write_exp_elt_opcode (UNOP_MEMVAL);				}			      else if (!have_full_symbols () && !have_partial_symbols ())				error ("No symbol table is loaded.  Use the \"file\" command.");			      else				error ("No symbol \"%s\" in current context.",				       copy_name ($1.stoken));			    }			}	;ptype	:	typebase	|	typebase abs_decl		{		  /* This is where the interesting stuff happens.  */		  int done = 0;		  int array_size;		  struct type *follow_type = $1;		  		  while (!done)		    switch (pop_type ())		      {		      case tp_end:			done = 1;			break;		      case tp_pointer:			follow_type = lookup_pointer_type (follow_type);			break;		      case tp_reference:			follow_type = lookup_reference_type (follow_type);			break;		      case tp_array:			array_size = pop_type_int ();			if (array_size != -1)			  follow_type = create_array_type (follow_type,							   array_size);			else			  follow_type = lookup_pointer_type (follow_type);			break;		      case tp_function:			follow_type = lookup_function_type (follow_type);			break;		      }		  $$ = follow_type;		}	;abs_decl:	'*'			{ push_type (tp_pointer); $$ = 0; }	|	'*' abs_decl			{ push_type (tp_pointer); $$ = $2; }	|	'&'			{ push_type (tp_reference); $$ = 0; }	|	'&' abs_decl			{ push_type (tp_reference); $$ = $2; }	|	direct_abs_decl	;direct_abs_decl: '(' abs_decl ')'			{ $$ = $2; }	|	direct_abs_decl array_mod			{			  push_type_int ($2);			  push_type (tp_array);			}	|	array_mod			{			  push_type_int ($1);			  push_type (tp_array);			  $$ = 0;			}	| 	direct_abs_decl func_mod			{ push_type (tp_function); }	|	func_mod			{ push_type (tp_function); }	;array_mod:	'[' ']'			{ $$ = -1; }	|	'[' INT ']'			{ $$ = $2; }	;func_mod:	'(' ')'			{ $$ = 0; }	|	'(' nonempty_typelist ')'			{ free ((PTR)$2); $$ = 0; }	;type	:	ptype	|	typebase COLONCOLON '*'			{ $$ = lookup_member_type (builtin_type_int, $1); }	|	type '(' typebase COLONCOLON '*' ')'			{ $$ = lookup_member_type ($1, $3); }	|	type '(' typebase COLONCOLON '*' ')' '(' ')'			{ $$ = lookup_member_type			    (lookup_function_type ($1), $3); }	|	type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'			{ $$ = lookup_member_type			    (lookup_function_type ($1), $3);			  free ((PTR)$8); }	;typebase  /* Implements (approximately): (type-qualifier)* type-specifier */	:	TYPENAME			{ $$ = $1.type; }	|	INT_KEYWORD			{ $$ = builtin_type_int; }	|	LONG			{ $$ = builtin_type_long; }	|	SHORT			{ $$ = builtin_type_short; }	|	LONG INT_KEYWORD			{ $$ = builtin_type_long; }	|	UNSIGNED LONG INT_KEYWORD			{ $$ = builtin_type_unsigned_long; }	|	LONG LONG			{ $$ = builtin_type_long_long; }	|	LONG LONG INT_KEYWORD			{ $$ = builtin_type_long_long; }	|	UNSIGNED LONG LONG			{ $$ = builtin_type_unsigned_long_long; }	|	UNSIGNED LONG LONG INT_KEYWORD			{ $$ = builtin_type_unsigned_long_long; }	|	SHORT INT_KEYWORD			{ $$ = builtin_type_short; }	|	UNSIGNED SHORT INT_KEYWORD			{ $$ = builtin_type_unsigned_short; }	|	STRUCT name			{ $$ = lookup_struct (copy_name ($2),					      expression_context_block); }	|	CLASS name			{ $$ = lookup_struct (copy_name ($2),					      expression_context_block); }	|	UNION name			{ $$ = lookup_union (copy_name ($2),					     expression_context_block); }	|	ENUM name			{ $$ = lookup_enum (copy_name ($2),					    expression_context_block); }	|	UNSIGNED typename			{ $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }	|	UNSIGNED			{ $$ = builtin_type_unsigned_int; }	|	SIGNED_KEYWORD typename			{ $$ = lookup_signed_typename (TYPE_NAME($2.type)); }	|	SIGNED_KEYWORD			{ $$ = builtin_type_int; }	|	TEMPLATE name '<' type '>'			{ $$ = lookup_template_type(copy_name($2), $4,						    expression_context_block);			}	/* "const" and "volatile" are curently ignored. */	|	CONST_KEYWORD typebase { $$ = $2; }	|	VOLATILE_KEYWORD typebase { $$ = $2; }	;typename:	TYPENAME	|	INT_KEYWORD		{		  $$.stoken.ptr = "int";		  $$.stoken.length = 3;		  $$.type = builtin_type_int;		}	|	LONG		{		  $$.stoken.ptr = "long";		  $$.stoken.length = 4;		  $$.type = builtin_type_long;		}	|	SHORT		{		  $$.stoken.ptr = "short";		  $$.stoken.length = 5;		  $$.type = builtin_type_short;		}	;nonempty_typelist	:	type		{ $$ = (struct type **) xmalloc (sizeof (struct type *) * 2);		  $<ivec>$[0] = 1;	/* Number of types in vector */		  $$[1] = $1;		}	|	nonempty_typelist ',' type		{ int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);		  $$ = (struct type **) xrealloc ((char *) $1, len);		  $$[$<ivec>$[0]] = $3;		}	;name	:	NAME { $$ = $1.stoken; }	|	BLOCKNAME { $$ = $1.stoken; }	|	TYPENAME { $$ = $1.stoken; }	|	NAME_OR_INT  { $$ = $1.stoken; }	|	NAME_OR_UINT  { $$ = $1.stoken; }	;name_not_typename :	NAME	|	BLOCKNAME/* These would be useful if name_not_typename was useful, but it is just   a fake for "variable", so these cause reduce/reduce conflicts because   the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,   =exp) or just an exp.  If name_not_typename was ever used in an lvalue   context where only a name could occur, this might be useful.  	|	NAME_OR_INT  	|	NAME_OR_UINT */	;%%/* Take care of parsing a number (anything that starts with a digit).   Set yylval and return the token type; update lexptr.   LEN is the number of characters in it.  *//*** Needs some error checking for the float case ***/static intparse_number (p, len, parsed_float, putithere)     register char *p;     register int len;     int parsed_float;     YYSTYPE *putithere;{  register LONGEST n = 0;  register LONGEST prevn = 0;  register int i;  register int c;  register int base = input_radix;  int unsigned_p = 0;  if (parsed_float)    {      /* It's a float since it contains a point or an exponent.  */      putithere->dval = atof (p);      return FLOAT;    }  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */  if (p[0] == '0')    switch (p[1])      {      case 'x':      case 'X':	if (len >= 3)	  {	    p += 2;	    base = 16;	    len -= 2;	  }	break;      case 't':      case 'T':      case 'd':      case 'D':	if (len >= 3)	  {	    p += 2;	    base = 10;	    len -= 2;	  }	break;      default:	base = 8;	break;      }  while (len-- > 0)    {      c = *p++;      if (c >= 'A' && c <= 'Z')	c += 'a' - 'A';      if (c != 'l' && c != 'u')	n *= base;      if (c >= '0' && c <= '9')	n += i = c - '0';      else	{	  if (base > 10 && c >= 'a' && c <= 'f')	    n += i = c - 'a' + 10;	  else if (len == 0 && c == 'l')	    ;	  else if (len == 0 && c == 'u')	    unsigned_p = 1;	  else	    return ERROR;	/* Char not a digit */	}      if (i >= base)	return ERROR;		/* Invalid digit in this base */      /* Portably test for overflow (only works for nonzero values, so make	 a second check for zero).  */      if((prevn >= n) && n != 0)	 unsigned_p=1;		/* Try something unsigned */      /* If range checking enabled, portably test for unsigned overflow.  */      if(RANGE_CHECK && n!=0)      {		 if((unsigned_p && (unsigned)prevn >= (unsigned)n))	    range_error("Overflow on numeric constant.");	       }      prevn=n;    }  if (unsigned_p)    {      putithere->ulval = n;      return UINT;    }  else    {      putithere->lval = n;      return INT;    }}struct token{  char *operator;  int token;  enum exp_opcode opcode;};const static struct token tokentab3[] =  {    {">>=", ASSIGN_MODIFY, BINOP_RSH},    {"<<=", ASSIGN_MODIFY, BINOP_LSH}  };const static struct token tokentab2[] =  {    {"+=", ASSIGN_MODIFY, BINOP_ADD},    {"-=", ASSIGN_MODIFY, BINOP_SUB},    {"*=", ASSIGN_MODIFY, BINOP_MUL},    {"/=", ASSIGN_MODIFY, BINOP_DIV},    {"%=", ASSIGN_MODIFY, BINOP_REM},    {"|=", ASSIGN_MODIFY, BINOP_LOGIOR},    {"&=", ASSIGN_MODIFY, BINOP_LOGAND},    {"^=", ASSIGN_MODIFY, BINOP_LOGXOR},    {"++", INCREMENT, BINOP_END},    {"--", DECREMENT, BINOP_END},    {"->", ARROW, BINOP_END},    {"&&", ANDAND, BINOP_END},    {"||", OROR, BINOP_END},    {"::", COLONCOLON, BINOP_END},    {"<<", LSH, BINOP_END},    {">>", RSH, BINOP_END},    {"==", EQUAL, BINOP_END},    {"!=", NOTEQUAL, BINOP_END},    {"<=", LEQ, BINOP_END},    {">=", GEQ, BINOP_END}  };/* Read one token, getting characters through lexptr.  */intyylex (){  register int c;  register int namelen;  register unsigned i;  register char *tokstart; retry:  tokstart = lexptr;  /* See if it is a special token of length 3.  */  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)    if (!strncmp (tokstart, tokentab3[i].operator, 3))      {	lexptr += 3;	yylval.opcode = tokentab3[i].opcode;	return tokentab3[i].token;      }  /* See if it is a special token of length 2.  */  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)    if (!strncmp (tokstart, tokentab2[i].operator, 2))      {	lexptr += 2;	yylval.opcode = tokentab2[i].opcode;	return tokentab2[i].token;      }

⌨️ 快捷键说明

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