42 |
int typed = 0; |
int typed = 0; |
43 |
|
|
44 |
static symbol_list * |
static symbol_list * |
45 |
symbol_list_new (symbol_t *sym) |
symbol_list_new (symbol_t *sym, location_t location) |
46 |
{ |
{ |
47 |
symbol_list *res = XMALLOC (symbol_list, 1); |
symbol_list *res = XMALLOC (symbol_list, 1); |
48 |
res->next = NULL; |
res->next = NULL; |
49 |
res->sym = sym; |
res->sym = sym; |
50 |
res->line = lineno; |
res->location = location; |
51 |
res->action = NULL; |
res->action = NULL; |
|
res->action_line = 0; |
|
52 |
res->ruleprec = NULL; |
res->ruleprec = NULL; |
53 |
return res; |
return res; |
54 |
} |
} |
94 |
`-----------------------*/ |
`-----------------------*/ |
95 |
|
|
96 |
void |
void |
97 |
grammar_start_symbol_set (symbol_t *s) |
grammar_start_symbol_set (symbol_t *s, location_t l) |
98 |
{ |
{ |
99 |
if (start_flag) |
if (start_flag) |
100 |
complain (_("multiple %s declarations"), "%start"); |
complain (_("multiple %s declarations"), "%start"); |
102 |
{ |
{ |
103 |
start_flag = 1; |
start_flag = 1; |
104 |
startsymbol = s; |
startsymbol = s; |
105 |
|
startsymbol_location = l; |
106 |
} |
} |
107 |
} |
} |
108 |
|
|
197 |
|
|
198 |
/* Append S to the GRAMMAR. */ |
/* Append S to the GRAMMAR. */ |
199 |
void |
void |
200 |
grammar_symbol_append (symbol_t *s) |
grammar_symbol_append (symbol_t *symbol, location_t location) |
201 |
{ |
{ |
202 |
symbol_list *p = symbol_list_new (s); |
symbol_list *p = symbol_list_new (symbol, location); |
203 |
|
|
204 |
if (grammar_end) |
if (grammar_end) |
205 |
grammar_end->next = p; |
grammar_end->next = p; |
209 |
grammar_end = p; |
grammar_end = p; |
210 |
} |
} |
211 |
|
|
212 |
/* The rule currently being defined, and the previous rule. Point to |
/* The rule currently being defined, and the previous rule. |
213 |
the first symbol of each list: their lhs. */ |
CURRENT_RULE points to the first LHS of the current rule, while |
214 |
|
PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */ |
215 |
symbol_list *current_rule = NULL; |
symbol_list *current_rule = NULL; |
216 |
symbol_list *previous_rule = NULL; |
symbol_list *previous_rule_end = NULL; |
217 |
|
|
218 |
|
|
219 |
/* Create a new rule for LHS in to the GRAMMAR. */ |
/*----------------------------------------------. |
220 |
|
| Create a new rule for LHS in to the GRAMMAR. | |
221 |
|
`----------------------------------------------*/ |
222 |
|
|
223 |
void |
void |
224 |
grammar_rule_begin (symbol_t *lhs) |
grammar_rule_begin (symbol_t *lhs, location_t location) |
225 |
{ |
{ |
226 |
if (!start_flag) |
if (!start_flag) |
227 |
{ |
{ |
228 |
startsymbol = lhs; |
startsymbol = lhs; |
229 |
|
startsymbol_location = location; |
230 |
start_flag = 1; |
start_flag = 1; |
231 |
} |
} |
232 |
|
|
234 |
++nrules; |
++nrules; |
235 |
++nritems; |
++nritems; |
236 |
|
|
237 |
previous_rule = grammar_end; |
previous_rule_end = grammar_end; |
238 |
grammar_symbol_append (lhs); |
grammar_symbol_append (lhs, location); |
239 |
current_rule = grammar_end; |
current_rule = grammar_end; |
240 |
|
|
241 |
/* Mark the rule's lhs as a nonterminal if not already so. */ |
/* Mark the rule's lhs as a nonterminal if not already so. */ |
283 |
} |
} |
284 |
|
|
285 |
|
|
286 |
/* End the currently being grown rule. */ |
/*-------------------------------------. |
287 |
|
| End the currently being grown rule. | |
288 |
|
`-------------------------------------*/ |
289 |
|
|
290 |
void |
void |
291 |
grammar_rule_end (void) |
grammar_rule_end (location_t location) |
292 |
{ |
{ |
293 |
/* Put an empty link in the list to mark the end of this rule */ |
/* Put an empty link in the list to mark the end of this rule */ |
294 |
grammar_symbol_append (NULL); |
grammar_symbol_append (NULL, grammar_end->location); |
295 |
|
current_rule->location = location; |
296 |
grammar_current_rule_check (); |
grammar_current_rule_check (); |
297 |
} |
} |
298 |
|
|
299 |
|
|
300 |
/* The previous action turns out the be a mid-rule action. Attach it |
/*-------------------------------------------------------------------. |
301 |
to the current rule, i.e., create a dummy symbol, attach it this |
| The previous action turns out the be a mid-rule action. Attach it | |
302 |
mid-rule action, and append this dummy nonterminal to the current |
| to the current rule, i.e., create a dummy symbol, attach it this | |
303 |
rule. */ |
| mid-rule action, and append this dummy nonterminal to the current | |
304 |
|
| rule. | |
305 |
|
`-------------------------------------------------------------------*/ |
306 |
|
|
307 |
void |
void |
308 |
grammar_midrule_action (void) |
grammar_midrule_action (void) |
311 |
give the new rule this number by inserting the new rule before |
give the new rule this number by inserting the new rule before |
312 |
it. */ |
it. */ |
313 |
|
|
314 |
/* Make a dummy nonterminal, a gensym. */ |
/* Make a DUMMY nonterminal, whose location is that of the midrule |
315 |
symbol_t *sdummy = gensym (); |
action. Create the MIDRULE. */ |
316 |
symbol_list *midrule_action = symbol_list_new (sdummy); |
symbol_t *dummy = gensym (); |
317 |
|
location_t dummy_location = current_rule->action_location; |
318 |
|
symbol_list *midrule = symbol_list_new (dummy, dummy_location); |
319 |
|
|
320 |
/* Make a new rule, whose body is empty, before the current one, so |
/* Make a new rule, whose body is empty, before the current one, so |
321 |
that the action just read can belong to it. */ |
that the action just read can belong to it. */ |
322 |
++nrules; |
++nrules; |
323 |
++nritems; |
++nritems; |
324 |
/* Attach its lineno to that of the host rule. */ |
/* Attach its location and actions to that of the DUMMY. */ |
325 |
midrule_action->line = current_rule->line; |
midrule->location = dummy_location; |
326 |
/* Move the action from the host rule to this one. */ |
midrule->action = current_rule->action; |
327 |
midrule_action->action = current_rule->action; |
midrule->action_location = dummy_location; |
|
midrule_action->action_line = current_rule->action_line; |
|
328 |
current_rule->action = NULL; |
current_rule->action = NULL; |
329 |
|
|
330 |
if (previous_rule) |
if (previous_rule_end) |
331 |
previous_rule->next = midrule_action; |
previous_rule_end->next = midrule; |
332 |
else |
else |
333 |
grammar = midrule_action; |
grammar = midrule; |
334 |
|
|
335 |
/* End of the rule. */ |
/* End the dummy's rule. */ |
336 |
previous_rule = symbol_list_new (NULL); |
previous_rule_end = symbol_list_new (NULL, dummy_location); |
337 |
previous_rule->next = current_rule; |
previous_rule_end->next = current_rule; |
338 |
|
|
339 |
midrule_action->next = previous_rule; |
midrule->next = previous_rule_end; |
340 |
|
|
341 |
/* Insert the dummy generated by that rule into this rule. */ |
/* Insert the dummy nonterminal replacing the midrule action into |
342 |
++nritems; |
the current rule. */ |
343 |
grammar_symbol_append (sdummy); |
grammar_current_rule_symbol_append (dummy, dummy_location); |
344 |
} |
} |
345 |
|
|
346 |
/* Set the precedence symbol of the current rule to PRECSYM. */ |
/* Set the precedence symbol of the current rule to PRECSYM. */ |
357 |
action as a mid-rule action. */ |
action as a mid-rule action. */ |
358 |
|
|
359 |
void |
void |
360 |
grammar_current_rule_symbol_append (symbol_t *symbol) |
grammar_current_rule_symbol_append (symbol_t *symbol, location_t location) |
361 |
{ |
{ |
362 |
if (current_rule->action) |
if (current_rule->action) |
363 |
grammar_midrule_action (); |
grammar_midrule_action (); |
364 |
++nritems; |
++nritems; |
365 |
grammar_symbol_append (symbol); |
grammar_symbol_append (symbol, location); |
366 |
} |
} |
367 |
|
|
368 |
|
|
370 |
action as a mid-rule action. */ |
action as a mid-rule action. */ |
371 |
|
|
372 |
void |
void |
373 |
grammar_current_rule_action_append (const char *action, int action_line) |
grammar_current_rule_action_append (const char *action, location_t location) |
374 |
{ |
{ |
375 |
if (current_rule->action) |
if (current_rule->action) |
376 |
grammar_midrule_action (); |
grammar_midrule_action (); |
377 |
current_rule->action = action; |
current_rule->action = action; |
378 |
current_rule->action_line = action_line; |
current_rule->action_location = location; |
379 |
} |
} |
380 |
|
|
381 |
|
|
405 |
rules[ruleno].number = ruleno; |
rules[ruleno].number = ruleno; |
406 |
rules[ruleno].lhs = p->sym; |
rules[ruleno].lhs = p->sym; |
407 |
rules[ruleno].rhs = ritem + itemno; |
rules[ruleno].rhs = ritem + itemno; |
408 |
rules[ruleno].line = p->line; |
rules[ruleno].location = p->location; |
409 |
rules[ruleno].useful = TRUE; |
rules[ruleno].useful = TRUE; |
410 |
rules[ruleno].action = p->action; |
rules[ruleno].action = p->action; |
411 |
rules[ruleno].action_line = p->action_line; |
rules[ruleno].action_location = p->action_location; |
412 |
|
|
413 |
p = p->next; |
p = p->next; |
414 |
while (p && p->sym) |
while (p && p->sym) |
510 |
|
|
511 |
axiom: %start EOF. */ |
axiom: %start EOF. */ |
512 |
{ |
{ |
513 |
symbol_list *p = symbol_list_new (axiom); |
symbol_list *p = symbol_list_new (axiom, empty_location); |
514 |
p->line = grammar->line; |
p->location = grammar->location; |
515 |
p->next = symbol_list_new (startsymbol); |
p->next = symbol_list_new (startsymbol, empty_location); |
516 |
p->next->next = symbol_list_new (eoftoken); |
p->next->next = symbol_list_new (eoftoken, empty_location); |
517 |
p->next->next->next = symbol_list_new (NULL); |
p->next->next->next = symbol_list_new (NULL, empty_location); |
518 |
p->next->next->next->next = grammar; |
p->next->next->next->next = grammar; |
519 |
nrules += 1; |
nrules += 1; |
520 |
nritems += 3; |
nritems += 3; |