📄 a2py.c
字号:
/* $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 + -