[Scummvm-cvs-logs] scummvm master -> 3d0c691694ddcf00a5bfc347626d38625f057dee

wjp wjp at usecode.org
Sun May 3 17:24:25 CEST 2015


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
3d0c691694 SCI: Handle pronouns in parser


Commit: 3d0c691694ddcf00a5bfc347626d38625f057dee
    https://github.com/scummvm/scummvm/commit/3d0c691694ddcf00a5bfc347626d38625f057dee
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2015-05-03T17:21:07+02:00

Commit Message:
SCI: Handle pronouns in parser

When parsing a sentence, its type 0x142 word (presumably the object) is
now stored. Any pronouns (type 0x080) are then automatically replaced by
this stored word.

Changed paths:
    engines/sci/engine/kparse.cpp
    engines/sci/parser/vocabulary.cpp
    engines/sci/parser/vocabulary.h



diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp
index aa89b96..f85f33e 100644
--- a/engines/sci/engine/kparse.cpp
+++ b/engines/sci/engine/kparse.cpp
@@ -117,6 +117,8 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
 		}
 #endif
 
+		voc->replacePronouns(words);
+
 		int syntax_fail = voc->parseGNF(words);
 
 		if (syntax_fail) {
@@ -130,6 +132,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
 
 		} else {
 			voc->parserIsValid = true;
+			voc->storePronounReference();
 			writeSelectorValue(segMan, event, SELECTOR(claimed), 0);
 
 #ifdef DEBUG_PARSER
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 000b037..828a57a 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -74,6 +74,8 @@ Vocabulary::Vocabulary(ResourceManager *resMan, bool foreign) : _resMan(resMan),
 
 	parser_event = NULL_REG;
 	parserIsValid = false;
+
+	_pronounReference = 0x1000; // Non-existent word
 }
 
 Vocabulary::~Vocabulary() {
@@ -738,4 +740,79 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c
 	return oldPos;
 }
 
+
+// FIXME: Duplicated from said.cpp
+static int node_major(ParseTreeNode* node) {
+	assert(node->type == kParseTreeBranchNode);
+	assert(node->left->type == kParseTreeLeafNode);
+	return node->left->value;
+}
+static bool node_is_terminal(ParseTreeNode* node) {
+	return (node->right->right &&
+            node->right->right->type != kParseTreeBranchNode);
+}
+static int node_terminal_value(ParseTreeNode* node) {
+	assert(node_is_terminal(node));
+	return node->right->right->value;
+}
+
+static ParseTreeNode* scanForMajor(ParseTreeNode *tree, int major) {
+	assert(tree);
+
+	if (node_is_terminal(tree)) {
+		if (node_major(tree) == major)
+			return tree;
+		else
+			return 0;
+	}
+
+	ParseTreeNode* ptr = tree->right;
+
+	// Scan children
+	while (ptr->right) {
+		ptr = ptr->right;
+
+		if (node_major(ptr->left) == major)
+			return ptr->left;
+	}
+
+	if (major == 0x141)
+		return 0;
+
+	// If not found, go into a 0x141 and try again
+	tree = scanForMajor(tree, 0x141);
+	if (!tree)
+		return 0;
+	return scanForMajor(tree, major);
+}
+
+bool Vocabulary::storePronounReference() {
+	assert(parserIsValid);
+
+	ParseTreeNode *ptr = scanForMajor(_parserNodes, 0x142); // 0x142 = object?
+
+	while (ptr && !node_is_terminal(ptr))
+		ptr = scanForMajor(ptr, 0x141);
+
+	if (!ptr)
+		return false;
+
+	_pronounReference = node_terminal_value(ptr);
+
+	debugC(kDebugLevelParser, "Stored pronoun reference: %x", _pronounReference);
+	return true;
+}
+
+void Vocabulary::replacePronouns(ResultWordListList &words) {
+	if (_pronounReference == 0x1000)
+		return;
+
+	for (ResultWordListList::iterator i = words.begin(); i != words.end(); ++i)
+		for (ResultWordList::iterator j = i->begin(); j != i->end(); ++j)
+			if (j->_class & (VOCAB_CLASS_PRONOUN << 4)) {
+				j->_class = VOCAB_CLASS_NOUN << 4;
+				j->_group = _pronounReference;
+			}
+}
+
 } // End of namespace Sci
diff --git a/engines/sci/parser/vocabulary.h b/engines/sci/parser/vocabulary.h
index 0949994..f4adee6 100644
--- a/engines/sci/parser/vocabulary.h
+++ b/engines/sci/parser/vocabulary.h
@@ -233,6 +233,16 @@ public:
 	int parseGNF(const ResultWordListList &words, bool verbose = false);
 
 	/**
+	 * Find and store reference for future pronouns
+	 */
+	bool storePronounReference();
+
+	/**
+	 * Replace pronouns by stored reference
+	 */
+	void replacePronouns(ResultWordListList &words);
+
+	/**
 	 * Constructs the Greibach Normal Form of the grammar supplied in 'branches'.
 	 * @param verbose	Set to true for debugging. If true, the list is
 	 *					freed before the function ends
@@ -360,6 +370,8 @@ private:
 	SynonymList _synonyms; /**< The list of synonyms */
 	Common::Array<Common::List<AltInput> > _altInputs;
 
+	int _pronounReference;
+
 public:
 	// Accessed by said()
 	ParseTreeNode _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */






More information about the Scummvm-git-logs mailing list