Commit | Line | Data |
---|---|---|
d0dc5e26 RC |
1 | %{ |
2 | #ifndef lint | |
82572cb6 | 3 | static char *sccsid = "@(#)gram.y 4.2 (Berkeley) 83/09/27"; |
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 | |
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 | ||
33 | file: /* VOID */ | |
34 | | file command | |
35 | ; | |
36 | ||
37 | command: 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 | ||
50 | namelist: NAME = { | |
51 | $$ = $1; | |
52 | } | |
53 | | LP names RP = { | |
54 | $$ = $2; | |
55 | } | |
56 | ; | |
57 | ||
58 | names: /* 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 | ||
72 | cmdlist: /* 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 | ||
86 | cmd: 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 | ||
112 | int yylineno = 1; | |
113 | extern FILE *fin; | |
114 | ||
115 | yylex() | |
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 |
123 | again: |
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 | ||
202 | any(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 | */ | |
215 | yyerror(s) | |
216 | char *s; | |
217 | { | |
218 | extern int yychar; | |
219 | ||
220 | fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); | |
221 | } |