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

📄 parse_gnu.c

📁 Minix比较全的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static expression_t *gnu_get_C_expression(int *pn)/* Read a "C-like" expression.  Note that we don't worry about precedence, * the expression is printed later like it is read.  If the target language * does not have all the operators (like ~) then this has to be repaired by * changing the source file.  (No problem, you still have one source file * to maintain, not two.) */{	expression_t *e, *a1, *a2;	token_t *t;	if ((t= get_token(*pn))->symbol == '(') {		/* ( expr ): grouping. */		(*pn)++;		if ((a1= gnu_get_C_expression(pn)) == nil) return nil;		if (get_token(*pn)->symbol != ')') {			parse_err(1, t, "missing )\n");			del_expr(a1);			return nil;		}		(*pn)++;		e= new_expr();		e->operator= '[';		e->middle= a1;	} else	if (t->type == T_WORD || t->type == T_STRING) {		/* Label, number, or string. */		e= new_expr();		e->operator= t->type == T_WORD ? 'W' : 'S';		e->name= allocate(nil, (t->len+1) * sizeof(e->name[0]));		memcpy(e->name, t->name , t->len+1);		e->len= t->len;		(*pn)++;	} else	if (t->symbol == '+' || t->symbol == '-' || t->symbol == '~') {		/* Unary operator. */		(*pn)++;		if ((a1= gnu_get_C_expression(pn)) == nil) return nil;		e= new_expr();		e->operator= t->symbol;		e->middle= a1;	} else {		parse_err(1, t, "expression syntax error\n");		return nil;	}	switch ((t= get_token(*pn))->symbol) {	case '%': 	case '+':	case '-':	case '*':	case '/':	case '&':	case '|':	case '^':	case S_LEFTSHIFT:	case S_RIGHTSHIFT:		(*pn)++;		a1= e;		if ((a2= gnu_get_C_expression(pn)) == nil) {			del_expr(a1);			return nil;		}		e= new_expr();		e->operator= t->symbol;		e->left= a1;		e->right= a2;	}	return e;}static expression_t *gnu_get_operand(int *pn, int deref)/* Get something like: $immed, memory, offset(%base,%index,scale), or simpler. */{	expression_t *e, *offset, *base, *index;	token_t *t;	int c;	if (get_token(*pn)->symbol == '$') {		/* An immediate value. */		(*pn)++;		return gnu_get_C_expression(pn);	}	if (get_token(*pn)->symbol == '*') {		/* Indirection. */		(*pn)++;		if ((offset= gnu_get_operand(pn, deref)) == nil) return nil;		e= new_expr();		e->operator= '(';		e->middle= offset;		return e;	}	if ((get_token(*pn)->symbol == '%')		&& (t= get_token(*pn + 1))->type == T_WORD		&& isregister(t->name)	) {		/* A register operand. */		(*pn)+= 2;		e= new_expr();		e->operator= 'W';		e->name= copystr(t->name);		return e;	}	/* Offset? */	if (get_token(*pn)->symbol != '('				|| get_token(*pn + 1)->symbol != '%') {		/* There is an offset. */		if ((offset= gnu_get_C_expression(pn)) == nil) return nil;	} else {		/* No offset. */		offset= nil;	}	/* (%base,%index,scale) ? */	base= index= nil;	if (get_token(*pn)->symbol == '(') {		(*pn)++;		/* %base ? */		if (get_token(*pn)->symbol == '%'			&& (t= get_token(*pn + 1))->type == T_WORD			&& isregister(t->name)		) {			/* A base register expression. */			base= new_expr();			base->operator= 'B';			base->name= copystr(t->name);			(*pn)+= 2;		}		if (get_token(*pn)->symbol == ',') (*pn)++;		/* %index ? */		if (get_token(*pn)->symbol == '%'			&& (t= get_token(*pn + 1))->type == T_WORD			&& isregister(t->name)		) {			/* A index register expression. */			index= new_expr();			index->operator= '1';		/* for now */			index->name= copystr(t->name);			(*pn)+= 2;		}		if (get_token(*pn)->symbol == ',') (*pn)++;		/* scale ? */		if ((base != nil || index != nil)			&& (t= get_token(*pn))->type == T_WORD			&& strchr("1248", t->name[0]) != nil			&& t->name[1] == 0		) {					if (index == nil) {				/* Base is really an index register. */				index= base;				base= nil;			}			index->operator= t->name[0];			(*pn)++;		}		if (get_token(*pn)->symbol == ')') {			/* Ending paren. */			(*pn)++;		} else {			/* Alas. */			parse_err(1, t, "operand syntax error\n");			del_expr(offset);			del_expr(base);			del_expr(index);			return nil;		}	}	if (base == nil && index == nil) {		if (deref) {			/* Return a lone offset as (offset). */			e= new_expr();			e->operator= '(';			e->middle= offset;		} else {			/* Return a lone offset as is. */			e= offset;		}	} else {		e= new_expr();		e->operator= 'O';		e->left= offset;		e->middle= base;		e->right= index;	}	return e;}static expression_t *gnu_get_oplist(int *pn, int deref)/* Get a comma (or colon for jmpf and callf) separated list of instruction * operands. */{	expression_t *e, *o1, *o2;	token_t *t;	if ((e= gnu_get_operand(pn, deref)) == nil) return nil;	if ((t= get_token(*pn))->symbol == ',' || t->symbol == ':') {		o1= e;		(*pn)++;		if ((o2= gnu_get_oplist(pn, deref)) == nil) {			del_expr(o1);			return nil;		}		e= new_expr();		e->operator= ',';		e->left= o1;		e->right= o2;	}	return e;}static asm86_t *gnu_get_statement(void)/* Get a pseudo op or machine instruction with arguments. */{	token_t *t= get_token(0);	asm86_t *a;	mnemonic_t *m;	int n;	int prefix_seen;	int deref;	assert(t->type == T_WORD);	a= new_asm86();	/* Process instruction prefixes. */	for (prefix_seen= 0;; prefix_seen= 1) {		if (strcmp(t->name, "rep") == 0			|| strcmp(t->name, "repe") == 0			|| strcmp(t->name, "repne") == 0			|| strcmp(t->name, "repz") == 0			|| strcmp(t->name, "repnz") == 0		) {			if (a->rep != ONCE) {				parse_err(1, t,					"can't have more than one rep\n");			}			switch (t->name[3]) {			case 0:		a->rep= REP;	break;			case 'e':			case 'z':	a->rep= REPE;	break;			case 'n':	a->rep= REPNE;	break;			}		} else		if (!prefix_seen) {			/* No prefix here, get out! */			break;		} else {			/* No more prefixes, next must be an instruction. */			if (t->type != T_WORD				|| (m= search_mnem(t->name)) == nil				|| m->optype == PSEUDO			) {				parse_err(1, t,		"machine instruction expected after instruction prefix\n");				del_asm86(a);				return nil;			}			break;		}		/* Skip the prefix and extra newlines. */		do {			skip_token(1);		} while ((t= get_token(0))->symbol == ';');	}	/* All the readahead being done upsets the line counter. */	a->line= t->line;	/* Read a machine instruction or pseudo op. */	if ((m= search_mnem(t->name)) == nil) {		parse_err(1, t, "unknown instruction '%s'\n", t->name);		del_asm86(a);		return nil;	}	a->opcode= m->opcode;	a->optype= m->optype;	a->oaz= 0;	if (a->optype == OWORD) {		a->oaz|= OPZ;		a->optype= WORD;	}	switch (a->opcode) {	case IN:	case OUT:	case INT:		deref= 0;		break;	default:		deref= (a->optype >= BYTE);	}	n= 1;	if (get_token(1)->symbol != ';'			&& (a->args= gnu_get_oplist(&n, deref)) == nil) {		del_asm86(a);		return nil;	}	if (get_token(n)->symbol != ';') {		parse_err(1, t, "garbage at end of instruction\n");		del_asm86(a);		return nil;	}	if (!is_pseudo(a->opcode)) {		/* GNU operand order is the other way around. */		expression_t *e, *t;		e= a->args;		while (e != nil && e->operator == ',') {			t= e->right; e->right= e->left; e->left= t;			e= e->left;		}	}	switch (a->opcode) {	case DOT_ALIGN:		/* Delete two argument .align, because ACK can't do it.		 * Raise 2 to the power of .align's argument.		 */		if (a->args == nil || a->args->operator != 'W') {				del_asm86(a);			return nil;		}		if (a->args != nil && a->args->operator == 'W'			&& isanumber(a->args->name)		) {				unsigned n;			char num[sizeof(int) * CHAR_BIT / 3 + 1];			n= 1 << strtoul(a->args->name, nil, 0);			sprintf(num, "%u", n);			deallocate(a->args->name);			a->args->name= copystr(num);		}		break;	case JMPF:	case CALLF:		/*FALL THROUGH*/	case JMP:	case CALL:		break;	default:;	}	skip_token(n+1);	return a;}asm86_t *gnu_get_instruction(void){	asm86_t *a= nil;	expression_t *e;	token_t *t;	while ((t= get_token(0))->symbol == ';' || t->symbol == '/') {		zap();		/* if a comment started by a '/' */		skip_token(1);	}	if (t->type == T_EOF) return nil;	if (t->symbol == '#') {		/* Preprocessor line and file change. */		if ((t= get_token(1))->type != T_WORD || !isanumber(t->name)			|| get_token(2)->type != T_STRING		) {			parse_err(1, t, "file not preprocessed?\n");			zap();		} else {			set_file(get_token(2)->name,				strtol(get_token(1)->name, nil, 0) - 1);			/* GNU CPP adds extra cruft, simply zap the line. */			zap();		}		a= gnu_get_instruction();	} else	if (t->type == T_WORD && get_token(1)->symbol == ':') {		/* A label definition. */		a= new_asm86();		a->line= t->line;		a->opcode= DOT_LABEL;		a->optype= PSEUDO;		a->args= e= new_expr();		e->operator= ':';		e->name= copystr(t->name);		skip_token(2);	} else	if (t->type == T_WORD && get_token(1)->symbol == '=') {		int n= 2;		if ((e= gnu_get_C_expression(&n)) == nil) {			zap();			a= gnu_get_instruction();		} else		if (get_token(n)->symbol != ';') {			parse_err(1, t, "garbage after assignment\n");			zap();			a= gnu_get_instruction();		} else {			a= new_asm86();			a->line= t->line;			a->opcode= DOT_EQU;			a->optype= PSEUDO;			a->args= new_expr();			a->args->operator= '=';			a->args->name= copystr(t->name);			a->args->middle= e;			skip_token(n+1);		}	} else	if (t->type == T_WORD) {		if ((a= gnu_get_statement()) == nil) {			zap();			a= gnu_get_instruction();		}	} else {		parse_err(1, t, "syntax error\n");		zap();		a= gnu_get_instruction();	}	return a;}

⌨️ 快捷键说明

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