📄 y.c
字号:
/* * a small awk clone * * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi * * Absolutely no warranty. Use this software with your own risk. * * Permission to use, copy, modify and distribute this software for any * purpose and without fee is hereby granted, provided that the above * copyright and disclaimer notice. * * This program was written to fit into 64K+64K memory of the Minix 1.2. */#include <stdio.h>#include "awk.h"extern char *mkpat();extern char *cmd;extern char text[];extern char funnam[];extern int sym;extern int sym1;extern int regexflg;extern int funflg;extern int printflg;extern int getlineflg;extern SYMBOL *hashtab[], *funtab[];extern CELL *field[];char *emalloc(), *strsave();NODE *node0(), *node1(), *node2(), *node3(), *node4();NODE *stat(), *pastat();NODE *expr(), *expr1(), *expr2(), *expr3(), *expr4();NODE *expr5(), *expr6(), *expr7(), *expr8(), *expr9(), *expr10();NODE *doprint(), *dofuncn(), *doif(), *dowhile(), *dofor(), *body();NODE *doassign(), *dodo(), *doarray(), *doreturn(), *doelement();CELL *mkcell(), *getvar();CELL *execute(), *lookup();int forflg; /* parsing for(expr in array), inhibit 'expr in array' */int prmflg; /* parsing pass parameters */NODE *begin, *loop, *End;parse(){ NODE *p, *q, *r, *stat(); CELL *u; lex(); skipeol(); while (sym) { switch (sym) { case BEGIN: lex(); begin = stat(); break; case END: lex(); if (End == NULL) End = stat(); else { for (p = End; p; p = q) { if ((q = p->n_next) == NULL) p->n_next = stat(); } } break; case FUNC: lex(); dousrfun(); break; default: q = loop = pastat(); skipeol(); while (sym && sym != BEGIN && sym != END && sym != FUNC) { r = pastat(); q->n_next = r; q = r; skipeol(); } break; } skipeol(); } if (begin) { u = execute(begin); c_free(u); } if (End || loop) while (Getrec(NULL)) { if (loop) { u = execute(loop); c_free(u); } } if (End) { u = execute(End); c_free(u); }}#define MAXARG 100static char *argnam[MAXARG];static int narg;staticdousrfun(){ CELL *u; strcpy(funnam, text); u = getvar(text, funtab, FUN); lex(); if (sym != '(') synerr("'(' expected"); for (lex(); sym != ')'; narg++) { if (sym != IDENT) synerr("argument expected"); argnam[narg] = strsave(text); lex(); if (sym == ',') lex(); } u->c_fval = (double) narg; lex(); skipeol(); funflg++; u->c_sval = (char *) stat(); funflg--; if (narg > 0) { do { sfree(argnam[--narg]); } while (narg > 0); } skipeol();}isarg(s) char *s;{ int i; if (narg > 0) { for (i = narg - 1; i >= 0; i--) if (strcmp(s, argnam[i]) == 0) break; } else i = -1; return i;}/*interactive(){ NODE *p, *q; CELL *u; for (lex(); sym; lex()) { p = stat(); if (p->n_type != PRINT && !iscntl(p->n_type)) { q = (NODE *) emalloc(sizeof(NODE) + sizeof(NODE *) * 4); q->n_type = PRINT; q->n_arg[0] = q->n_arg[1] = q->n_arg[3] = NULL; q->n_arg[2] = p; q->n_next = NULL; p = q; } u = execute(p); printf("[%g(%s)]\n", u->c_fval, u->c_sval); c_free(u); } closeall(); exit(0);}*/staticiscntl(t){ static int tab[] = { IF, DO, WHILE, FOR, JUMP, GETLINE, 0 }; int i; for (i = 0; tab[i]; i++) if (t == tab[i]) break; return tab[i];}static NODE *pastat(){ NODE *p, *q, *r; if (sym == '{') /* action only */ p = stat(); else { /* exp [, expr] [{ .. }] */ p = expr(); if (sym == ',') { lex(); q = expr(); } else q = NULL; if (sym && sym != EOL) r = stat(); else r = node0(PRINT0); if (q) p = node3(P2STAT, p, q, r); else p = node2(P1STAT, p, r); } return p;}static NODE *stat(){ NODE *p, *q, *r; CELL *u, *v; int op;/*printf("@stat(%d)(%s)\n", sym, text);*/ while (sym == EOL) lex(); switch(sym) { case PRINT: p = doprint(0); break; case PRINTF: p = doprint(FORMAT); break; case IF: p = doif(); break; case WHILE: p = dowhile(); break; case DO: p = dodo(); break; case FOR: p = dofor(); break; case RETURN: p = doreturn(); break; case EXIT: p = node2(JUMP, (NODE *)sym, (NODE *)NULL); lex(); if (sym == IDENT || sym == NUMBER || sym == ARG) p->n_arg[1] = expr(); break; case BREAK: case CONTIN: case NEXT: p = node1(JUMP, (NODE *)sym); lex(); break; case DELETE: lex(); u = getvar(text, hashtab, ARR); if (Getc() != '[') synerr("'[' expected"); p = doarray(u); p->n_type = DELETE; lex(); /* ']' */ break; case '{': lex(); skipeol(); if (sym == '}') p = node0(NULPROC); else p = q = stat(); skipeol(); while (sym != '}') { r = stat(); q->n_next = r; q = r; skipeol(); } lex(); break; default: p = expr();#if 0 if (sym == BINOR) { /* expr | GETLINE */ lex(); if (sym != GETLINE) synerr("'GETLINE' expected"); lex(); if (sym == IDENT || sym == STRING || sym == ARG) { q = expr(); } else q = NULL; p = node3(GETLINE, q, p, (NODE *)R_PIN); }#endif break; } if (p->n_type == VALUE) synerr("statement expected"); return p;}staticskipeol(){ while (sym == EOL) lex();}static NODE *doprint(fmt){ NODE *p, *q, *r; CELL *u; int i, op; int n = 0; printflg++; lex(); if (sym == '(') lex(); if (sym != '}' && sym != ')' && sym != EOL && sym != R_OUT && sym != R_APD && sym != R_POUT) { p = q = expr(); n++; while (sym == ',') { lex(); skipeol(); r = expr(); n++; q->n_next = r; q = r; } } if (sym == ')') lex(); if (sym == R_OUT || sym == R_APD || sym == R_POUT) { op = sym; lex();/* q = expr10();*/ q = expr(); /* 94-04-02 */ } else q = (NODE *) (op = 0); /* stdout */ printflg = 0; r = (NODE *) emalloc(sizeof(*r) + sizeof(r) * (n + 3)); r->n_type = PRINT; /* convert list to arg */ r->n_next = NULL; r->n_arg[0] = (NODE *) (op | fmt); r->n_arg[1] = q; if (n == 0) { p = node1(VALUE, (NODE *)field[0]); } for (i = 2; p != NULL; i++) { r->n_arg[i] = p; q = p->n_next; p->n_next = NULL; p = q; } r->n_arg[i] = NULL; return r;}static NODE *doif(){ NODE *p, *q, *r; lex(); if (sym != '(') synerr("'(' expected"); lex(); p = expr(); if (sym != ')') synerr("')' expected"); lex(); skipeol(); q = stat(); skipeol(); if (sym == ELSE) { lex(); skipeol(); r = stat(); } else r = NULL; return node3(IF, p, q, r);}static NODE *dowhile(){ NODE *p, *q; lex(); if (sym != '(') synerr("'(' expected"); lex(); p = stat(); if (sym != ')') synerr("')' expected"); q = body(); return node2(WHILE, p, q);}static NODE *dofor(){ NODE *p, *q, *r, *s; CELL *u; int i; lex(); if (sym != '(') synerr("'(' expected"); lex(); if (sym != EOL) { forflg++; /* inhibit parsing 'expr IN array' */ p = expr(); forflg = 0; } else p = NULL; if (sym == IN) { lex(); if (sym == ARG) {/*printf("***FOR_IN_ARG(%d)***\n", sym);*/ u = mkcell(POS, NULL, (double)sym1); q = node1(ARG, u); } else { u = getvar(text, hashtab, ARR); q = node1(VALUE, u); } lex(); if (sym != ')') synerr("')' expected"); lex(); skipeol(); s = stat(); r = node3(FORIN, p, q, s); } else { if (sym != EOL) synerr("'in' or ';' expected"); lex(); if (sym != EOL) q = expr(); else q = NULL; if (sym != EOL) synerr("';' expected"); lex(); if (sym != ')') r = expr(); else r = NULL; if (sym != ')') synerr("')' expected"); s = body(); r = node4(FOR, p, q, r, s); } return r;}static NODE *body(){ NODE *r; while ((sym = Getc()) == '\n' || sym == ' ' || sym == '\t') ; if (sym == ';') { r = node0(NULPROC); lex(); } else { Ungetc(sym); lex(); r = stat(); } return r;}static NODE *dodo(){ NODE *p, *q; lex(); skipeol(); p = stat(); skipeol(); if (sym != WHILE) synerr("'while' expected"); lex(); if (sym != '(') synerr("'(' expected"); lex(); q = stat(); if (sym != ')') synerr("')' expected"); lex(); return node2(DO, p, q);}static NODE *doreturn(){ NODE *p, *q, *r; int i, n = 0; if (lex() != EOL) { p = q = expr(); n++; while (sym == ',') { lex(); skipeol(); r = expr(); n++; q ->n_next = r; q = r; } } else p = (NODE *)NULL; r = (NODE *) emalloc(sizeof(*r) + sizeof (r) * (n + 1)); r->n_type = JUMP; r->n_next = NULL; r->n_arg[0] = (NODE *) RETURN; for (i = 1; p != NULL; i++) { r->n_arg[i] = p; q = p->n_next; p->n_next = NULL; p = q; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -