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