Annotation of coherent/d/bin/sh/sh.y, revision 1.1.1.1

1.1       root        1: /*
                      2:  * sh/sh.y
                      3:  * The Bourne shell.
                      4:  * This shell is dedicated to Ciaran Gerald Aidan O'Donnell.
                      5:  * May he live a thousand minutes (long enough to fix up YACC).
                      6:  * It is also dedicated to Steve Bourne.
                      7:  * May he live a thousand seconds.
                      8:  */
                      9: %{
                     10: #include "sh.h"
                     11: 
                     12: #define YYERROR        { yyerrflag=1; goto YYerract; }
                     13: 
                     14: extern NODE    *node();
                     15: %}
                     16: 
                     17: %union {
                     18:        NODE    *yu_node;
                     19:        char    *yu_strp;
                     20:        int     yu_nval;
                     21: }
                     22: 
                     23: %token _ANDF
                     24: %token _ASGN
                     25: %token _CASE
                     26: %token _CBRAC
                     27: %token _DO
                     28: %token _DONE
                     29: %token _DSEMI
                     30: %token _ELIF
                     31: %token _ELSE
                     32: %token _ESAC
                     33: %token _FI
                     34: %token _FOR
                     35: %token _IF
                     36: %token _IN
                     37: %token _IORS
                     38: %token _NAME
                     39: %token _NULL
                     40: %token _OBRAC
                     41: %token _ORF
                     42: %token _THEN
                     43: %token _UNTIL
                     44: %token _WHILE
                     45: 
                     46: %type <yu_node>        arg             arg_list        case_line       case_list
                     47: %type <yu_node>        cmd             cmd_line        cmd_list        cmd_seq
                     48: %type <yu_node>        control         do_list         else_part       in_name_list
                     49: %type <yu_node>        logical_cmd     name_list       opt_cmd_seq     pattern_list
                     50: %type <yu_node>        pipe_cmd        sub_shell
                     51: 
                     52: %type <yu_strp>        asgn            name            redirect
                     53: 
                     54: %type <yu_nval> whuntile
                     55: 
                     56: %%
                     57: 
                     58: session:
                     59:        session cmd_line
                     60: |
                     61: ;
                     62: 
                     63: cmd_line:
                     64:        '\n' {
                     65:                sesp->s_node = NULL;
                     66:                reset(RCMD);
                     67:                NOTREACHED;
                     68:        }
                     69: |
                     70:        cmd_list '\n' {
                     71:                sesp->s_node = $1;
                     72:                reset(errflag ? RERR : RCMD);
                     73:                NOTREACHED;
                     74:        }
                     75: |      error '\n' {
                     76:                keyflush();
                     77:                keyflag = 1;
                     78:                reset(RERR);
                     79:                NOTREACHED;
                     80:        }
                     81: ;
                     82: 
                     83: if:    _IF optnls ;
                     84: 
                     85: then:  _THEN optnls ;
                     86: 
                     87: elif:  _ELIF optnls ;
                     88: 
                     89: else:  _ELSE optnls ;
                     90: 
                     91: whuntile:      _WHILE optnls { $$ = NWHILE;    }
                     92: |      _UNTIL optnls { $$ = NUNTIL;    }
                     93: ;
                     94: 
                     95: do:    _DO optnls | _DO ';' optnls ;
                     96: 
                     97: in:    _IN | _IN sep ;
                     98: 
                     99: oror:  _ORF optnls;
                    100: 
                    101: andand:        _ANDF optnls;
                    102: 
                    103: or:    '|' optnls;
                    104: 
                    105: oparen:        '(' optnls ;
                    106: 
                    107: obrack:        _OBRAC optnls ;
                    108: 
                    109: cparen:        ')' optnls ;
                    110: 
                    111: dsemi: _DSEMI optnls ;
                    112: 
                    113: cmd_list:
                    114:        logical_cmd {
                    115:                $$ = $1;
                    116:        }
                    117: |      logical_cmd '&' {
                    118:                $$ = node(NBACK, $1, NULL);
                    119:        }
                    120: |      logical_cmd ';' {
                    121:                $$ = $1;
                    122:        }
                    123: |      logical_cmd '&' cmd_list {
                    124:                $$ = node(NBACK, $1, $3);
                    125:        }
                    126: |      logical_cmd ';' cmd_list {
                    127:                $$ = node(NLIST, $1, $3);
                    128:        }
                    129: ;
                    130: 
                    131: logical_cmd:
                    132:        pipe_cmd {
                    133:                $$ = $1;
                    134:        }
                    135: |      pipe_cmd oror logical_cmd {
                    136:                $$ = node(NORF, $1, $3);
                    137:        }
                    138: |      pipe_cmd andand logical_cmd {
                    139:                $$ = node(NANDF, $1, $3);
                    140:        }
                    141: ;
                    142: 
                    143: pipe_cmd:
                    144:        cmd or pipe_cmd {
                    145:                $$ = node(NPIPE, $1, $3);
                    146:        }
                    147: |      cmd {
                    148:                $$ = $1;
                    149:        }
                    150: ;
                    151: 
                    152: cmd:
                    153:        arg_list_init arg_list {
                    154:                $$ = node(NCOMS, $2, NULL);
                    155:                keypop();
                    156:        }
                    157: ;
                    158: 
                    159: arg_list_init:
                    160:        {
                    161:                keypush();
                    162:                keyflag = 1;
                    163:        }
                    164: ;
                    165: 
                    166: arg_list:
                    167:        arg arg_list {
                    168:                if (($1->n_type == NCTRL && $2->n_type == NARGS)
                    169:                 || ($1->n_type == NARGS && $2->n_type == NCTRL)) {
                    170:                        YYERROR;
                    171:                }
                    172:                ($$ = $1)->n_next = $2;
                    173:        }
                    174: |      arg {
                    175:                $$ = $1;
                    176:        }
                    177: ;
                    178: 
                    179: arg:
                    180:        redirect {
                    181:                $$ = node(NIORS, $1, NULL);
                    182:        }
                    183: |      name {
                    184:                $$ = node(NARGS, $1, NULL);
                    185:                keyflag = 0;
                    186:        }
                    187: |      asgn {
                    188:                $$ = node(NASSG, $1, NULL);
                    189:        }
                    190: |      control {
                    191:                if (!keyflag) {
                    192:                        YYERROR;
                    193:                }
                    194:                $$ = node(NCTRL, $1, NULL);
                    195:                keyflag = 0;
                    196:        }
                    197: ;
                    198: 
                    199: redirect:      _IORS {
                    200:                $$ = duplstr(strt, 0);
                    201:        }
                    202: ;
                    203: 
                    204: name:  _NAME {
                    205:                $$ = duplstr(strt, 0);
                    206:        }
                    207: ;
                    208: 
                    209: asgn:  _ASGN {
                    210:                $$ = duplstr(strt, 0);
                    211:        }
                    212: ;
                    213: 
                    214: control:
                    215:        _FOR name in_name_list sep do_list _DONE {
                    216:                $$ = node(NFOR, $2, node(NFOR2, $3, node(NLIST, $5, NULL)));
                    217:                $$->n_next->n_next->n_next = $$->n_next;
                    218:        }
                    219: |      _FOR name in_name_list do_list _DONE {
                    220:                $$ = node(NFOR, $2, node(NFOR2, $3, node(NLIST, $4, NULL)));
                    221:                $$->n_next->n_next->n_next = $$->n_next;
                    222:        }
                    223: |      _CASE name sep in case_list _ESAC {
                    224:                $$ = node(NCASE, $2, $5);
                    225:        }
                    226: |      _CASE name in case_list _ESAC {
                    227:                $$ = node(NCASE, $2, $4);
                    228:        }
                    229: |      whuntile cmd_seq do_list _DONE {
                    230:                $$ = node($1, $2, node(NLIST, $3, NULL));
                    231:                $$->n_next->n_next = $$;
                    232:        }
                    233: |      if cmd_seq then opt_cmd_seq else_part _FI {
                    234:                $$ = node(NIF, node(NNULL, $2, $4), $5);
                    235:        }
                    236: |      oparen opt_cmd_seq ')' {
                    237:                $$ = node(NPARN, $2, NULL);
                    238:        }
                    239: |      obrack opt_cmd_seq _CBRAC {
                    240:                $$ = node(NBRAC, $2, NULL);
                    241:        }
                    242: ;
                    243: 
                    244: in_name_list:
                    245:        _IN name_list {
                    246:                $$ = $2;
                    247:        }
                    248: |      {
                    249:                $$ = node(NARGS, "\"$@\"", NULL);
                    250:        }
                    251: ;
                    252: 
                    253: name_list:
                    254:        name name_list {
                    255:                $$ = node(NARGS, $1, $2);
                    256:        }
                    257: |      {
                    258:                $$ = NULL;
                    259:        }
                    260: ;
                    261: 
                    262: case_list:
                    263:        case_line dsemi case_list {
                    264:                register NODE *np;
                    265: 
                    266:                for (np=$1; np->n_next; np=np->n_next)
                    267:                        ;
                    268:                np->n_next = $3;
                    269:                $$ = $1;
                    270:        }
                    271: |      case_line {
                    272:                $$ = $1;
                    273:        }
                    274: |      {
                    275:                $$ = NULL;
                    276:        }
                    277: ;
                    278: 
                    279: case_line:
                    280:        pattern_list cparen opt_cmd_seq {
                    281:                $$ = node(NCASE2, $3, $1);
                    282:        }
                    283: ;
                    284: 
                    285: pattern_list:
                    286:        name '|' pattern_list {
                    287:                $$ = node(NCASE3, $1, $3);
                    288:        }
                    289: |      name {
                    290:                $$ = node(NCASE3, $1, NULL);
                    291:        }
                    292: ;
                    293: 
                    294: do_list:
                    295:        do opt_cmd_seq {
                    296:                $$ = $2;
                    297:        }
                    298: |      {
                    299:                $$ = NULL;
                    300:        }
                    301: ;
                    302: 
                    303: else_part:
                    304:        elif cmd_seq then opt_cmd_seq else_part {
                    305:                $$ = node(NIF, node(NNULL, $2, $4), $5);
                    306:        }
                    307: |      else opt_cmd_seq {
                    308:                $$ = node(NELSE, $2, NULL);
                    309:        }
                    310: |      {
                    311:                $$ = NULL;
                    312:        }
                    313: ;
                    314: 
                    315: opt_cmd_seq:
                    316:        cmd_seq {
                    317:                $$ = $1;
                    318:        }
                    319: |
                    320:        {
                    321:                $$ = NULL;
                    322:        }
                    323: ;
                    324: 
                    325: cmd_seq:
                    326:        cmd_list nls cmd_seq {
                    327:                $$ = node(NLIST, $1, $3);
                    328:        }
                    329: |      cmd_list optnls {
                    330:                $$ = $1;
                    331:        }
                    332: ;
                    333: 
                    334: sep:   nls
                    335: |      ';'
                    336: |      ';' nls
                    337: ;
                    338: 
                    339: optnls:        nls
                    340: |
                    341: ;
                    342: 
                    343: nls:   '\n'
                    344: |      nls '\n'
                    345: ;
                    346: 
                    347: %%
                    348: /*
                    349:  * Create a node.
                    350:  */
                    351: NODE *
                    352: node(type, auxp, next)
                    353: NODE *auxp, *next;
                    354: {
                    355:        register NODE *np;
                    356: 
                    357:        np = (NODE *) balloc(sizeof (NODE));
                    358:        np->n_type = type;
                    359:        np->n_auxp = auxp;
                    360:        np->n_next = next;
                    361:        return np;
                    362: }
                    363: 
                    364: #define NBPC 8
                    365: #define NKEY 8
                    366: static char keys[NKEY] = { 0 };
                    367: static int  keyi = NKEY * NBPC;
                    368: 
                    369: keyflush()
                    370: {
                    371:        register char *kp;
                    372: 
                    373:        for (kp = keys+NKEY; kp > keys; *--kp = 0)
                    374:                ;
                    375:        keyi = NKEY * NBPC;
                    376: }
                    377: 
                    378: keypop()
                    379: {
                    380:        register char   *kp;
                    381:        register int    km;
                    382: 
                    383:        if ((km = keyi++) >= NKEY * NBPC) {
                    384:                panic(11);
                    385:                NOTREACHED;
                    386:        }
                    387:        kp = keys + (km / NBPC);
                    388:        km = 1 << (km %= NBPC);
                    389:        keyflag = (*kp & km) ? 1 : 0;
                    390:        *kp &= ~km;
                    391: }
                    392: 
                    393: keypush()
                    394: {
                    395:        register char   *kp;
                    396:        register int    km;
                    397: 
                    398:        if ((km = --keyi) < 0) {
                    399:                panic(12);
                    400:                NOTREACHED;
                    401:        }
                    402:        if (keyflag) {
                    403:                kp = keys + (km / NBPC);
                    404:                km = 1 << (km %= NBPC);
                    405:                *kp |= km;
                    406:        }
                    407: }
                    408: /*
                    409:  * The following fragments might implement named pipes.
                    410:  * The token declaration goes in the header.
                    411:  * The nopen production should go with the others of its ilk.
                    412:  * The production fragment goes into arg:
                    413: %token _NOPEN _NCLOSE
                    414: nopen: _NOPEN optnls ;
                    415: 
                    416: |      nopen pipe_cmd ')' {
                    417:                $$ = node(NRPIPE, $2, NULL);
                    418:        }
                    419: |      oparen pipe_cmd _NCLOSE {
                    420:                $$ = node(NWPIPE, $2, NULL);
                    421:        }
                    422:  *
                    423:  */
                    424: 
                    425: /* end of sh/sh.y */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.