[Scummvm-cvs-logs] SF.net SVN: scummvm:[44481] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Wed Sep 30 14:17:40 CEST 2009


Revision: 44481
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44481&view=rev
Author:   thebluegr
Date:     2009-09-30 12:17:38 +0000 (Wed, 30 Sep 2009)

Log Message:
-----------
- Moved the list of synonyms and parser nodes inside the vocabulary class
- Added a convenience member inside the EngineState struct to access the instance of the Vocabulary class

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/engine/game.cpp
    scummvm/trunk/engines/sci/engine/grammar.cpp
    scummvm/trunk/engines/sci/engine/kstring.cpp
    scummvm/trunk/engines/sci/engine/said.cpp
    scummvm/trunk/engines/sci/engine/said.y
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/state.h
    scummvm/trunk/engines/sci/sci.cpp
    scummvm/trunk/engines/sci/vocabulary.cpp
    scummvm/trunk/engines/sci/vocabulary.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/console.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -464,66 +464,6 @@
 	return true;
 }
 
-enum {
-	kParseEndOfInput = 0,
-	kParseOpeningParenthesis = 1,
-	kParseClosingParenthesis = 2,
-	kParseNil = 3,
-	kParseNumber = 4
-};
-
-int parseNodes(EngineState *s, int *i, int *pos, int type, int nr, int argc, const char **argv) {
-	int nextToken = 0, nextValue = 0, newPos = 0, oldPos = 0;
-	Console *con = ((SciEngine *)g_engine)->getSciDebugger();
-
-	if (type == kParseNil)
-		return 0;
-
-	if (type == kParseNumber) {
-		s->parser_nodes[*pos += 1].type = kParseTreeLeafNode;
-		s->parser_nodes[*pos].content.value = nr;
-		return *pos;
-	}
-	if (type == kParseEndOfInput) {
-		con->DebugPrintf("Unbalanced parentheses\n");
-		return -1;
-	}
-	if (type == kParseClosingParenthesis) {
-		con->DebugPrintf("Syntax error at token %d\n", *i);
-		return -1;
-	}
-
-	s->parser_nodes[oldPos = ++(*pos)].type = kParseTreeBranchNode;
-
-	for (int j = 0; j <= 1; j++) {
-		if (*i == argc) {
-			nextToken = kParseEndOfInput;
-		} else {
-			const char *token = argv[(*i)++];
-
-			if (!strcmp(token, "(")) {
-				nextToken = kParseOpeningParenthesis;
-			} else if (!strcmp(token, ")")) {
-				nextToken = kParseClosingParenthesis;
-			} else if (!strcmp(token, "nil")) {
-				nextToken = kParseNil;
-			} else {
-				nextValue = strtol(token, NULL, 0);
-				nextToken = kParseNumber;
-			}
-		}
-
-		if ((newPos = s->parser_nodes[oldPos].content.branches[j] = parseNodes(s, i, pos, nextToken, nextValue, argc, argv)) == -1)
-			return -1;
-	}
-
-	const char *token = argv[(*i)++];
-	if (strcmp(token, ")"))
-		con->DebugPrintf("Expected ')' at token %d\n", *i);
-
-	return oldPos;
-}
-
 bool Console::cmdSetParseNodes(int argc, const char **argv) {
 	if (argc < 2) {
 		DebugPrintf("Sets the contents of all parse nodes.\n");
@@ -549,10 +489,10 @@
 		nextToken = kParseNumber;
 	}
 
-	if (parseNodes(_vm->_gamestate, &i, &pos, nextToken, nextValue, argc, argv) == -1)
+	if (_vm->getVocabulary()->parseNodes(&i, &pos, nextToken, nextValue, argc, argv) == -1)
 		return 1;
 
-	vocab_dump_parse_tree("debug-parse-tree", _vm->_gamestate->parser_nodes);
+	_vm->getVocabulary()->dumpParseTree();
 
 	return true;
 }
