Commit | Line | Data |
---|---|---|
d0dc5e26 RC |
1 | %{ |
2 | #ifndef lint | |
3024eb6f | 3 | static char *sccsid = "@(#)gram.y 4.3 (Berkeley) 83/10/10"; |
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 | |
16 | %term ARROW 4 | |
17 | %term DCOLON 5 | |
18 | %term NAME 6 | |
19 | %term INSTALL 7 | |
3024eb6f RC |
20 | %term NOTIFY 8 |
21 | %term EXCEPT 9 | |
22 | %term OPTION 10 | |
d0dc5e26 | 23 | |
3024eb6f | 24 | %union { |
d0dc5e26 | 25 | struct block *blk; |
3024eb6f RC |
26 | int intval; |
27 | } | |
d0dc5e26 | 28 | |
3024eb6f RC |
29 | %type <blk> NAME, INSTALL, NOTIFY, EXCEPT, namelist, names, cmdlist, cmd |
30 | %type <intval> OPTION, options | |
d0dc5e26 RC |
31 | |
32 | %% | |
33 | ||
34 | file: /* VOID */ | |
35 | | file command | |
36 | ; | |
37 | ||
38 | command: NAME EQUAL namelist = { | |
39 | $1->b_args = $3; | |
82572cb6 | 40 | (void) lookup($1->b_name, $1, 1); |
d0dc5e26 RC |
41 | } |
42 | | namelist ARROW namelist cmdlist = { | |
82572cb6 RC |
43 | dohcmds($1, $3, $4); |
44 | } | |
45 | | namelist DCOLON namelist cmdlist = { | |
46 | dofcmds($1, $3, $4); | |
d0dc5e26 RC |
47 | } |
48 | | error | |
49 | ; | |
50 | ||
51 | namelist: NAME = { | |
52 | $$ = $1; | |
53 | } | |
54 | | LP names RP = { | |
55 | $$ = $2; | |
56 | } | |
57 | ; | |
58 | ||
59 | names: /* VOID */ { | |
82572cb6 | 60 | $$ = lastn = NULL; |
d0dc5e26 RC |
61 | } |
62 | | names NAME = { | |
82572cb6 RC |
63 | if (lastn == NULL) |
64 | $$ = lastn = $2; | |
d0dc5e26 | 65 | else { |
82572cb6 RC |
66 | lastn->b_next = $2; |
67 | lastn = $2; | |
d0dc5e26 RC |
68 | $$ = $1; |
69 | } | |
70 | } | |
71 | ; | |
72 | ||
73 | cmdlist: /* VOID */ { | |
82572cb6 | 74 | $$ = lastc = NULL; |
d0dc5e26 RC |
75 | } |
76 | | cmdlist cmd = { | |
82572cb6 RC |
77 | if (lastc == NULL) |
78 | $$ = lastc = $2; | |
d0dc5e26 | 79 | else { |
82572cb6 RC |
80 | lastc->b_next = $2; |
81 | lastc = $2; | |
d0dc5e26 RC |
82 | $$ = $1; |
83 | } | |
84 | } | |
85 | ; | |
86 | ||
3024eb6f | 87 | cmd: INSTALL options NAME = { |
82572cb6 RC |
88 | register struct block *b; |
89 | ||
3024eb6f RC |
90 | $1->b_options = $2; |
91 | b = expand($3, 0); | |
82572cb6 RC |
92 | if (b == NULL || b->b_next != NULL) |
93 | fatal("exactly one name allowed\n"); | |
94 | $1->b_name = b->b_name; | |
d0dc5e26 RC |
95 | $$ = $1; |
96 | } | |
d0dc5e26 | 97 | | NOTIFY namelist = { |
82572cb6 | 98 | $1->b_args = expand($2, 1); |
d0dc5e26 RC |
99 | $$ = $1; |
100 | } | |
101 | | EXCEPT namelist = { | |
82572cb6 | 102 | $1->b_args = expand($2, 0); |
d0dc5e26 RC |
103 | $$ = $1; |
104 | } | |
105 | ; | |
3024eb6f RC |
106 | options: /* VOID */ = { |
107 | $$ = 0; | |
108 | } | |
109 | | options OPTION = { | |
110 | $$ |= $2; | |
111 | } | |
112 | ; | |
d0dc5e26 RC |
113 | |
114 | %% | |
115 | ||
116 | int yylineno = 1; | |
117 | extern FILE *fin; | |
118 | ||
119 | yylex() | |
120 | { | |
121 | static char yytext[INMAX]; | |
122 | register int c; | |
123 | register char *cp1, *cp2; | |
3024eb6f | 124 | static char quotechars[] = "[]{}*?$"; |
d0dc5e26 | 125 | |
82572cb6 RC |
126 | again: |
127 | switch (c = getc(fin)) { | |
128 | case EOF: /* end of file */ | |
129 | return(0); | |
130 | ||
131 | case '#': /* start of comment */ | |
132 | while ((c = getc(fin)) != EOF && c != '\n') | |
133 | ; | |
134 | if (c == EOF) | |
d0dc5e26 | 135 | return(0); |
82572cb6 RC |
136 | case '\n': |
137 | yylineno++; | |
138 | case ' ': | |
139 | case '\t': /* skip blanks */ | |
140 | goto again; | |
141 | ||
142 | case '=': /* EQUAL */ | |
143 | return(EQUAL); | |
144 | ||
145 | case '(': /* LP */ | |
146 | return(LP); | |
147 | ||
148 | case ')': /* RP */ | |
149 | return(RP); | |
150 | ||
151 | case '-': /* -> */ | |
152 | if ((c = getc(fin)) == '>') | |
153 | return(ARROW); | |
154 | ungetc(c, fin); | |
155 | c = '-'; | |
156 | break; | |
157 | ||
158 | case ':': /* :: */ | |
159 | if ((c = getc(fin)) == ':') | |
160 | return(DCOLON); | |
161 | ungetc(c, fin); | |
162 | c = ':'; | |
163 | } | |
82572cb6 RC |
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 | 187 | *cp1 = '\0'; |
3024eb6f RC |
188 | if (yytext[0] == '-' && yytext[2] == '\0') { |
189 | switch (yytext[1]) { | |
190 | case 'v': | |
191 | yylval.intval = VERIFY; | |
192 | return(OPTION); | |
193 | ||
194 | case 'w': | |
195 | yylval.intval = WHOLE; | |
196 | return(OPTION); | |
197 | ||
198 | case 'y': | |
199 | yylval.intval = YOUNGER; | |
200 | return(OPTION); | |
201 | } | |
202 | } | |
82572cb6 RC |
203 | if (!strcmp(yytext, "install")) |
204 | c = INSTALL; | |
82572cb6 RC |
205 | else if (!strcmp(yytext, "notify")) |
206 | c = NOTIFY; | |
207 | else if (!strcmp(yytext, "except")) | |
208 | c = EXCEPT; | |
209 | else | |
210 | c = NAME; | |
3024eb6f | 211 | yylval.blk = makeblock(c, yytext); |
82572cb6 | 212 | return(c); |
d0dc5e26 RC |
213 | } |
214 | ||
215 | any(c, str) | |
216 | register int c; | |
217 | register char *str; | |
218 | { | |
219 | while (*str) | |
220 | if (c == *str++) | |
221 | return(1); | |
222 | return(0); | |
223 | } | |
224 | ||
225 | /* | |
226 | * Error printing routine in parser. | |
227 | */ | |
228 | yyerror(s) | |
229 | char *s; | |
230 | { | |
231 | extern int yychar; | |
232 | ||
233 | fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); | |
234 | } |