SCI: Store parse_tree_branch_t in a Common::Arraay
svn-id: r40100
This commit is contained in:
parent
7b11ef429e
commit
486f10edaf
9 changed files with 57 additions and 78 deletions
|
@ -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();
|
||||
|
|
|
@ -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<parse_tree_branch_t> &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<parse_tree_branch_t> &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<parse_tree_branch_t> &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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -252,9 +252,8 @@ public:
|
|||
/* Parser data: */
|
||||
WordMap _parserWords;
|
||||
SuffixList _parserSuffixes;
|
||||
parse_tree_branch_t *parser_branches;
|
||||
Common::Array<parse_tree_branch_t> _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 */
|
||||
|
|
|
@ -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<parse_tree_branch_t> &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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<parse_tree_branch_t> &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<parse_tree_branch_t> &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<parse_tree_branch_t> &branches);
|
||||
|
||||
} // End of namespace Sci
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue