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

📄 a2py.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $RCSfile: a2py.c,v $$Revision: 4.0.1.2 $$Date: 92/06/08 16:15:16 $ * *    Copyright (c) 1991, Larry Wall * *    You may distribute under the terms of either the GNU General Public *    License or the Artistic License, as specified in the README file. * * $Log:	a2py.c,v $ * Revision 4.0.1.2  92/06/08  16:15:16  lwall * patch20: in a2p, now warns about spurious backslashes * patch20: in a2p, now allows [ to be backslashed in pattern * patch20: in a2p, now allows numbers of the form 2. *  * Revision 4.0.1.1  91/06/07  12:12:59  lwall * patch4: new copyright notice *  * Revision 4.0  91/03/20  01:57:26  lwall * 4.0 baseline. *  */#ifdef OS2#include "../patchlevel.h"#endif#include "util.h"char *index();char *filename;char *myname;int checkers = 0;STR *walk();#ifdef OS2usage(){    printf("\nThis is the AWK to PERL translator, version 4.0, patchlevel %d\n", PATCHLEVEL);    printf("\nUsage: %s [-D<number>] [-F<char>] [-n<fieldlist>] [-<number>] filename\n", myname);    printf("\n  -D<number>      sets debugging flags."           "\n  -F<character>   the awk script to translate is always invoked with"           "\n                  this -F switch."           "\n  -n<fieldlist>   specifies the names of the input fields if input does"           "\n                  not have to be split into an array."           "\n  -<number>       causes a2p to assume that input will always have that"           "\n                  many fields.\n");    exit(1);}#endifmain(argc,argv,env)register int argc;register char **argv;register char **env;{    register STR *str;    register char *s;    int i;    STR *tmpstr;    myname = argv[0];    linestr = str_new(80);    str = str_new(0);		/* first used for -I flags */    for (argc--,argv++; argc; argc--,argv++) {	if (argv[0][0] != '-' || !argv[0][1])	    break;      reswitch:	switch (argv[0][1]) {#ifdef DEBUGGING	case 'D':	    debug = atoi(argv[0]+2);#ifdef YYDEBUG	    yydebug = (debug & 1);#endif	    break;#endif	case '0': case '1': case '2': case '3': case '4':	case '5': case '6': case '7': case '8': case '9':	    maxfld = atoi(argv[0]+1);	    absmaxfld = TRUE;	    break;	case 'F':	    fswitch = argv[0][2];	    break;	case 'n':	    namelist = savestr(argv[0]+2);	    break;	case '-':	    argc--,argv++;	    goto switch_end;	case 0:	    break;	default:	    fatal("Unrecognized switch: %s\n",argv[0]);#ifdef OS2            usage();#endif	}    }  switch_end:    /* open script */    if (argv[0] == Nullch) {#ifdef OS2	if ( isatty(fileno(stdin)) )	    usage();#endif        argv[0] = "-";    }    filename = savestr(argv[0]);    filename = savestr(argv[0]);    if (strEQ(filename,"-"))	argv[0] = "";    if (!*argv[0])	rsfp = stdin;    else	rsfp = fopen(argv[0],"r");    if (rsfp == Nullfp)	fatal("Awk script \"%s\" doesn't seem to exist.\n",filename);    /* init tokener */    bufptr = str_get(linestr);    symtab = hnew();    curarghash = hnew();    /* now parse the report spec */    if (yyparse())	fatal("Translation aborted due to syntax errors.\n");#ifdef DEBUGGING    if (debug & 2) {	int type, len;	for (i=1; i<mop;) {	    type = ops[i].ival;	    len = type >> 8;	    type &= 255;	    printf("%d\t%d\t%d\t%-10s",i++,type,len,opname[type]);	    if (type == OSTRING)		printf("\t\"%s\"\n",ops[i].cval),i++;	    else {		while (len--) {		    printf("\t%d",ops[i].ival),i++;		}		putchar('\n');	    }	}    }    if (debug & 8)	dump(root);#endif    /* first pass to look for numeric variables */    prewalk(0,0,root,&i);    /* second pass to produce new program */    tmpstr = walk(0,0,root,&i,P_MIN);    str = str_make("#!");    str_cat(str, BIN);    str_cat(str, "/perl\neval \"exec ");    str_cat(str, BIN);    str_cat(str, "/perl -S $0 $*\"\n\    if $running_under_some_shell;\n\			# this emulates #! processing on NIH machines.\n\			# (remove #! line above if indigestible)\n\n");    str_cat(str,      "eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;\n");    str_cat(str,      "			# process any FOO=bar switches\n\n");    if (do_opens && opens) {	str_scat(str,opens);	str_free(opens);	str_cat(str,"\n");    }    str_scat(str,tmpstr);    str_free(tmpstr);#ifdef DEBUGGING    if (!(debug & 16))#endif    fixup(str);    putlines(str);    if (checkers) {	fprintf(stderr,	  "Please check my work on the %d line%s I've marked with \"#???\".\n",		checkers, checkers == 1 ? "" : "s" );	fprintf(stderr,	  "The operation I've selected may be wrong for the operand types.\n");    }    exit(0);}#define RETURN(retval) return (bufptr = s,retval)#define XTERM(retval) return (expectterm = TRUE,bufptr = s,retval)#define XOP(retval) return (expectterm = FALSE,bufptr = s,retval)#define ID(x) return (yylval=string(x,0),expectterm = FALSE,bufptr = s,idtype)int idtype;yylex(){    register char *s = bufptr;    register char *d;    register int tmp;  retry:#ifdef YYDEBUG    if (yydebug)	if (index(s,'\n'))	    fprintf(stderr,"Tokener at %s",s);	else	    fprintf(stderr,"Tokener at %s\n",s);#endif    switch (*s) {    default:	fprintf(stderr,	    "Unrecognized character %c in file %s line %d--ignoring.\n",	     *s++,filename,line);	goto retry;    case '\\':	s++;	if (*s && *s != '\n') {	    yyerror("Ignoring spurious backslash");	    goto retry;	}	/*FALLSTHROUGH*/    case 0:	s = str_get(linestr);	*s = '\0';	if (!rsfp)	    RETURN(0);	line++;	if ((s = str_gets(linestr, rsfp)) == Nullch) {	    if (rsfp != stdin)		fclose(rsfp);	    rsfp = Nullfp;	    s = str_get(linestr);	    RETURN(0);	}	goto retry;    case ' ': case '\t':	s++;	goto retry;    case '\n':	*s = '\0';	XTERM(NEWLINE);    case '#':	yylval = string(s,0);	*s = '\0';	XTERM(COMMENT);    case ';':	tmp = *s++;	if (*s == '\n') {	    s++;	    XTERM(SEMINEW);	}	XTERM(tmp);    case '(':	tmp = *s++;	XTERM(tmp);    case '{':    case '[':    case ')':    case ']':    case '?':    case ':':	tmp = *s++;	XOP(tmp);    case 127:	s++;	XTERM('}');    case '}':	for (d = s + 1; isspace(*d); d++) ;	if (!*d)	    s = d - 1;	*s = 127;	XTERM(';');    case ',':	tmp = *s++;	XTERM(tmp);    case '~':	s++;	yylval = string("~",1);	XTERM(MATCHOP);    case '+':    case '-':	if (s[1] == *s) {	    s++;	    if (*s++ == '+')		XTERM(INCR);	    else		XTERM(DECR);	}	/* FALL THROUGH */    case '*':    case '%':    case '^':	tmp = *s++;	if (*s == '=') {	    if (tmp == '^')		yylval = string("**=",3);	    else		yylval = string(s-1,2);	    s++;	    XTERM(ASGNOP);	}	XTERM(tmp);    case '&':	s++;	tmp = *s++;	if (tmp == '&')	    XTERM(ANDAND);	s--;	XTERM('&');    case '|':	s++;	tmp = *s++;	if (tmp == '|')	    XTERM(OROR);	s--;	while (*s == ' ' || *s == '\t')	    s++;	if (strnEQ(s,"getline",7))	    XTERM('p');	else	    XTERM('|');    case '=':	s++;	tmp = *s++;	if (tmp == '=') {	    yylval = string("==",2);	    XTERM(RELOP);	}	s--;	yylval = string("=",1);	XTERM(ASGNOP);    case '!':	s++;	tmp = *s++;	if (tmp == '=') {	    yylval = string("!=",2);	    XTERM(RELOP);	}	if (tmp == '~') {	    yylval = string("!~",2);	    XTERM(MATCHOP);	}	s--;	XTERM(NOT);    case '<':	s++;	tmp = *s++;	if (tmp == '=') {	    yylval = string("<=",2);	    XTERM(RELOP);	}	s--;	XTERM('<');    case '>':	s++;	tmp = *s++;	if (tmp == '>') {	    yylval = string(">>",2);	    XTERM(GRGR);	}	if (tmp == '=') {	    yylval = string(">=",2);	    XTERM(RELOP);	}	s--;	XTERM('>');#define SNARFWORD \	d = tokenbuf; \	while (isalpha(*s) || isdigit(*s) || *s == '_') \	    *d++ = *s++; \	*d = '\0'; \	d = tokenbuf; \	if (*s == '(') \	    idtype = USERFUN; \	else \	    idtype = VAR;    case '$':	s++;	if (*s == '0') {	    s++;	    do_chop = TRUE;	    need_entire = TRUE;	    idtype = VAR;	    ID("0");	}	do_split = TRUE;	if (isdigit(*s)) {	    for (d = s; isdigit(*s); s++) ;	    yylval = string(d,s-d);	    tmp = atoi(d);	    if (tmp > maxfld)		maxfld = tmp;	    XOP(FIELD);	}	split_to_array = set_array_base = TRUE;	XOP(VFIELD);    case '/':			/* may either be division or pattern */	if (expectterm) {	    s = scanpat(s);	    XTERM(REGEX);	}	tmp = *s++;	if (*s == '=') {	    yylval = string("/=",2);	    s++;	    XTERM(ASGNOP);	}	XTERM(tmp);    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9': case '.':	s = scannum(s);	XOP(NUMBER);    case '"':	s++;	s = cpy2(tokenbuf,s,s[-1]);	if (!*s)	    fatal("String not terminated:\n%s",str_get(linestr));	s++;	yylval = string(tokenbuf,0);	XOP(STRING);    case 'a': case 'A':	SNARFWORD;	if (strEQ(d,"ARGC"))	    set_array_base = TRUE;	if (strEQ(d,"ARGV")) {	    yylval=numary(string("ARGV",0));	    XOP(VAR);	}	if (strEQ(d,"atan2")) {	    yylval = OATAN2;	    XTERM(FUNN);	}	ID(d);    case 'b': case 'B':	SNARFWORD;	if (strEQ(d,"break"))	    XTERM(BREAK);	if (strEQ(d,"BEGIN"))	    XTERM(BEGIN);	ID(d);    case 'c': case 'C':	SNARFWORD;	if (strEQ(d,"continue"))	    XTERM(CONTINUE);	if (strEQ(d,"cos")) {	    yylval = OCOS;	    XTERM(FUN1);	}	if (strEQ(d,"close")) {	    do_fancy_opens = 1;	    yylval = OCLOSE;	    XTERM(FUN1);	}	if (strEQ(d,"chdir"))	    *d = toupper(*d);	else if (strEQ(d,"crypt"))	    *d = toupper(*d);	else if (strEQ(d,"chop"))	    *d = toupper(*d);	else if (strEQ(d,"chmod"))	    *d = toupper(*d);	else if (strEQ(d,"chown"))	    *d = toupper(*d);	ID(d);    case 'd': case 'D':	SNARFWORD;	if (strEQ(d,"do"))	    XTERM(DO);	if (strEQ(d,"delete"))	    XTERM(DELETE);	if (strEQ(d,"die"))	    *d = toupper(*d);	ID(d);    case 'e': case 'E':	SNARFWORD;	if (strEQ(d,"END"))	    XTERM(END);	if (strEQ(d,"else"))	    XTERM(ELSE);	if (strEQ(d,"exit")) {	    saw_line_op = TRUE;	    XTERM(EXIT);	}	if (strEQ(d,"exp")) {	    yylval = OEXP;	    XTERM(FUN1);	}	if (strEQ(d,"elsif"))	    *d = toupper(*d);	else if (strEQ(d,"eq"))	    *d = toupper(*d);	else if (strEQ(d,"eval"))	    *d = toupper(*d);	else if (strEQ(d,"eof"))	    *d = toupper(*d);	else if (strEQ(d,"each"))	    *d = toupper(*d);	else if (strEQ(d,"exec"))	    *d = toupper(*d);	ID(d);    case 'f': case 'F':	SNARFWORD;	if (strEQ(d,"FS")) {	    saw_FS++;	    if (saw_FS == 1 && in_begin) {		for (d = s; *d && isspace(*d); d++) ;		if (*d == '=') {		    for (d++; *d && isspace(*d); d++) ;		    if (*d == '"' && d[2] == '"')			const_FS = d[1];		}	    }	    ID(tokenbuf);	}	if (strEQ(d,"for"))	    XTERM(FOR);	else if (strEQ(d,"function"))	    XTERM(FUNCTION);	if (strEQ(d,"FILENAME"))	    d = "ARGV";	if (strEQ(d,"foreach"))	    *d = toupper(*d);	else if (strEQ(d,"format"))	    *d = toupper(*d);	else if (strEQ(d,"fork"))	    *d = toupper(*d);	else if (strEQ(d,"fh"))	    *d = toupper(*d);	ID(d);    case 'g': case 'G':	SNARFWORD;	if (strEQ(d,"getline"))	    XTERM(GETLINE);	if (strEQ(d,"gsub"))	    XTERM(GSUB);	if (strEQ(d,"ge"))	    *d = toupper(*d);	else if (strEQ(d,"gt"))	    *d = toupper(*d);	else if (strEQ(d,"goto"))	    *d = toupper(*d);	else if (strEQ(d,"gmtime"))	    *d = toupper(*d);	ID(d);    case 'h': case 'H':	SNARFWORD;	if (strEQ(d,"hex"))	    *d = toupper(*d);	ID(d);    case 'i': case 'I':	SNARFWORD;	if (strEQ(d,"if"))	    XTERM(IF);	if (strEQ(d,"in"))	    XTERM(IN);	if (strEQ(d,"index")) {	    set_array_base = TRUE;	    XTERM(INDEX);	}	if (strEQ(d,"int")) {	    yylval = OINT;	    XTERM(FUN1);	}	ID(d);    case 'j': case 'J':	SNARFWORD;	if (strEQ(d,"join"))	    *d = toupper(*d);	ID(d);    case 'k': case 'K':	SNARFWORD;	if (strEQ(d,"keys"))	    *d = toupper(*d);	else if (strEQ(d,"kill"))	    *d = toupper(*d);	ID(d);    case 'l': case 'L':	SNARFWORD;	if (strEQ(d,"length")) {	    yylval = OLENGTH;	    XTERM(FUN1);	}	if (strEQ(d,"log")) {	    yylval = OLOG;	    XTERM(FUN1);	}	if (strEQ(d,"last"))	    *d = toupper(*d);	else if (strEQ(d,"local"))	    *d = toupper(*d);	else if (strEQ(d,"lt"))	    *d = toupper(*d);	else if (strEQ(d,"le"))	    *d = toupper(*d);	else if (strEQ(d,"locatime"))	    *d = toupper(*d);	else if (strEQ(d,"link"))	    *d = toupper(*d);	ID(d);    case 'm': case 'M':	SNARFWORD;	if (strEQ(d,"match")) {	    set_array_base = TRUE;	    XTERM(MATCH);	}	if (strEQ(d,"m"))	    *d = toupper(*d);	ID(d);    case 'n': case 'N':	SNARFWORD;	if (strEQ(d,"NF"))	    do_chop = do_split = split_to_array = set_array_base = TRUE;	if (strEQ(d,"next")) {	    saw_line_op = TRUE;	    XTERM(NEXT);	}	if (strEQ(d,"ne"))	    *d = toupper(*d);	ID(d);    case 'o': case 'O':	SNARFWORD;	if (strEQ(d,"ORS")) {	    saw_ORS = TRUE;	    d = "\\";	}	if (strEQ(d,"OFS")) {	    saw_OFS = TRUE;	    d = ",";	}	if (strEQ(d,"OFMT")) {	    d = "#";	}	if (strEQ(d,"open"))	    *d = toupper(*d);	else if (strEQ(d,"ord"))	    *d = toupper(*d);	else if (strEQ(d,"oct"))

⌨️ 快捷键说明

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