Annotation of coherent/b/bin/sh_B4_420/sh.y, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The Bourne shell.
                      3:  * This shell is dedicated to Ciaran Gerald Aidan O'Donnell.
                      4:  * May he live a thousand minutes (long enough to fix up YACC).
                      5:  * It is also dedicated to Steve Bourne.
                      6:  * May he live a thousand seconds.
                      7:  */
                      8: %{
                      9: #include "sh.h"
                     10: 
                     11: #define YYERROR        { yyerrflag=1; goto YYerract; }
                     12: 
                     13: extern NODE    *node();
                     14: %}
                     15: 
                     16: %union {
                     17:        NODE    *yu_node;
                     18:        char    *yu_strp;
                     19:        int     yu_nval;
                     20: }
                     21: 
                     22: %token _ANDF
                     23: %token _ASGN
                     24: %token _CASE
                     25: %token _CBRAC
                     26: %token _DO
                     27: %token _DONE
                     28: %token _DSEMI
                     29: %token _ELIF
                     30: %token _ELSE
                     31: %token _ESAC
                     32: %token _FI
                     33: %token _FOR
                     34: %token _IF
                     35: %token _IN
                     36: %token _IORS
                     37: %token _NAME
                     38: %token _NULL
                     39: %token _OBRAC
                     40: %token _ORF
                     41: %token _PARENS
                     42: %token _RET
                     43: %token _THEN
                     44: %token _UNTIL
                     45: %token _WHILE
                     46: 
                     47: %type <yu_node>        arg             arg_list        case_line       case_list
                     48: %type <yu_node>        cmd             cmd_line        cmd_list        cmd_seq
                     49: %type <yu_node>        control         do_list         else_part       in_name_list
                     50: %type <yu_node>        logical_cmd     name_list       opt_cmd_seq     pattern_list
                     51: %type <yu_node>        pipe_cmd        sub_shell
                     52: 
                     53: %type <yu_node>        command         simple_command  redirect_list   cmd_prefix
                     54: %type <yu_node>        cmd_word        cmd_suffix      cmd_name        redirect_list
                     55: %type <yu_node>        asgn_node       redirect_node   name_node
                     56: %type <yu_node>        function_definition     compound_command
                     57: %type <yu_node>        non_keyword_name
                     58: 
                     59: %type <yu_strp>        asgn            name            redirect
                     60: 
                     61: %type <yu_nval> whuntile
                     62: 
                     63: %%
                     64: 
                     65: session:
                     66:        session cmd_line
                     67: |
                     68: ;
                     69: 
                     70: cmd_line:
                     71:        '\n' {
                     72:                sesp->s_node = NULL;
                     73:                reset(RCMD);
                     74:                NOTREACHED;
                     75:        }
                     76: |
                     77:        cmd_list '\n' {
                     78:                sesp->s_node = $1;
                     79:                reset(errflag ? RERR : RCMD);
                     80:                NOTREACHED;
                     81:        }
                     82: |      error '\n' {
                     83:                keyflush();
                     84:                keyflag = 1;
                     85:                reset(RERR);
                     86:                NOTREACHED;
                     87:        }
                     88: ;
                     89: 
                     90: if:    _IF optnls ;
                     91: 
                     92: then:  _THEN optnls ;
                     93: 
                     94: elif:  _ELIF optnls ;
                     95: 
                     96: else:  _ELSE optnls ;
                     97: 
                     98: whuntile:      _WHILE optnls { $$ = NWHILE;    }
                     99: |      _UNTIL optnls { $$ = NUNTIL;    }
                    100: ;
                    101: 
                    102: do:    _DO optnls | _DO ';' optnls ;
                    103: 
                    104: in:    _IN | _IN sep ;
                    105: 
                    106: oror:  _ORF optnls;
                    107: 
                    108: andand:        _ANDF optnls;
                    109: 
                    110: or:    '|' optnls;
                    111: 
                    112: oparen:        '(' optnls ;
                    113: 
                    114: obrack:        _OBRAC optnls ;
                    115: 
                    116: cparen:        ')' optnls ;
                    117: 
                    118: dsemi: _DSEMI optnls ;
                    119: 
                    120: cmd_list:
                    121:        logical_cmd {
                    122:                $$ = $1;
                    123:        }
                    124: |      logical_cmd '&' {
                    125:                $$ = node(NBACK, $1, NULL);
                    126:        }
                    127: |      logical_cmd ';' {
                    128:                $$ = $1;
                    129:        }
                    130: |      logical_cmd '&' cmd_list {
                    131:                $$ = node(NBACK, $1, $3);
                    132:        }
                    133: |      logical_cmd ';' cmd_list {
                    134:                $$ = node(NLIST, $1, $3);
                    135:        }
                    136: ;
                    137: 
                    138: logical_cmd:
                    139:        pipe_cmd {
                    140:                $$ = $1;
                    141:        }
                    142: |      pipe_cmd oror logical_cmd {
                    143:                $$ = node(NORF, $1, $3);
                    144:        }
                    145: |      pipe_cmd andand logical_cmd {
                    146:                $$ = node(NANDF, $1, $3);
                    147:        }
                    148: ;
                    149: 
                    150: pipe_cmd:
                    151:        cmd or pipe_cmd {
                    152:                $$ = node(NPIPE, $1, $3);
                    153:        }
                    154: |      cmd {
                    155:                $$ = $1;
                    156:        }
                    157: ;
                    158: 
                    159: /*
                    160:  * In the original grammar, no distinction between simple command and compound
                    161:  * commands was made. This, along with the right-recursive formulation of the
                    162:  * command grammar, created a need for lookahead that defeated the complex
                    163:  * machinery for context-sensitive lexing that is required.
                    164:  */
                    165: 
                    166: cmd:   turn_on_keywords command {
                    167:                $$ = $2;
                    168:                keypop ();
                    169:        }
                    170: ;
                    171: 
                    172: turn_on_keywords: {
                    173:                keypush ();
                    174:                keyflag = 1;
                    175:        }
                    176: ;
                    177: 
                    178: command:
                    179:        simple_command {
                    180:                $$ = node (NCOMS, $1, NULL);
                    181:        }
                    182: |      compound_command {
                    183:                $$ = node (NCOMS, $1, NULL);
                    184:        }
                    185: |      compound_command redirect_list {
                    186:                $$ = node (NCOMS, $1->n_next = $2, NULL);
                    187:        }
                    188: |      function_definition {
                    189:                $$ = node (NCOMS, $1, NULL);
                    190:        }
                    191: |      _RET name {
                    192:                $$ = node (NRET, $2, NULL);
                    193:        }
                    194: |      _RET {
                    195:                $$ = node (NRET, "", NULL);
                    196:        }
                    197: ;
                    198: 
                    199: compound_command:
                    200:        control {
                    201:                $$ = node (NCTRL, $1, NULL);
                    202:        }
                    203: ;
                    204:        
                    205: function_definition:
                    206:        name _PARENS optnls obrack cmd_seq _CBRAC  {
                    207:                $$ = node (NCTRL, node (NFUNC, $1, $5), NULL);
                    208:        }
                    209: ;
                    210: 
                    211: redirect_list:
                    212:        redirect_node {
                    213:                $$ = $1;
                    214:        }
                    215: |      redirect_list redirect_node {
                    216:                ($$ = $1)->n_next = $2;
                    217:        }
                    218: ;
                    219: 
                    220: simple_command:
                    221:        cmd_prefix cmd_word cmd_suffix {
                    222:                (($$ = $1)->n_next = $2)->n_next = $3;
                    223:        }
                    224: |      cmd_prefix cmd_word {
                    225:                ($$ = $1)->n_next = $2;
                    226:        }
                    227: |      cmd_prefix {
                    228:                $$ = $1;
                    229:        }
                    230: |      cmd_name cmd_suffix {
                    231:                ($$ = $1)->n_next = $2;
                    232:        }
                    233: |      cmd_name {
                    234:                $$ = $1;
                    235:        }
                    236: ;
                    237: 
                    238: cmd_prefix:
                    239:        redirect_node {
                    240:                $$ = $1;
                    241:        }
                    242: |      redirect_node cmd_prefix {
                    243:                ($$ = $1)->n_next = $2;
                    244:        }
                    245: |      asgn_node {
                    246:                $$ = $1;
                    247:        }
                    248: |      asgn_node cmd_prefix {
                    249:                ($$ = $1)->n_next = $2;
                    250:        }
                    251: ;
                    252: 
                    253: cmd_name:
                    254:        name_node {
                    255:                $$ = $1;
                    256:                keyflag = 0;
                    257:        }
                    258: ;
                    259: 
                    260: cmd_word:
                    261:        name_node {
                    262:                $$ = $1;
                    263:                keyflag = 0;
                    264:        }
                    265: ;
                    266: 
                    267: /*
                    268:  * The main part of this shell has some silliness with assignments and some
                    269:  * flag called '-k'. To support this, we allow assignments after the command
                    270:  * name and code elsewhere turns them back into parameters... it seems
                    271:  * preferable to do it here, but because of the '-k' thing we'll just
                    272:  * accept them.
                    273:  */
                    274: 
                    275: cmd_suffix:
                    276:        redirect_node {
                    277:                $$ = $1;
                    278:        }
                    279: |      redirect_node cmd_suffix {
                    280:                ($$ = $1)->n_next = $2;
                    281:        }
                    282: |      non_keyword_name {
                    283:                $$ = $1;
                    284:        }
                    285: |      non_keyword_name cmd_suffix {
                    286:                ($$ = $1)->n_next = $2;
                    287:        }
                    288: |      asgn_node {
                    289:                $$ = $1;
                    290:        }
                    291: |      asgn_node cmd_suffix {
                    292:                ($$ = $1)->n_next = $2;
                    293:        }
                    294: ;
                    295: 
                    296: non_keyword_name:
                    297:        non_keyword_string {
                    298:                $$ = node (NARGS, duplstr (strt, 0), NULL);
                    299:        }
                    300: ;
                    301: 
                    302: /*
                    303:  * Many of the following cause S/R conflicts. This reflects the fact that the
                    304:  * decision about whether to recognise a token in a given place needs some
                    305:  * extra disambiguation or not. In all cases, the correct result is to shift
                    306:  * (treating the reserved word as a normal word), which is the default.
                    307:  */
                    308: non_keyword_string:
                    309:        _NAME
                    310: |      _CASE
                    311: |      _DO
                    312: |      _DONE
                    313: |      _ELIF
                    314: |      _ELSE
                    315: |      _ESAC
                    316: |      _FI
                    317: |      _FOR
                    318: |      _IF
                    319: |      _IN
                    320: |      _RET
                    321: |      _THEN
                    322: |      _UNTIL
                    323: |      _WHILE
                    324: ;
                    325:        
                    326: /*
                    327:  * Replaced by detailed cases above.
                    328: cmd:
                    329:        arg_list_init arg_list {
                    330:                $$ = node(NCOMS, $2, NULL);
                    331:                keypop();
                    332:        }
                    333: |      _RET name {
                    334:                $$ = node(NRET, $2, NULL);
                    335:        }
                    336: |      _RET {
                    337:                $$ = node(NRET, "", NULL);
                    338:        }
                    339: ;
                    340: 
                    341: arg_list_init:
                    342:        {
                    343:                keypush();
                    344:                keyflag = 1;
                    345:        }
                    346: ;
                    347: 
                    348: arg_list:
                    349:        arg arg_list {
                    350:                if (($1->n_type == NCTRL && $2->n_type == NARGS)
                    351:                 || ($1->n_type == NARGS && $2->n_type == NCTRL)) {
                    352:                        YYERROR;
                    353:                }
                    354:                ($$ = $1)->n_next = $2;
                    355:        }
                    356: |      arg {
                    357:                $$ = $1;
                    358:        }
                    359: ;
                    360: 
                    361: arg:
                    362:        redirect_node {
                    363:                $$ = $1;
                    364:        }
                    365: |      name_node {
                    366:                $$ = $1;
                    367:                keyflag = 0;
                    368:        }
                    369: |      asgn_node {
                    370:                $$ = $1;
                    371:        }
                    372: |      control {
                    373:                if (!keyflag) {
                    374:                        YYERROR;
                    375:                }
                    376:                $$ = node(NCTRL, $1, NULL);
                    377:                keyflag = 0;
                    378:        }
                    379: ;
                    380: */
                    381: 
                    382: /*
                    383:  * The form of the following productions arranges for the contents of the
                    384:  * global "strt" to be duplicated ASAP, hopefully before lookahead gets
                    385:  * involved.
                    386:  */
                    387: 
                    388: redirect_node: redirect {
                    389:                $$ = node (NIORS, $1, NULL);
                    390:        }
                    391: ;
                    392: 
                    393: redirect:      _IORS {
                    394:                $$ = duplstr (strt, 0);
                    395:        }
                    396: ;
                    397: 
                    398: name_node: name {
                    399:                $$ = node (NARGS, $1, NULL);
                    400:        }
                    401: ;
                    402: 
                    403: name:  _NAME {
                    404:                $$ = duplstr (strt, 0);
                    405:        }
                    406: ;
                    407: 
                    408: 
                    409: asgn_node: asgn {
                    410:                $$ = node (NASSG, $1, NULL);
                    411:        }
                    412: ;
                    413: 
                    414: asgn:  _ASGN {
                    415:                $$ = duplstr (strt, 0);
                    416:        }
                    417: ;
                    418: 
                    419: control:
                    420:        _FOR name in_name_list sep do_list _DONE {
                    421:                $$ = node(NFOR, $2, node(NFOR2, $3, node(NLIST, $5, NULL)));
                    422:                $$->n_next->n_next->n_next = $$->n_next;
                    423:        }
                    424: |      _FOR name in_name_list do_list _DONE {
                    425:                $$ = node(NFOR, $2, node(NFOR2, $3, node(NLIST, $4, NULL)));
                    426:                $$->n_next->n_next->n_next = $$->n_next;
                    427:        }
                    428: |      _CASE name sep in case_list _ESAC {
                    429:                $$ = node(NCASE, $2, $5);
                    430:        }
                    431: |      _CASE name in case_list _ESAC {
                    432:                $$ = node(NCASE, $2, $4);
                    433:        }
                    434: |      whuntile cmd_seq do_list _DONE {
                    435:                $$ = node($1, $2, node(NLIST, $3, NULL));
                    436:                $$->n_next->n_next = $$;
                    437:        }
                    438: |      if cmd_seq then opt_cmd_seq else_part _FI {
                    439:                $$ = node(NIF, node(NNULL, $2, $4), $5);
                    440:        }
                    441: |      oparen opt_cmd_seq ')' {
                    442:                $$ = node(NPARN, $2, NULL);
                    443:        }
                    444: |      obrack opt_cmd_seq _CBRAC {
                    445:                $$ = node(NBRAC, $2, NULL);
                    446:        }
                    447: ;
                    448: 
                    449: in_name_list:
                    450:        _IN name_list {
                    451:                $$ = $2;
                    452:        }
                    453: |      {
                    454:                $$ = node(NARGS, "\"$@\"", NULL);
                    455:        }
                    456: ;
                    457: 
                    458: name_list:
                    459:        name name_list {
                    460:                $$ = node(NARGS, $1, $2);
                    461:        }
                    462: |      {
                    463:                $$ = NULL;
                    464:        }
                    465: ;
                    466: 
                    467: case_list:
                    468:        case_line dsemi case_list {
                    469:                register NODE *np;
                    470: 
                    471:                for (np=$1; np->n_next; np=np->n_next)
                    472:                        ;
                    473:                np->n_next = $3;
                    474:                $$ = $1;
                    475:        }
                    476: |      case_line {
                    477:                $$ = $1;
                    478:        }
                    479: |      {
                    480:                $$ = NULL;
                    481:        }
                    482: ;
                    483: 
                    484: case_line:
                    485:        pattern_list cparen opt_cmd_seq {
                    486:                $$ = node(NCASE2, $3, $1);
                    487:        }
                    488: ;
                    489: 
                    490: pattern_list:
                    491:        name '|' pattern_list {
                    492:                $$ = node(NCASE3, $1, $3);
                    493:        }
                    494: |      name {
                    495:                $$ = node(NCASE3, $1, NULL);
                    496:        }
                    497: ;
                    498: 
                    499: do_list:
                    500:        do opt_cmd_seq {
                    501:                $$ = $2;
                    502:        }
                    503: |      {
                    504:                $$ = NULL;
                    505:        }
                    506: ;
                    507: 
                    508: else_part:
                    509:        elif cmd_seq then opt_cmd_seq else_part {
                    510:                $$ = node(NIF, node(NNULL, $2, $4), $5);
                    511:        }
                    512: |      else opt_cmd_seq {
                    513:                $$ = node(NELSE, $2, NULL);
                    514:        }
                    515: |      {
                    516:                $$ = NULL;
                    517:        }
                    518: ;
                    519: 
                    520: opt_cmd_seq:
                    521:        cmd_seq {
                    522:                $$ = $1;
                    523:        }
                    524: |
                    525:        {
                    526:                $$ = NULL;
                    527:        }
                    528: ;
                    529: 
                    530: cmd_seq:
                    531:        cmd_list nls cmd_seq {
                    532:                $$ = node(NLIST, $1, $3);
                    533:        }
                    534: |      cmd_list optnls {
                    535:                $$ = $1;
                    536:        }
                    537: ;
                    538: 
                    539: sep:   nls
                    540: |      ';'
                    541: |      ';' nls
                    542: ;
                    543: 
                    544: optnls:        nls
                    545: |
                    546: ;
                    547: 
                    548: nls:   '\n'
                    549: |      nls '\n'
                    550: ;
                    551: 
                    552: %%
                    553: /*
                    554:  * Create a node.
                    555:  */
                    556: NODE *
                    557: node(type, auxp, next)
                    558: NODE *auxp, *next;
                    559: {
                    560:        register NODE *np;
                    561: 
                    562:        np = (NODE *) balloc(sizeof (NODE));
                    563:        np->n_type = type;
                    564:        np->n_auxp = auxp;
                    565:        np->n_next = next;
                    566:        return np;
                    567: }
                    568: 
                    569: #define NBPC 8
                    570: #define NKEY 8
                    571: static char keys[NKEY] = { 0 };
                    572: static int  keyi = NKEY * NBPC;
                    573: 
                    574: keyflush()
                    575: {
                    576:        register char *kp;
                    577: 
                    578:        for (kp = keys+NKEY; kp > keys; *--kp = 0)
                    579:                ;
                    580:        keyi = NKEY * NBPC;
                    581: }
                    582: 
                    583: keypop()
                    584: {
                    585:        register char   *kp;
                    586:        register int    km;
                    587: 
                    588:        if ((km = keyi++) >= NKEY * NBPC) {
                    589:                panic(11);
                    590:                NOTREACHED;
                    591:        }
                    592:        kp = keys + (km / NBPC);
                    593:        km = 1 << (km %= NBPC);
                    594:        keyflag = (*kp & km) ? 1 : 0;
                    595:        *kp &= ~km;
                    596: }
                    597: 
                    598: keypush()
                    599: {
                    600:        register char   *kp;
                    601:        register int    km;
                    602: 
                    603:        if ((km = --keyi) < 0) {
                    604:                panic(12);
                    605:                NOTREACHED;
                    606:        }
                    607:        if (keyflag) {
                    608:                kp = keys + (km / NBPC);
                    609:                km = 1 << (km %= NBPC);
                    610:                *kp |= km;
                    611:        }
                    612: }
                    613: /*
                    614:  * The following fragments might implement named pipes.
                    615:  * The token declaration goes in the header.
                    616:  * The nopen production should go with the others of its ilk.
                    617:  * The production fragment goes into arg:
                    618: %token _NOPEN _NCLOSE
                    619: nopen: _NOPEN optnls ;
                    620: 
                    621: |      nopen pipe_cmd ')' {
                    622:                $$ = node(NRPIPE, $2, NULL);
                    623:        }
                    624: |      oparen pipe_cmd _NCLOSE {
                    625:                $$ = node(NWPIPE, $2, NULL);
                    626:        }
                    627:  *
                    628:  */

unix.superglobalmegacorp.com

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