First stable version.
[unix-history] / usr / src / usr.bin / rdist / gram.y
CommitLineData
d0dc5e26
RC
1%{
2#ifndef lint
82572cb6 3static char *sccsid = "@(#)gram.y 4.2 (Berkeley) 83/09/27";
d0dc5e26
RC
4#endif
5
6#include "defs.h"
7
82572cb6
RC
8struct block *lastn;
9struct block *lastc;
d0dc5e26
RC
10
11%}
12
13%term EQUAL 1
82572cb6
RC
14%term LP 2
15%term RP 3
16%term ARROW 4
17%term DCOLON 5
18%term NAME 6
19%term INSTALL 7
20%term VERIFY 8
21%term NOTIFY 9
22%term EXCEPT 10
d0dc5e26
RC
23
24%union
25 {
26 struct block *blk;
27 }
28
29%type <blk> NAME, INSTALL, VERIFY, NOTIFY, EXCEPT, namelist, names, cmdlist, cmd
30
31%%
32
33file: /* VOID */
34 | file command
35 ;
36
37command: NAME EQUAL namelist = {
38 $1->b_args = $3;
82572cb6 39 (void) lookup($1->b_name, $1, 1);
d0dc5e26
RC
40 }
41 | namelist ARROW namelist cmdlist = {
82572cb6
RC
42 dohcmds($1, $3, $4);
43 }
44 | namelist DCOLON namelist cmdlist = {
45 dofcmds($1, $3, $4);
d0dc5e26
RC
46 }
47 | error
48 ;
49
50namelist: NAME = {
51 $$ = $1;
52 }
53 | LP names RP = {
54 $$ = $2;
55 }
56 ;
57
58names: /* VOID */ {
82572cb6 59 $$ = lastn = NULL;
d0dc5e26
RC
60 }
61 | names NAME = {
82572cb6
RC
62 if (lastn == NULL)
63 $$ = lastn = $2;
d0dc5e26 64 else {
82572cb6
RC
65 lastn->b_next = $2;
66 lastn = $2;
d0dc5e26
RC
67 $$ = $1;
68 }
69 }
70 ;
71
72cmdlist: /* VOID */ {
82572cb6 73 $$ = lastc = NULL;
d0dc5e26
RC
74 }
75 | cmdlist cmd = {
82572cb6
RC
76 if (lastc == NULL)
77 $$ = lastc = $2;
d0dc5e26 78 else {
82572cb6
RC
79 lastc->b_next = $2;
80 lastc = $2;
d0dc5e26
RC
81 $$ = $1;
82 }
83 }
84 ;
85
86cmd: INSTALL NAME = {
82572cb6
RC
87 register struct block *b;
88
89 inst_name:
90 b = expand($2, 0);
91 if (b == NULL || b->b_next != NULL)
92 fatal("exactly one name allowed\n");
93 $1->b_name = b->b_name;
d0dc5e26
RC
94 free($2);
95 $$ = $1;
96 }
97 | VERIFY NAME = {
82572cb6 98 goto inst_name;
d0dc5e26
RC
99 }
100 | NOTIFY namelist = {
82572cb6 101 $1->b_args = expand($2, 1);
d0dc5e26
RC
102 $$ = $1;
103 }
104 | EXCEPT namelist = {
82572cb6 105 $1->b_args = expand($2, 0);
d0dc5e26
RC
106 $$ = $1;
107 }
108 ;
109
110%%
111
112int yylineno = 1;
113extern FILE *fin;
114
115yylex()
116{
117 static char yytext[INMAX];
118 register int c;
119 register char *cp1, *cp2;
120 register struct block *bp;
82572cb6 121 static char quotechars[] = "[]{}*?";
d0dc5e26 122
82572cb6
RC
123again:
124 switch (c = getc(fin)) {
125 case EOF: /* end of file */
126 return(0);
127
128 case '#': /* start of comment */
129 while ((c = getc(fin)) != EOF && c != '\n')
130 ;
131 if (c == EOF)
d0dc5e26 132 return(0);
82572cb6
RC
133 case '\n':
134 yylineno++;
135 case ' ':
136 case '\t': /* skip blanks */
137 goto again;
138
139 case '=': /* EQUAL */
140 return(EQUAL);
141
142 case '(': /* LP */
143 return(LP);
144
145 case ')': /* RP */
146 return(RP);
147
148 case '-': /* -> */
149 if ((c = getc(fin)) == '>')
150 return(ARROW);
151 ungetc(c, fin);
152 c = '-';
153 break;
154
155 case ':': /* :: */
156 if ((c = getc(fin)) == ':')
157 return(DCOLON);
158 ungetc(c, fin);
159 c = ':';
160 }
161 /*
162 * Start of a name.
163 */
164 cp1 = yytext;
165 cp2 = &yytext[INMAX - 1];
166 for (;;) {
167 if (cp1 >= cp2) {
168 fatal("input line too long\n");
169 break;
170 }
171 if (c == '\\') {
172 if ((c = getc(fin)) != EOF) {
173 if (any(c, quotechars))
174 c |= QUOTE;
175 } else {
176 *cp1++ = '\\';
d0dc5e26
RC
177 break;
178 }
179 }
82572cb6
RC
180 *cp1++ = c;
181 c = getc(fin);
182 if (c == EOF || any(c, " \t()=\n")) {
183 ungetc(c, fin);
184 break;
185 }
d0dc5e26 186 }
82572cb6
RC
187 *cp1 = '\0';
188 if (!strcmp(yytext, "install"))
189 c = INSTALL;
190 else if (!strcmp(yytext, "verify"))
191 c = VERIFY;
192 else if (!strcmp(yytext, "notify"))
193 c = NOTIFY;
194 else if (!strcmp(yytext, "except"))
195 c = EXCEPT;
196 else
197 c = NAME;
198 yylval.blk = bp = makeblock(c, yytext);
199 return(c);
d0dc5e26
RC
200}
201
202any(c, str)
203 register int c;
204 register char *str;
205{
206 while (*str)
207 if (c == *str++)
208 return(1);
209 return(0);
210}
211
212/*
213 * Error printing routine in parser.
214 */
215yyerror(s)
216 char *s;
217{
218 extern int yychar;
219
220 fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
221}