Commit | Line | Data |
---|---|---|
d0dc5e26 RC |
1 | %{ |
2 | #ifndef lint | |
d1dee8e8 | 3 | static char *sccsid = "@(#)gram.y 4.5 (Berkeley) 83/10/20"; |
d0dc5e26 RC |
4 | #endif |
5 | ||
6 | #include "defs.h" | |
7 | ||
82572cb6 RC |
8 | struct block *lastn; |
9 | struct block *lastc; | |
d0dc5e26 RC |
10 | |
11 | %} | |
12 | ||
13 | %term EQUAL 1 | |
82572cb6 RC |
14 | %term LP 2 |
15 | %term RP 3 | |
d1dee8e8 RC |
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 | |
d0dc5e26 | 24 | |
3024eb6f | 25 | %union { |
d0dc5e26 | 26 | struct block *blk; |
3024eb6f RC |
27 | int intval; |
28 | } | |
d0dc5e26 | 29 | |
d1dee8e8 RC |
30 | %type <blk> NAME, INSTALL, NOTIFY, EXCEPT |
31 | %type <blk> namelist, names, opt_name, cmdlist, cmd | |
3024eb6f | 32 | %type <intval> OPTION, options |
d0dc5e26 RC |
33 | |
34 | %% | |
35 | ||
36 | file: /* VOID */ | |
37 | | file command | |
38 | ; | |
39 | ||
40 | command: NAME EQUAL namelist = { | |
41 | $1->b_args = $3; | |
82572cb6 | 42 | (void) lookup($1->b_name, $1, 1); |
d0dc5e26 RC |
43 | } |
44 | | namelist ARROW namelist cmdlist = { | |
82572cb6 RC |
45 | dohcmds($1, $3, $4); |
46 | } | |
47 | | namelist DCOLON namelist cmdlist = { | |
48 | dofcmds($1, $3, $4); | |
d0dc5e26 RC |
49 | } |
50 | | error | |
51 | ; | |
52 | ||
53 | namelist: NAME = { | |
54 | $$ = $1; | |
55 | } | |
56 | | LP names RP = { | |
57 | $$ = $2; | |
58 | } | |
59 | ; | |
60 | ||
61 | names: /* VOID */ { | |
82572cb6 | 62 | $$ = lastn = NULL; |
d0dc5e26 RC |
63 | } |
64 | | names NAME = { | |
82572cb6 RC |
65 | if (lastn == NULL) |
66 | $$ = lastn = $2; | |
d0dc5e26 | 67 | else { |
82572cb6 RC |
68 | lastn->b_next = $2; |
69 | lastn = $2; | |
d0dc5e26 RC |
70 | $$ = $1; |
71 | } | |
72 | } | |
73 | ; | |
74 | ||
75 | cmdlist: /* VOID */ { | |
82572cb6 | 76 | $$ = lastc = NULL; |
d0dc5e26 RC |
77 | } |
78 | | cmdlist cmd = { | |
82572cb6 RC |
79 | if (lastc == NULL) |
80 | $$ = lastc = $2; | |
d0dc5e26 | 81 | else { |
82572cb6 RC |
82 | lastc->b_next = $2; |
83 | lastc = $2; | |
d0dc5e26 RC |
84 | $$ = $1; |
85 | } | |
86 | } | |
87 | ; | |
88 | ||
d1dee8e8 | 89 | cmd: INSTALL options opt_name SM = { |
82572cb6 RC |
90 | register struct block *b; |
91 | ||
f7770429 | 92 | $1->b_options = $2 | options; |
d1dee8e8 RC |
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 | } | |
d0dc5e26 RC |
99 | $$ = $1; |
100 | } | |
d1dee8e8 | 101 | | NOTIFY namelist SM = { |
82572cb6 | 102 | $1->b_args = expand($2, 1); |
d0dc5e26 RC |
103 | $$ = $1; |
104 | } | |
d1dee8e8 | 105 | | EXCEPT namelist SM = { |
82572cb6 | 106 | $1->b_args = expand($2, 0); |
d0dc5e26 RC |
107 | $$ = $1; |
108 | } | |
109 | ; | |
d1dee8e8 | 110 | |
3024eb6f RC |
111 | options: /* VOID */ = { |
112 | $$ = 0; | |
113 | } | |
114 | | options OPTION = { | |
115 | $$ |= $2; | |
116 | } | |
117 | ; | |
d0dc5e26 | 118 | |
d1dee8e8 RC |
119 | opt_name: /* VOID */ = { |
120 | $$ = NULL; | |
121 | } | |
122 | | NAME = { | |
123 | $$ = $1; | |
124 | } | |
125 | ; | |
126 | ||
d0dc5e26 RC |
127 | %% |
128 | ||
129 | int yylineno = 1; | |
130 | extern FILE *fin; | |
131 | ||
132 | yylex() | |
133 | { | |
134 | static char yytext[INMAX]; | |
135 | register int c; | |
136 | register char *cp1, *cp2; | |
3024eb6f | 137 | static char quotechars[] = "[]{}*?$"; |
d0dc5e26 | 138 | |
82572cb6 RC |
139 | again: |
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) | |
d0dc5e26 | 148 | return(0); |
82572cb6 RC |
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 | ||
d1dee8e8 RC |
164 | case ';': /* SM */ |
165 | return(SM); | |
166 | ||
82572cb6 RC |
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 | } | |
82572cb6 RC |
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++ = '\\'; | |
d0dc5e26 RC |
193 | break; |
194 | } | |
195 | } | |
82572cb6 RC |
196 | *cp1++ = c; |
197 | c = getc(fin); | |
d1dee8e8 | 198 | if (c == EOF || any(c, " \t()=;\n")) { |
82572cb6 RC |
199 | ungetc(c, fin); |
200 | break; | |
201 | } | |
d0dc5e26 | 202 | } |
82572cb6 | 203 | *cp1 = '\0'; |
3024eb6f RC |
204 | if (yytext[0] == '-' && yytext[2] == '\0') { |
205 | switch (yytext[1]) { | |
d1dee8e8 RC |
206 | case 'r': |
207 | yylval.intval = REMOVE; | |
208 | return(OPTION); | |
209 | ||
3024eb6f RC |
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 | } | |
82572cb6 RC |
223 | if (!strcmp(yytext, "install")) |
224 | c = INSTALL; | |
82572cb6 RC |
225 | else if (!strcmp(yytext, "notify")) |
226 | c = NOTIFY; | |
227 | else if (!strcmp(yytext, "except")) | |
228 | c = EXCEPT; | |
229 | else | |
230 | c = NAME; | |
3024eb6f | 231 | yylval.blk = makeblock(c, yytext); |
82572cb6 | 232 | return(c); |
d0dc5e26 RC |
233 | } |
234 | ||
235 | any(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 | */ | |
248 | yyerror(s) | |
249 | char *s; | |
250 | { | |
251 | extern int yychar; | |
252 | ||
d1dee8e8 | 253 | errs++; |
d0dc5e26 RC |
254 | fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); |
255 | } |