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

📄 awk.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 3 页
字号:
	case '+':		if ((c = nextc()) == '=') {			yylval.nodetypeval = Node_assign_plus;			return ASSIGNOP;		}		if (c == '+')			return INCREMENT;		pushback();		return '+';	case '!':		if ((c = nextc()) == '=') {			yylval.nodetypeval = Node_notequal;			return RELOP;		}		if (c == '~') {			yylval.nodetypeval = Node_nomatch;			want_assign = 0;			return MATCHOP;		}		pushback();		return '!';	case '<':		if (nextc() == '=') {			yylval.nodetypeval = Node_leq;			return RELOP;		}		yylval.nodetypeval = Node_less;		pushback();		return '<';	case '=':		if (nextc() == '=') {			yylval.nodetypeval = Node_equal;			return RELOP;		}		yylval.nodetypeval = Node_assign;		pushback();		return ASSIGNOP;	case '>':		if ((c = nextc()) == '=') {			yylval.nodetypeval = Node_geq;			return RELOP;		} else if (c == '>') {			yylval.nodetypeval = Node_redirect_append;			return APPEND_OP;		}		yylval.nodetypeval = Node_greater;		pushback();		return '>';	case '~':		yylval.nodetypeval = Node_match;		want_assign = 0;		return MATCHOP;	case '}':		/*		 * Added did newline stuff.  Easier than		 * hacking the grammar		 */		if (did_newline) {			did_newline = 0;			return c;		}		did_newline++;		--lexptr;	/* pick up } next time */		return NEWLINE;	case '"':		esc_seen = 0;		while ((c = nextc()) != '"') {			if (c == '\n') {				pushback();				yyerror("unterminated string");			}			if (c == '\\') {				c = nextc();				if (c == '\n') {					sourceline++;					continue;				}				esc_seen = 1;				tokadd('\\');			}			if (c == '\0') {				pushback();				yyerror("unterminated string");			}			tokadd(c);		}		yylval.nodeval = make_str_node(tokstart,					token - tokstart, esc_seen ? SCAN : 0);		yylval.nodeval->flags |= PERM;		return YSTRING;	case '-':		if ((c = nextc()) == '=') {			yylval.nodetypeval = Node_assign_minus;			return ASSIGNOP;		}		if (c == '-')			return DECREMENT;		pushback();		return '-';	case '.':		c = nextc();		pushback();		if (!isdigit(c))			return '.';		else			c = '.';	/* FALL THROUGH */	case '0':	case '1':	case '2':	case '3':	case '4':	case '5':	case '6':	case '7':	case '8':	case '9':		/* It's a number */		for (;;) {			int gotnumber = 0;			tokadd(c);			switch (c) {			case '.':				if (seen_point) {					gotnumber++;					break;				}				++seen_point;				break;			case 'e':			case 'E':				if (seen_e) {					gotnumber++;					break;				}				++seen_e;				if ((c = nextc()) == '-' || c == '+')					tokadd(c);				else					pushback();				break;			case '0':			case '1':			case '2':			case '3':			case '4':			case '5':			case '6':			case '7':			case '8':			case '9':				break;			default:				gotnumber++;			}			if (gotnumber)				break;			c = nextc();		}		pushback();		yylval.nodeval = make_number(atof(tokstart));		yylval.nodeval->flags |= PERM;		return YNUMBER;	case '&':		if ((c = nextc()) == '&') {			yylval.nodetypeval = Node_and;			for (;;) {				c = nextc();				if (c == '\0')					break;				if (c == '#') {					while ((c = nextc()) != '\n' && c != '\0')						;					if (c == '\0')						break;				}				if (c == '\n')					sourceline++;				if (! isspace(c)) {					pushback();					break;				}			}			want_assign = 0;			return LEX_AND;		}		pushback();		return '&';	case '|':		if ((c = nextc()) == '|') {			yylval.nodetypeval = Node_or;			for (;;) {				c = nextc();				if (c == '\0')					break;				if (c == '#') {					while ((c = nextc()) != '\n' && c != '\0')						;					if (c == '\0')						break;				}				if (c == '\n')					sourceline++;				if (! isspace(c)) {					pushback();					break;				}			}			want_assign = 0;			return LEX_OR;		}		pushback();		return '|';	}	if (c != '_' && ! isalpha(c))		yyerror("Invalid char '%c' in expression\n", c);	/* it's some type of name-type-thing.  Find its length */	token = tokstart;	while (is_identchar(c)) {		tokadd(c);		c = nextc();	}	tokadd('\0');	emalloc(tokkey, char *, token - tokstart, "yylex");	memcpy(tokkey, tokstart, token - tokstart);	pushback();	/* See if it is a special token.  */	low = 0;	high = (sizeof (tokentab) / sizeof (tokentab[0])) - 1;	while (low <= high) {		int i/* , c */;		mid = (low + high) / 2;		c = *tokstart - tokentab[mid].operator[0];		i = c ? c : strcmp (tokstart, tokentab[mid].operator);		if (i < 0) {		/* token < mid */			high = mid - 1;		} else if (i > 0) {	/* token > mid */			low = mid + 1;		} else {			if (do_lint) {				if (tokentab[mid].flags & GAWKX)					warning("%s() is a gawk extension",						tokentab[mid].operator);				if (tokentab[mid].flags & NOT_POSIX)					warning("POSIX does not allow %s",						tokentab[mid].operator);				if (tokentab[mid].flags & NOT_OLD)					warning("%s is not supported in old awk",						tokentab[mid].operator);			}			if ((do_unix && (tokentab[mid].flags & GAWKX))			    || (do_posix && (tokentab[mid].flags & NOT_POSIX)))				break;			if (tokentab[mid].class == LEX_BUILTIN			    || tokentab[mid].class == LEX_LENGTH			   )				yylval.lval = mid;			else				yylval.nodetypeval = tokentab[mid].value;			return tokentab[mid].class;		}	}	yylval.sval = tokkey;	if (*lexptr == '(')		return FUNC_CALL;	else {		want_assign = 1;		return NAME;	}}static NODE *node_common(op)NODETYPE op;{	register NODE *r;	getnode(r);	r->type = op;	r->flags = MALLOC;	/* if lookahead is NL, lineno is 1 too high */	if (lexeme && *lexeme == '\n')		r->source_line = sourceline - 1;	else		r->source_line = sourceline;	r->source_file = source;	return r;}/* * This allocates a node with defined lnode and rnode.  */NODE *node(left, op, right)NODE *left, *right;NODETYPE op;{	register NODE *r;	r = node_common(op);	r->lnode = left;	r->rnode = right;	return r;}/* * This allocates a node with defined subnode and proc for builtin functions * Checks for arg. count and supplies defaults where possible. */static NODE *snode(subn, op, idx)NODETYPE op;int idx;NODE *subn;{	register NODE *r;	register NODE *n;	int nexp = 0;	int args_allowed;	r = node_common(op);	/* traverse expression list to see how many args. given */	for (n= subn; n; n= n->rnode) {		nexp++;		if (nexp > 3)			break;	}	/* check against how many args. are allowed for this builtin */	args_allowed = tokentab[idx].flags & ARGS;	if (args_allowed && !(args_allowed & A(nexp)))		fatal("%s() cannot have %d argument%c",			tokentab[idx].operator, nexp, nexp == 1 ? ' ' : 's');	r->proc = tokentab[idx].ptr;	/* special case processing for a few builtins */	if (nexp == 0 && r->proc == do_length) {		subn = node(node(make_number(0.0),Node_field_spec,(NODE *)NULL),		            Node_expression_list,			    (NODE *) NULL);	} else if (r->proc == do_match) {		if (subn->rnode->lnode->type != Node_regex)			subn->rnode->lnode = mk_rexp(subn->rnode->lnode);	} else if (r->proc == do_sub || r->proc == do_gsub) {		if (subn->lnode->type != Node_regex)			subn->lnode = mk_rexp(subn->lnode);		if (nexp == 2)			append_right(subn, node(node(make_number(0.0),						     Node_field_spec,						     (NODE *) NULL),					        Node_expression_list,						(NODE *) NULL));		else if (do_lint && subn->rnode->rnode->lnode->type == Node_val)			warning("string literal as last arg of substitute");	} else if (r->proc == do_split) {		if (nexp == 2)			append_right(subn,			    node(FS_node, Node_expression_list, (NODE *) NULL));		n = subn->rnode->rnode->lnode;		if (n->type != Node_regex)			subn->rnode->rnode->lnode = mk_rexp(n);		if (nexp == 2)			subn->rnode->rnode->lnode->re_flags |= FS_DFLT;	}	r->subnode = subn;	return r;}/* * This allocates a Node_line_range node with defined condpair and * zeroes the trigger word to avoid the temptation of assuming that calling * 'node( foo, Node_line_range, 0)' will properly initialize 'triggered'.  *//* Otherwise like node() */static NODE *mkrangenode(cpair)NODE *cpair;{	register NODE *r;	getnode(r);	r->type = Node_line_range;	r->condpair = cpair;	r->triggered = 0;	return r;}/* Build a for loop */static NODE *make_for_loop(init, cond, incr)NODE *init, *cond, *incr;{	register FOR_LOOP_HEADER *r;	NODE *n;	emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop");	getnode(n);	n->type = Node_illegal;	r->init = init;	r->cond = cond;	r->incr = incr;	n->sub.nodep.r.hd = r;	return n;}/* * Install a name in the symbol table, even if it is already there. * Caller must check against redefinition if that is desired.  */NODE *install(name, value)char *name;NODE *value;{	register NODE *hp;	register int len, bucket;	len = strlen(name);	bucket = hash(name, len);	getnode(hp);	hp->type = Node_hashnode;	hp->hnext = variables[bucket];	variables[bucket] = hp;	hp->hlength = len;	hp->hvalue = value;	hp->hname = name;	hp->hvalue->vname = name;	return hp->hvalue;}/* find the most recent hash node for name installed by install */NODE *lookup(name)char *name;{	register NODE *bucket;	register int len;	len = strlen(name);	bucket = variables[hash(name, len)];	while (bucket) {		if (bucket->hlength == len && STREQN(bucket->hname, name, len))			return bucket->hvalue;		bucket = bucket->hnext;	}	return NULL;}/* * Add new to the rightmost branch of LIST.  This uses n^2 time, so we make * a simple attempt at optimizing it. */static NODE *append_right(list, new)NODE *list, *new;{	register NODE *oldlist;	static NODE *savefront = NULL, *savetail = NULL;	oldlist = list;	if (savefront == oldlist) {		savetail = savetail->rnode = new;		return oldlist;	} else		savefront = oldlist;	while (list->rnode != NULL)		list = list->rnode;	savetail = list->rnode = new;	return oldlist;}/* * check if name is already installed;  if so, it had better have Null value, * in which case def is added as the value. Otherwise, install name with def * as value.  */static voidfunc_install(params, def)NODE *params;NODE *def;{	NODE *r;	pop_params(params->rnode);	pop_var(params, 0);	r = lookup(params->param);	if (r != NULL) {		fatal("function name `%s' previously defined", params->param);	} else		(void) install(params->param, node(params, Node_func, def));}static voidpop_var(np, freeit)NODE *np;int freeit;{	register NODE *bucket, **save;	register int len;	char *name;	name = np->param;	len = strlen(name);	save = &(variables[hash(name, len)]);	for (bucket = *save; bucket; bucket = bucket->hnext) {		if (len == bucket->hlength && STREQN(bucket->hname, name, len)) {			*save = bucket->hnext;			freenode(bucket);			if (freeit)				free(np->param);			return;		}		save = &(bucket->hnext);	}}static voidpop_params(params)NODE *params;{	register NODE *np;	for (np = params; np != NULL; np = np->rnode)		pop_var(np, 1);}static NODE *make_param(name)char *name;{	NODE *r;	getnode(r);	r->type = Node_param_list;	r->rnode = NULL;	r->param = name;	r->param_cnt = param_counter++;	return (install(name, r));}/* Name points to a variable name.  Make sure its in the symbol table */NODE *variable(name, can_free)char *name;int can_free;{	register NODE *r;	static int env_loaded = 0;	if (!env_loaded && STREQ(name, "ENVIRON")) {		load_environ();		env_loaded = 1;	}	if ((r = lookup(name)) == NULL)		r = install(name, node(Nnull_string, Node_var, (NODE *) NULL));	else if (can_free)		free(name);	return r;}static NODE *mk_rexp(exp)NODE *exp;{	if (exp->type == Node_regex)		return exp;	else {		NODE *n;		getnode(n);		n->type = Node_regex;		n->re_exp = exp;		n->re_text = NULL;		n->re_reg = NULL;		n->re_flags = 0;		n->re_cnt = 1;		return n;	}}

⌨️ 快捷键说明

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