diff options
Diffstat (limited to 'engines/sci/engine/said.y')
-rw-r--r-- | engines/sci/engine/said.y | 950 |
1 files changed, 0 insertions, 950 deletions
diff --git a/engines/sci/engine/said.y b/engines/sci/engine/said.y deleted file mode 100644 index fdef2360ae..0000000000 --- a/engines/sci/engine/said.y +++ /dev/null @@ -1,950 +0,0 @@ -/*************************************************************************** - said.y Copyright (C) 1999 Christoph Reichenbach - - - This program may be modified and copied freely according to the terms of - the GNU general public license (GPL), as long as the above copyright - notice and the licensing information contained herein are preserved. - - Please refer to www.gnu.org for licensing details. - - This work is provided AS IS, without warranty of any kind, expressed or - implied, including but not limited to the warranties of merchantibility, - noninfringement, and fitness for a specific purpose. The author will not - be held liable for any damage caused by this work or derivatives of it. - - By using this source code, you agree to the licensing terms as stated - above. - - - Please contact the maintainer for bug reports or inquiries. - - Current Maintainer: - - Christoph Reichenbach (CJR) [jameson@linuxgames.com] - -***************************************************************************/ - -%{ - -#include <engine.h> - -#define SAID_BRANCH_NULL 0 - -#define MAX_SAID_TOKENS 128 - -/* Maximum number of words to be expected in a parsed sentence */ -#define AUGMENT_MAX_WORDS 64 - - -#define ANYWORD 0xfff - -#define WORD_TYPE_BASE 0x141 -#define WORD_TYPE_REF 0x144 -#define WORD_TYPE_SYNTACTIC_SUGAR 0x145 - -#define AUGMENT_SENTENCE_PART_BRACKETS 0x152 - -/* Minor numbers */ -#define AUGMENT_SENTENCE_MINOR_MATCH_PHRASE 0x14c -#define AUGMENT_SENTENCE_MINOR_MATCH_WORD 0x153 -#define AUGMENT_SENTENCE_MINOR_RECURSE 0x144 -#define AUGMENT_SENTENCE_MINOR_PARENTHESES 0x14f - - -#undef YYDEBUG /*1*/ -/*#define SAID_DEBUG*/ -/*#define SCI_DEBUG_PARSE_TREE_AUGMENTATION*/ /* uncomment to debug parse tree augmentation*/ - - -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION -#define scidprintf sciprintf -#else -#define scidprintf if (0) sciprintf -#endif - - -static char *said_parse_error; - -static int said_token; -static int said_tokens_nr; -static int said_tokens[MAX_SAID_TOKENS]; - -static int said_blessed; /* increminated by said_top_branch */ - -static int said_tree_pos; /* Set to 0 if we're out of space */ -#define SAID_TREE_START 4; /* Reserve space for the 4 top nodes */ - -#define VALUE_IGNORE -424242 - -static parse_tree_node_t said_tree[VOCAB_TREE_NODES]; - -typedef int wgroup_t; -typedef int tree_t; -typedef int said_spec_t; - -static tree_t -said_aug_branch(int, int, tree_t, tree_t); - -static tree_t -said_attach_branch(tree_t, tree_t); -/* -static tree_t -said_wgroup_branch(wgroup_t); -*/ -static said_spec_t -said_top_branch(tree_t); - -static tree_t -said_paren(tree_t, tree_t); - -static tree_t -said_value(int, tree_t); - -static tree_t -said_terminal(int); - - -static int -yylex(void); - -static int -yyerror(char *s) -{ - said_parse_error = sci_strdup(s); - return 1; /* Abort */ -} - -%} - -%token WGROUP /* Word group */ -%token YY_COMMA /* 0xf0 */ -%token YY_AMP /* 0xf1 */ -%token YY_SLASH /* 0xf2 */ -%token YY_PARENO /* 0xf3 */ -%token YY_PARENC /* 0xf4 */ -%token YY_BRACKETSO /* 0xf5 */ -%token YY_BRACKETSC /* 0xf6 */ -%token YY_HASH /* 0xf7 */ -%token YY_LT /* 0xf8 */ -%token YY_GT /* 0xf9 */ -%token YY_BRACKETSO_LT /* special token used to imitate LR(2) behaviour */ -%token YY_BRACKETSO_SLASH /* special token used to imitate LR(2) behaviour */ -%token YY_LT_BRACKETSO /* special token used to imitate LR(2) behaviour */ -%token YY_LT_PARENO /* special token used to imitate LR(2) behaviour */ - -%% - -saidspec : leftspec optcont - { $$ = said_top_branch(said_attach_branch($1, $2)); } - | leftspec midspec optcont - { $$ = said_top_branch(said_attach_branch($1, said_attach_branch($2, $3))); } - | leftspec midspec rightspec optcont - { $$ = said_top_branch(said_attach_branch($1, said_attach_branch($2, said_attach_branch($3, $4)))); } - ; - - -optcont : /* empty */ - { $$ = SAID_BRANCH_NULL; } - | YY_GT - { $$ = said_paren(said_value(0x14b, said_value(0xf900, said_terminal(0xf900))), SAID_BRANCH_NULL); } - ; - - - -leftspec : /* empty */ - { $$ = SAID_BRANCH_NULL; } - | expr - { $$ = said_paren(said_value(0x141, said_value(0x149, $1)), SAID_BRANCH_NULL); } - ; - - - -midspec : YY_SLASH expr - { $$ = said_aug_branch(0x142, 0x14a, $2, SAID_BRANCH_NULL); } - | YY_BRACKETSO_SLASH YY_SLASH expr YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x142, said_aug_branch(0x142, 0x14a, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_SLASH - { $$ = SAID_BRANCH_NULL; } - ; - - - -rightspec : YY_SLASH expr - { $$ = said_aug_branch(0x143, 0x14a, $2, SAID_BRANCH_NULL); } - | YY_BRACKETSO_SLASH YY_SLASH expr YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x143, said_aug_branch(0x143, 0x14a, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_SLASH - { $$ = SAID_BRANCH_NULL; } - ; - - - -word : WGROUP - { $$ = said_paren(said_value(0x141, said_value(0x153, said_terminal($1))), SAID_BRANCH_NULL); } - ; - - -cwordset : wordset - { $$ = said_aug_branch(0x141, 0x14f, $1, SAID_BRANCH_NULL); } - | YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_aug_branch(0x141, 0x14f, said_aug_branch(0x152, 0x14c, said_aug_branch(0x141, 0x14f, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - ; - - -wordset : word - { $$ = $1; } - | YY_PARENO expr YY_PARENC - { $$ = $1; } - | wordset YY_COMMA wordset - { $$ = said_attach_branch($1, $3); } - | wordset YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_attach_branch($1, $3); } - | wordset YY_COMMA YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_attach_branch($1, $3); } - ; - - - -expr : cwordset cwordrefset - { $$ = said_attach_branch($1, $2); } - | cwordset - { $$ = $1; } - | cwordrefset - { $$ = $1; } - ; - - - -cwordrefset : wordrefset - { $$ = $1; } - | YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x144, $2, SAID_BRANCH_NULL); } - | wordrefset YY_BRACKETSO_LT wordrefset YY_BRACKETSC - { $$ = said_attach_branch($1, said_aug_branch(0x152, 0x144, $3, SAID_BRANCH_NULL)); } - ; - - - -wordrefset : YY_LT word recref - { $$ = said_aug_branch(0x144, 0x14f, $2, $3); } - | YY_LT_PARENO YY_PARENO expr YY_PARENC - { $$ = said_aug_branch(0x144, 0x14f, said_aug_branch(0x141, 0x144, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_LT wordset - { $$ = said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL); } - | YY_LT_BRACKETSO YY_BRACKETSO wordset YY_BRACKETSC - { $$ = said_aug_branch(0x152, 0x144, said_aug_branch(0x144, 0x14f, $3, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - ; - - - -recref : YY_LT wordset recref - { $$ = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL), $3); } - | YY_LT wordset - { $$ = said_aug_branch(0x141, 0x144, said_aug_branch(0x144, 0x14f, $2, SAID_BRANCH_NULL), SAID_BRANCH_NULL); } - | YY_LT_PARENO YY_PARENO expr YY_PARENC - { $$ = said_aug_branch(0x141, 0x14c, $2, SAID_BRANCH_NULL); } - ; - - - -%% - - -int -parse_yy_token_lookup[] = {YY_COMMA, YY_AMP, YY_SLASH, YY_PARENO, YY_PARENC, YY_BRACKETSO, YY_BRACKETSC, - YY_HASH, YY_LT, YY_GT}; - -static int -yylex(void) -{ - int retval = said_tokens[said_token++]; - - if (retval < SAID_LONG(SAID_FIRST)) { - yylval = retval; - retval = WGROUP; - } else { - retval >>= 8; - - if (retval == SAID_TERM) - retval = 0; - else { - assert(retval >= SAID_FIRST); - retval = parse_yy_token_lookup[retval - SAID_FIRST]; - if (retval == YY_BRACKETSO) { - if ((said_tokens[said_token] >> 8) == SAID_LT) - retval = YY_BRACKETSO_LT; - else - if ((said_tokens[said_token] >> 8) == SAID_SLASH) - retval = YY_BRACKETSO_SLASH; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_BRACKO) { - retval = YY_LT_BRACKETSO; - } else if (retval == YY_LT && (said_tokens[said_token] >> 8) == SAID_PARENO) { - retval = YY_LT_PARENO; - } - } - } - - return retval; -} - -#define SAID_NEXT_NODE ((said_tree_pos == 0) || (said_tree_pos >= VOCAB_TREE_NODES))? said_tree_pos = 0 : said_tree_pos++ - -static inline int -said_leaf_node(tree_t pos, int value) -{ - said_tree[pos].type = PARSE_TREE_NODE_LEAF; - - if (value != VALUE_IGNORE) - said_tree[pos].content.value = value; - - return pos; -} - -static inline int -said_branch_node(tree_t pos, int left, int right) -{ - said_tree[pos].type = PARSE_TREE_NODE_BRANCH; - - if (left != VALUE_IGNORE) - said_tree[pos].content.branches[0] = left; - - if (right != VALUE_IGNORE) - said_tree[pos].content.branches[1] = right; - - return pos; -} - - -static tree_t -said_paren(tree_t t1, tree_t t2) -{ - if (t1) - return said_branch_node(SAID_NEXT_NODE, - t1, - t2 - ); - else - return t2; -} - -static tree_t -said_value(int val, tree_t t) -{ - return said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, val), - t - ); - -} - -static tree_t -said_terminal(int val) -{ - return said_leaf_node(SAID_NEXT_NODE, val); -} - - -static tree_t -said_aug_branch(int n1, int n2, tree_t t1, tree_t t2) -{ - int retval; - - retval = said_branch_node(SAID_NEXT_NODE, - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n1), - said_branch_node(SAID_NEXT_NODE, - said_leaf_node(SAID_NEXT_NODE, n2), - t1 - ) - ), - t2 - ); - -#ifdef SAID_DEBUG - fprintf(stderr,"AUG(0x%x, 0x%x, [%04x], [%04x]) = [%04x]\n", n1, n2, t1, t2, retval); -#endif - - return retval; -} - -static tree_t -said_attach_branch(tree_t base, tree_t attacheant) -{ -#ifdef SAID_DEBUG - fprintf(stderr,"ATT2([%04x], [%04x]) = [%04x]\n", base, attacheant, base); -#endif - - if (!attacheant) - return base; - if (!base) - return attacheant; - - if (!base) - return 0; /* Happens if we're out of space */ - - said_branch_node(base, VALUE_IGNORE, attacheant); - - return base; -} - -static said_spec_t -said_top_branch(tree_t first) -{ -#ifdef SAID_DEBUG - fprintf(stderr, "TOP([%04x])\n", first); -#endif - said_branch_node(0, 1, 2); - said_leaf_node(1, 0x141); /* Magic number #1 */ - said_branch_node(2, 3, first); - said_leaf_node(3, 0x13f); /* Magic number #2 */ - - ++said_blessed; - - return 0; -} - - -int -said_parse_spec(state_t *s, byte *spec) -{ - int nextitem; - - said_parse_error = NULL; - said_token = 0; - said_tokens_nr = 0; - said_blessed = 0; - - said_tree_pos = SAID_TREE_START; - - do { - nextitem = *spec++; - if (nextitem < SAID_FIRST) - said_tokens[said_tokens_nr++] = nextitem << 8 | *spec++; - else - said_tokens[said_tokens_nr++] = SAID_LONG(nextitem); - - } while ((nextitem != SAID_TERM) && (said_tokens_nr < MAX_SAID_TOKENS)); - - if (nextitem == SAID_TERM) - yyparse(); - else { - sciprintf("Error: SAID spec is too long\n"); - return 1; - } - - if (said_parse_error) { - sciprintf("Error while parsing SAID spec: %s\n", said_parse_error); - free(said_parse_error); - return 1; - } - - if (said_tree_pos == 0) { - sciprintf("Error: Out of tree space while parsing SAID spec\n"); - return 1; - } - - if (said_blessed != 1) { - sciprintf("Error: Found %d top branches\n"); - return 1; - } - - return 0; -} - -/**********************/ -/**** Augmentation ****/ -/**********************/ - - -/** primitive functions **/ - -#define AUG_READ_BRANCH(a, br, p) \ - if (tree[p].type != PARSE_TREE_NODE_BRANCH) \ - return 0; \ - a = tree[p].content.branches[br]; - -#define AUG_READ_VALUE(a, p) \ - if (tree[p].type != PARSE_TREE_NODE_LEAF) \ - return 0; \ - a = tree[p].content.value; - -#define AUG_ASSERT(i) \ - if (!i) return 0; - -static int -aug_get_next_sibling(parse_tree_node_t *tree, int pos, int *first, int *second) - /* Returns the next sibling relative to the specified position in 'tree', - ** sets *first and *second to its augment node values, returns the new position - ** or 0 if there was no next sibling - */ -{ - int seek, valpos; - - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(seek, 0, pos); - AUG_ASSERT(seek); - - /* Now retreive first value */ - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*first, valpos); - - /* Get second value */ - AUG_READ_BRANCH(seek, 1, seek); - AUG_ASSERT(seek); - AUG_READ_BRANCH(valpos, 0, seek); - AUG_ASSERT(valpos); - AUG_READ_VALUE(*second, valpos); - - return pos; -} - - -static int -aug_get_wgroup(parse_tree_node_t *tree, int pos) - /* Returns 0 if pos in tree is not the root of a 3-element list, otherwise - ** it returns the last element (which, in practice, is the word group - */ -{ - int val; - - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - AUG_READ_VALUE(val, pos); - - return val; -} - - -static int -aug_get_base_node(parse_tree_node_t *tree) -{ - int startpos = 0; - AUG_READ_BRANCH(startpos, 1, startpos); - return startpos; -} - - -/** semi-primitive functions **/ - - -static int -aug_get_first_child(parse_tree_node_t *tree, int pos, int *first, int *second) - /* like aug_get_next_sibling, except that it recurses into the tree and - ** finds the first child (usually *not* Ayanami Rei) of the current branch - ** rather than its next sibling. - */ -{ - AUG_READ_BRANCH(pos, 0, pos); - AUG_ASSERT(pos); - AUG_READ_BRANCH(pos, 1, pos); - AUG_ASSERT(pos); - - return aug_get_next_sibling(tree, pos, first, second); -} - -static void -aug_find_words_recursively(parse_tree_node_t *tree, int startpos, - int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, - int maxwords, int refbranch) - /* Finds and lists all base (141) and reference (144) words */ -{ - int major, minor; - int word; - int pos = aug_get_first_child(tree, startpos, &major, &minor); - - /* if (major == WORD_TYPE_REF) - refbranch = 1;*/ - - while (pos) { - if ((word = aug_get_wgroup(tree, pos))) { /* found a word */ - - if (!refbranch && major == WORD_TYPE_BASE) { - if ((*base_words_nr) == maxwords) { - sciprintf("Out of regular words\n"); - return; /* return gracefully */ - } - - base_words[*base_words_nr] = word; /* register word */ - ++(*base_words_nr); - - } - if (major == WORD_TYPE_REF || refbranch) { - if ((*ref_words_nr) == maxwords) { - sciprintf("Out of reference words\n"); - return; /* return gracefully */ - } - - ref_words[*ref_words_nr] = word; /* register word */ - ++(*ref_words_nr); - - } - if (major != WORD_TYPE_SYNTACTIC_SUGAR && major != WORD_TYPE_BASE && major != WORD_TYPE_REF) - sciprintf("aug_find_words_recursively(): Unknown word type %03x\n", major); - - } else /* Did NOT find a word group: Attempt to recurse */ - aug_find_words_recursively(tree, pos, base_words, base_words_nr, - ref_words, ref_words_nr, maxwords, refbranch || major == WORD_TYPE_REF); - - pos = aug_get_next_sibling(tree, pos, &major, &minor); - } -} - - -static void -aug_find_words(parse_tree_node_t *tree, int startpos, - int *base_words, int *base_words_nr, - int *ref_words, int *ref_words_nr, - int maxwords) - /* initializing wrapper for aug_find_words_recursively() */ -{ - *base_words_nr = 0; - *ref_words_nr = 0; - - aug_find_words_recursively(tree, startpos, base_words, base_words_nr, ref_words, ref_words_nr, maxwords, 0); -} - - -static inline int -aug_contains_word(int *list, int length, int word) -{ - int i; - if (word == ANYWORD) - return (length); - - for (i = 0; i < length; i++) - if (list[i] == word) - return 1; - - return 0; -} - - -static int -augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, - parse_tree_node_t *parset, int parse_branch, - int major, int minor, - int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr); - -static int -augment_match_expression_p(parse_tree_node_t *saidt, int augment_pos, - parse_tree_node_t *parset, int parse_basepos, - int major, int minor, - int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr) -{ - int cmajor, cminor, cpos; - cpos = aug_get_first_child(saidt, augment_pos, &cmajor, &cminor); - if (!cpos) { - sciprintf("augment_match_expression_p(): Empty condition\n"); - return 1; - } - - scidprintf("Attempting to match (%03x %03x (%03x %03x\n", major, minor, cmajor, cminor); - - if ((major == WORD_TYPE_BASE) && (minor == AUGMENT_SENTENCE_MINOR_RECURSE)) - return augment_match_expression_p(saidt, cpos, - parset, parse_basepos, - cmajor, cminor, - base_words, base_words_nr, - ref_words, ref_words_nr); - - - switch (major) { - - case WORD_TYPE_BASE: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for word %03x\n", word); - - if (aug_contains_word(base_words, base_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_sentence_expression(saidt, cpos, - parset, parse_basepos, - cmajor, cminor, - base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, - parset, parse_basepos, - major, minor, - base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - sciprintf("augment_match_expression_p(): Unknown type 141 minor number %3x\n", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); - - } - break; - - case WORD_TYPE_REF: - while (cpos) { - if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_WORD) { - int word = aug_get_wgroup(saidt, cpos); - scidprintf("Looking for refword %03x\n", word); - - if (aug_contains_word(ref_words, ref_words_nr, word)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_MATCH_PHRASE) { - if (augment_match_expression_p(saidt, cpos, - parset, parse_basepos, - cmajor, cminor, - base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - } else if (cminor == AUGMENT_SENTENCE_MINOR_PARENTHESES) { - int gc_major, gc_minor; - int gchild = aug_get_first_child(saidt, cpos, &gc_major, &gc_minor); - - while (gchild) { - if (augment_match_expression_p(saidt, cpos, - parset, parse_basepos, - major, minor, - base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - gchild = aug_get_next_sibling(saidt, gchild, &gc_major, &gc_minor); - } - } else - sciprintf("augment_match_expression_p(): Unknown type 144 minor number %3x\n", cminor); - - cpos = aug_get_next_sibling(saidt, cpos, &cmajor, &cminor); - - } - break; - - case AUGMENT_SENTENCE_PART_BRACKETS: - if (augment_match_expression_p(saidt, cpos, - parset, parse_basepos, - cmajor, cminor, - base_words, base_words_nr, - ref_words, ref_words_nr)) - return 1; - - scidprintf("Didn't match subexpression; checking sub-bracked predicate %03x\n", cmajor); - - switch (cmajor) { - case WORD_TYPE_BASE: - if (!base_words_nr) - return 1; - break; - - case WORD_TYPE_REF: - if (!ref_words_nr) - return 1; - break; - - default: - sciprintf("augment_match_expression_p(): (subp1) Unkonwn sub-bracket predicate %03x\n", cmajor); - } - - break; - - default: - sciprintf("augment_match_expression_p(): Unknown predicate %03x\n", major); - - } - - scidprintf("Generic failure\n"); - return 0; -} - -static int -augment_sentence_expression(parse_tree_node_t *saidt, int augment_pos, - parse_tree_node_t *parset, int parse_branch, - int major, int minor, - int *base_words, int base_words_nr, - int *ref_words, int ref_words_nr) -{ - int check_major, check_minor; - int check_pos = aug_get_first_child(saidt, augment_pos, &check_major, &check_minor); - do { - if (!(augment_match_expression_p(saidt, check_pos, parset, parse_branch, - check_major, check_minor, base_words, base_words_nr, - ref_words, ref_words_nr))) - return 0; - } while ((check_pos = aug_get_next_sibling(saidt, check_pos, &check_major, &check_minor))); - return 1; -} - - - -static int -augment_sentence_part(parse_tree_node_t *saidt, int augment_pos, - parse_tree_node_t *parset, int parse_basepos, - int major, int minor) -{ - int pmajor, pminor; - int parse_branch = parse_basepos; - int optional = 0; - int foundwords = 0; - - scidprintf("Augmenting (%03x %03x\n", major, minor); - - if (major == AUGMENT_SENTENCE_PART_BRACKETS) { /* '[/ foo]' is true if '/foo' or if there - ** exists no x for which '/x' is true - */ - if ((augment_pos = aug_get_first_child(saidt, augment_pos, &major, &minor))) { - scidprintf("Optional part: Now augmenting (%03x %03x\n", major, minor); - optional = 1; - } else { - scidprintf("Matched empty optional expression\n"); - return 1; - } - } - - if ((major < 0x141) - || (major > 0x143)) { - scidprintf("augment_sentence_part(): Unexpected sentence part major number %03x\n", major); - return 0; - } - - while ((parse_branch = aug_get_next_sibling(parset, parse_branch, &pmajor, &pminor))) - if (pmajor == major) { /* found matching sentence part */ - int success; - int base_words_nr; - int ref_words_nr; - int base_words[AUGMENT_MAX_WORDS]; - int ref_words[AUGMENT_MAX_WORDS]; -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - int i; -#endif - - scidprintf("Found match with pminor = %03x\n", pminor); - aug_find_words(parset, parse_branch, base_words, &base_words_nr, - ref_words, &ref_words_nr, AUGMENT_MAX_WORDS); - foundwords |= (ref_words_nr | base_words_nr); -#ifdef SCI_DEBUG_PARSE_TREE_AUGMENTATION - sciprintf("%d base words:", base_words_nr); - for (i = 0; i < base_words_nr; i++) - sciprintf(" %03x", base_words[i]); - sciprintf("\n%d reference words:", ref_words_nr); - for (i = 0; i < ref_words_nr; i++) - sciprintf(" %03x", ref_words[i]); - sciprintf("\n"); -#endif - - success = augment_sentence_expression(saidt, augment_pos, - parset, parse_basepos, major, minor, - base_words, base_words_nr, - ref_words, ref_words_nr); - - if (success) { - scidprintf("SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; - } - } - - if (optional && (foundwords == 0)) { - scidprintf("Found no words and optional branch => SUCCESS on augmenting (%03x %03x\n", major, minor); - return 1; - } - scidprintf("FAILURE on augmenting (%03x %03x\n", major, minor); - return 0; -} - -static int -augment_parse_nodes(parse_tree_node_t *parset, parse_tree_node_t *saidt) -{ - int augment_basepos = 0; - int parse_basepos; - int major, minor; - int dontclaim = 0; - - parse_basepos = aug_get_base_node(parset); - if (!parse_basepos) { - sciprintf("augment_parse_nodes(): Parse tree is corrupt\n"); - return 0; - } - - augment_basepos = aug_get_base_node(saidt); - if (!augment_basepos) { - sciprintf("augment_parse_nodes(): Said tree is corrupt\n"); - return 0; - } - while ((augment_basepos = aug_get_next_sibling(saidt, augment_basepos, &major, &minor))) { - - if ((major == 0x14b) - && (minor == SAID_LONG(SAID_GT))) - dontclaim = 1; /* special case */ - else /* normal sentence part */ - if (!(augment_sentence_part(saidt, augment_basepos, parset, parse_basepos, major, minor))) { - scidprintf("Returning failure\n"); - return 0; /* fail */ - } - } - - scidprintf("Returning success with dontclaim=%d\n", dontclaim); - - if (dontclaim) - return SAID_PARTIAL_MATCH; - else return 1; /* full match */ -} - - -/*******************/ -/**** Main code ****/ -/*******************/ - -int -said(state_t *s, byte *spec, int verbose) -{ - int retval; - - parse_tree_node_t *parse_tree_ptr = s->parser_nodes; - - if (s->parser_valid) { - - if (said_parse_spec(s, spec)) { - sciprintf("Offending spec was: "); - vocab_decypher_said_block(s, spec); - return SAID_NO_MATCH; - } - - if (verbose) - vocab_dump_parse_tree("Said-tree", said_tree); /* Nothing better to do yet */ - retval = augment_parse_nodes(parse_tree_ptr, &(said_tree[0])); - - if (!retval) - return SAID_NO_MATCH; - else if (retval != SAID_PARTIAL_MATCH) - return SAID_FULL_MATCH; - else return SAID_PARTIAL_MATCH; - } - - return SAID_NO_MATCH; -} - - - -#ifdef SAID_DEBUG_PROGRAM -int -main (int argc, char *argv) -{ - byte block[] = {0x01, 0x00, 0xf8, 0xf5, 0x02, 0x01, 0xf6, 0xf2, 0x02, 0x01, 0xf2, 0x01, 0x03, 0xff}; - state_t s; - con_passthrough = 1; - - s.parser_valid = 1; - said(&s, block); -} -#endif |