8 /* -------- csyn.c -------- */
10 * shell: syntax (C version)
39 #define CONTIN 01 /* skip new lines to complete command */
42 #define SYNTAXERR zzerr()
46 static int iounit
= IODEFAULT
;
48 static YYSTYPE yylval
;
50 _PROTOTYPE(static struct op
*pipeline
, (int cf
));
51 _PROTOTYPE(static struct op
*andor
, (void));
52 _PROTOTYPE(static struct op
*c_list
, (void));
53 _PROTOTYPE(static int synio
, (int cf
));
54 _PROTOTYPE(static void musthave
, (int c
, int cf
));
55 _PROTOTYPE(static struct op
*simple
, (void));
56 _PROTOTYPE(static struct op
*nested
, (int type
, int mark
));
57 _PROTOTYPE(static struct op
*command
, (int cf
));
58 _PROTOTYPE(static struct op
*dogroup
, (int onlydone
));
59 _PROTOTYPE(static struct op
*thenpart
, (void));
60 _PROTOTYPE(static struct op
*elsepart
, (void));
61 _PROTOTYPE(static struct op
*caselist
, (void));
62 _PROTOTYPE(static struct op
*casepart
, (void));
63 _PROTOTYPE(static char **pattern
, (void));
64 _PROTOTYPE(static char **wordlist
, (void));
65 _PROTOTYPE(static struct op
*list
, (struct op
*t1
, struct op
*t2
));
66 _PROTOTYPE(static struct op
*block
, (int type
, struct op
*t1
, struct op
*t2
, char **wp
));
67 _PROTOTYPE(static struct op
*newtp
, (void));
68 _PROTOTYPE(static struct op
*namelist
, (struct op
*t
));
69 _PROTOTYPE(static char **copyw
, (void));
70 _PROTOTYPE(static void word
, (char *cp
));
71 _PROTOTYPE(static struct ioword
**copyio
, (void));
72 _PROTOTYPE(static struct ioword
*io
, (int u
, int f
, char *cp
));
73 _PROTOTYPE(static void zzerr
, (void));
74 _PROTOTYPE(void yyerror
, (char *s
));
75 _PROTOTYPE(static int yylex
, (int cf
));
76 _PROTOTYPE(int collect
, (int c
, int c1
));
77 _PROTOTYPE(int dual
, (int c
));
78 _PROTOTYPE(static void diag
, (int ec
));
79 _PROTOTYPE(static char *tree
, (unsigned size
));
80 _PROTOTYPE(void printf
, (char *s
));
97 register struct op
*t
, *p
;
102 while ((c
= yylex(0)) == '|') {
103 if ((p
= command(CONTIN
)) == NULL
)
105 if (t
->type
!= TPAREN
&& t
->type
!= TCOM
) {
106 /* shell statement */
107 t
= block(TPAREN
, t
, NOBLOCK
, NOWORDS
);
109 t
= block(TPIPE
, t
, p
, NOWORDS
);
119 register struct op
*t
, *p
;
124 while ((c
= yylex(0)) == LOGAND
|| c
== LOGOR
) {
125 if ((p
= pipeline(CONTIN
)) == NULL
)
127 t
= block(c
== LOGAND
? TAND
: TOR
, t
, p
, NOWORDS
);
137 register struct op
*t
, *p
;
142 if((peeksym
= yylex(0)) == '&')
143 t
= block(TASYNC
, t
, NOBLOCK
, NOWORDS
);
144 while ((c
= yylex(0)) == ';' || c
== '&' || (multiline
&& c
== '\n')) {
145 if ((p
= andor()) == NULL
)
147 if((peeksym
= yylex(0)) == '&')
148 p
= block(TASYNC
, p
, NOBLOCK
, NOWORDS
);
161 register struct ioword
*iop
;
165 if ((c
= yylex(cf
)) != '<' && c
!= '>') {
171 iop
= io(iounit
, i
, yylval
.cp
);
174 markhere(yylval
.cp
, iop
);
182 if ((peeksym
= yylex(cf
)) != c
)
190 register struct op
*t
;
194 switch (peeksym
= yylex(0)) {
219 register struct op
*t
;
225 return(block(type
, t
, NOBLOCK
, NOWORDS
));
232 register struct op
*t
;
233 struct wdblock
*iosave
;
242 switch (c
= yylex(cf
)) {
245 if ((t
= simple()) == NULL
) {
247 return((struct op
*)NULL
);
254 t
= nested(TPAREN
, ')');
258 t
= nested(TBRACE
, '}');
268 t
->words
= wordlist();
269 if ((c
= yylex(0)) != '\n' && c
!= ';')
271 t
->left
= dogroup(0);
279 t
->type
= c
== WHILE
? TWHILE
: TUNTIL
;
281 t
->right
= dogroup(1);
293 musthave(IN
, CONTIN
);
295 t
->left
= caselist();
305 t
->right
= thenpart();
322 register struct op
*list
;
325 if (c
== DONE
&& onlydone
)
326 return((struct op
*)NULL
);
338 register struct op
*t
;
340 if ((c
= yylex(0)) != THEN
) {
342 return((struct op
*)NULL
);
349 t
->right
= elsepart();
357 register struct op
*t
;
359 switch (c
= yylex(0)) {
361 if ((t
= c_list()) == NULL
)
369 t
->right
= thenpart();
374 return((struct op
*)NULL
);
381 register struct op
*t
;
384 while ((peeksym
= yylex(CONTIN
)) != ESAC
)
385 t
= list(t
, casepart());
392 register struct op
*t
;
396 t
->words
= pattern();
399 if ((peeksym
= yylex(CONTIN
)) != ESAC
)
400 musthave(BREAK
, CONTIN
);
414 } while ((c
= yylex(0)) == '|');
425 if ((c
= yylex(0)) != IN
) {
427 return((char **)NULL
);
430 while ((c
= yylex(0)) == WORD
)
438 * supporting functions
442 register struct op
*t1
, *t2
;
448 return(block(TLIST
, t1
, t2
, NOWORDS
));
452 block(type
, t1
, t2
, wp
)
457 register struct op
*t
;
498 register struct res
*rp
;
500 for (rp
= restab
; rp
->r_name
; rp
++)
501 if (strcmp(rp
->r_name
, n
) == 0)
509 register struct op
*t
;
511 t
= (struct op
*)tree(sizeof(*t
));
523 register struct op
*t
;
526 iolist
= addword((char *)NULL
, iolist
);
530 if (t
->type
!= TCOM
) {
531 if (t
->type
!= TPAREN
&& t
->ioact
!= NULL
) {
532 t
= block(TPAREN
, t
, NOBLOCK
, NOWORDS
);
533 t
->ioact
= t
->left
->ioact
;
534 t
->left
->ioact
= NULL
;
548 wd
= getwords(wdlist
);
557 wdlist
= addword(cp
, wdlist
);
560 static struct ioword
**
563 register struct ioword
**iop
;
565 iop
= (struct ioword
**) getwords(iolist
);
570 static struct ioword
*
576 register struct ioword
*iop
;
578 iop
= (struct ioword
*) tree(sizeof(*iop
));
582 iolist
= addword((char *)iop
, iolist
);
589 yyerror("syntax error");
597 if (talking
&& e
.iop
<= iostack
) {
599 while (eofc() == 0 && yylex(0) != '\n')
613 if ((c
= peeksym
) > 0) {
626 while ((c
= getc(0)) == ' ' || c
== '\t')
630 if (any(c
, "0123456789")) {
632 if (c1
== '<' || c1
== '>') {
642 while ((c
= getc(0)) != 0 && c
!= '\n')
652 if ((c
= getc(0)) == '{') {
653 if ((c
= collect(c
, '}')) != '\0')
662 if ((c
= collect(c
, c
)) != '\0')
669 if ((c1
= dual(c
)) != '\0') {
687 if (multiline
|| cf
& CONTIN
) {
688 if (talking
&& e
.iop
<= iostack
)
704 while ((c
= getc(0)) != 0 && !any(c
, "`$ '\"\t;&<>()|^\n"))
705 if (e
.linep
>= elinep
)
706 err("word too long");
713 if (atstart
&& (c
= rlookup(line
))!=0) {
717 yylval
.cp
= strsave(line
, areanum
);
728 while ((c
= getc(c1
)) != c1
) {
733 prs("no closing "); yyerror(s
);
736 if (talking
&& c
== '\n' && e
.iop
<= iostack
)
749 register char *cp
= s
;
754 if ((c
= rlookup(s
)) == 0)
766 if (c
== '>' || c
== '<') {
769 yylval
.i
= ec
== '>'? IOWRITE
|IOCAT
: IOHERE
;
772 yylval
.i
= ec
== '>'? IOWRITE
: IOREAD
;
773 if (c
!= '&' || yylval
.i
== IOHERE
)
785 if ((t
= getcell(size
)) == NULL
) {
786 prs("command line too complicated\n");
796 printf(s
) /* yyparse calls it */