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

📄 parser.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 2 页
字号:
	      case S_TWORD:		if (!setsize)		    result->oprs[operand].type |= BITS80;		setsize = 1;		break;	      case S_TO:		result->oprs[operand].type |= TO;		break;	      case S_STRICT:		result->oprs[operand].type |= STRICT;		break;	      case S_FAR:		result->oprs[operand].type |= FAR;		break;	      case S_NEAR:		result->oprs[operand].type |= NEAR;		break;	      case S_SHORT:		result->oprs[operand].type |= SHORT;		break;	      default:		error (ERR_NONFATAL, "invalid operand size specification");	    }	    i = stdscan(NULL, &tokval);	}	if (i == '[' || i == '&') {    /* memory reference */	    mref = TRUE;	    bracket = (i == '[');	    i = stdscan(NULL, &tokval);	    if (i == TOKEN_SPECIAL) {  /* check for address size override */		if (tasm_compatible_mode) {		  switch ((int)tokval.t_integer) {		    /* For TASM compatibility a size override inside the		     * brackets changes the size of the operand, not the		     * address type of the operand as it does in standard		     * NASM syntax. Hence:		     *		     *	mov	eax,[DWORD val]		     *		     * is valid syntax in TASM compatibility mode. Note that		     * you lose the ability to override the default address		     * type for the instruction, but we never use anything		     * but 32-bit flat model addressing in our code.		     */		    case S_BYTE:		      result->oprs[operand].type |= BITS8;		      break;		    case S_WORD:		      result->oprs[operand].type |= BITS16;		      break;		    case S_DWORD:		    case S_LONG:		      result->oprs[operand].type |= BITS32;		      break;		    case S_QWORD:		      result->oprs[operand].type |= BITS64;		      break;		    case S_TWORD:		      result->oprs[operand].type |= BITS80;		      break;		    default:		      error (ERR_NONFATAL, "invalid operand size specification");		  }		} else {		  /* Standard NASM compatible syntax */		  switch ((int)tokval.t_integer) {		    case S_NOSPLIT:		      result->oprs[operand].eaflags |= EAF_TIMESTWO;		      break;		    case S_BYTE:		      result->oprs[operand].eaflags |= EAF_BYTEOFFS;		      break;		    case S_WORD:		      result->oprs[operand].addr_size = 16;		      result->oprs[operand].eaflags |= EAF_WORDOFFS;		      break;		    case S_DWORD:		    case S_LONG:		      result->oprs[operand].addr_size = 32;		      result->oprs[operand].eaflags |= EAF_WORDOFFS;		      break;		    default:		      error (ERR_NONFATAL, "invalid size specification in"			     " effective address");		  }		}		i = stdscan(NULL, &tokval);	    }	} else {		       /* immediate operand, or register */	    mref = FALSE;	    bracket = FALSE;	       /* placate optimisers */	}	if((result->oprs[operand].type & FAR) && !mref &&	     result->opcode != I_JMP && result->opcode != I_CALL)	{	    error (ERR_NONFATAL, "invalid use of FAR operand specifier");	}	value = evaluate (stdscan, NULL, &tokval,			  &result->oprs[operand].opflags,			  critical, error, &hints);	i = tokval.t_type;	if (result->oprs[operand].opflags & OPFLAG_FORWARD) {	    result->forw_ref = TRUE;	}	if (!value) {		       /* error in evaluator */	    result->opcode = -1;       /* unrecoverable parse error: */	    return result;	       /* ignore this instruction */	}	if (i == ':' && mref) {	       /* it was seg:offset */	    /*	     * Process the segment override.	     */	    if (value[1].type!=0 || value->value!=1 ||		REG_SREG & ~reg_flags[value->type])		error (ERR_NONFATAL, "invalid segment override");	    else if (result->nprefix == MAXPREFIX)		error (ERR_NONFATAL,		       "instruction has more than %d prefixes",		       MAXPREFIX);	    else		result->prefixes[result->nprefix++] = value->type;	    i = stdscan(NULL, &tokval);	       /* then skip the colon */	    if (i == TOKEN_SPECIAL) {  /* another check for size override */		switch ((int)tokval.t_integer) {		  case S_WORD:		    result->oprs[operand].addr_size = 16;		    break;		  case S_DWORD:		  case S_LONG:		    result->oprs[operand].addr_size = 32;		    break;		  default:		    error (ERR_NONFATAL, "invalid size specification in"			   " effective address");		}		i = stdscan(NULL, &tokval);	    }	    value = evaluate (stdscan, NULL, &tokval,			      &result->oprs[operand].opflags,			      critical, error, &hints);	    i = tokval.t_type;	    if (result->oprs[operand].opflags & OPFLAG_FORWARD) {		result->forw_ref = TRUE;	    }	    /* and get the offset */	    if (!value) {	       /* but, error in evaluator */		result->opcode = -1;   /* unrecoverable parse error: */		return result;	       /* ignore this instruction */	    }	}	if (mref && bracket) {	       /* find ] at the end */	    if (i != ']') {		error (ERR_NONFATAL, "parser: expecting ]");		do {		       /* error recovery again */		    i = stdscan(NULL, &tokval);		} while (i != 0 && i != ',');	    } else		       /* we got the required ] */		i = stdscan(NULL, &tokval);	} else {		       /* immediate operand */	    if (i != 0 && i != ',' && i != ':') {		error (ERR_NONFATAL, "comma or end of line expected");		do {		       /* error recovery */		    i = stdscan(NULL, &tokval);		} while (i != 0 && i != ',');	    } else if (i == ':') {		result->oprs[operand].type |= COLON;	    }	}	/* now convert the exprs returned from evaluate() into operand	 * descriptions... */	if (mref) {		       /* it's a memory reference */	    expr *e = value;	    int b, i, s;	       /* basereg, indexreg, scale */	    long o;		       /* offset */	    b = i = -1, o = s = 0;	    result->oprs[operand].hintbase = hints.base;	    result->oprs[operand].hinttype = hints.type;	    if (e->type && e->type <= EXPR_REG_END)   /* this bit's a register */	    {		if (e->value == 1) /* in fact it can be basereg */		    b = e->type;		else	       /* no, it has to be indexreg */		    i = e->type, s = e->value;		e++;	    }	    if (e->type && e->type <= EXPR_REG_END)   /* it's a 2nd register */	    {		if (b != -1)               /* If the first was the base, ... */		    i = e->type, s = e->value;  /* second has to be indexreg */		else if (e->value != 1)          /* If both want to be index */		{		    error(ERR_NONFATAL, "beroset-p-592-invalid effective address");		    result->opcode = -1;		    return result;		} 		else		    b = e->type;		e++;	    }	    if (e->type != 0) {	       /* is there an offset? */		if (e->type <= EXPR_REG_END)  /* in fact, is there an error? */		{		    error (ERR_NONFATAL, "beroset-p-603-invalid effective address");		    result->opcode = -1;		    return result;		} 		else 		{		    if (e->type == EXPR_UNKNOWN) {			o = 0;	                     /* doesn't matter what */			result->oprs[operand].wrt = NO_SEG;     /* nor this */			result->oprs[operand].segment = NO_SEG;  /* or this */			while (e->type) e++;   /* go to the end of the line */		    } 		    else 		    {			if (e->type == EXPR_SIMPLE) {			    o = e->value;			    e++;			}			if (e->type == EXPR_WRT) {			    result->oprs[operand].wrt = e->value;			    e++;			} else			    result->oprs[operand].wrt = NO_SEG;			/*			 * Look for a segment base type.			 */			if (e->type && e->type < EXPR_SEGBASE) {			    error (ERR_NONFATAL, "beroset-p-630-invalid effective address");			    result->opcode = -1;			    return result;			}			while (e->type && e->value == 0)			    e++;			if (e->type && e->value != 1) {			    error (ERR_NONFATAL, "beroset-p-637-invalid effective address");			    result->opcode = -1;			    return result;			}			if (e->type) {			    result->oprs[operand].segment =				e->type - EXPR_SEGBASE;			    e++;			} else			    result->oprs[operand].segment = NO_SEG;			while (e->type && e->value == 0)			    e++;			if (e->type) {			    error (ERR_NONFATAL, "beroset-p-650-invalid effective address");			    result->opcode = -1;			    return result;			}		    }		}	    } else {		o = 0;		result->oprs[operand].wrt = NO_SEG;		result->oprs[operand].segment = NO_SEG;	    }	    if (e->type != 0) {    /* there'd better be nothing left! */		error (ERR_NONFATAL, "beroset-p-663-invalid effective address");		result->opcode = -1;		return result;	    }	    result->oprs[operand].type |= MEMORY;	    if (b==-1 && (i==-1 || s==0))		result->oprs[operand].type |= MEM_OFFS;	    result->oprs[operand].basereg = b;	    result->oprs[operand].indexreg = i;	    result->oprs[operand].scale = s;	    result->oprs[operand].offset = o;	} 	else		                      /* it's not a memory reference */	{	    if (is_just_unknown(value)) {     /* it's immediate but unknown */		result->oprs[operand].type |= IMMEDIATE;		result->oprs[operand].offset = 0;   /* don't care */		result->oprs[operand].segment = NO_SEG; /* don't care again */		result->oprs[operand].wrt = NO_SEG;/* still don't care */	    } 	    else if (is_reloc(value))         /* it's immediate */	    {		result->oprs[operand].type |= IMMEDIATE;		result->oprs[operand].offset = reloc_value(value);		result->oprs[operand].segment = reloc_seg(value);		result->oprs[operand].wrt = reloc_wrt(value);		if (is_simple(value)) {		    if (reloc_value(value)==1)			result->oprs[operand].type |= UNITY;		    if (optimizing>=0 &&			!(result->oprs[operand].type & STRICT)) {  		        if (reloc_value(value) >= -128 &&		                 reloc_value(value) <= 127)		            result->oprs[operand].type |= SBYTE;		    }		}	    } 	    else	       /* it's a register */	    {		if (value->type>=EXPR_SIMPLE || value->value!=1) {		    error (ERR_NONFATAL, "invalid operand type");		    result->opcode = -1;		    return result;		}		/*		 * check that its only 1 register, not an expression...		 */		for (i = 1; value[i].type; i++)		    if (value[i].value) {			error (ERR_NONFATAL, "invalid operand type");			result->opcode = -1;			return result;		    }		/* clear overrides, except TO which applies to FPU regs */		if (result->oprs[operand].type & ~TO) {		    /*		     * we want to produce a warning iff the specified size		     * is different from the register size		     */		    i = result->oprs[operand].type & SIZE_MASK;		}		else		    i = 0;		result->oprs[operand].type &= TO;		result->oprs[operand].type |= REGISTER;		result->oprs[operand].type |= reg_flags[value->type];		result->oprs[operand].basereg = value->type;		if (i && (result->oprs[operand].type & SIZE_MASK) != i)		    error (ERR_WARNING|ERR_PASS1,			   "register size specification ignored");	    }	}    }    result->operands = operand;       /* set operand count */    while (operand<3)		       /* clear remaining operands */	result->oprs[operand++].type = 0;    /*     * Transform RESW, RESD, RESQ, REST into RESB.     */    switch (result->opcode) {      case I_RESW: result->opcode=I_RESB; result->oprs[0].offset*=2; break;      case I_RESD: result->opcode=I_RESB; result->oprs[0].offset*=4; break;      case I_RESQ: result->opcode=I_RESB; result->oprs[0].offset*=8; break;      case I_REST: result->opcode=I_RESB; result->oprs[0].offset*=10; break;    }    return result;}static int is_comma_next (void) {    char *p;    int i;    struct tokenval tv;    p = stdscan_bufptr;    i = stdscan (NULL, &tv);    stdscan_bufptr = p;    return (i == ',' || i == ';' || !i);}void cleanup_insn (insn *i) {    extop *e;    while (i->eops) {	e = i->eops;	i->eops = i->eops->next;	nasm_free (e);    }}

⌨️ 快捷键说明

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