@@ -971,20 +911,20 @@
 	if (res && !words.empty()) {
 		int syntax_fail = 0;
 
-		vocab_synonymize_tokens(words, _vm->_gamestate->_synonyms);
+		_vm->getVocabulary()->synonymizeTokens(words);
 
 		DebugPrintf("Parsed to the following blocks:\n");
 
 		for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i)
 			DebugPrintf("   Type[%04x] Group[%04x]\n", i->_class, i->_group);
 
-		if (_vm->getVocabulary()->parseGNF(_vm->_gamestate->parser_nodes, words, true))
+		if (_vm->getVocabulary()->parseGNF(words, true))
 			syntax_fail = 1; // Building a tree failed
 
 		if (syntax_fail)
 			DebugPrintf("Building a tree failed.\n");
 		else
-			vocab_dump_parse_tree("debug-parse-tree", _vm->_gamestate->parser_nodes);
+			_vm->getVocabulary()->dumpParseTree();
 
 	} else {
 		DebugPrintf("Unknown word: '%s'\n", error);
@@ -1004,14 +944,7 @@
 
 	int end = MIN<int>(atoi(argv[1]), VOCAB_TREE_NODES);
 
-	for (int i = 0; i < end; i++) {
-		DebugPrintf(" Node %03x: ", i);
-		if (_vm->_gamestate->parser_nodes[i].type == kParseTreeLeafNode)
-			DebugPrintf("Leaf: %04x\n", _vm->_gamestate->parser_nodes[i].content.value);
-		else
-			DebugPrintf("Branch: ->%04x, ->%04x\n", _vm->_gamestate->parser_nodes[i].content.branches[0],
-			          _vm->_gamestate->parser_nodes[i].content.branches[1]);
-	}
+	_vm->getVocabulary()->printParserNodes(end);
 
 	return true;
 }

Modified: scummvm/trunk/engines/sci/engine/game.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/game.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/game.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -413,11 +413,8 @@
 		return 1;
 	}
 
-	s->parser_valid = 0; // Invalidate parser
+	s->parserIsValid = false; // Invalidate parser
 	s->parser_event = NULL_REG; // Invalidate parser event
-
-	s->_synonyms.clear(); // No synonyms
-
 	if (s->gfx_state && _reset_graphics_input(s))
 		return 1;
 
@@ -446,10 +443,6 @@
 
 	debug(2, " \"%s\" at %04x:%04x", s->_gameName.c_str(), PRINT_REG(s->game_obj));
 
-	// Mark parse tree as unused
-	s->parser_nodes[0].type = kParseTreeLeafNode;
-	s->parser_nodes[0].content.value = 0;
-
 	s->_menubar = new Menubar(); // Create menu bar
 
 	if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
@@ -474,8 +467,6 @@
 	delete s->segMan;
 	s->segMan = 0;
 
-	s->_synonyms.clear();
-
 	debug(2, "Freeing miscellaneous data...");
 
 	// TODO Free parser segment here

Modified: scummvm/trunk/engines/sci/engine/grammar.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/grammar.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/grammar.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -476,7 +476,7 @@
 	return rulepos;
 }
 
