]>
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 ); } | |
11fdf7f2 TL |
167 | | LOCAL_t { yymode( SCAN_ASSIGN ); } list assign_list_opt _SEMIC_t { yymode( SCAN_NORMAL ); } block |
168 | { $$.parse = plocal( $3.parse, $4.parse, $7.parse ); } | |
7c673cae FG |
169 | ; |
170 | ||
171 | null : /* empty */ | |
172 | { $$.parse = pnull(); } | |
173 | ; | |
174 | ||
11fdf7f2 TL |
175 | assign_list_opt : _EQUALS_t { yymode( SCAN_PUNCT ); } list |
176 | { $$.parse = $3.parse; $$.number = ASSIGN_SET; } | |
7c673cae FG |
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 | ||
11fdf7f2 TL |
193 | else_opt : ELSE_t rule |
194 | { $$.parse = $2.parse; } | |
195 | | /* empty */ | |
196 | { $$.parse = pnull(); } | |
197 | ||
7c673cae FG |
198 | rule : _LBRACE_t block _RBRACE_t |
199 | { $$.parse = $2.parse; } | |
11fdf7f2 TL |
200 | | INCLUDE_t { yymode( SCAN_PUNCT ); } list _SEMIC_t |
201 | { $$.parse = pincl( $3.parse ); yymode( SCAN_NORMAL ); } | |
202 | | ARG { yymode( SCAN_PUNCT ); } lol _SEMIC_t | |
203 | { $$.parse = prule( $1.string, $3.parse ); yymode( SCAN_NORMAL ); } | |
204 | | arg assign { yymode( SCAN_PUNCT ); } list _SEMIC_t | |
205 | { $$.parse = pset( $1.parse, $4.parse, $2.number ); yymode( SCAN_NORMAL ); } | |
206 | | arg ON_t { yymode( SCAN_ASSIGN ); } list assign { yymode( SCAN_PUNCT ); } list _SEMIC_t | |
207 | { $$.parse = pset1( $1.parse, $4.parse, $7.parse, $5.number ); yymode( SCAN_NORMAL ); } | |
208 | | RETURN_t { yymode( SCAN_PUNCT ); } list _SEMIC_t | |
209 | { $$.parse = preturn( $3.parse ); yymode( SCAN_NORMAL ); } | |
7c673cae FG |
210 | | BREAK_t _SEMIC_t |
211 | { $$.parse = pbreak(); } | |
212 | | CONTINUE_t _SEMIC_t | |
213 | { $$.parse = pcontinue(); } | |
11fdf7f2 TL |
214 | | FOR_t local_opt ARG IN_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t |
215 | { $$.parse = pfor( $3.string, $6.parse, $9.parse, $2.number ); } | |
216 | | SWITCH_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } cases _RBRACE_t | |
217 | { $$.parse = pswitch( $3.parse, $6.parse ); } | |
218 | | IF_t { yymode( SCAN_CONDB ); } expr _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t else_opt | |
219 | { $$.parse = pif( $3.parse, $6.parse, $8.parse ); } | |
220 | | MODULE_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t | |
221 | { $$.parse = pmodule( $3.parse, $6.parse ); } | |
222 | | CLASS_t { yymode( SCAN_PUNCT ); } lol _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t | |
223 | { $$.parse = pclass( $3.parse, $6.parse ); } | |
224 | | WHILE_t { yymode( SCAN_CONDB ); } expr { yymode( SCAN_NORMAL ); } _LBRACE_t block _RBRACE_t | |
225 | { $$.parse = pwhile( $3.parse, $6.parse ); } | |
226 | | local_opt RULE_t { yymode( SCAN_PUNCT ); } ARG { yymode( SCAN_PARAMS ); } arglist_opt { yymode( SCAN_NORMAL ); } rule | |
227 | { $$.parse = psetc( $4.string, $8.parse, $6.parse, $1.number ); } | |
7c673cae FG |
228 | | ON_t arg rule |
229 | { $$.parse = pon( $2.parse, $3.parse ); } | |
230 | | ACTIONS_t eflags ARG bindlist _LBRACE_t | |
231 | { yymode( SCAN_STRING ); } | |
232 | STRING | |
233 | { yymode( SCAN_NORMAL ); } | |
234 | _RBRACE_t | |
235 | { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } | |
236 | ; | |
237 | ||
238 | /* | |
239 | * assign - = or += | |
240 | */ | |
241 | ||
242 | assign : _EQUALS_t | |
243 | { $$.number = ASSIGN_SET; } | |
244 | | _PLUS_EQUALS_t | |
245 | { $$.number = ASSIGN_APPEND; } | |
246 | | _QUESTION_EQUALS_t | |
247 | { $$.number = ASSIGN_DEFAULT; } | |
248 | | DEFAULT_t _EQUALS_t | |
249 | { $$.number = ASSIGN_DEFAULT; } | |
250 | ; | |
251 | ||
252 | /* | |
253 | * expr - an expression for if | |
254 | */ | |
255 | expr : arg | |
11fdf7f2 TL |
256 | { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); yymode( SCAN_COND ); } |
257 | | expr _EQUALS_t { yymode( SCAN_CONDB ); } expr | |
258 | { $$.parse = peval( EXPR_EQUALS, $1.parse, $4.parse ); } | |
259 | | expr _BANG_EQUALS_t { yymode( SCAN_CONDB ); } expr | |
260 | { $$.parse = peval( EXPR_NOTEQ, $1.parse, $4.parse ); } | |
261 | | expr _LANGLE_t { yymode( SCAN_CONDB ); } expr | |
262 | { $$.parse = peval( EXPR_LESS, $1.parse, $4.parse ); } | |
263 | | expr _LANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr | |
264 | { $$.parse = peval( EXPR_LESSEQ, $1.parse, $4.parse ); } | |
265 | | expr _RANGLE_t { yymode( SCAN_CONDB ); } expr | |
266 | { $$.parse = peval( EXPR_MORE, $1.parse, $4.parse ); } | |
267 | | expr _RANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr | |
268 | { $$.parse = peval( EXPR_MOREEQ, $1.parse, $4.parse ); } | |
269 | | expr _AMPER_t { yymode( SCAN_CONDB ); } expr | |
270 | { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } | |
271 | | expr _AMPERAMPER_t { yymode( SCAN_CONDB ); } expr | |
272 | { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } | |
273 | | expr _BAR_t { yymode( SCAN_CONDB ); } expr | |
274 | { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } | |
275 | | expr _BARBAR_t { yymode( SCAN_CONDB ); } expr | |
276 | { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } | |
277 | | arg IN_t { yymode( SCAN_PUNCT ); } list | |
278 | { $$.parse = peval( EXPR_IN, $1.parse, $4.parse ); yymode( SCAN_COND ); } | |
279 | | _BANG_t { yymode( SCAN_CONDB ); } expr | |
280 | { $$.parse = peval( EXPR_NOT, $3.parse, pnull() ); } | |
281 | | _LPAREN_t { yymode( SCAN_CONDB ); } expr _RPAREN_t | |
282 | { $$.parse = $3.parse; } | |
7c673cae FG |
283 | ; |
284 | ||
285 | ||
286 | /* | |
287 | * cases - action elements inside a 'switch' | |
288 | * case - a single action element inside a 'switch' | |
289 | * right-recursive rule so cases can be examined in order. | |
290 | */ | |
291 | ||
292 | cases : /* empty */ | |
293 | { $$.parse = P0; } | |
294 | | case cases | |
295 | { $$.parse = pnode( $1.parse, $2.parse ); } | |
296 | ; | |
297 | ||
11fdf7f2 TL |
298 | case : CASE_t { yymode( SCAN_CASE ); } ARG _COLON_t { yymode( SCAN_NORMAL ); } block |
299 | { $$.parse = psnode( $3.string, $6.parse ); } | |
7c673cae FG |
300 | ; |
301 | ||
302 | /* | |
303 | * lol - list of lists | |
304 | * right-recursive rule so that lists can be added in order. | |
305 | */ | |
306 | ||
307 | lol : list | |
308 | { $$.parse = pnode( P0, $1.parse ); } | |
309 | | list _COLON_t lol | |
310 | { $$.parse = pnode( $3.parse, $1.parse ); } | |
311 | ; | |
312 | ||
313 | /* | |
314 | * list - zero or more args in a LIST | |
315 | * listp - list (in puncutation only mode) | |
316 | * arg - one ARG or function call | |
317 | */ | |
318 | ||
319 | list : listp | |
11fdf7f2 | 320 | { $$.parse = $1.parse; } |
7c673cae FG |
321 | ; |
322 | ||
323 | listp : /* empty */ | |
11fdf7f2 | 324 | { $$.parse = pnull(); } |
7c673cae FG |
325 | | listp arg |
326 | { $$.parse = pappend( $1.parse, $2.parse ); } | |
327 | ; | |
328 | ||
329 | arg : ARG | |
330 | { $$.parse = plist( $1.string ); } | |
11fdf7f2 TL |
331 | | _LBRACKET_t { $$.number = yymode( SCAN_CALL ); } func _RBRACKET_t |
332 | { $$.parse = $3.parse; yymode( $2.number ); } | |
7c673cae FG |
333 | ; |
334 | ||
335 | /* | |
336 | * func - a function call (inside []) | |
337 | * This needs to be split cleanly out of 'rule' | |
338 | */ | |
339 | ||
11fdf7f2 TL |
340 | func : ARG { yymode( SCAN_PUNCT ); } lol |
341 | { $$.parse = prule( $1.string, $3.parse ); } | |
342 | | ON_t arg ARG { yymode( SCAN_PUNCT ); } lol | |
343 | { $$.parse = pon( $2.parse, prule( $3.string, $5.parse ) ); } | |
344 | | ON_t arg RETURN_t { yymode( SCAN_PUNCT ); } list | |
345 | { $$.parse = pon( $2.parse, $5.parse ); } | |
7c673cae FG |
346 | ; |
347 | ||
348 | ||
349 | /* | |
350 | * eflags - zero or more modifiers to 'executes' | |
351 | * eflag - a single modifier to 'executes' | |
352 | */ | |
353 | ||
354 | eflags : /* empty */ | |
355 | { $$.number = 0; } | |
356 | | eflags eflag | |
357 | { $$.number = $1.number | $2.number; } | |
358 | ; | |
359 | ||
360 | eflag : UPDATED_t | |
361 | { $$.number = EXEC_UPDATED; } | |
362 | | TOGETHER_t | |
363 | { $$.number = EXEC_TOGETHER; } | |
364 | | IGNORE_t | |
365 | { $$.number = EXEC_IGNORE; } | |
366 | | QUIETLY_t | |
367 | { $$.number = EXEC_QUIETLY; } | |
368 | | PIECEMEAL_t | |
369 | { $$.number = EXEC_PIECEMEAL; } | |
370 | | EXISTING_t | |
371 | { $$.number = EXEC_EXISTING; } | |
372 | ; | |
373 | ||
374 | ||
375 | /* | |
376 | * bindlist - list of variable to bind for an action | |
377 | */ | |
378 | ||
379 | bindlist : /* empty */ | |
380 | { $$.parse = pnull(); } | |
11fdf7f2 TL |
381 | | BIND_t { yymode( SCAN_PUNCT ); } list |
382 | { $$.parse = $3.parse; } | |
7c673cae FG |
383 | ; |
384 | ||
385 |