diff options
Diffstat (limited to 'engines/sci/engine/grammar.cpp')
-rw-r--r-- | engines/sci/engine/grammar.cpp | 696 |
1 files changed, 336 insertions, 360 deletions
diff --git a/engines/sci/engine/grammar.cpp b/engines/sci/engine/grammar.cpp index 311679ed87..3050cd800a 100644 --- a/engines/sci/engine/grammar.cpp +++ b/engines/sci/engine/grammar.cpp @@ -37,221 +37,213 @@ #define TOKEN_NON_NT (TOKEN_OPAREN | TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP | TOKEN_STUFFING_WORD) #define TOKEN_TERMINAL (TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP) - int _allocd_rules = 0; +int _allocd_rules = 0; static void -vocab_print_rule(parse_rule_t *rule) -{ - int i; - int wspace = 0; - - if (!rule) { - sciprintf("NULL rule"); - return; - } - - sciprintf("[%03x] -> ", rule->id); - - if (!rule->length) - sciprintf("e"); - - for(i = 0; i < rule->length; i++) { - uint token = rule->data[i]; - - if (token == TOKEN_OPAREN) { - - if (i == rule->first_special) - sciprintf("_"); - - sciprintf("("); - wspace = 0; - } else if (token == TOKEN_CPAREN) { - - if (i == rule->first_special) - sciprintf("_"); - - sciprintf(")"); - wspace = 0; - } else { - if (wspace) - sciprintf(" "); - - if (i == rule->first_special) - sciprintf("_"); - if (token & TOKEN_TERMINAL_CLASS) - sciprintf("C(%04x)", token & 0xffff); - else if (token & TOKEN_TERMINAL_GROUP) - sciprintf("G(%04x)", token & 0xffff); - else if (token & TOKEN_STUFFING_WORD) - sciprintf("%03x", token & 0xffff); - else - sciprintf("[%03x]", token); /* non-terminal */ - wspace = 1; - } - - if (i == rule->first_special) - sciprintf("_"); - } - sciprintf(" [%d specials]", rule->specials_nr); +vocab_print_rule(parse_rule_t *rule) { + int i; + int wspace = 0; + + if (!rule) { + sciprintf("NULL rule"); + return; + } + + sciprintf("[%03x] -> ", rule->id); + + if (!rule->length) + sciprintf("e"); + + for (i = 0; i < rule->length; i++) { + uint token = rule->data[i]; + + if (token == TOKEN_OPAREN) { + + if (i == rule->first_special) + sciprintf("_"); + + sciprintf("("); + wspace = 0; + } else if (token == TOKEN_CPAREN) { + + if (i == rule->first_special) + sciprintf("_"); + + sciprintf(")"); + wspace = 0; + } else { + if (wspace) + sciprintf(" "); + + if (i == rule->first_special) + sciprintf("_"); + if (token & TOKEN_TERMINAL_CLASS) + sciprintf("C(%04x)", token & 0xffff); + else if (token & TOKEN_TERMINAL_GROUP) + sciprintf("G(%04x)", token & 0xffff); + else if (token & TOKEN_STUFFING_WORD) + sciprintf("%03x", token & 0xffff); + else + sciprintf("[%03x]", token); /* non-terminal */ + wspace = 1; + } + + if (i == rule->first_special) + sciprintf("_"); + } + sciprintf(" [%d specials]", rule->specials_nr); } static void -_vfree(parse_rule_t *rule) -{ - free(rule); - --_allocd_rules; - rule = NULL; +_vfree(parse_rule_t *rule) { + free(rule); + --_allocd_rules; + rule = NULL; } static parse_rule_t * -_vdup(parse_rule_t *a) -{ - parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + 4)); +_vdup(parse_rule_t *a) { + parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + 4)); - rule->id = a->id; - rule->length = a->length; - rule->specials_nr = a->specials_nr; - rule->first_special = a->first_special; - ++_allocd_rules; + rule->id = a->id; + rule->length = a->length; + rule->specials_nr = a->specials_nr; + rule->first_special = a->first_special; + ++_allocd_rules; - memcpy(rule->data, a->data, sizeof(int) * a->length); + memcpy(rule->data, a->data, sizeof(int) * a->length); - return rule; + return rule; } static parse_rule_t * -_vinsert(parse_rule_t *turkey, parse_rule_t *stuffing) -{ - int firstnt = turkey->first_special; - parse_rule_t *rule; - - while ((firstnt < turkey->length) - && (turkey->data[firstnt] & TOKEN_NON_NT)) - firstnt++; - - if ((firstnt == turkey->length) - || (turkey->data[firstnt] != stuffing->id)) - return NULL; - - rule = (parse_rule_t*)sci_malloc(sizeof(int) * (turkey->length - 1 + stuffing->length + 4)); - rule->id = turkey->id; - rule->specials_nr = turkey->specials_nr + stuffing->specials_nr - 1; - rule->first_special = firstnt + stuffing->first_special; - rule->length = turkey->length - 1 + stuffing->length; - ++_allocd_rules; - - if (firstnt > 0) - memcpy(rule->data, turkey->data, sizeof(int) * firstnt); - memcpy(&(rule->data[firstnt]), stuffing->data, sizeof(int) * stuffing->length); - if (firstnt < turkey->length - 1) - memcpy(&(rule->data[firstnt + stuffing->length]), &(turkey->data[firstnt + 1]), - sizeof(int) * (turkey->length - firstnt - 1)); - - return rule; +_vinsert(parse_rule_t *turkey, parse_rule_t *stuffing) { + int firstnt = turkey->first_special; + parse_rule_t *rule; + + while ((firstnt < turkey->length) + && (turkey->data[firstnt] & TOKEN_NON_NT)) + firstnt++; + + if ((firstnt == turkey->length) + || (turkey->data[firstnt] != stuffing->id)) + return NULL; + + rule = (parse_rule_t*)sci_malloc(sizeof(int) * (turkey->length - 1 + stuffing->length + 4)); + rule->id = turkey->id; + rule->specials_nr = turkey->specials_nr + stuffing->specials_nr - 1; + rule->first_special = firstnt + stuffing->first_special; + rule->length = turkey->length - 1 + stuffing->length; + ++_allocd_rules; + + if (firstnt > 0) + memcpy(rule->data, turkey->data, sizeof(int) * firstnt); + memcpy(&(rule->data[firstnt]), stuffing->data, sizeof(int) * stuffing->length); + if (firstnt < turkey->length - 1) + memcpy(&(rule->data[firstnt + stuffing->length]), &(turkey->data[firstnt + 1]), + sizeof(int) * (turkey->length - firstnt - 1)); + + return rule; } static parse_rule_t * -_vbuild_rule(parse_tree_branch_t *branch) -{ - parse_rule_t *rule; - int tokens = 0, tokenpos = 0, i; - - while (tokenpos < 10 && branch->data[tokenpos]) { - int type = branch->data[tokenpos]; - tokenpos += 2; - - if ((type == VOCAB_TREE_NODE_COMPARE_TYPE) - || (type == VOCAB_TREE_NODE_COMPARE_GROUP) - || (type == VOCAB_TREE_NODE_FORCE_STORAGE)) - ++tokens; - else if (type > VOCAB_TREE_NODE_LAST_WORD_STORAGE) - tokens += 5; - else return NULL; /* invalid */ - } - - rule = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + tokens)); - - ++_allocd_rules; - rule->id = branch->id; - rule->specials_nr = tokenpos >> 1; - rule->length = tokens; - rule->first_special = 0; - - tokens = 0; - for (i = 0; i < tokenpos; i += 2) { - int type = branch->data[i]; - int value = branch->data[i + 1]; - - if (type == VOCAB_TREE_NODE_COMPARE_TYPE) - rule->data[tokens++] = value | TOKEN_TERMINAL_CLASS; - else if (type == VOCAB_TREE_NODE_COMPARE_GROUP) - rule->data[tokens++] = value | TOKEN_TERMINAL_GROUP; - else if (type == VOCAB_TREE_NODE_FORCE_STORAGE) - rule->data[tokens++] = value | TOKEN_STUFFING_WORD; - else { /* normal inductive rule */ - rule->data[tokens++] = TOKEN_OPAREN; - rule->data[tokens++] = type | TOKEN_STUFFING_WORD; - rule->data[tokens++] = value | TOKEN_STUFFING_WORD; - - if (i == 0) - rule->first_special = tokens; - - rule->data[tokens++] = value; /* The non-terminal */ - rule->data[tokens++] = TOKEN_CPAREN; - } - } - - return rule; +_vbuild_rule(parse_tree_branch_t *branch) { + parse_rule_t *rule; + int tokens = 0, tokenpos = 0, i; + + while (tokenpos < 10 && branch->data[tokenpos]) { + int type = branch->data[tokenpos]; + tokenpos += 2; + + if ((type == VOCAB_TREE_NODE_COMPARE_TYPE) + || (type == VOCAB_TREE_NODE_COMPARE_GROUP) + || (type == VOCAB_TREE_NODE_FORCE_STORAGE)) + ++tokens; + else if (type > VOCAB_TREE_NODE_LAST_WORD_STORAGE) + tokens += 5; + else return NULL; /* invalid */ + } + + rule = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + tokens)); + + ++_allocd_rules; + rule->id = branch->id; + rule->specials_nr = tokenpos >> 1; + rule->length = tokens; + rule->first_special = 0; + + tokens = 0; + for (i = 0; i < tokenpos; i += 2) { + int type = branch->data[i]; + int value = branch->data[i + 1]; + + if (type == VOCAB_TREE_NODE_COMPARE_TYPE) + rule->data[tokens++] = value | TOKEN_TERMINAL_CLASS; + else if (type == VOCAB_TREE_NODE_COMPARE_GROUP) + rule->data[tokens++] = value | TOKEN_TERMINAL_GROUP; + else if (type == VOCAB_TREE_NODE_FORCE_STORAGE) + rule->data[tokens++] = value | TOKEN_STUFFING_WORD; + else { /* normal inductive rule */ + rule->data[tokens++] = TOKEN_OPAREN; + rule->data[tokens++] = type | TOKEN_STUFFING_WORD; + rule->data[tokens++] = value | TOKEN_STUFFING_WORD; + + if (i == 0) + rule->first_special = tokens; + + rule->data[tokens++] = value; /* The non-terminal */ + rule->data[tokens++] = TOKEN_CPAREN; + } + } + + return rule; } static parse_rule_t * -_vsatisfy_rule(parse_rule_t *rule, result_word_t *input) -{ - int dep; - - if (!rule->specials_nr) - return NULL; - - dep = rule->data[rule->first_special]; - - if (((dep & TOKEN_TERMINAL_CLASS) - && ((dep & 0xffff) & input->w_class)) - || - ((dep & TOKEN_TERMINAL_GROUP) - && ((dep & 0xffff) & input->group))) { - parse_rule_t *retval = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + rule->length)); - ++_allocd_rules; - retval->id = rule->id; - retval->specials_nr = rule->specials_nr - 1; - retval->length = rule->length; - memcpy(retval->data, rule->data, sizeof(int) * retval->length); - retval->data[rule->first_special] = TOKEN_STUFFING_WORD | input->group; - retval->first_special = 0; - - if (retval->specials_nr) { /* find first special, if it exists */ - int tmp, i = rule->first_special; - - while ((i < rule->length) - && ((tmp = retval->data[i]) & TOKEN_NON_NT) - && !(tmp & TOKEN_TERMINAL)) - ++i; - - if (i < rule->length) - retval->first_special = i; - } - - return retval; - } - else return NULL; +_vsatisfy_rule(parse_rule_t *rule, result_word_t *input) { + int dep; + + if (!rule->specials_nr) + return NULL; + + dep = rule->data[rule->first_special]; + + if (((dep & TOKEN_TERMINAL_CLASS) + && ((dep & 0xffff) & input->w_class)) + || + ((dep & TOKEN_TERMINAL_GROUP) + && ((dep & 0xffff) & input->group))) { + parse_rule_t *retval = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + rule->length)); + ++_allocd_rules; + retval->id = rule->id; + retval->specials_nr = rule->specials_nr - 1; + retval->length = rule->length; + memcpy(retval->data, rule->data, sizeof(int) * retval->length); + retval->data[rule->first_special] = TOKEN_STUFFING_WORD | input->group; + retval->first_special = 0; + + if (retval->specials_nr) { /* find first special, if it exists */ + int tmp, i = rule->first_special; + + while ((i < rule->length) + && ((tmp = retval->data[i]) & TOKEN_NON_NT) + && !(tmp & TOKEN_TERMINAL)) + ++i; + + if (i < rule->length) + retval->first_special = i; + } + + return retval; + } else return NULL; } /************** Rule lists **************/ void -vocab_free_rule_list(parse_rule_list_t *list) -{ +vocab_free_rule_list(parse_rule_list_t *list) { if (list) { _vfree(list->rule); vocab_free_rule_list(list->next); /* Yep, this is slow and memory-intensive. */ @@ -260,19 +252,17 @@ vocab_free_rule_list(parse_rule_list_t *list) } static inline int -_rules_equal_p(parse_rule_t *r1, parse_rule_t *r2) -{ +_rules_equal_p(parse_rule_t *r1, parse_rule_t *r2) { if ((r1->id != r2->id) - || (r1->length != r2->length) - || (r1->first_special != r2->first_special)) + || (r1->length != r2->length) + || (r1->first_special != r2->first_special)) return 0; return !(memcmp(r1->data, r2->data, sizeof(int) * r1->length)); } static parse_rule_list_t * -_vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule) -{ +_vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule) { parse_rule_list_t *new_elem; int term; @@ -284,7 +274,7 @@ _vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule) new_elem->rule = rule; new_elem->next = NULL; - new_elem->terminal = term = ((term & TOKEN_TERMINAL)? term : 0); + new_elem->terminal = term = ((term & TOKEN_TERMINAL) ? term : 0); if (!list) return new_elem; @@ -311,39 +301,34 @@ _vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule) } static void -_vprl(parse_rule_list_t *list, int pos) -{ +_vprl(parse_rule_list_t *list, int pos) { if (list) { sciprintf("R%03d: ", pos); vocab_print_rule(list->rule); sciprintf("\n"); - _vprl(list->next, pos+1); + _vprl(list->next, pos + 1); } else { sciprintf("%d rules total.\n", pos); } } void -vocab_print_rule_list(parse_rule_list_t *list) -{ +vocab_print_rule_list(parse_rule_list_t *list) { _vprl(list, 0); } static parse_rule_list_t * -_vocab_split_rule_list(parse_rule_list_t *list) -{ +_vocab_split_rule_list(parse_rule_list_t *list) { if (!list->next - || (list->next->terminal)) { + || (list->next->terminal)) { parse_rule_list_t *tmp = list->next; list->next = NULL; return tmp; - } - else return _vocab_split_rule_list(list->next); + } else return _vocab_split_rule_list(list->next); } static void -_vocab_free_empty_rule_list(parse_rule_list_t *list) -{ +_vocab_free_empty_rule_list(parse_rule_list_t *list) { if (list->next) _vocab_free_empty_rule_list(list->next); @@ -351,8 +336,7 @@ _vocab_free_empty_rule_list(parse_rule_list_t *list) } static parse_rule_list_t * -_vocab_merge_rule_lists(parse_rule_list_t *l1, parse_rule_list_t *l2) -{ +_vocab_merge_rule_lists(parse_rule_list_t *l1, parse_rule_list_t *l2) { parse_rule_list_t *retval = l1, *seeker = l2; while (seeker) { retval = _vocab_add_rule(retval, seeker->rule); @@ -364,15 +348,13 @@ _vocab_merge_rule_lists(parse_rule_list_t *l1, parse_rule_list_t *l2) } static int -_vocab_rule_list_length(parse_rule_list_t *list) -{ - return ((list)? _vocab_rule_list_length(list->next) + 1 : 0); +_vocab_rule_list_length(parse_rule_list_t *list) { + return ((list) ? _vocab_rule_list_length(list->next) + 1 : 0); } static parse_rule_list_t * -_vocab_clone_rule_list_by_id(parse_rule_list_t *list, int id) -{ +_vocab_clone_rule_list_by_id(parse_rule_list_t *list, int id) { parse_rule_list_t *result = NULL; parse_rule_list_t *seeker = list; @@ -388,8 +370,7 @@ _vocab_clone_rule_list_by_id(parse_rule_list_t *list, int id) parse_rule_list_t * -_vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose) -{ +_vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose) { int i; int iterations = 0; int last_termrules, termrules = 0; @@ -453,27 +434,24 @@ _vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose) } parse_rule_list_t * -vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr) -{ - return _vocab_build_gnf(branches, branches_nr, 0); +vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr) { + return _vocab_build_gnf(branches, branches_nr, 0); } void -vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr) -{ - parse_rule_list_t *tlist = _vocab_build_gnf(branches, branches_nr, 1); +vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr) { + parse_rule_list_t *tlist = _vocab_build_gnf(branches, branches_nr, 1); - sciprintf("%d allocd rules\n", _allocd_rules); - vocab_free_rule_list(tlist); + sciprintf("%d allocd rules\n", _allocd_rules); + vocab_free_rule_list(tlist); } int vocab_build_parse_tree(parse_tree_node_t *nodes, result_word_t *words, int words_nr, - parse_tree_branch_t *branch0, parse_rule_list_t *rules) -{ - return vocab_gnf_parse(nodes, words, words_nr, branch0, rules, 0); + parse_tree_branch_t *branch0, parse_rule_list_t *rules) { + return vocab_gnf_parse(nodes, words, words_nr, branch0, rules, 0); } @@ -481,11 +459,11 @@ static int _vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base) /* Opens parentheses */ { - nodes[base].content.branches[0] = (*pos)+1; - nodes[++(*pos)].type = PARSE_TREE_NODE_BRANCH; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; - return *pos; + nodes[base].content.branches[0] = (*pos) + 1; + nodes[++(*pos)].type = PARSE_TREE_NODE_BRANCH; + nodes[*pos].content.branches[0] = 0; + nodes[*pos].content.branches[1] = 0; + return *pos; } @@ -493,11 +471,11 @@ static int _vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren) /* Closes parentheses for appending */ { - nodes[paren].content.branches[1] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_BRANCH; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; - return *pos; + nodes[paren].content.branches[1] = ++(*pos); + nodes[*pos].type = PARSE_TREE_NODE_BRANCH; + nodes[*pos].content.branches[0] = 0; + nodes[*pos].content.branches[1] = 0; + return *pos; } @@ -505,154 +483,152 @@ static int _vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value) /* writes one value to an existing base node and creates a successor node for writing */ { - nodes[base].content.branches[0] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_LEAF; - nodes[*pos].content.value = value; - nodes[base].content.branches[1] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_BRANCH; - nodes[*pos].content.branches[0] = 0; - nodes[*pos].content.branches[1] = 0; - return *pos; + nodes[base].content.branches[0] = ++(*pos); + nodes[*pos].type = PARSE_TREE_NODE_LEAF; + nodes[*pos].content.value = value; + nodes[base].content.branches[1] = ++(*pos); + nodes[*pos].type = PARSE_TREE_NODE_BRANCH; + nodes[*pos].content.branches[0] = 0; + nodes[*pos].content.branches[1] = 0; + return *pos; } static int _vbpt_terminate(parse_tree_node_t *nodes, int *pos, int base, int value) - /* Terminates, overwriting a nextwrite forknode */ +/* Terminates, overwriting a nextwrite forknode */ { - nodes[base].type = PARSE_TREE_NODE_LEAF; - nodes[base].content.value = value; - return *pos; + nodes[base].type = PARSE_TREE_NODE_LEAF; + nodes[base].content.value = value; + return *pos; } static int _vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos, - parse_rule_t *rule, int rulepos, int writepos) -{ - uint token; - while ((token = ((rulepos < rule->length)? rule->data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) { - uint nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN; - if (token == TOKEN_OPAREN) { - int wpold; - int writepos2 = _vbpt_pareno(nodes, pos, wpold = writepos); - rulepos = _vbpt_write_subexpression(nodes, pos, rule, rulepos, writepos2); - nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN; - if (nexttoken != TOKEN_CPAREN) - writepos = _vbpt_parenc(nodes, pos, wpold); - } else if (token & TOKEN_STUFFING_WORD) { - if (nexttoken == TOKEN_CPAREN) - writepos = _vbpt_terminate(nodes, pos, writepos, token & 0xffff); - else - writepos = _vbpt_append(nodes, pos, writepos, token & 0xffff); - } else { - sciprintf("\nError in parser (grammar.c, _vbpt_write_subexpression()): Rule data broken in rule "); - vocab_print_rule(rule); - sciprintf(", at token position %d\n", *pos); - return rulepos; - } - } - - return rulepos; + parse_rule_t *rule, int rulepos, int writepos) { + uint token; + while ((token = ((rulepos < rule->length) ? rule->data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) { + uint nexttoken = (rulepos < rule->length) ? rule->data[rulepos] : TOKEN_CPAREN; + if (token == TOKEN_OPAREN) { + int wpold; + int writepos2 = _vbpt_pareno(nodes, pos, wpold = writepos); + rulepos = _vbpt_write_subexpression(nodes, pos, rule, rulepos, writepos2); + nexttoken = (rulepos < rule->length) ? rule->data[rulepos] : TOKEN_CPAREN; + if (nexttoken != TOKEN_CPAREN) + writepos = _vbpt_parenc(nodes, pos, wpold); + } else if (token & TOKEN_STUFFING_WORD) { + if (nexttoken == TOKEN_CPAREN) + writepos = _vbpt_terminate(nodes, pos, writepos, token & 0xffff); + else + writepos = _vbpt_append(nodes, pos, writepos, token & 0xffff); + } else { + sciprintf("\nError in parser (grammar.c, _vbpt_write_subexpression()): Rule data broken in rule "); + vocab_print_rule(rule); + sciprintf(", at token position %d\n", *pos); + return rulepos; + } + } + + return rulepos; } int vocab_gnf_parse(parse_tree_node_t *nodes, result_word_t *words, int words_nr, - parse_tree_branch_t *branch0, parse_rule_list_t *tlist, int verbose) -{ - /* Get the start rules: */ - parse_rule_list_t *work = _vocab_clone_rule_list_by_id(tlist, branch0->data[1]); - parse_rule_list_t *results = NULL; - int word; + parse_tree_branch_t *branch0, parse_rule_list_t *tlist, int verbose) { + /* Get the start rules: */ + parse_rule_list_t *work = _vocab_clone_rule_list_by_id(tlist, branch0->data[1]); + parse_rule_list_t *results = NULL; + int word; - for (word = 0; word < words_nr; word++) { - parse_rule_list_t *new_work = NULL; - parse_rule_list_t *reduced_rules = NULL; - parse_rule_list_t *seeker, *subseeker; + for (word = 0; word < words_nr; word++) { + parse_rule_list_t *new_work = NULL; + parse_rule_list_t *reduced_rules = NULL; + parse_rule_list_t *seeker, *subseeker; - if (verbose) - sciprintf("Adding word %d...\n", word); + if (verbose) + sciprintf("Adding word %d...\n", word); - seeker = work; - while (seeker) { + seeker = work; + while (seeker) { - if (seeker->rule->specials_nr <= (words_nr - word)) - reduced_rules = _vocab_add_rule(reduced_rules, _vsatisfy_rule(seeker->rule, words + word)); + if (seeker->rule->specials_nr <= (words_nr - word)) + reduced_rules = _vocab_add_rule(reduced_rules, _vsatisfy_rule(seeker->rule, words + word)); - seeker = seeker->next; - } + seeker = seeker->next; + } + + if (reduced_rules == NULL) { + vocab_free_rule_list(work); + if (verbose) + sciprintf("No results.\n"); + return 1; + } + + vocab_free_rule_list(work); + + if (word + 1 < words_nr) { + seeker = reduced_rules; + + while (seeker) { + if (seeker->rule->specials_nr) { + int my_id = seeker->rule->data[seeker->rule->first_special]; + + subseeker = tlist; + while (subseeker) { + if (subseeker->rule->id == my_id) + new_work = _vocab_add_rule(new_work, _vinsert(seeker->rule, subseeker->rule)); + + subseeker = subseeker->next; + } + } + + seeker = seeker->next; + } + vocab_free_rule_list(reduced_rules); + } else /* last word */ + new_work = reduced_rules; + + work = new_work; + if (verbose) + sciprintf("Now at %d candidates\n", _vocab_rule_list_length(work)); + if (work == NULL) { + if (verbose) + sciprintf("No results.\n"); + return 1; + } + } + + results = work; + + if (verbose) { + sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", + branch0->id); + vocab_print_rule_list(results); + sciprintf("\n"); + } - if (reduced_rules == NULL) { - vocab_free_rule_list(work); - if (verbose) - sciprintf("No results.\n"); - return 1; - } + /* now use the first result */ + { + int temp, pos; - vocab_free_rule_list(work); + nodes[0].type = PARSE_TREE_NODE_BRANCH; + nodes[0].content.branches[0] = 1; + nodes[0].content.branches[1] = 2; - if (word +1 < words_nr) { - seeker = reduced_rules; + nodes[1].type = PARSE_TREE_NODE_LEAF; + nodes[1].content.value = 0x141; - while (seeker) { - if (seeker->rule->specials_nr) { - int my_id = seeker->rule->data[seeker->rule->first_special]; + nodes[2].type = PARSE_TREE_NODE_BRANCH; + nodes[2].content.branches[0] = 0; + nodes[2].content.branches[1] = 0; - subseeker = tlist; - while (subseeker) { - if (subseeker->rule->id == my_id) - new_work = _vocab_add_rule(new_work, _vinsert(seeker->rule, subseeker->rule)); + pos = 2; - subseeker = subseeker->next; - } + temp = _vbpt_append(nodes, &pos, 2, branch0->id); + /* _vbpt_write_subexpression(nodes, &pos, results[_vocab_rule_list_length(results)].rule, 0, temp); */ + _vbpt_write_subexpression(nodes, &pos, results->rule, 0, temp); } - seeker = seeker->next; - } - vocab_free_rule_list(reduced_rules); - } else /* last word */ - new_work = reduced_rules; - - work = new_work; - if (verbose) - sciprintf("Now at %d candidates\n", _vocab_rule_list_length(work)); - if (work == NULL) { - if (verbose) - sciprintf("No results.\n"); - return 1; - } - } - - results = work; - - if (verbose) { - sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", - branch0->id); - vocab_print_rule_list(results); - sciprintf("\n"); - } - - /* now use the first result */ - { - int temp, pos; - - nodes[0].type = PARSE_TREE_NODE_BRANCH; - nodes[0].content.branches[0] = 1; - nodes[0].content.branches[1] = 2; - - nodes[1].type = PARSE_TREE_NODE_LEAF; - nodes[1].content.value = 0x141; - - nodes[2].type = PARSE_TREE_NODE_BRANCH; - nodes[2].content.branches[0] = 0; - nodes[2].content.branches[1] = 0; - - pos = 2; - - temp = _vbpt_append(nodes, &pos, 2, branch0->id); - /* _vbpt_write_subexpression(nodes, &pos, results[_vocab_rule_list_length(results)].rule, 0, temp); */ - _vbpt_write_subexpression(nodes, &pos, results->rule, 0, temp); - } - - vocab_free_rule_list(results); - return 0; + vocab_free_rule_list(results); + return 0; } |