1089 |
grammar_end = p; |
grammar_end = p; |
1090 |
} |
} |
1091 |
|
|
1092 |
|
/* The rule currently being defined, and the previous rule. Point to |
1093 |
|
the first symbol of each list: their lhs. */ |
1094 |
|
symbol_list *current_rule = NULL; |
1095 |
|
symbol_list *previous_rule = NULL; |
1096 |
|
|
1097 |
|
|
1098 |
|
/* Create a new rule for LHS in to the GRAMMAR. */ |
1099 |
|
|
1100 |
|
static void |
1101 |
|
grammar_rule_begin (symbol_t *lhs) |
1102 |
|
{ |
1103 |
|
if (!start_flag) |
1104 |
|
{ |
1105 |
|
startsymbol = lhs; |
1106 |
|
start_flag = 1; |
1107 |
|
} |
1108 |
|
|
1109 |
|
/* Start a new rule and record its lhs. */ |
1110 |
|
++nrules; |
1111 |
|
++nritems; |
1112 |
|
|
1113 |
|
previous_rule = grammar_end; |
1114 |
|
grammar_symbol_append (lhs); |
1115 |
|
current_rule = grammar_end; |
1116 |
|
|
1117 |
|
/* Mark the rule's lhs as a nonterminal if not already so. */ |
1118 |
|
|
1119 |
|
if (lhs->class == unknown_sym) |
1120 |
|
{ |
1121 |
|
lhs->class = nterm_sym; |
1122 |
|
lhs->number = nvars; |
1123 |
|
++nvars; |
1124 |
|
} |
1125 |
|
else if (lhs->class == token_sym) |
1126 |
|
complain (_("rule given for %s, which is a token"), lhs->tag); |
1127 |
|
} |
1128 |
|
|
1129 |
static void |
static void |
1130 |
readgram (void) |
readgram (void) |
1131 |
{ |
{ |
1132 |
token_t t; |
token_t t; |
1133 |
symbol_t *lhs = NULL; |
symbol_t *lhs = NULL; |
1134 |
|
|
|
/* Points to first symbol_list of current rule. its symbol is the |
|
|
lhs of the rule. */ |
|
|
symbol_list *crule = NULL; |
|
|
/* Points to the symbol_list preceding crule. */ |
|
|
symbol_list *crule1 = NULL; |
|
|
|
|
1135 |
t = lex (); |
t = lex (); |
1136 |
|
|
1137 |
while (t != tok_two_percents && t != tok_eof) |
while (t != tok_two_percents && t != tok_eof) |
1147 |
{ |
{ |
1148 |
lhs = symval; |
lhs = symval; |
1149 |
|
|
|
if (!start_flag) |
|
|
{ |
|
|
startsymbol = lhs; |
|
|
start_flag = 1; |
|
|
} |
|
|
|
|
1150 |
t = lex (); |
t = lex (); |
1151 |
if (t != tok_colon) |
if (t != tok_colon) |
1152 |
{ |
{ |
1154 |
unlex (t); |
unlex (t); |
1155 |
} |
} |
1156 |
} |
} |
|
|
|
1157 |
if (nrules == 0 && t == tok_bar) |
if (nrules == 0 && t == tok_bar) |
1158 |
{ |
{ |
1159 |
complain (_("grammar starts with vertical bar")); |
complain (_("grammar starts with vertical bar")); |
1160 |
lhs = symval; /* BOGUS: use a random symval */ |
lhs = symval; /* BOGUS: use a random symval */ |
1161 |
} |
} |
|
/* start a new rule and record its lhs. */ |
|
|
|
|
|
++nrules; |
|
|
++nritems; |
|
|
|
|
|
crule1 = grammar_end; |
|
|
grammar_symbol_append (lhs); |
|
|
crule = grammar_end; |
|
|
|
|
|
/* mark the rule's lhs as a nonterminal if not already so. */ |
|
|
|
|
|
if (lhs->class == unknown_sym) |
|
|
{ |
|
|
lhs->class = nterm_sym; |
|
|
lhs->number = nvars; |
|
|
++nvars; |
|
|
} |
|
|
else if (lhs->class == token_sym) |
|
|
complain (_("rule given for %s, which is a token"), lhs->tag); |
|
1162 |
|
|
1163 |
|
grammar_rule_begin (lhs); |
1164 |
/* read the rhs of the rule. */ |
/* read the rhs of the rule. */ |
1165 |
|
|
1166 |
for (;;) |
for (;;) |
1169 |
if (t == tok_prec) |
if (t == tok_prec) |
1170 |
{ |
{ |
1171 |
t = lex (); |
t = lex (); |
1172 |
crule->ruleprec = symval; |
current_rule->ruleprec = symval; |
1173 |
t = lex (); |
t = lex (); |
1174 |
} |
} |
1175 |
|
|
1218 |
++nrules; |
++nrules; |
1219 |
++nritems; |
++nritems; |
1220 |
/* Attach its lineno to that of the host rule. */ |
/* Attach its lineno to that of the host rule. */ |
1221 |
p->line = crule->line; |
p->line = current_rule->line; |
1222 |
/* Move the action from the host rule to this one. */ |
/* Move the action from the host rule to this one. */ |
1223 |
p->action = crule->action; |
p->action = current_rule->action; |
1224 |
p->action_line = crule->action_line; |
p->action_line = current_rule->action_line; |
1225 |
crule->action = NULL; |
current_rule->action = NULL; |
1226 |
|
|
1227 |
if (crule1) |
if (previous_rule) |
1228 |
crule1->next = p; |
previous_rule->next = p; |
1229 |
else |
else |
1230 |
grammar = p; |
grammar = p; |
1231 |
/* End of the rule. */ |
/* End of the rule. */ |
1232 |
crule1 = symbol_list_new (NULL); |
previous_rule = symbol_list_new (NULL); |
1233 |
crule1->next = crule; |
previous_rule->next = current_rule; |
1234 |
|
|
1235 |
p->next = crule1; |
p->next = previous_rule; |
1236 |
|
|
1237 |
/* Insert the dummy generated by that rule into this |
/* Insert the dummy generated by that rule into this |
1238 |
rule. */ |
rule. */ |
1248 |
} |
} |
1249 |
else /* handle an action. */ |
else /* handle an action. */ |
1250 |
{ |
{ |
1251 |
parse_action (crule, rulelength); |
parse_action (current_rule, rulelength); |
1252 |
action_flag = 1; |
action_flag = 1; |
1253 |
++xactions; /* JF */ |
++xactions; /* JF */ |
1254 |
} |
} |
1262 |
{ |
{ |
1263 |
complain (_("two @prec's in a row")); |
complain (_("two @prec's in a row")); |
1264 |
t = lex (); |
t = lex (); |
1265 |
crule->ruleprec = symval; |
current_rule->ruleprec = symval; |
1266 |
t = lex (); |
t = lex (); |
1267 |
} |
} |
1268 |
|
|
1271 |
/* This case never occurs -wjh */ |
/* This case never occurs -wjh */ |
1272 |
if (action_flag) |
if (action_flag) |
1273 |
complain (_("two actions at end of one rule")); |
complain (_("two actions at end of one rule")); |
1274 |
parse_action (crule, rulelength); |
parse_action (current_rule, rulelength); |
1275 |
action_flag = 1; |
action_flag = 1; |
1276 |
++xactions; /* -wjh */ |
++xactions; /* -wjh */ |
1277 |
t = lex (); |
t = lex (); |