From 486f10edaf813e19ce55812f7ab75e0b6d349fb6 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 24 Apr 2009 10:42:53 +0000 Subject: SCI: Store parse_tree_branch_t in a Common::Arraay svn-id: r40100 --- engines/sci/engine/game.cpp | 6 +++--- engines/sci/engine/grammar.cpp | 27 +++++++++++++-------------- engines/sci/engine/kstring.cpp | 2 +- engines/sci/engine/savegame.cpp | 3 +-- engines/sci/engine/scriptdebug.cpp | 24 +++++++++++------------- engines/sci/engine/state.cpp | 2 -- engines/sci/engine/state.h | 3 +-- engines/sci/scicore/vocabulary.cpp | 38 ++++++++++++++++---------------------- engines/sci/scicore/vocabulary.h | 30 +++++++++++------------------- 9 files changed, 57 insertions(+), 78 deletions(-) (limited to 'engines') diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index a955b0058b..b19db3475f 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -45,9 +45,9 @@ static int _init_vocabulary(EngineState *s) { // initialize vocabulary and relat if ((s->resmgr->_sciVersion < SCI_VERSION_01_VGA) && vocab_get_words(s->resmgr, s->_parserWords)) { vocab_get_suffixes(s->resmgr, s->_parserSuffixes); - if ((s->parser_branches = vocab_get_branches(s->resmgr, &(s->parser_branches_nr)))) + if (vocab_get_branches(s->resmgr, s->_parserBranches)) // Now build a GNF grammar out of this - s->parser_rules = vocab_build_gnf(s->parser_branches, s->parser_branches_nr); + s->parser_rules = vocab_build_gnf(s->_parserBranches); } else { sciprintf("Assuming that this game does not use a parser.\n"); s->parser_rules = NULL; @@ -530,7 +530,7 @@ void script_free_engine(EngineState *s) { s->_parserWords.clear(); vocab_free_suffixes(s->resmgr, s->_parserSuffixes); - vocab_free_branches(s->parser_branches); + s->_parserBranches.clear(); vocab_free_rule_list(s->parser_rules); s->_selectorNames.clear(); diff --git a/engines/sci/engine/grammar.cpp b/engines/sci/engine/grammar.cpp index 1d4e800765..0d07169449 100644 --- a/engines/sci/engine/grammar.cpp +++ b/engines/sci/engine/grammar.cpp @@ -144,7 +144,7 @@ static parse_rule_t *_vinsert(parse_rule_t *turkey, parse_rule_t *stuffing) { return rule; } -static parse_rule_t *_vbuild_rule(parse_tree_branch_t *branch) { +static parse_rule_t *_vbuild_rule(const parse_tree_branch_t *branch) { parse_rule_t *rule; int tokens = 0, tokenpos = 0, i; @@ -344,16 +344,15 @@ static parse_rule_list_t *_vocab_clone_rule_list_by_id(parse_rule_list_t *list, return result; } -parse_rule_list_t *_vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose) { - int i; +parse_rule_list_t *_vocab_build_gnf(const Common::Array &branches, int verbose) { int iterations = 0; int last_termrules, termrules = 0; int ntrules_nr; parse_rule_list_t *ntlist = NULL; parse_rule_list_t *tlist, *new_tlist; - for (i = 1; i < branches_nr; i++) { // branch rule 0 is treated specially - parse_rule_t *rule = _vbuild_rule(branches + i); + for (uint i = 1; i < branches.size(); i++) { // branch rule 0 is treated specially + parse_rule_t *rule = _vbuild_rule(&branches[i]); if (!rule) return NULL; ntlist = _vocab_add_rule(ntlist, rule); @@ -406,19 +405,19 @@ parse_rule_list_t *_vocab_build_gnf(parse_tree_branch_t *branches, int branches_ return tlist; } -parse_rule_list_t *vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr) { - return _vocab_build_gnf(branches, branches_nr, 0); +parse_rule_list_t *vocab_build_gnf(const Common::Array &branches) { + return _vocab_build_gnf(branches, 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); +void vocab_gnf_dump(const Common::Array &branches) { + parse_rule_list_t *tlist = _vocab_build_gnf(branches, 1); sciprintf("%d allocd rules\n", _allocd_rules); vocab_free_rule_list(tlist); } int vocab_build_parse_tree(parse_tree_node_t *nodes, const ResultWordList &words, - parse_tree_branch_t *branch0, parse_rule_list_t *rules) { + const parse_tree_branch_t &branch0, parse_rule_list_t *rules) { return vocab_gnf_parse(nodes, words, branch0, rules, 0); } @@ -489,9 +488,9 @@ static int _vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos, parse_r } int vocab_gnf_parse(parse_tree_node_t *nodes, const ResultWordList &words, - parse_tree_branch_t *branch0, parse_rule_list_t *tlist, int verbose) { + const 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 *work = _vocab_clone_rule_list_by_id(tlist, branch0.data[1]); parse_rule_list_t *results = NULL; int word = 0; const int words_nr = words.size(); @@ -557,7 +556,7 @@ int vocab_gnf_parse(parse_tree_node_t *nodes, const ResultWordList &words, results = work; if (verbose) { - sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", branch0->id); + sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", branch0.id); vocab_print_rule_list(results); sciprintf("\n"); } @@ -579,7 +578,7 @@ int vocab_gnf_parse(parse_tree_node_t *nodes, const ResultWordList &words, pos = 2; - temp = _vbpt_append(nodes, &pos, 2, branch0->id); + 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); } diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 5e98749732..babdb07bd6 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -271,7 +271,7 @@ reg_t kParse(EngineState *s, int funct_nr, int argc, reg_t *argv) { SCIkdebug(SCIkPARSER, " Type[%04x] Group[%04x]\n", i->_class, i->_group); } - if (vocab_build_parse_tree(&(s->parser_nodes[0]), words, s->parser_branches, + if (vocab_build_parse_tree(s->parser_nodes, words, s->_parserBranches[0], s->parser_rules)) syntax_fail = 1; /* Building a tree failed */ diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index e8bd7a2020..e8924eedb4 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -898,8 +898,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->parser_rules = s->parser_rules; retval->_parserWords = s->_parserWords; retval->_parserSuffixes = s->_parserSuffixes; - retval->parser_branches_nr = s->parser_branches_nr; - retval->parser_branches = s->parser_branches; + retval->_parserBranches = s->_parserBranches; // static VM/Kernel information: retval->_selectorNames = s->_selectorNames; diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 41fe16909b..d2760f7315 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -889,39 +889,37 @@ int c_viewinfo(EngineState *s) { } int c_list_sentence_fragments(EngineState *s) { - int i; - if (!s) { sciprintf("Not in debug state\n"); return 1; } - for (i = 0; i < s->parser_branches_nr; i++) { + for (uint i = 0; i < s->_parserBranches.size(); i++) { int j = 0; - sciprintf("R%02d: [%x] ->", i, s->parser_branches[i].id); - while ((j < 10) && s->parser_branches[i].data[j]) { - int dat = s->parser_branches[i].data[j++]; + sciprintf("R%02d: [%x] ->", i, s->_parserBranches[i].id); + while ((j < 10) && s->_parserBranches[i].data[j]) { + int dat = s->_parserBranches[i].data[j++]; switch (dat) { case VOCAB_TREE_NODE_COMPARE_TYPE: - dat = s->parser_branches[i].data[j++]; + dat = s->_parserBranches[i].data[j++]; sciprintf(" C(%x)", dat); break; case VOCAB_TREE_NODE_COMPARE_GROUP: - dat = s->parser_branches[i].data[j++]; + dat = s->_parserBranches[i].data[j++]; sciprintf(" WG(%x)", dat); break; case VOCAB_TREE_NODE_FORCE_STORAGE: - dat = s->parser_branches[i].data[j++]; + dat = s->_parserBranches[i].data[j++]; sciprintf(" FORCE(%x)", dat); break; default: if (dat > VOCAB_TREE_NODE_LAST_WORD_STORAGE) { - int dat2 = s->parser_branches[i].data[j++]; + int dat2 = s->_parserBranches[i].data[j++]; sciprintf(" %x[%x]", dat, dat2); } else sciprintf(" ?%x?", dat); @@ -930,7 +928,7 @@ int c_list_sentence_fragments(EngineState *s) { sciprintf("\n"); } - sciprintf("%d rules.\n", s->parser_branches_nr); + sciprintf("%d rules.\n", s->_parserBranches.size()); return 0; } @@ -1043,7 +1041,7 @@ int c_parse(EngineState *s) { for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i) sciprintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group); - if (vocab_gnf_parse(&(s->parser_nodes[0]), words, s->parser_branches, s->parser_rules, 1)) + if (vocab_gnf_parse(s->parser_nodes, words, s->_parserBranches[0], s->parser_rules, 1)) syntax_fail = 1; // Building a tree failed if (syntax_fail) @@ -2717,7 +2715,7 @@ int c_gnf(EngineState *s) { return 1; } - vocab_gnf_dump(s->parser_branches, s->parser_branches_nr); + vocab_gnf_dump(s->_parserBranches); return 0; } diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 60fed060ff..9c7d2f78bb 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -142,9 +142,7 @@ EngineState::EngineState() : _dirseeker(this) { debug_mode = 0; sys_strings_segment = 0; sys_strings = 0; - parser_branches = 0; parser_rules = 0; - parser_branches_nr = 0; memset(parser_nodes, 0, sizeof(parser_nodes)); parser_valid = 0; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 037a99883b..e924c86919 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -252,9 +252,8 @@ public: /* Parser data: */ WordMap _parserWords; SuffixList _parserSuffixes; - parse_tree_branch_t *parser_branches; + Common::Array _parserBranches; parse_rule_list_t *parser_rules; /* GNF rules used in the parser algorithm */ - int parser_branches_nr; parse_tree_node_t parser_nodes[VOCAB_TREE_NODES]; /* The parse tree */ int parser_valid; /* If something has been correctly parsed */ diff --git a/engines/sci/scicore/vocabulary.cpp b/engines/sci/scicore/vocabulary.cpp index 76fbf292fc..d708e95563 100644 --- a/engines/sci/scicore/vocabulary.cpp +++ b/engines/sci/scicore/vocabulary.cpp @@ -193,46 +193,40 @@ void vocab_free_suffixes(ResourceManager *resmgr, SuffixList &suffixes) { suffixes.clear(); } -void vocab_free_branches(parse_tree_branch_t *parser_branches) { - free(parser_branches); -} - -parse_tree_branch_t *vocab_get_branches(ResourceManager * resmgr, int *branches_nr) { +bool vocab_get_branches(ResourceManager * resmgr, Common::Array &branches) { Resource *resource = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_PARSE_TREE_BRANCHES, 0); - parse_tree_branch_t *retval; - int i; + + branches.clear(); if (!resource) { fprintf(stderr, "No parser tree data found!\n"); - return NULL; + return false; } - *branches_nr = resource->size / 20; + int branches_nr = resource->size / 20; - if (*branches_nr == 0) { + if (branches_nr == 0) { fprintf(stderr, "Parser tree data is empty!\n"); - return NULL; + return false; } - retval = (parse_tree_branch_t *)sci_malloc(sizeof(parse_tree_branch_t) * *branches_nr); - - for (i = 0; i < *branches_nr; i++) { - int k; + branches.resize(branches_nr); + for (int i = 0; i < branches_nr; i++) { byte *base = resource->data + i * 20; - retval[i].id = (int16)READ_LE_UINT16(base); + branches[i].id = (int16)READ_LE_UINT16(base); - for (k = 0; k < 9; k++) - retval[i].data[k] = READ_LE_UINT16(base + 2 + 2 * k); + for (int k = 0; k < 9; k++) + branches[i].data[k] = READ_LE_UINT16(base + 2 + 2 * k); - retval[i].data[9] = 0; // Always terminate + branches[i].data[9] = 0; // Always terminate } - if (!retval[*branches_nr - 1].id) /* branch lists may be terminated by empty rules */ - --(*branches_nr); + if (!branches[branches_nr - 1].id) // branch lists may be terminated by empty rules + branches.remove_at(branches_nr - 1); - return retval; + return true; } diff --git a/engines/sci/scicore/vocabulary.h b/engines/sci/scicore/vocabulary.h index 9a073d2e79..a8d58c04e1 100644 --- a/engines/sci/scicore/vocabulary.h +++ b/engines/sci/scicore/vocabulary.h @@ -243,20 +243,13 @@ void vocab_free_suffixes(ResourceManager *resmgr, SuffixList &suffixes); ** (SuffixList) suffixes: The suffixes to free */ -parse_tree_branch_t *vocab_get_branches(ResourceManager *resmgr, int *branches_nr); -/* Retrieves all grammar rules from the resource data -** Parameters: (ResourceManager*) resmgr: Resource manager the rules are -** read from -** (int *) branches_nr: Pointer to the variable which the number of entries is to be -** stored in -** Returns : (parse_tree_branch_t *): The rules, or NULL on error -*/ - -void vocab_free_branches(parse_tree_branch_t *parser_branches); -/* Frees all branches -** Parameters: (parse_tree_branch_t *) parser_branches: The branches to free -** Returns : (null) -*/ +/** + * Retrieves all grammar rules from the resource data. + * @param resmgr Resource manager the rules are read from + * @param branches The rules are stored into this Array + * @return true on success, false on error + */ +bool vocab_get_branches(ResourceManager *resmgr, Common::Array &branches); ResultWord vocab_lookup_word(char *word, int word_len, const WordMap &words, const SuffixList &suffixes); @@ -284,10 +277,9 @@ bool vocab_tokenize_string(ResultWordList &retval, char *sentence, */ -parse_rule_list_t *vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr); +parse_rule_list_t *vocab_build_gnf(const Common::Array &branches); /* Constructs the Greibach Normal Form of the grammar supplied in 'branches' ** Parameters: (parse_tree_branch_t *) branches: The parser's branches -** (int) branches_nr: Number of parser branches ** Returns : (parse_rule_list_t *): Pointer to a list of singly linked ** GNF rules describing the same language ** that was described by 'branches' @@ -304,7 +296,7 @@ void vocab_free_rule_list(parse_rule_list_t *rule_list); int vocab_build_parse_tree(parse_tree_node_t *nodes, const ResultWordList &words, - parse_tree_branch_t *branch0, parse_rule_list_t *rules); + const parse_tree_branch_t &branch0, parse_rule_list_t *rules); /* Builds a parse tree from a list of words ** Parameters: (parse_tree_node_t *) nodes: A node list to store the tree in (must have ** at least VOCAB_TREE_NODES entries) @@ -357,9 +349,9 @@ void vocab_synonymize_tokens(ResultWordList &words, const SynonymList &synonyms) */ int vocab_gnf_parse(parse_tree_node_t *nodes, const ResultWordList &words, - parse_tree_branch_t *branch0, parse_rule_list_t *tlist, int verbose); + const parse_tree_branch_t &branch0, parse_rule_list_t *tlist, int verbose); -void vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr); +void vocab_gnf_dump(const Common::Array &branches); } // End of namespace Sci -- cgit v1.2.3