From 88261f69ba4f4cd0da3bd6aed8330b153ed2edd6 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Sat, 11 May 2013 19:26:22 +0200 Subject: [PATCH] derp, forgot to save original nonterminal in stack frame --- src/backends/llk.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/backends/llk.c b/src/backends/llk.c index 37ee8c38..60587d29 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -177,6 +177,9 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* // derivations are produced this linearization is unique. // the 'mark' allocated below simply reserves a memory address to use as the // frame delimiter. + // nonterminals, instead of being popped and forgotten, are put back onto the + // stack below the mark to tell us which validations and semantic actions to + // execute on their corresponding result. // also on the stack below the mark, we store the previously accumulated // value for the surrounding production. void *mark = h_arena_malloc(tarena, 1); @@ -200,8 +203,7 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* // pop top of stack and check for frame delimiter HCFChoice *x = h_slist_pop(stack); assert(x != NULL); - if(x == mark) - { + if(x == mark) { // hit stack frame boundary // wrap the accumulated parse result, this sequence is finished @@ -210,22 +212,25 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* tok->seq = seq; // XXX tok->index and tok->bit_offset (don't take directly from stream, cuz peek!) + // recover original nonterminal and result sequence + x = h_slist_pop(stack); + seq = h_slist_pop(stack); + // tok becomes next left-most element of higher-level sequence + // call validation and semantic action, if present if(x->pred && !x->pred(make_result(tarena, tok))) goto no_parse; // validation failed -> no parse if(x->action) tok = (HParsedToken *)x->action(make_result(arena, tok)); - // result becomes next left-most element of higher-level sequence - seq = h_slist_pop(stack); h_carray_append(seq, tok); } - else if(x->type == HCF_CHOICE) - { + else if(x->type == HCF_CHOICE) { // x is a nonterminal; apply the appropriate production // push stack frame h_slist_push(stack, seq); // save current partial value + h_slist_push(stack, x); // save the nonterminal h_slist_push(stack, mark); // frame delimiter // open a fresh result sequence @@ -240,8 +245,7 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* for(s--; s >= p->items; s--) h_slist_push(stack, *s); } - else - { + else { // x is a terminal, or simple charset; match against input // consume the input token -- GitLab