- Moved the kSetSynonyms() function inside kscripts (as it's for script synonyms, not parser word synonyms) - The parser vocabulary is now only initialized for SCI0 and SCI01 games, which had a parser svn-id: r47483
152 lines
4 KiB
C++
152 lines
4 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
/* String and parser handling */
|
|
|
|
#include "sci/resource.h"
|
|
#include "sci/engine/state.h"
|
|
#include "sci/engine/message.h"
|
|
#include "sci/engine/kernel.h"
|
|
|
|
namespace Sci {
|
|
|
|
/*************************************************************/
|
|
/* Parser */
|
|
/**********/
|
|
|
|
|
|
reg_t kSaid(EngineState *s, int argc, reg_t *argv) {
|
|
reg_t heap_said_block = argv[0];
|
|
byte *said_block;
|
|
int new_lastmatch;
|
|
#ifdef DEBUG_PARSER
|
|
const int debug_parser = 1;
|
|
#else
|
|
const int debug_parser = 0;
|
|
#endif
|
|
|
|
if (!heap_said_block.segment)
|
|
return NULL_REG;
|
|
|
|
said_block = (byte *)s->_segMan->derefBulkPtr(heap_said_block, 0);
|
|
|
|
if (!said_block) {
|
|
warning("Said on non-string, pointer %04x:%04x", PRINT_REG(heap_said_block));
|
|
return NULL_REG;
|
|
}
|
|
|
|
#ifdef DEBUG_PARSER
|
|
debugC(2, kDebugLevelParser, "Said block:", 0);
|
|
s->_voc->decipherSaidBlock(said_block);
|
|
#endif
|
|
|
|
if (s->_voc->parser_event.isNull() || (GET_SEL32V(s->_segMan, s->_voc->parser_event, claimed))) {
|
|
return NULL_REG;
|
|
}
|
|
|
|
new_lastmatch = said(s, said_block, debug_parser);
|
|
if (new_lastmatch != SAID_NO_MATCH) { /* Build and possibly display a parse tree */
|
|
|
|
#ifdef DEBUG_PARSER
|
|
printf("kSaid: Match.\n");
|
|
#endif
|
|
|
|
s->r_acc = make_reg(0, 1);
|
|
|
|
if (new_lastmatch != SAID_PARTIAL_MATCH)
|
|
PUT_SEL32V(s->_segMan, s->_voc->parser_event, claimed, 1);
|
|
|
|
} else {
|
|
return NULL_REG;
|
|
}
|
|
return s->r_acc;
|
|
}
|
|
|
|
reg_t kParse(EngineState *s, int argc, reg_t *argv) {
|
|
SegManager *segMan = s->_segMan;
|
|
reg_t stringpos = argv[0];
|
|
Common::String string = s->_segMan->getString(stringpos);
|
|
char *error;
|
|
ResultWordList words;
|
|
reg_t event = argv[1];
|
|
Vocabulary *voc = s->_voc;
|
|
|
|
s->_voc->parser_event = event;
|
|
|
|
bool res = voc->tokenizeString(words, string.c_str(), &error);
|
|
s->_voc->parserIsValid = false; /* not valid */
|
|
|
|
if (res && !words.empty()) {
|
|
s->_voc->synonymizeTokens(words);
|
|
|
|
s->r_acc = make_reg(0, 1);
|
|
|
|
#ifdef DEBUG_PARSER
|
|
debugC(2, kDebugLevelParser, "Parsed to the following blocks:\n", 0);
|
|
|
|
for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i)
|
|
debugC(2, kDebugLevelParser, " Type[%04x] Group[%04x]\n", i->_class, i->_group);
|
|
#endif
|
|
|
|
int syntax_fail = voc->parseGNF(words);
|
|
|
|
if (syntax_fail) {
|
|
s->r_acc = make_reg(0, 1);
|
|
PUT_SEL32V(segMan, event, claimed, 1);
|
|
|
|
invoke_selector(INV_SEL(s->_gameObj, syntaxFail, kStopOnInvalidSelector), 2, s->_voc->parser_base, stringpos);
|
|
/* Issue warning */
|
|
|
|
debugC(2, kDebugLevelParser, "Tree building failed\n");
|
|
|
|
} else {
|
|
s->_voc->parserIsValid = true;
|
|
PUT_SEL32V(segMan, event, claimed, 0);
|
|
|
|
#ifdef DEBUG_PARSER
|
|
s->_voc->dumpParseTree();
|
|
#endif
|
|
}
|
|
|
|
} else {
|
|
|
|
s->r_acc = make_reg(0, 0);
|
|
PUT_SEL32V(segMan, event, claimed, 1);
|
|
if (error) {
|
|
s->_segMan->strcpy(s->_voc->parser_base, error);
|
|
debugC(2, kDebugLevelParser, "Word unknown: %s\n", error);
|
|
/* Issue warning: */
|
|
|
|
invoke_selector(INV_SEL(s->_gameObj, wordFail, kStopOnInvalidSelector), 2, s->_voc->parser_base, stringpos);
|
|
free(error);
|
|
return make_reg(0, 1); /* Tell them that it didn't work */
|
|
}
|
|
}
|
|
|
|
return s->r_acc;
|
|
}
|
|
|
|
|
|
} // End of namespace Sci
|