eliminate duplication of result handling code in LL driver
This commit is contained in:
parent
88261f69ba
commit
ccdb0fa85c
1 changed files with 34 additions and 37 deletions
|
|
@ -200,33 +200,12 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
lookahead = char_token(c);
|
lookahead = char_token(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop top of stack and check for frame delimiter
|
// pop top of stack for inspection
|
||||||
HCFChoice *x = h_slist_pop(stack);
|
HCFChoice *x = h_slist_pop(stack);
|
||||||
assert(x != NULL);
|
assert(x != NULL);
|
||||||
if(x == mark) {
|
|
||||||
// hit stack frame boundary
|
|
||||||
|
|
||||||
// wrap the accumulated parse result, this sequence is finished
|
if(x != mark && x->type == HCF_CHOICE) {
|
||||||
HParsedToken *tok = h_arena_malloc(arena, sizeof(HParsedToken));
|
// x is a nonterminal; apply the appropriate production and continue
|
||||||
tok->token_type = TT_SEQUENCE;
|
|
||||||
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));
|
|
||||||
|
|
||||||
h_carray_append(seq, tok);
|
|
||||||
}
|
|
||||||
else if(x->type == HCF_CHOICE) {
|
|
||||||
// x is a nonterminal; apply the appropriate production
|
|
||||||
|
|
||||||
// push stack frame
|
// push stack frame
|
||||||
h_slist_push(stack, seq); // save current partial value
|
h_slist_push(stack, seq); // save current partial value
|
||||||
|
|
@ -244,15 +223,31 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
for(s = p->items; *s; s++);
|
for(s = p->items; *s; s++);
|
||||||
for(s--; s >= p->items; s--)
|
for(s--; s >= p->items; s--)
|
||||||
h_slist_push(stack, *s);
|
h_slist_push(stack, *s);
|
||||||
|
|
||||||
|
continue; // no result to record
|
||||||
|
}
|
||||||
|
|
||||||
|
// the top of stack is such that there will be a result...
|
||||||
|
HParsedToken *tok; // will hold result token
|
||||||
|
if(x == mark) {
|
||||||
|
// hit stack frame boundary...
|
||||||
|
// wrap the accumulated parse result, this sequence is finished
|
||||||
|
tok = h_arena_malloc(arena, sizeof(HParsedToken));
|
||||||
|
tok->token_type = TT_SEQUENCE;
|
||||||
|
tok->seq = seq;
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// x is a terminal, or simple charset; match against input
|
// x is a terminal or simple charset; match against input
|
||||||
|
|
||||||
// consume the input token
|
// consume the input token
|
||||||
HCFToken input = lookahead;
|
HCFToken input = lookahead;
|
||||||
lookahead = 0;
|
lookahead = 0;
|
||||||
|
|
||||||
HParsedToken *tok;
|
|
||||||
switch(x->type) {
|
switch(x->type) {
|
||||||
case HCF_END:
|
case HCF_END:
|
||||||
if(input != end_token)
|
if(input != end_token)
|
||||||
|
|
@ -282,18 +277,20 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
assert_message(0, "unknown HCFChoice type");
|
assert_message(0, "unknown HCFChoice type");
|
||||||
goto no_parse;
|
goto no_parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX tok->index and tok->bit_offset (don't take directly from stream, cuz peek!)
|
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
// append to result sequence
|
|
||||||
h_carray_append(seq, tok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 'tok' has been parsed; process it
|
||||||
|
|
||||||
|
// XXX set tok->index and tok->bit_offset (don't take directly from stream, cuz peek!)
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// append to result sequence
|
||||||
|
h_carray_append(seq, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
// since we started with a single nonterminal on the stack, seq should
|
// since we started with a single nonterminal on the stack, seq should
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue