diff options
Diffstat (limited to 'engines/parallaction/parser.h')
-rw-r--r-- | engines/parallaction/parser.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index 79e6cf6640..7e7937fb19 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -35,6 +35,7 @@ namespace Parallaction { char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false); #define MAX_TOKEN_LEN 50 +extern int _numTokens; extern char _tokens[][MAX_TOKEN_LEN]; class Script { @@ -63,6 +64,7 @@ typedef Common::Functor0<void> Opcode; typedef Common::Array<const Opcode*> OpcodeSet; + class Parser { public: @@ -95,6 +97,7 @@ public: class Parallaction_ns; class Parallaction_br; + class LocationParser_ns { protected: @@ -240,6 +243,23 @@ public: }; +/* + TODO: adapt the parser to effectively use the + statement list provided by preprocessor as its + input, instead of relying on the current Script + class. + + This would need a major rewrite of the parsing + system! + + parseNextToken could then be sealed into the + PreProcessor class forever, together with the + _tokens[] and _numTokens stuff, now dangling as + global objects. + + NS balloons code should be dealt with before, + though. +*/ class LocationParser_br : public LocationParser_ns { protected: @@ -402,6 +422,117 @@ public: }; + +/* + This simple stream is temporarily needed to hook the + preprocessor output to the parser. It will go away + when the parser is rewritten to fully exploit the + statement list provided by the preprocessor. +*/ + +class ReadStringStream : public Common::ReadStream { + + char *_text; + uint32 _pos; + uint32 _size; + +public: + ReadStringStream(const Common::String &text) { + _text = new char[text.size() + 1]; + strcpy(_text, text.c_str()); + _size = text.size(); + _pos = 0; + } + + ~ReadStringStream() { + delete []_text; + } + + uint32 read(void *buffer, uint32 size) { + if (_pos + size > _size) { + size = _size - _pos; + } + memcpy(buffer, _text + _pos, size); + _pos += size; + return size; + } + + bool eos() const { + return _pos == _size; + } + +}; + + +/* + Demented as it may sound, the success of a parsing operation in the + original BRA depends on what has been parsed before. The game features + an innovative chaos system that involves the parser and the very game + engine, in order to inflict the user an unforgettable game experience. + + Ok, now for the serious stuff. + + The PreProcessor implemented here fixes the location scripts before + they are fed to the parser. It tries to do so by a preliminary scan + of the text file, during which a score is assigned to each statement + (more on this later). When the whole file has been analyzed, the + statements are sorted according to their score, to create a parsable + sequence. + + For parsing, the statements in location scripts can be conveniently + divided into 3 groups: + + * location definitions + * element definitions + * start-up commands + + Since the parsing of element definitions requires location parameters + to be set, location definitions should be encountered first in the + script. Start-up commands in turn may reference elements, so they can + be parsed last. The first goal is to make sure the parser gets these + three sets in this order. + + Location definitions must also be presented in a certain sequence, + because resource files are not fully self-describing. In short, some + critical game data in contained in certain files, that must obviously + be read before any other can be analyzed. This is the second goal. + + TODO: some words about actual implementation. +*/ + +class StatementDef; + +struct StatementListNode { + int _score; + Common::String _name; + Common::String _text; + + StatementListNode(int score, const Common::String &name, const Common::String &text) : _score(score), _name(name), _text(text) { } + + bool operator<(const StatementListNode& node) const { + return _score < node._score; + } +}; +typedef Common::List<StatementListNode> StatementList; + + +class PreProcessor { + typedef Common::List<StatementDef*> DefList; + + int _numZones; + DefList _defs; + + StatementDef* findDef(const char* name); + uint getDefScore(StatementDef*); + +public: + PreProcessor(); + ~PreProcessor(); + void preprocessScript(Script &script, StatementList &list); +}; + + + } // namespace Parallaction #endif |