A future patch will introduce next sites where we want to
discard the current token.
Rather than calling "token_next" at each site, make it possible
to just set "tk = NULL", and the next token will automatically
be collected when needed.
Signed-off-by: NeilBrown <neilb@suse.de>
FILE *trace, const char *non_term[], int knowns)
{
struct parser p = { 0 };
FILE *trace, const char *non_term[], int knowns)
{
struct parser p = { 0 };
+ struct token *tk = NULL;
int accepted = 0;
void *ret;
int accepted = 0;
void *ret;
- tk = tok_copy(token_next(tokens));
+ struct token *err_tk;
+ if (!tk)
+ tk = tok_copy(token_next(tokens));
p.next.sym = tk->num;
if (trace)
parser_trace(trace, &p, tk, states, non_term, knowns);
if (shift(&p, tk, states)) {
p.next.sym = tk->num;
if (trace)
parser_trace(trace, &p, tk, states, non_term, knowns);
if (shift(&p, tk, states)) {
- tk = tok_copy(token_next(tokens));
continue;
}
if (states[p.next.state].reduce_prod >= 0) {
continue;
}
if (states[p.next.state].reduce_prod >= 0) {
* Then we discard input tokens until
* we find one that is acceptable.
*/
* Then we discard input tokens until
* we find one that is acceptable.
*/
+
+ err_tk = tok_copy(*tk);
- while (shift(&p, tk, states) == 0
+ while (shift(&p, err_tk, states) == 0
&& p.tos > 0)
// discard this state
pop(&p, 1, do_free);
&& p.tos > 0)
// discard this state
pop(&p, 1, do_free);
+ if (p.tos == 0) {
+ free(err_tk);
+ // no state accepted TK_error
+ break;
+ }
while (search(&states[p.next.state], tk->num) < 0 &&
tk->num != TK_eof) {
free(tk);
while (search(&states[p.next.state], tk->num) < 0 &&
tk->num != TK_eof) {
free(tk);