-int Vocabulary::parseGNF(parse_tree_node_t *nodes, const ResultWordList &words, bool verbose) {
+int Vocabulary::parseGNF(const ResultWordList &words, bool verbose) {
 	Console *con = ((SciEngine *)g_engine)->getSciDebugger();
 	// Get the start rules:
 	parse_rule_list_t *work = _vocab_clone_rule_list_by_id(_parserRules, _parserBranches[0].data[1]);
@@ -554,22 +554,22 @@
 	{
 		int temp, pos;
 
-		nodes[0].type = kParseTreeBranchNode;
-		nodes[0].content.branches[0] = 1;
-		nodes[0].content.branches[1] = 2;
+		_parserNodes[0].type = kParseTreeBranchNode;
+		_parserNodes[0].content.branches[0] = 1;
+		_parserNodes[0].content.branches[1] = 2;
 
-		nodes[1].type = kParseTreeLeafNode;
-		nodes[1].content.value = 0x141;
+		_parserNodes[1].type = kParseTreeLeafNode;
+		_parserNodes[1].content.value = 0x141;
 
-		nodes[2].type = kParseTreeBranchNode;
-		nodes[2].content.branches[0] = 0;
-		nodes[2].content.branches[1] = 0;
+		_parserNodes[2].type = kParseTreeBranchNode;
+		_parserNodes[2].content.branches[0] = 0;
+		_parserNodes[2].content.branches[1] = 0;
 
 		pos = 2;
 
-		temp = _vbpt_append(nodes, &pos, 2, _parserBranches[0].id);
+		temp = _vbpt_append(_parserNodes, &pos, 2, _parserBranches[0].id);
 		//_vbpt_write_subexpression(nodes, &pos, results[_vocab_rule_list_length(results)].rule, 0, temp);
-		_vbpt_write_subexpression(nodes, &pos, results->rule, 0, temp);
+		_vbpt_write_subexpression(_parserNodes, &pos, results->rule, 0, temp);
 	}
 
 	freeRuleList(results);

Modified: scummvm/trunk/engines/sci/engine/kstring.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kstring.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/kstring.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -96,7 +96,7 @@
 
 #ifdef DEBUG_PARSER
 		debugC(2, kDebugLevelParser, "Said block:", 0);
-		((SciEngine*)g_engine)->getVocabulary()->decipherSaidBlock(said_block);
+		s->_voc->decipherSaidBlock(said_block);
 #endif
 
 	if (s->parser_event.isNull() || (GET_SEL32V(s->parser_event, claimed))) {
@@ -134,8 +134,9 @@
 	List *list;
 	Node *node;
 	int script;
+	int numSynonyms = 0;
 
-	s->_synonyms.clear();
+	s->_voc->clearSynonyms();
 
 	list = lookup_list(s, GET_SEL32(object, elements));
 	node = lookup_node(s, list->first);
@@ -143,33 +144,31 @@
 	while (node) {
 		reg_t objpos = node->value;
 		int seg;
-		int _numSynonyms = 0;
 
 		script = GET_SEL32V(objpos, number);
 		seg = s->segMan->getScriptSegment(script);
 
 		if (seg > 0)
-			_numSynonyms = s->segMan->getScript(seg)->getSynonymsNr();
+			numSynonyms = s->segMan->getScript(seg)->getSynonymsNr();
 
-		if (_numSynonyms) {
-			byte *synonyms;
+		if (numSynonyms) {
+			byte *synonyms = s->segMan->getScript(seg)->getSynonyms();
 
-			synonyms = s->segMan->getScript(seg)->getSynonyms();
 			if (synonyms) {
 				debugC(2, kDebugLevelParser, "Setting %d synonyms for script.%d\n",
-				          _numSynonyms, script);
+				          numSynonyms, script);
 
-				if (_numSynonyms > 16384) {
+				if (numSynonyms > 16384) {
 					error("Segtable corruption: script.%03d has %d synonyms",
-					         script, _numSynonyms);
+					         script, numSynonyms);
 					/* We used to reset the corrupted value here. I really don't think it's appropriate.
 					 * Lars */
 				} else
-					for (int i = 0; i < _numSynonyms; i++) {
+					for (int i = 0; i < numSynonyms; i++) {
 						synonym_t tmp;
 						tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4);
 						tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2);
-						s->_synonyms.push_back(tmp);
+						s->_voc->addSynonym(tmp);
 					}
 			} else
 				warning("Synonyms of script.%03d were requested, but script is not available", script);
@@ -179,7 +178,7 @@
 		node = lookup_node(s, node->succ);
 	}
 
-	debugC(2, kDebugLevelParser, "A total of %d synonyms are active now.\n", s->_synonyms.size());
+	debugC(2, kDebugLevelParser, "A total of %d synonyms are active now.\n", numSynonyms);
 
 	return s->r_acc;
 }
@@ -193,19 +192,16 @@
 	char *error;
 	ResultWordList words;
 	reg_t event = argv[1];
-	Vocabulary *voc = ((SciEngine*)g_engine)->getVocabulary();
+	Vocabulary *voc = s->_voc;
 
 	s->parser_event = event;
 
 	bool res = voc->tokenizeString(words, string.c_str(), &error);
-	s->parser_valid = 0; /* not valid */
+	s->parserIsValid = false; /* not valid */
 
 	if (res && !words.empty()) {
+		s->_voc->synonymizeTokens(words);
 
-		int syntax_fail = 0;
-
-		vocab_synonymize_tokens(words, s->_synonyms);
-
 		s->r_acc = make_reg(0, 1);
 
 #ifdef DEBUG_PARSER
@@ -215,11 +211,9 @@
 				debugC(2, kDebugLevelParser, "   Type[%04x] Group[%04x]\n", i->_class, i->_group);
 #endif
 
-		if (voc->parseGNF(s->parser_nodes, words))
-			syntax_fail = 1; /* Building a tree failed */
+		int syntax_fail = voc->parseGNF(words);
 
 		if (syntax_fail) {
-
 			s->r_acc = make_reg(0, 1);
 			PUT_SEL32V(event, claimed, 1);
 
@@ -229,11 +223,11 @@
 			debugC(2, kDebugLevelParser, "Tree building failed\n");
 
 		} else {
-			s->parser_valid = 1;
+			s->parserIsValid = true;
 			PUT_SEL32V(event, claimed, 0);
 
 #ifdef DEBUG_PARSER
-			vocab_dump_parse_tree("Parse-tree", s->parser_nodes);
+			s->_voc->dumpParseTree();
 #endif
 		}
 

Modified: scummvm/trunk/engines/sci/engine/said.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/said.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/said.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -2006,7 +2006,7 @@
 	return 0;
 }
 
-static int said_parse_spec(EngineState *s, byte *spec) {
+static int said_parse_spec(byte *spec) {
 	int nextitem;
 
 	said_parse_error = NULL;
@@ -2441,15 +2441,15 @@
 /**** Main code ****/
 /*******************/
 
-int said(EngineState *s, byte *spec, int verbose) {
+int said(EngineState *s, byte *spec, bool verbose) {
 	int retval;
 
-	parse_tree_node_t *parse_tree_ptr = s->parser_nodes;
+	parse_tree_node_t *parse_tree_ptr = s->_voc->_parserNodes;
 
-	if (s->parser_valid) {
-		if (said_parse_spec(s, spec)) {
+	if (s->parserIsValid) {
+		if (said_parse_spec(spec)) {
 			printf("Offending spec was: ");
-			((SciEngine*)g_engine)->getVocabulary()->decipherSaidBlock(spec);
+			s->_voc->decipherSaidBlock(spec);
 			return SAID_NO_MATCH;
 		}
 

Modified: scummvm/trunk/engines/sci/engine/said.y
===================================================================
--- scummvm/trunk/engines/sci/engine/said.y	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/said.y	2009-09-30 12:17:38 UTC (rev 44481)
@@ -362,7 +362,7 @@
 	return 0;
 }
 
-static int said_parse_spec(EngineState *s, byte *spec) {
+static int said_parse_spec(byte *spec) {
 	int nextitem;
 
 	said_parse_error = NULL;
@@ -797,15 +797,15 @@
 /**** Main code ****/
 /*******************/
 
-int said(EngineState *s, byte *spec, int verbose) {
+int said(EngineState *s, byte *spec, bool verbose) {
 	int retval;
 
-	parse_tree_node_t *parse_tree_ptr = s->parser_nodes;
+	parse_tree_node_t *parse_tree_ptr = s->_voc->_parser_nodes;
 
-	if (s->parser_valid) {
+	if (s->parserIsValid) {
 		if (said_parse_spec(s, spec)) {
 			warning("Offending spec was: ");
-			((SciEngine*)g_engine)->getVocabulary()->decypherSaidBlock(spec);
+			s->_voc->decipherSaidBlock(spec);
 			return SAID_NO_MATCH;
 		}
 

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -736,7 +736,7 @@
 	}
 
 	// FIXME: Do in-place loading at some point, instead of creating a new EngineState instance from scratch.
-	retval = new EngineState(s->resMan, s->_kernel, s->_flags);
+	retval = new EngineState(s->resMan, s->_kernel, s->_voc, s->_flags);
 
 	// Copy some old data
 	retval->gfx_state = s->gfx_state;

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -30,8 +30,8 @@
 
 namespace Sci {
 
-EngineState::EngineState(ResourceManager *res, Kernel *kernel, uint32 flags)
-: resMan(res), _kernel(kernel), _flags(flags), _dirseeker(this) {
+EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, uint32 flags)
+: resMan(res), _kernel(kernel), _voc(voc), _flags(flags), _dirseeker(this) {
 
 	gfx_state = 0;
 	old_screen = 0;
@@ -100,10 +100,8 @@
 	sys_strings = 0;
 	string_frag_segment = 0;
 
-	memset(parser_nodes, 0, sizeof(parser_nodes));
+	parserIsValid = false;
 
-	parser_valid = 0;
-
 	game_obj = NULL_REG;
 
 	segMan = 0;

Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/engine/state.h	2009-09-30 12:17:38 UTC (rev 44481)
@@ -158,7 +158,7 @@
 
 struct EngineState : public Common::Serializable {
 public:
-	EngineState(ResourceManager *res, Kernel *kernel, uint32 flags);
+	EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, uint32 flags);
 	virtual ~EngineState();
 
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
@@ -167,6 +167,7 @@
 public:
 	ResourceManager *resMan; /**< The resource manager */
 	Kernel *_kernel;
+	Vocabulary *_voc;
 
 	const uint32 _flags;			/**< Specific game flags */
 
@@ -227,6 +228,11 @@
 
 	DirSeeker _dirseeker;
 
+	/* Parser data: */
+	reg_t parser_base; /**< Base address for the parser error reporting mechanism */
+	reg_t parser_event; /**< The event passed to Parse() and later used by Said() */
+	bool parserIsValid; /**< If something has been correctly parsed */
+
 	/* VM Information */
 
 	Common::List<ExecStack> _executionStack; /**< The execution stack */
@@ -245,8 +251,6 @@
 	StackPtr stack_base; /**< Pointer to the least stack element */
 	StackPtr stack_top; /**< First invalid stack element */
 
-	reg_t parser_base; /**< Base address for the parser error reporting mechanism */
-	reg_t parser_event; /**< The event passed to Parse() and later used by Said() */
 	Script *script_000;  /**< script 000, e.g. for globals */
 
 	uint16 currentRoomNumber() const;
@@ -289,13 +293,6 @@
 
 	SegmentId string_frag_segment;
 
-	/* Parser data: */
-	parse_tree_node_t parser_nodes[VOCAB_TREE_NODES]; /**< The parse tree */
-
-	int parser_valid; /**< If something has been correctly parsed */
-
-	SynonymList _synonyms; /**< The list of synonyms */
-
 	reg_t game_obj; /**< Pointer to the game object */
 
 	SegManager *segMan;

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -138,7 +138,7 @@
 	_kernel = new Kernel(_resMan);
 	_vocabulary = new Vocabulary(_resMan);
 
-	_gamestate = new EngineState(_resMan, _kernel, flags);
+	_gamestate = new EngineState(_resMan, _kernel, _vocabulary, flags);
 
 	if (script_init_engine(_gamestate))
 		return Common::kUnknownError;

Modified: scummvm/trunk/engines/sci/vocabulary.cpp
===================================================================
--- scummvm/trunk/engines/sci/vocabulary.cpp	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/vocabulary.cpp	2009-09-30 12:17:38 UTC (rev 44481)
@@ -90,6 +90,13 @@
 	_parserRules = NULL;
 	_vocabVersion = kVocabularySCI0;
 
+	memset(_parserNodes, 0, sizeof(_parserNodes));
+	// Mark parse tree as unused
+	_parserNodes[0].type = kParseTreeLeafNode;
+	_parserNodes[0].content.value = 0;
+
+	_synonyms.clear(); // No synonyms
+
 	debug(2, "Initializing vocabulary");
 
 	if (getSciVersion() <= SCI_VERSION_1_EGA && loadParserWords()) {
@@ -108,6 +115,7 @@
 	_parserWords.clear();
 	_parserBranches.clear();
 	freeSuffixes();
+	_synonyms.clear();
 }
 
 bool Vocabulary::loadParserWords() {
@@ -543,14 +551,86 @@
 	printf("))\n");
 }
 
-void vocab_synonymize_tokens(ResultWordList &words, const SynonymList &synonyms) {
-	if (synonyms.empty())
+void Vocabulary::dumpParseTree() {
+	//_vocab_recursive_ptree_dump_treelike(nodes, 0, 0);
+	printf("(setq parse-tree \n'(");
+	_vocab_recursive_ptree_dump(_parserNodes, 0, 0, 1);
+	printf("))\n");
+}
+
+void Vocabulary::synonymizeTokens(ResultWordList &words) {
+	if (_synonyms.empty())
 		return; // No synonyms: Nothing to check
 
 	for (ResultWordList::iterator i = words.begin(); i != words.end(); ++i)
-		for (SynonymList::const_iterator sync = synonyms.begin(); sync != synonyms.end(); ++sync)
+		for (SynonymList::const_iterator sync = _synonyms.begin(); sync != _synonyms.end(); ++sync)
 			if (i->_group == sync->replaceant)
 				i->_group = sync->replacement;
 }
 
+void Vocabulary::printParserNodes(int num) {
+	Console *con = ((SciEngine *)g_engine)->getSciDebugger();
+
+	for (int i = 0; i < num; i++) {
+		con->DebugPrintf(" Node %03x: ", i);
+		if (_parserNodes[i].type == kParseTreeLeafNode)
+			con->DebugPrintf("Leaf: %04x\n", _parserNodes[i].content.value);
+		else
+			con->DebugPrintf("Branch: ->%04x, ->%04x\n", _parserNodes[i].content.branches[0],
+			          _parserNodes[i].content.branches[1]);
+	}
+}
+
+int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const char **argv) {
+	int nextToken = 0, nextValue = 0, newPos = 0, oldPos = 0;
+	Console *con = ((SciEngine *)g_engine)->getSciDebugger();
+
+	if (type == kParseNil)
+		return 0;
+
+	if (type == kParseNumber) {
+		_parserNodes[*pos += 1].type = kParseTreeLeafNode;
+		_parserNodes[*pos].content.value = nr;
+		return *pos;
+	}
+	if (type == kParseEndOfInput) {
+		con->DebugPrintf("Unbalanced parentheses\n");
+		return -1;
+	}
+	if (type == kParseClosingParenthesis) {
+		con->DebugPrintf("Syntax error at token %d\n", *i);
+		return -1;
+	}
+
+	_parserNodes[oldPos = ++(*pos)].type = kParseTreeBranchNode;
+
+	for (int j = 0; j <= 1; j++) {
+		if (*i == argc) {
+			nextToken = kParseEndOfInput;
+		} else {
+			const char *token = argv[(*i)++];
+
+			if (!strcmp(token, "(")) {
+				nextToken = kParseOpeningParenthesis;
+			} else if (!strcmp(token, ")")) {
+				nextToken = kParseClosingParenthesis;
+			} else if (!strcmp(token, "nil")) {
+				nextToken = kParseNil;
+			} else {
+				nextValue = strtol(token, NULL, 0);
+				nextToken = kParseNumber;
+			}
+		}
+
+		if ((newPos = _parserNodes[oldPos].content.branches[j] = parseNodes(i, pos, nextToken, nextValue, argc, argv)) == -1)
+			return -1;
+	}
+
+	const char *token = argv[(*i)++];
+	if (strcmp(token, ")"))
+		con->DebugPrintf("Expected ')' at token %d\n", *i);
+
+	return oldPos;
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/vocabulary.h
===================================================================
--- scummvm/trunk/engines/sci/vocabulary.h	2009-09-30 11:21:09 UTC (rev 44480)
+++ scummvm/trunk/engines/sci/vocabulary.h	2009-09-30 12:17:38 UTC (rev 44481)
@@ -67,6 +67,14 @@
 	VOCAB_CLASS_NUMBER = 0x001
 };
 
+enum {
+	kParseEndOfInput = 0,
+	kParseOpeningParenthesis = 1,
+	kParseClosingParenthesis = 2,
+	kParseNil = 3,
+	kParseNumber = 4
+};
+
 #define VOCAB_CLASS_ANYWORD 0xff
 /* Anywords are ignored by the parser */
 
@@ -207,17 +215,14 @@
 	bool tokenizeString(ResultWordList &retval, const char *sentence, char **error);
 
 	/* Builds a parse tree from a list of words, using a set of Greibach Normal Form rules
-	** Parameters: (parse_tree_node_t *) nodes: A node list to store the tree in (must have
-	**                                          at least VOCAB_TREE_NODES entries)
+	** Parameters: 
 	**             (const ResultWordList &) words: The words to build the tree from
-	**             (parse_tree_branch_t *) branche0: The zeroeth original branch of the
-	**                                     original CNF parser grammar
 	**             bool verbose: Set to true for debugging
 	** Returns   : 0 on success, 1 if the tree couldn't be built in VOCAB_TREE_NODES nodes
 	**             or if the sentence structure in 'words' is not part of the language
 	**             described by the grammar passed in 'rules'.
 	*/
-	int parseGNF(parse_tree_node_t *nodes, const ResultWordList &words, bool verbose = false);
+	int parseGNF(const ResultWordList &words, bool verbose = false);
 
 	/* Constructs the Greibach Normal Form of the grammar supplied in 'branches'
 	**             bool verbose: Set to true for debugging.
@@ -251,6 +256,31 @@
 	uint getParserBranchesSize() const { return _parserBranches.size(); }
 	const parse_tree_branch_t &getParseTreeBranch(int number) const { return _parserBranches[number]; }
 
+	/**
+	 * Adds a new synonym to the list
+	 */
+	void addSynonym(synonym_t syn) { _synonyms.push_back(syn); }
+	
+	/**
+	 * Clears the list of synonyms
+	 */
+	void clearSynonyms() { _synonyms.clear(); }
+	
+	/** 
+	 * Synonymizes a token list
+	 * Parameters: (ResultWordList &) words: The word list to synonymize
+	 */
+	void synonymizeTokens(ResultWordList &words);
+
+	void printParserNodes(int num);
+
+	void dumpParseTree();
+
+	int parseNodes(int *i, int *pos, int type, int nr, int argc, const char **argv);
+
+	// Accessed by said()
+	parse_tree_node_t _parserNodes[VOCAB_TREE_NODES]; /**< The parse tree */
+
 private:
 	/**
 	 * Loads all words from the main vocabulary.
@@ -290,6 +320,7 @@
 	parse_rule_list_t *_parserRules; /**< GNF rules used in the parser algorithm */
 	Common::Array<parse_tree_branch_t> _parserBranches;
 	WordMap _parserWords;
+	SynonymList _synonyms; /**< The list of synonyms */
 };
 
 /* Prints a parse tree
@@ -303,18 +334,11 @@
 /* Builds a parse tree from a spec and compares it to a parse tree
 ** Parameters: (EngineState *) s: The affected state
 **             (byte *) spec: Pointer to the spec to build
-**             (int) verbose: Whether to display the parse tree after building it
+**             (bool) verbose: Whether to display the parse tree after building it
 ** Returns   : (int) 1 on a match, 0 otherwise
 */
-int said(EngineState *s, byte *spec, int verbose);
+int said(EngineState *s, byte *spec, bool verbose);
 
-
-/* Synonymizes a token list
-** Parameters: (ResultWordList &) words: The word list to synonymize
-**             (const SynonymList &) synonyms: Synonym list
-*/
-void vocab_synonymize_tokens(ResultWordList &words, const SynonymList &synonyms);
-
 int getAllocatedRulesCount();
 
 } // End of namespace Sci


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list