]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | %token _BANG_t |
2 | %token _BANG_EQUALS_t | |
3 | %token _AMPER_t | |
4 | %token _AMPERAMPER_t | |
5 | %token _LPAREN_t | |
6 | %token _RPAREN_t | |
7 | %token _PLUS_EQUALS_t | |
8 | %token _COLON_t | |
9 | %token _SEMIC_t | |
10 | %token _LANGLE_t | |
11 | %token _LANGLE_EQUALS_t | |
12 | %token _EQUALS_t | |
13 | %token _RANGLE_t | |
14 | %token _RANGLE_EQUALS_t | |
15 | %token _QUESTION_EQUALS_t | |
16 | %token _LBRACKET_t | |
17 | %token _RBRACKET_t | |
18 | %token ACTIONS_t | |
19 | %token BIND_t | |
20 | %token BREAK_t | |
21 | %token CASE_t | |
22 | %token CLASS_t | |
23 | %token CONTINUE_t | |
24 | %token DEFAULT_t | |
25 | %token ELSE_t | |
26 | %token EXISTING_t | |
27 | %token FOR_t | |
28 | %token IF_t | |
29 | %token IGNORE_t | |
30 | %token IN_t | |
31 | %token INCLUDE_t | |
32 | %token LOCAL_t | |
33 | %token MODULE_t | |
34 | %token ON_t | |
35 | %token PIECEMEAL_t | |
36 | %token QUIETLY_t | |
37 | %token RETURN_t | |
38 | %token RULE_t | |
39 | %token SWITCH_t | |
40 | %token TOGETHER_t | |
41 | %token UPDATED_t | |
42 | %token WHILE_t | |
43 | %token _LBRACE_t | |
44 | %token _BAR_t | |
45 | %token _BARBAR_t | |
46 | %token _RBRACE_t | |
47 | /* | |
48 | * Copyright 1993, 2000 Christopher Seiwald. | |
49 | * | |
50 | * This file is part of Jam - see jam.c for Copyright information. | |
51 | */ | |
52 | ||
53 | /* This file is ALSO: | |
54 | * Copyright 2001-2004 David Abrahams. | |
55 | * Distributed under the Boost Software License, Version 1.0. | |
56 | * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
57 | */ | |
58 | ||
59 | /* | |
60 | * jamgram.yy - jam grammar | |
61 | * | |
62 | * 04/13/94 (seiwald) - added shorthand L0 for null list pointer | |
63 | * 06/01/94 (seiwald) - new 'actions existing' does existing sources | |
64 | * 08/23/94 (seiwald) - Support for '+=' (append to variable) | |
65 | * 08/31/94 (seiwald) - Allow ?= as alias for "default =". | |
66 | * 09/15/94 (seiwald) - if conditionals take only single arguments, so | |
67 | * that 'if foo == bar' gives syntax error (use =). | |
68 | * 02/11/95 (seiwald) - when scanning arguments to rules, only treat | |
69 | * punctuation keywords as keywords. All arg lists | |
70 | * are terminated with punctuation keywords. | |
71 | * | |
72 | * 09/11/00 (seiwald) - Support for function calls: | |
73 | * | |
74 | * Rules now return lists (LIST *), rather than void. | |
75 | * | |
76 | * New "[ rule ]" syntax evals rule into a LIST. | |
77 | * | |
78 | * Lists are now generated by compile_list() and | |
79 | * compile_append(), and any other rule that indirectly | |
80 | * makes a list, rather than being built directly here, | |
81 | * so that lists values can contain rule evaluations. | |
82 | * | |
83 | * New 'return' rule sets the return value, though | |
84 | * other statements also may have return values. | |
85 | * | |
86 | * 'run' production split from 'block' production so | |
87 | * that empty blocks can be handled separately. | |
88 | */ | |
89 | ||
90 | %token ARG STRING | |
91 | ||
92 | %left _BARBAR_t _BAR_t | |
93 | %left _AMPERAMPER_t _AMPER_t | |
94 | %left _EQUALS_t _BANG_EQUALS_t IN_t | |
95 | %left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t | |
96 | %left _BANG_t | |
97 | ||
98 | %{ | |
99 | #include "jam.h" | |
100 | ||
101 | #include "lists.h" | |
102 | #include "parse.h" | |
103 | #include "scan.h" | |
104 | #include "compile.h" | |
105 | #include "object.h" | |
106 | #include "rules.h" | |
107 | ||
108 | # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ | |
109 | ||
110 | # define F0 -1 | |
111 | # define P0 (PARSE *)0 | |
112 | # define S0 (OBJECT *)0 | |
113 | ||
114 | # define pappend( l,r ) parse_make( PARSE_APPEND,l,r,P0,S0,S0,0 ) | |
115 | # define peval( c,l,r ) parse_make( PARSE_EVAL,l,r,P0,S0,S0,c ) | |
116 | # define pfor( s,l,r,x ) parse_make( PARSE_FOREACH,l,r,P0,s,S0,x ) | |
117 | # define pif( l,r,t ) parse_make( PARSE_IF,l,r,t,S0,S0,0 ) | |
118 | # define pincl( l ) parse_make( PARSE_INCLUDE,l,P0,P0,S0,S0,0 ) | |
119 | # define plist( s ) parse_make( PARSE_LIST,P0,P0,P0,s,S0,0 ) | |
120 | # define plocal( l,r,t ) parse_make( PARSE_LOCAL,l,r,t,S0,S0,0 ) | |
121 | # define pmodule( l,r ) parse_make( PARSE_MODULE,l,r,P0,S0,S0,0 ) | |
122 | # define pclass( l,r ) parse_make( PARSE_CLASS,l,r,P0,S0,S0,0 ) | |
123 | # define pnull() parse_make( PARSE_NULL,P0,P0,P0,S0,S0,0 ) | |
124 | # define pon( l,r ) parse_make( PARSE_ON,l,r,P0,S0,S0,0 ) | |
125 | # define prule( s,p ) parse_make( PARSE_RULE,p,P0,P0,s,S0,0 ) | |
126 | # define prules( l,r ) parse_make( PARSE_RULES,l,r,P0,S0,S0,0 ) | |
127 | # define pset( l,r,a ) parse_make( PARSE_SET,l,r,P0,S0,S0,a ) | |
128 | # define pset1( l,r,t,a ) parse_make( PARSE_SETTINGS,l,r,t,S0,S0,a ) | |
129 | # define psetc( s,p,a,l ) parse_make( PARSE_SETCOMP,p,a,P0,s,S0,l ) | |
130 | # define psete( s,l,s1,f ) parse_make( PARSE_SETEXEC,l,P0,P0,s,s1,f ) | |
131 | # define pswitch( l,r ) parse_make( PARSE_SWITCH,l,r,P0,S0,S0,0 ) | |
132 | # define pwhile( l,r ) parse_make( PARSE_WHILE,l,r,P0,S0,S0,0 ) | |
133 | # define preturn( l ) parse_make( PARSE_RETURN,l,P0,P0,S0,S0,0 ) | |
134 | # define pbreak() parse_make( PARSE_BREAK,P0,P0,P0,S0,S0,0 ) | |
135 | # define pcontinue() parse_make( PARSE_CONTINUE,P0,P0,P0,S0,S0,0 ) | |
136 | ||
137 | # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) | |
138 | # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) | |
139 | ||
140 | %} | |
141 | ||
142 | %% | |
143 | ||
144 | run : /* empty */ | |
145 | /* do nothing */ | |
146 | | rules | |
147 | { parse_save( $1.parse ); } | |
148 | ; | |
149 | ||
150 | /* | |
151 | * block - zero or more rules | |
152 | * rules - one or more rules | |
153 | * rule - any one of jam's rules | |
154 | * right-recursive so rules execute in order. | |
155 | */ | |
156 | ||
157 | block : null | |
158 | { $$.parse = $1.parse; } | |
159 | | rules | |
160 | { $$.parse = $1.parse; } | |
161 | ; | |
162 | ||
163 | rules : rule | |
164 | { $$.parse = $1.parse; } | |
165 | | rule rules | |
166 | { $$.parse = prules( $1.parse, $2.parse ); } | |
167 | | LOCAL_t list assign_list_opt _SEMIC_t block | |
168 | { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } | |
169 | ; | |
170 | ||
171 | null : /* empty */ | |
172 | { $$.parse = pnull(); } | |
173 | ; | |
174 | ||
175 | assign_list_opt : _EQUALS_t list | |
176 | { $$.parse = $2.parse; $$.number = ASSIGN_SET; } | |
177 | | null | |
178 | { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } | |
179 | ; | |
180 | ||
181 | arglist_opt : _LPAREN_t lol _RPAREN_t | |
182 | { $$.parse = $2.parse; } | |
183 | | | |
184 | { $$.parse = P0; } | |
185 | ; | |
186 | ||
187 | local_opt : LOCAL_t | |
188 | { $$.number = 1; } | |
189 | | /* empty */ | |
190 | { $$.number = 0; } | |
191 | ; | |
192 | ||
193 | rule : _LBRACE_t block _RBRACE_t | |
194 | { $$.parse = $2.parse; } | |
195 | | INCLUDE_t list _SEMIC_t | |
196 | { $$.parse = pincl( $2.parse ); } | |
197 | | ARG lol _SEMIC_t | |
198 | { $$.parse = prule( $1.string, $2.parse ); } | |
199 | | arg assign list _SEMIC_t | |
200 | { $$.parse = pset( $1.parse, $3.parse, $2.number ); } | |
201 | | arg ON_t list assign list _SEMIC_t | |
202 | { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | |
203 | | RETURN_t list _SEMIC_t | |
204 | { $$.parse = preturn( $2.parse ); } | |
205 | | BREAK_t _SEMIC_t | |
206 | { $$.parse = pbreak(); } | |
207 | | CONTINUE_t _SEMIC_t | |
208 | { $$.parse = pcontinue(); } | |
209 | | FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t | |
210 | { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } | |
211 | | SWITCH_t list _LBRACE_t cases _RBRACE_t | |
212 | { $$.parse = pswitch( $2.parse, $4.parse ); } | |
213 | | IF_t expr _LBRACE_t block _RBRACE_t | |
214 | { $$.parse = pif( $2.parse, $4.parse, pnull() ); } | |
215 | | MODULE_t list _LBRACE_t block _RBRACE_t | |
216 | { $$.parse = pmodule( $2.parse, $4.parse ); } | |
217 | | CLASS_t lol _LBRACE_t block _RBRACE_t | |
218 | { $$.parse = pclass( $2.parse, $4.parse ); } | |
219 | | WHILE_t expr _LBRACE_t block _RBRACE_t | |
220 | { $$.parse = pwhile( $2.parse, $4.parse ); } | |
221 | | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule | |
222 | { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } | |
223 | | local_opt RULE_t ARG arglist_opt rule | |
224 | { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } | |
225 | | ON_t arg rule | |
226 | { $$.parse = pon( $2.parse, $3.parse ); } | |
227 | | ACTIONS_t eflags ARG bindlist _LBRACE_t | |
228 | { yymode( SCAN_STRING ); } | |
229 | STRING | |
230 | { yymode( SCAN_NORMAL ); } | |
231 | _RBRACE_t | |
232 | { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } | |
233 | ; | |
234 | ||
235 | /* | |
236 | * assign - = or += | |
237 | */ | |
238 | ||
239 | assign : _EQUALS_t | |
240 | { $$.number = ASSIGN_SET; } | |
241 | | _PLUS_EQUALS_t | |
242 | { $$.number = ASSIGN_APPEND; } | |
243 | | _QUESTION_EQUALS_t | |
244 | { $$.number = ASSIGN_DEFAULT; } | |
245 | | DEFAULT_t _EQUALS_t | |
246 | { $$.number = ASSIGN_DEFAULT; } | |
247 | ; | |
248 | ||
249 | /* | |
250 | * expr - an expression for if | |
251 | */ | |
252 | expr : arg | |
253 | { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } | |
254 | | expr _EQUALS_t expr | |
255 | { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } | |
256 | | expr _BANG_EQUALS_t expr | |
257 | { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } | |
258 | | expr _LANGLE_t expr | |
259 | { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } | |
260 | | expr _LANGLE_EQUALS_t expr | |
261 | { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } | |
262 | | expr _RANGLE_t expr | |
263 | { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } | |
264 | | expr _RANGLE_EQUALS_t expr | |
265 | { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } | |
266 | | expr _AMPER_t expr | |
267 | { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | |
268 | | expr _AMPERAMPER_t expr | |
269 | { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } | |
270 | | expr _BAR_t expr | |
271 | { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | |
272 | | expr _BARBAR_t expr | |
273 | { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } | |
274 | | arg IN_t list | |
275 | { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } | |
276 | | _BANG_t expr | |
277 | { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } | |
278 | | _LPAREN_t expr _RPAREN_t | |
279 | { $$.parse = $2.parse; } | |
280 | ; | |
281 | ||
282 | ||
283 | /* | |
284 | * cases - action elements inside a 'switch' | |
285 | * case - a single action element inside a 'switch' | |
286 | * right-recursive rule so cases can be examined in order. | |
287 | */ | |
288 | ||
289 | cases : /* empty */ | |
290 | { $$.parse = P0; } | |
291 | | case cases | |
292 | { $$.parse = pnode( $1.parse, $2.parse ); } | |
293 | ; | |
294 | ||
295 | case : CASE_t ARG _COLON_t block | |
296 | { $$.parse = psnode( $2.string, $4.parse ); } | |
297 | ; | |
298 | ||
299 | /* | |
300 | * lol - list of lists | |
301 | * right-recursive rule so that lists can be added in order. | |
302 | */ | |
303 | ||
304 | lol : list | |
305 | { $$.parse = pnode( P0, $1.parse ); } | |
306 | | list _COLON_t lol | |
307 | { $$.parse = pnode( $3.parse, $1.parse ); } | |
308 | ; | |
309 | ||
310 | /* | |
311 | * list - zero or more args in a LIST | |
312 | * listp - list (in puncutation only mode) | |
313 | * arg - one ARG or function call | |
314 | */ | |
315 | ||
316 | list : listp | |
317 | { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } | |
318 | ; | |
319 | ||
320 | listp : /* empty */ | |
321 | { $$.parse = pnull(); yymode( SCAN_PUNCT ); } | |
322 | | listp arg | |
323 | { $$.parse = pappend( $1.parse, $2.parse ); } | |
324 | ; | |
325 | ||
326 | arg : ARG | |
327 | { $$.parse = plist( $1.string ); } | |
328 | | _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t | |
329 | { $$.parse = $3.parse; } | |
330 | ; | |
331 | ||
332 | /* | |
333 | * func - a function call (inside []) | |
334 | * This needs to be split cleanly out of 'rule' | |
335 | */ | |
336 | ||
337 | func : ARG lol | |
338 | { $$.parse = prule( $1.string, $2.parse ); } | |
339 | | ON_t arg ARG lol | |
340 | { $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); } | |
341 | | ON_t arg RETURN_t list | |
342 | { $$.parse = pon( $2.parse, $4.parse ); } | |
343 | ; | |
344 | ||
345 | ||
346 | /* | |
347 | * eflags - zero or more modifiers to 'executes' | |
348 | * eflag - a single modifier to 'executes' | |
349 | */ | |
350 | ||
351 | eflags : /* empty */ | |
352 | { $$.number = 0; } | |
353 | | eflags eflag | |
354 | { $$.number = $1.number | $2.number; } | |
355 | ; | |
356 | ||
357 | eflag : UPDATED_t | |
358 | { $$.number = EXEC_UPDATED; } | |
359 | | TOGETHER_t | |
360 | { $$.number = EXEC_TOGETHER; } | |
361 | | IGNORE_t | |
362 | { $$.number = EXEC_IGNORE; } | |
363 | | QUIETLY_t | |
364 | { $$.number = EXEC_QUIETLY; } | |
365 | | PIECEMEAL_t | |
366 | { $$.number = EXEC_PIECEMEAL; } | |
367 | | EXISTING_t | |
368 | { $$.number = EXEC_EXISTING; } | |
369 | ; | |
370 | ||
371 | ||
372 | /* | |
373 | * bindlist - list of variable to bind for an action | |
374 | */ | |
375 | ||
376 | bindlist : /* empty */ | |
377 | { $$.parse = pnull(); } | |
378 | | BIND_t list | |
379 | { $$.parse = $2.parse; } | |
380 | ; | |
381 | ||
382 |