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

📄 m2-exp.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 2 页
字号:
				{				  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 \"symbol-file\" command.");			      else				error ("No symbol \"%s\" in current context.",				       copy_name ($1));			    }			}	;type	:	TYPENAME			{ $$ = lookup_typename (copy_name ($1),						expression_context_block, 0); }	;%%#if 0  /* FIXME! */intoverflow(a,b)   long a,b;{   return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a;}intuoverflow(a,b)   unsigned long a,b;{   return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a;}#endif /* FIXME *//* 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 (olen)     int olen;{  register char *p = lexptr;  register LONGEST n = 0;  register LONGEST prevn = 0;  register int c,i,ischar=0;  register int base = input_radix;  register int len = olen;  int unsigned_p = number_sign == 1 ? 1 : 0;  if(p[len-1] == 'H')  {     base = 16;     len--;  }  else if(p[len-1] == 'C' || p[len-1] == 'B')  {     base = 8;     ischar = p[len-1] == 'C';     len--;  }  /* Scan the number */  for (c = 0; c < len; c++)  {    if (p[c] == '.' && base == 10)      {	/* It's a float since it contains a point.  */	yylval.dval = atof (p);	lexptr += len;	return FLOAT;      }    if (p[c] == '.' && base != 10)       error("Floating point numbers must be base 10.");    if (base == 10 && (p[c] < '0' || p[c] > '9'))       error("Invalid digit \'%c\' in number.",p[c]); }  while (len-- > 0)    {      c = *p++;      n *= base;      if( base == 8 && (c == '8' || c == '9'))	 error("Invalid digit \'%c\' in octal number.",c);      if (c >= '0' && c <= '9')	i = c - '0';      else	{	  if (base == 16 && c >= 'A' && c <= 'F')	    i = c - 'A' + 10;	  else	     return ERROR;	}      n+=i;      if(i >= base)	 return ERROR;      if(!unsigned_p && number_sign == 1 && (prevn >= n))	 unsigned_p=1;		/* Try something unsigned */      /* Don't do the range check if n==i and i==0, since that special	 case will give an overflow error. */      if(RANGE_CHECK && n!=i && i)      {	 if((unsigned_p && (unsigned)prevn >= (unsigned)n) ||	    ((!unsigned_p && number_sign==-1) && -prevn <= -n))	    range_error("Overflow on numeric constant.");      }	 prevn=n;    }  lexptr = p;  if(*p == 'B' || *p == 'C' || *p == 'H')     lexptr++;			/* Advance past B,C or H */  if (ischar)  {     yylval.ulval = n;     return CHAR;  }  else if ( unsigned_p && number_sign == 1)  {     yylval.ulval = n;     return UINT;  }  else if((unsigned_p && (n<0))) {     range_error("Overflow on numeric constant -- number too large.");     /* But, this can return if range_check == range_warn.  */  }  yylval.lval = n;  return INT;}/* Some tokens */static struct{   char name[4];   int token;} tokentab2[] ={    { {'<', '>'},    NOTEQUAL 	},    { {':', '='},    ASSIGN	},    { {'<', '='},    LEQ	},    { {'>', '='},    GEQ	},    { {':', ':'},    COLONCOLON },};/* Some specific keywords */struct keyword {   char keyw[10];   int token;};static struct keyword keytab[] ={    {"OR" ,   OROR	 },    {"IN",    IN         },/* Note space after IN */    {"AND",   ANDAND     },    {"ABS",   ABS	 },    {"CHR",   CHR	 },    {"DEC",   DEC	 },    {"NOT",   NOT	 },    {"DIV",   DIV    	 },    {"INC",   INC	 },    {"MAX",   MAX_FUNC	 },    {"MIN",   MIN_FUNC	 },    {"MOD",   MOD	 },    {"ODD",   ODD	 },    {"CAP",   CAP	 },    {"ORD",   ORD	 },    {"VAL",   VAL	 },    {"EXCL",  EXCL	 },    {"HIGH",  HIGH       },    {"INCL",  INCL	 },    {"SIZE",  SIZE       },    {"FLOAT", FLOAT_FUNC },    {"TRUNC", TRUNC	 },};/* Read one token, getting characters through lexptr.  *//* This is where we will check to make sure that the language and the operators used are   compatible  */static intyylex (){  register int c;  register int namelen;  register int i;  register char *tokstart;  register char quote; retry:  tokstart = lexptr;  /* See if it is a special token of length 2 */  for( i = 0 ; i < sizeof tokentab2 / sizeof tokentab2[0] ; i++)     if(!strncmp(tokentab2[i].name, tokstart, 2))     {	lexptr += 2;	return tokentab2[i].token;     }  switch (c = *tokstart)    {    case 0:      return 0;    case ' ':    case '\t':    case '\n':      lexptr++;      goto retry;    case '(':      paren_depth++;      lexptr++;      return c;    case ')':      if (paren_depth == 0)	return 0;      paren_depth--;      lexptr++;      return c;    case ',':      if (comma_terminates && paren_depth == 0)	return 0;      lexptr++;      return c;    case '.':      /* Might be a floating point number.  */      if (lexptr[1] >= '0' && lexptr[1] <= '9')	break;			/* Falls into number code.  */      else      {	 lexptr++;	 return DOT;      }/* These are character tokens that appear as-is in the YACC grammar */    case '+':    case '-':    case '*':    case '/':    case '^':    case '<':    case '>':    case '[':    case ']':    case '=':    case '{':    case '}':    case '#':    case '@':    case '~':    case '&':      lexptr++;      return c;    case '\'' :    case '"':      quote = c;      for (namelen = 1; (c = tokstart[namelen]) != quote && c != '\0'; namelen++)	if (c == '\\')	  {	    c = tokstart[++namelen];	    if (c >= '0' && c <= '9')	      {		c = tokstart[++namelen];		if (c >= '0' && c <= '9')		  c = tokstart[++namelen];	      }	  }      if(c != quote)	 error("Unterminated string or character constant.");      yylval.sval.ptr = tokstart + 1;      yylval.sval.length = namelen - 1;      lexptr += namelen + 1;      if(namelen == 2)  	/* Single character */      {	   yylval.ulval = tokstart[1];	   return CHAR;      }      else	 return STRING;    }  /* Is it a number?  */  /* Note:  We have already dealt with the case of the token '.'.     See case '.' above.  */  if ((c >= '0' && c <= '9'))    {      /* It's a number.  */      int got_dot = 0, got_e = 0;      register char *p = tokstart;      int toktype;      for (++p ;; ++p)	{	  if (!got_e && (*p == 'e' || *p == 'E'))	    got_dot = got_e = 1;	  else if (!got_dot && *p == '.')	    got_dot = 1;	  else if (got_e && (p[-1] == 'e' || p[-1] == 'E')		   && (*p == '-' || *p == '+'))	    /* This is the sign of the exponent, not the end of the	       number.  */	    continue;	  else if ((*p < '0' || *p > '9') &&		   (*p < 'A' || *p > 'F') &&		   (*p != 'H'))  /* Modula-2 hexadecimal number */	    break;	}	toktype = parse_number (p - tokstart);        if (toktype == ERROR)	  {	    char *err_copy = (char *) alloca (p - tokstart + 1);	    memcpy (err_copy, tokstart, p - tokstart);	    err_copy[p - tokstart] = 0;	    error ("Invalid number \"%s\".", err_copy);	  }	lexptr = p;	return toktype;    }  if (!(c == '_' || c == '$'	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))    /* We must have come across a bad character (e.g. ';').  */    error ("Invalid character '%c' in expression.", c);  /* It's a name.  See how long it is.  */  namelen = 0;  for (c = tokstart[namelen];       (c == '_' || c == '$' || (c >= '0' && c <= '9')	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));       c = tokstart[++namelen])    ;  /* The token "if" terminates the expression and is NOT     removed from the input stream.  */  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')    {      return 0;    }  lexptr += namelen;  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)     and $$digits (equivalent to $<-digits> if you could type that).     Make token type LAST, and put the number (the digits) in yylval.  */  if (*tokstart == '$')    {      register int negate = 0;      c = 1;      /* Double dollar means negate the number and add -1 as well.	 Thus $$ alone means -1.  */      if (namelen >= 2 && tokstart[1] == '$')	{	  negate = 1;	  c = 2;	}      if (c == namelen)	{	  /* Just dollars (one or two) */	  yylval.lval = - negate;	  return LAST;	}      /* Is the rest of the token digits?  */      for (; c < namelen; c++)	if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))	  break;      if (c == namelen)	{	  yylval.lval = atoi (tokstart + 1 + negate);	  if (negate)	    yylval.lval = - yylval.lval;	  return LAST;	}    }  /* Handle tokens that refer to machine registers:     $ followed by a register name.  */  if (*tokstart == '$') {    for (c = 0; c < NUM_REGS; c++)      if (namelen - 1 == strlen (reg_names[c])	  && !strncmp (tokstart + 1, reg_names[c], namelen - 1))	{	  yylval.lval = c;	  return REGNAME;	}    for (c = 0; c < num_std_regs; c++)     if (namelen - 1 == strlen (std_regs[c].name)	 && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))       {	 yylval.lval = std_regs[c].regnum;	 return REGNAME;       }  }  /*  Lookup special keywords */  for(i = 0 ; i < sizeof(keytab) / sizeof(keytab[0]) ; i++)     if(namelen == strlen(keytab[i].keyw) && !strncmp(tokstart,keytab[i].keyw,namelen))	   return keytab[i].token;  yylval.sval.ptr = tokstart;  yylval.sval.length = namelen;  /* Any other names starting in $ are debugger internal variables.  */  if (*tokstart == '$')    {      yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1);      return INTERNAL_VAR;    }  /* Use token-type BLOCKNAME for symbols that happen to be defined as     functions.  If this is not so, then ...     Use token-type TYPENAME for symbols that happen to be defined     currently as names of types; NAME for other symbols.     The caller is not constrained to care about the distinction.  */ {    char *tmp = copy_name (yylval.sval);    struct symbol *sym;    if (lookup_partial_symtab (tmp))      return BLOCKNAME;    sym = lookup_symbol (tmp, expression_context_block,			 VAR_NAMESPACE, 0, NULL);    if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)      return BLOCKNAME;    if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1))      return TYPENAME;    if(sym)    {       switch(sym->class)       {       case LOC_STATIC:       case LOC_REGISTER:       case LOC_ARG:       case LOC_REF_ARG:       case LOC_REGPARM:       case LOC_LOCAL:       case LOC_LOCAL_ARG:       case LOC_CONST:       case LOC_CONST_BYTES:	  return NAME;       case LOC_TYPEDEF:	  return TYPENAME;       case LOC_BLOCK:	  return BLOCKNAME;       case LOC_UNDEF:	  error("internal:  Undefined class in m2lex()");       case LOC_LABEL:	  error("internal:  Unforseen case in m2lex()");       }    }    else    {       /* Built-in BOOLEAN type.  This is sort of a hack. */       if(!strncmp(tokstart,"TRUE",4))       {	  yylval.ulval = 1;	  return M2_TRUE;       }       else if(!strncmp(tokstart,"FALSE",5))       {	  yylval.ulval = 0;	  return M2_FALSE;       }    }    /* Must be another type of name... */    return NAME; }}#if 0		/* Unused */static char *make_qualname(mod,ident)   char *mod, *ident;{   char *new = xmalloc(strlen(mod)+strlen(ident)+2);   strcpy(new,mod);   strcat(new,".");   strcat(new,ident);   return new;}#endif  /* 0 */static voidyyerror(msg)     char *msg;	/* unused */{   printf("Parsing:  %s\n",lexptr);   if (yychar < 256)     error("Invalid syntax in expression near character '%c'.",yychar);   else     error("Invalid syntax in expression");}/* Table of operators and their precedences for printing expressions.  */const static struct op_print m2_op_print_tab[] = {    {"+",   BINOP_ADD, PREC_ADD, 0},    {"+",   UNOP_PLUS, PREC_PREFIX, 0},    {"-",   BINOP_SUB, PREC_ADD, 0},    {"-",   UNOP_NEG, PREC_PREFIX, 0},    {"*",   BINOP_MUL, PREC_MUL, 0},    {"/",   BINOP_DIV, PREC_MUL, 0},    {"DIV", BINOP_INTDIV, PREC_MUL, 0},    {"MOD", BINOP_REM, PREC_MUL, 0},    {":=",  BINOP_ASSIGN, PREC_ASSIGN, 1},    {"OR",  BINOP_OR, PREC_OR, 0},    {"AND", BINOP_AND, PREC_AND, 0},    {"NOT", UNOP_ZEROP, PREC_PREFIX, 0},    {"=",   BINOP_EQUAL, PREC_EQUAL, 0},    {"<>",  BINOP_NOTEQUAL, PREC_EQUAL, 0},    {"<=",  BINOP_LEQ, PREC_ORDER, 0},    {">=",  BINOP_GEQ, PREC_ORDER, 0},    {">",   BINOP_GTR, PREC_ORDER, 0},    {"<",   BINOP_LESS, PREC_ORDER, 0},    {"^",   UNOP_IND, PREC_PREFIX, 0},    {"@",   BINOP_REPEAT, PREC_REPEAT, 0},};/* The built-in types of Modula-2.  */struct type *builtin_type_m2_char;struct type *builtin_type_m2_int;struct type *builtin_type_m2_card;struct type *builtin_type_m2_real;struct type *builtin_type_m2_bool;struct type ** const (m2_builtin_types[]) = {  &builtin_type_m2_char,  &builtin_type_m2_int,  &builtin_type_m2_card,  &builtin_type_m2_real,  &builtin_type_m2_bool,  0};const struct language_defn m2_language_defn = {  "modula-2",  language_m2,  m2_builtin_types,  range_check_on,  type_check_on,  m2_parse,			/* parser */  m2_error,			/* parser error function */  &builtin_type_m2_int,		/* longest signed   integral type */  &builtin_type_m2_card,		/* longest unsigned integral type */  &builtin_type_m2_real,		/* longest floating point type */  "0%XH", "0%", "XH",		/* Hex   format string, prefix, suffix */  "%oB",  "%",  "oB",		/* Octal format string, prefix, suffix */  m2_op_print_tab,		/* expression operators for printing */  LANG_MAGIC};/* Initialization for Modula-2 */void_initialize_m2_exp (){  /* Modula-2 "pervasive" types.  NOTE:  these can be redefined!!! */  builtin_type_m2_int =    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,	       0,	       "INTEGER", (struct objfile *) NULL);  builtin_type_m2_card =    init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,	       TYPE_FLAG_UNSIGNED,	       "CARDINAL", (struct objfile *) NULL);  builtin_type_m2_real =    init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,	       0,	       "REAL", (struct objfile *) NULL);  builtin_type_m2_char =    init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,	       TYPE_FLAG_UNSIGNED,	       "CHAR", (struct objfile *) NULL);  builtin_type_m2_bool =    init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,	       TYPE_FLAG_UNSIGNED,	       "BOOLEAN", (struct objfile *) NULL);  TYPE_NFIELDS(builtin_type_m2_bool) = 2;  TYPE_FIELDS(builtin_type_m2_bool) =      (struct field *) malloc (sizeof (struct field) * 2);  TYPE_FIELD_BITPOS(builtin_type_m2_bool,0) = 0;  TYPE_FIELD_NAME(builtin_type_m2_bool,0) = (char *)malloc(6);  strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,0),"FALSE");  TYPE_FIELD_BITPOS(builtin_type_m2_bool,1) = 1;  TYPE_FIELD_NAME(builtin_type_m2_bool,1) = (char *)malloc(5);  strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,1),"TRUE");  add_language (&m2_language_defn);}

⌨️ 快捷键说明

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