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

📄 toke.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	    /* FALL THROUGH */	default:	  defchar:	    if (d[1] == '*' || (d[1] == '{' && d[2] == '0') || d[1] == '?') {		e = d;		break;	    }	    d++;	}    }    if (d == t) {	str_free(tmpstr);	return;    }    *d = '\0';    tmpstr->str_cur = d - t;    if (d == t+len)	spat->spat_flags |= SPAT_ALL;    if (*origstring != '^')	spat->spat_flags |= SPAT_SCANFIRST;    spat->spat_short = tmpstr;    spat->spat_slen = d - t;}char *scanpat(s)register char *s;{    register SPAT *spat;    register char *d;    register char *e;    int len;    SPAT savespat;    STR *str = Str_new(93,0);    char delim;    Newz(801,spat,1,SPAT);    spat->spat_next = curstash->tbl_spatroot;	/* link into spat list */    curstash->tbl_spatroot = spat;    switch (*s++) {    case 'm':	s++;	break;    case '/':	break;    case '?':	spat->spat_flags |= SPAT_ONCE;	break;    default:	fatal("panic: scanpat");    }    s = str_append_till(str,s,bufend,s[-1],patleave);    if (s >= bufend) {	str_free(str);	yyerror("Search pattern not terminated");	yylval.arg = Nullarg;	return s;    }    delim = *s++;    while (*s == 'i' || *s == 'o' || *s == 'g') {	if (*s == 'i') {	    s++;	    sawi = TRUE;	    spat->spat_flags |= SPAT_FOLD;	}	if (*s == 'o') {	    s++;	    spat->spat_flags |= SPAT_KEEP;	}	if (*s == 'g') {	    s++;	    spat->spat_flags |= SPAT_GLOBAL;	}    }    len = str->str_cur;    e = str->str_ptr + len;    if (delim == '\'')	d = e;    else	d = str->str_ptr;    for (; d < e; d++) {	if (*d == '\\')	    d++;	else if ((*d == '$' && d[1] && d[1] != '|' && d[1] != ')') ||		 (*d == '@')) {	    register ARG *arg;	    spat->spat_runtime = arg = op_new(1);	    arg->arg_type = O_ITEM;	    arg[1].arg_type = A_DOUBLE;	    arg[1].arg_ptr.arg_str = str_smake(str);	    d = scanident(d,bufend,buf);	    (void)stabent(buf,TRUE);		/* make sure it's created */	    for (; d < e; d++) {		if (*d == '\\')		    d++;		else if (*d == '$' && d[1] && d[1] != '|' && d[1] != ')') {		    d = scanident(d,bufend,buf);		    (void)stabent(buf,TRUE);		}		else if (*d == '@') {		    d = scanident(d,bufend,buf);		    if (strEQ(buf,"ARGV") || strEQ(buf,"ENV") ||		      strEQ(buf,"SIG") || strEQ(buf,"INC"))			(void)stabent(buf,TRUE);		}	    }	    goto got_pat;		/* skip compiling for now */	}    }    if (spat->spat_flags & SPAT_FOLD)	StructCopy(spat, &savespat, SPAT);    scanconst(spat,str->str_ptr,len);    if ((spat->spat_flags & SPAT_ALL) && (spat->spat_flags & SPAT_SCANFIRST)) {	fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);	spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,	    spat->spat_flags & SPAT_FOLD);		/* Note that this regexp can still be used if someone says		 * something like /a/ && s//b/;  so we can't delete it.		 */    }    else {	if (spat->spat_flags & SPAT_FOLD)	StructCopy(&savespat, spat, SPAT);	if (spat->spat_short)	    fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);	spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,	    spat->spat_flags & SPAT_FOLD);	hoistmust(spat);    }  got_pat:    str_free(str);    yylval.arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);    return s;}char *scansubst(start)char *start;{    register char *s = start;    register SPAT *spat;    register char *d;    register char *e;    int len;    STR *str = Str_new(93,0);    char term = *s;    if (term && (d = index("([{< )]}> )]}>",term)))	term = d[5];    Newz(802,spat,1,SPAT);    spat->spat_next = curstash->tbl_spatroot;	/* link into spat list */    curstash->tbl_spatroot = spat;    s = str_append_till(str,s+1,bufend,term,patleave);    if (s >= bufend) {	str_free(str);	yyerror("Substitution pattern not terminated");	yylval.arg = Nullarg;	return s;    }    len = str->str_cur;    e = str->str_ptr + len;    for (d = str->str_ptr; d < e; d++) {	if (*d == '\\')	    d++;	else if ((*d == '$' && d[1] && d[1] != '|' && /*(*/ d[1] != ')') ||	    *d == '@' ) {	    register ARG *arg;	    spat->spat_runtime = arg = op_new(1);	    arg->arg_type = O_ITEM;	    arg[1].arg_type = A_DOUBLE;	    arg[1].arg_ptr.arg_str = str_smake(str);	    d = scanident(d,e,buf);	    (void)stabent(buf,TRUE);		/* make sure it's created */	    for (; *d; d++) {		if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') {		    d = scanident(d,e,buf);		    (void)stabent(buf,TRUE);		}		else if (*d == '@' && d[-1] != '\\') {		    d = scanident(d,e,buf);		    if (strEQ(buf,"ARGV") || strEQ(buf,"ENV") ||		      strEQ(buf,"SIG") || strEQ(buf,"INC"))			(void)stabent(buf,TRUE);		}	    }	    goto get_repl;		/* skip compiling for now */	}    }    scanconst(spat,str->str_ptr,len);get_repl:    if (term != *start)	s++;    s = scanstr(s, SCAN_REPL);    if (s >= bufend) {	str_free(str);	yyerror("Substitution replacement not terminated");	yylval.arg = Nullarg;	return s;    }    spat->spat_repl = yylval.arg;    if ((spat->spat_repl[1].arg_type & A_MASK) == A_SINGLE)	spat->spat_flags |= SPAT_CONST;    else if ((spat->spat_repl[1].arg_type & A_MASK) == A_DOUBLE) {	STR *tmpstr;	register char *t;	spat->spat_flags |= SPAT_CONST;	tmpstr = spat->spat_repl[1].arg_ptr.arg_str;	e = tmpstr->str_ptr + tmpstr->str_cur;	for (t = tmpstr->str_ptr; t < e; t++) {	    if (*t == '$' && t[1] && (index("`'&+0123456789",t[1]) ||	      (t[1] == '{' /*}*/ && isDIGIT(t[2])) ))		spat->spat_flags &= ~SPAT_CONST;	}    }    while (*s == 'g' || *s == 'i' || *s == 'e' || *s == 'o') {	int es = 0;	if (*s == 'e') {	    s++;	    es++;	    if ((spat->spat_repl[1].arg_type & A_MASK) == A_DOUBLE)		spat->spat_repl[1].arg_type = A_SINGLE;	    spat->spat_repl = make_op(		(!es && spat->spat_repl[1].arg_type == A_SINGLE			? O_EVALONCE			: O_EVAL),		2,		spat->spat_repl,		Nullarg,		Nullarg);	    spat->spat_flags &= ~SPAT_CONST;	}	if (*s == 'g') {	    s++;	    spat->spat_flags |= SPAT_GLOBAL;	}	if (*s == 'i') {	    s++;	    sawi = TRUE;	    spat->spat_flags |= SPAT_FOLD;	    if (!(spat->spat_flags & SPAT_SCANFIRST)) {		str_free(spat->spat_short);	/* anchored opt doesn't do */		spat->spat_short = Nullstr;	/* case insensitive match */		spat->spat_slen = 0;	    }	}	if (*s == 'o') {	    s++;	    spat->spat_flags |= SPAT_KEEP;	}    }    if (spat->spat_short && (spat->spat_flags & SPAT_SCANFIRST))	fbmcompile(spat->spat_short, spat->spat_flags & SPAT_FOLD);    if (!spat->spat_runtime) {	spat->spat_regexp = regcomp(str->str_ptr,str->str_ptr+len,	  spat->spat_flags & SPAT_FOLD);	hoistmust(spat);    }    yylval.arg = make_match(O_SUBST,stab2arg(A_STAB,defstab),spat);    str_free(str);    return s;}voidhoistmust(spat)register SPAT *spat;{    if (!spat->spat_short && spat->spat_regexp->regstart &&	(!spat->spat_regexp->regmust || spat->spat_regexp->reganch & ROPT_ANCH)       ) {	if (!(spat->spat_regexp->reganch & ROPT_ANCH))	    spat->spat_flags |= SPAT_SCANFIRST;	else if (spat->spat_flags & SPAT_FOLD)	    return;	spat->spat_short = str_smake(spat->spat_regexp->regstart);    }    else if (spat->spat_regexp->regmust) {/* is there a better short-circuit? */	if (spat->spat_short &&	  str_eq(spat->spat_short,spat->spat_regexp->regmust))	{	    if (spat->spat_flags & SPAT_SCANFIRST) {		str_free(spat->spat_short);		spat->spat_short = Nullstr;	    }	    else {		str_free(spat->spat_regexp->regmust);		spat->spat_regexp->regmust = Nullstr;		return;	    }	}	if (!spat->spat_short ||	/* promote the better string */	  ((spat->spat_flags & SPAT_SCANFIRST) &&	   (spat->spat_short->str_cur < spat->spat_regexp->regmust->str_cur) )){	    str_free(spat->spat_short);		/* ok if null */	    spat->spat_short = spat->spat_regexp->regmust;	    spat->spat_regexp->regmust = Nullstr;	    spat->spat_flags |= SPAT_SCANFIRST;	}    }}char *scantrans(start)char *start;{    register char *s = start;    ARG *arg =	l(make_op(O_TRANS,2,stab2arg(A_STAB,defstab),Nullarg,Nullarg));    STR *tstr;    STR *rstr;    register char *t;    register char *r;    register short *tbl;    register int i;    register int j;    int tlen, rlen;    int squash;    int delete;    int complement;    New(803,tbl,256,short);    arg[2].arg_type = A_NULL;    arg[2].arg_ptr.arg_cval = (char*) tbl;    s = scanstr(s, SCAN_TR);    if (s >= bufend) {	yyerror("Translation pattern not terminated");	yylval.arg = Nullarg;	return s;    }    tstr = yylval.arg[1].arg_ptr.arg_str;     yylval.arg[1].arg_ptr.arg_str = Nullstr;     arg_free(yylval.arg);    t = tstr->str_ptr;    tlen = tstr->str_cur;    if (s[-1] == *start)	s--;    s = scanstr(s, SCAN_TR|SCAN_REPL);    if (s >= bufend) {	yyerror("Translation replacement not terminated");	yylval.arg = Nullarg;	return s;    }    rstr = yylval.arg[1].arg_ptr.arg_str;     yylval.arg[1].arg_ptr.arg_str = Nullstr;     arg_free(yylval.arg);    r = rstr->str_ptr;    rlen = rstr->str_cur;    complement = delete = squash = 0;    while (*s == 'c' || *s == 'd' || *s == 's') {	if (*s == 'c')	    complement = 1;	else if (*s == 'd')	    delete = 2;	else	    squash = 1;	s++;    }    arg[2].arg_len = delete|squash;    yylval.arg = arg;    if (complement) {	Zero(tbl, 256, short);	for (i = 0; i < tlen; i++)	    tbl[t[i] & 0377] = -1;	for (i = 0, j = 0; i < 256; i++) {	    if (!tbl[i]) {		if (j >= rlen) {		    if (delete)			tbl[i] = -2;		    else if (rlen)			tbl[i] = r[j-1] & 0377;		    else			tbl[i] = i;		}		else		    tbl[i] = r[j++] & 0377;	    }	}    }    else {	if (!rlen && !delete) {	    r = t; rlen = tlen;	}	for (i = 0; i < 256; i++)	    tbl[i] = -1;	for (i = 0, j = 0; i < tlen; i++,j++) {	    if (j >= rlen) {		if (delete) {		    if (tbl[t[i] & 0377] == -1)			tbl[t[i] & 0377] = -2;		    continue;		}		--j;	    }	    if (tbl[t[i] & 0377] == -1)		tbl[t[i] & 0377] = r[j] & 0377;	}    }    str_free(tstr);    str_free(rstr);    return s;}char *scanstr(start, in_what)char *start;int in_what;{    register char *s = start;    register char term;    register char *d;    register ARG *arg;    register char *send;    register bool makesingle = FALSE;    register STAB *stab;    bool alwaysdollar = FALSE;    bool hereis = FALSE;    STR *herewas;    STR *str;    /* which backslash sequences to keep */    char *leave = (in_what & SCAN_TR)	? "\\$@nrtfbeacx0123456789-"	: "\\$@nrtfbeacx0123456789[{]}lLuUE";    int len;    arg = op_new(1);    yylval.arg = arg;    arg->arg_type = O_ITEM;    switch (*s) {    default:			/* a substitution replacement */	arg[1].arg_type = A_DOUBLE;	makesingle = TRUE;	/* maybe disable runtime scanning */	term = *s;	if (term == '\'')	    leave = Nullch;	goto snarf_it;    case '0':	{	    unsigned long i;	    int shift;	    arg[1].arg_type = A_SINGLE;	    if (s[1] == 'x') {		shift = 4;		s += 2;	    }	    else if (s[1] == '.')		goto decimal;	    else		shift = 3;	    i = 0;	    for (;;) {		switch (*s) {		default:		    goto out;		case '_':		    s++;		    break;		case '8': case '9':		    if (shift != 4)			yyerror("Illegal octal digit");		    /* FALL THROUGH */		case '0': case '1': case '2': case '3': case '4':		case '5': case '6': case '7':		    i <<= shift;		    i += *s++ & 15;		    break;		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':		    if (shift != 4)			goto out;		    i <<= 4;		    i += (*s++ & 7) + 9;		    break;		}	    }	  out:	    str = Str_new(92,0);	    str_numset(str,(double)i);	    if (str->str_ptr) {		Safefree(str->str_ptr);		str->str_ptr = Nullch;		str->str_len = str->str_cur = 0;	    }	    arg[1].arg_ptr.arg_str = str;	}	break;    case '1': case '2': case '3': case '4': case '5':    case '6': case '7': case '8': case '9': case '.':      decimal:	arg[1].arg_type = A_SINGLE;	d = tokenbuf;	while (isDIGIT(*s) || *s == '_') {	    if (*s == '_')		s++;	    else		*d++ = *s++;	}	if (*s == '.' && s[1] != '.') {	    *d++ = *s++;	    while (isDIGIT(*s) || *s == '_') {		if (*s == '_')		    s++;		else		    *d++ = *s++;	    }	}	if (*s && index("eE",*s) && index("+-0123456789",s[1])) {	    *d++ = *s++;	    if (*s == '+' || *s == '-')		*d++ = *s++;	    while (isDIGIT(*s))		*d++ = *s++;	}	*d = '\0';	str = Str_new(92,0);	str_numset(str,atof(tokenbuf));	if (str->str_ptr) {	    Safefree(str->str_ptr);	    str->str_ptr = Nullch;	    str->str_len = str->str_cur = 0;	}	arg[1].arg_ptr.arg_str = str;	break;    case '<':	if (in_what & (SCAN_REPL|SCAN_TR))	    goto do_double;	if (*++s == '<') {	    hereis = TRUE;	    d = tokenbuf;	    if (!rsfp)		*d++ = '\n';	    if (*++s && index("`'\"",*s)) {		term = *s++;		s = cpytill(d,s,bufend,term,&len);		if (s < bufend)		    s++;		d += len;	    }	    else {		if (*s == '\\')		    s++, term = '\'';		else

⌨️ 快捷键说明

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