ScummVM API documentation
yack.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef TWP_YACK_H
23#define TWP_YACK_H
24
25#include "common/array.h"
26#include "common/str.h"
27#include "common/stream.h"
28#include "common/debug.h"
29#include "twp/util.h"
30
31namespace Twp {
32
33enum class YackTokenId {
34 None,
35 NewLine,
36 Identifier,
37 WaitWhile,
38 Int,
39 Float,
40 Whitespace,
41 Colon,
42 Condition,
43 String,
44 Assign,
45 Comment,
46 Goto,
47 Code,
48 Dollar,
49 End
50};
51
52// enumeration that lists all errors that can occur
53enum YackError {
54 ERR_NONE, // no error
55 ERR_INVALIDYackToken, // invalid YackToken
56 ERR_STRINGEXPECTED, // string expected
57 ERR_COLONEXPECTED, // `:` expected
58 ERR_COMMAEXPECTED, // `,` expected
59 ERR_BRACKETRIEXPECTED, // `]` expected
60 ERR_CURLYRIEXPECTED, // `}` expected
61 ERR_QUOTEEXPECTED, // `"` or `'` expected
62 ERR_EOC_EXPECTED, // `*/` expected
63 ERR_EOFEXPECTED, // EOF expected
64 ERR_EXPREXPECTED // expr expected
65};
66
67class YackVisitor;
68class YackNode {
69public:
70 virtual ~YackNode() {}
71
72 virtual void accept(YackVisitor &v) = 0;
73};
74
75// Represents a condition
76class YCond : public YackNode {
77public:
78 virtual ~YCond() {}
79
80public:
81 int _line;
82};
83
84class YCodeCond : public YCond {
85public:
86 YCodeCond(int line) { _line = line; }
87 virtual ~YCodeCond() {}
88 virtual void accept(YackVisitor &v) override;
89
90public:
91 Common::String _code;
92};
93
94class YOnce : public YCond {
95public:
96 YOnce(int line) { _line = line; }
97 virtual ~YOnce() {}
98 virtual void accept(YackVisitor &v) override;
99};
100
101class YShowOnce : public YCond {
102public:
103 YShowOnce(int line) { _line = line; }
104 virtual ~YShowOnce() {}
105 virtual void accept(YackVisitor &v) override;
106};
107
108class YOnceEver : public YCond {
109public:
110 YOnceEver(int line) { _line = line; }
111 virtual ~YOnceEver() {}
112 virtual void accept(YackVisitor &v) override;
113};
114
115class YTempOnce : public YCond {
116public:
117 YTempOnce(int line) { _line = line; }
118 virtual ~YTempOnce() {}
119 virtual void accept(YackVisitor &v) override;
120};
121
122// Expression
123class YExp : public YackNode {
124public:
125 YExp() {}
126 virtual ~YExp() {}
127};
128
129class YGoto : public YExp {
130public:
131 YGoto(int line) { _line = line; }
132 virtual ~YGoto() {}
133 virtual void accept(YackVisitor &v) override;
134
135public:
136 Common::String _name;
137 int _line = 0;
138};
139
140class YCodeExp : public YExp {
141public:
142 virtual ~YCodeExp() {}
143 virtual void accept(YackVisitor &v) override;
144
145public:
146 Common::String _code;
147};
148
149class YChoice : public YExp {
150public:
151 virtual ~YChoice() {}
152 virtual void accept(YackVisitor &v) override;
153
154public:
155 int _number = 0;
156 Common::String _text;
158};
159
160class YSay : public YExp {
161public:
162 virtual ~YSay() {}
163 virtual void accept(YackVisitor &v) override;
164
165public:
166 Common::String _actor;
167 Common::String _text;
168};
169
170class YPause : public YExp {
171public:
172 virtual ~YPause() {}
173 virtual void accept(YackVisitor &v) override;
174
175public:
176 int _time = 0;
177};
178
179class YParrot : public YExp {
180public:
181 virtual ~YParrot() {}
182 virtual void accept(YackVisitor &v) override;
183
184public:
185 bool _active = true;
186};
187
188class YDialog : public YExp {
189public:
190 virtual ~YDialog() {}
191 virtual void accept(YackVisitor &v) override;
192
193public:
194 Common::String _actor;
195};
196
197class YOverride : public YExp {
198public:
199 virtual ~YOverride() {}
200 virtual void accept(YackVisitor &v) override;
201
202public:
203 Common::String _node;
204};
205
206class YShutup : public YExp {
207public:
208 virtual ~YShutup() {}
209 virtual void accept(YackVisitor &v) override;
210};
211
212class YAllowObjects : public YExp {
213public:
214 virtual ~YAllowObjects() {}
215 virtual void accept(YackVisitor &v) override;
216
217public:
218 bool _active = true;
219};
220
221class YLimit : public YExp {
222public:
223 virtual ~YLimit() {}
224 virtual void accept(YackVisitor &v) override;
225
226public:
227 int _max = 8;
228};
229
230class YWaitWhile : public YExp {
231public:
232 virtual ~YWaitWhile() {}
233 virtual void accept(YackVisitor &v) override;
234
235public:
236 Common::String _cond;
237};
238
239class YWaitFor : public YExp {
240public:
241 virtual ~YWaitFor() {}
242 virtual void accept(YackVisitor &v) override;
243
244public:
245 Common::String _actor;
246};
247
248//
249
250class YStatement : public YackNode {
251public:
252 virtual ~YStatement() override {}
253
254 virtual void accept(YackVisitor &v) override;
255
256public:
259};
260
261class YLabel : public YackNode {
262public:
263 YLabel(int line);
264 virtual ~YLabel() override;
265 virtual void accept(YackVisitor &v) override;
266
267public:
268 Common::String _name;
270 int _line = 0;
271};
272
274public:
275 virtual ~YCompilationUnit() override;
276 virtual void accept(YackVisitor &v) override;
277
278public:
280};
281
283public:
284 virtual ~YackVisitor() {}
285
286 virtual void visit(const YCompilationUnit &node) { defaultVisit(node); }
287 virtual void visit(const YStatement &node) { defaultVisit(node); }
288 virtual void visit(const YWaitFor &node) { defaultVisit(node); }
289 virtual void visit(const YWaitWhile &node) { defaultVisit(node); }
290 virtual void visit(const YLimit &node) { defaultVisit(node); }
291 virtual void visit(const YAllowObjects &node) { defaultVisit(node); }
292 virtual void visit(const YShutup &node) { defaultVisit(node); }
293 virtual void visit(const YOverride &node) { defaultVisit(node); }
294 virtual void visit(const YDialog &node) { defaultVisit(node); }
295 virtual void visit(const YParrot &node) { defaultVisit(node); }
296 virtual void visit(const YPause &node) { defaultVisit(node); }
297 virtual void visit(const YSay &node) { defaultVisit(node); }
298 virtual void visit(const YChoice &node) { defaultVisit(node); }
299 virtual void visit(const YCodeExp &node) { defaultVisit(node); }
300 virtual void visit(const YGoto &node) { defaultVisit(node); }
301 virtual void visit(const YTempOnce &node) { defaultVisit(node); }
302 virtual void visit(const YOnceEver &node) { defaultVisit(node); }
303 virtual void visit(const YShowOnce &node) { defaultVisit(node); }
304 virtual void visit(const YOnce &node) { defaultVisit(node); }
305 virtual void visit(const YCodeCond &node) { defaultVisit(node); }
306 virtual void visit(const YLabel &node) { defaultVisit(node); }
307
308 virtual void defaultVisit(const YackNode &node) {}
309};
310
311struct YackToken {
312 YackTokenId id = YackTokenId::None;
313 int64 start = 0;
314 int64 end = 0;
315 int line = 0;
316
317 Common::String toString() const;
318};
319
321public:
322 class Iterator {
323 public:
324 using value_type = YackToken;
325 using difference_type = ptrdiff_t;
326 using pointer = YackToken *;
327 using reference = YackToken &;
328
329 private:
330 YackTokenReader *_reader = nullptr;
331 int64 _pos = 0;
332 YackToken _token;
333
334 public:
335 Iterator() {}
336 Iterator(YackTokenReader &reader, int64 pos);
337 Iterator(const Iterator &it);
338 Iterator &operator++();
339 Iterator operator++(int);
340
341 Iterator &operator=(const Iterator &rhs) {
342 _pos = rhs._pos;
343 _token = rhs._token;
344 _reader = rhs._reader;
345 return *this;
346 }
347 bool operator==(const Iterator &rhs) const { return _pos == rhs._pos; }
348 bool operator!=(const Iterator &rhs) const { return _pos != rhs._pos; }
349 YackToken &operator*();
350 const YackToken &operator*() const;
351 YackToken *operator->();
352 };
353
354 using iterator = Iterator;
355
356public:
357 void open(Common::SeekableReadStream *stream);
358
359 iterator begin();
360 iterator end();
361 Common::String readText(const YackToken &YackToken);
362
363private:
364 bool readYackToken(YackToken &YackToken);
365 Common::String readText(int64 pos, int64 size);
366 YackTokenId readYackTokenId();
367 YackTokenId readCode();
368 YackTokenId readCondition();
369 YackTokenId readDollar();
370 YackTokenId readNumber();
371 YackTokenId readComment();
372 YackTokenId readString();
373 YackTokenId readIdentifier(char c);
374 byte peek();
375 void ignore(int64 n = 1, int delim = EOF);
376
377private:
378 Common::SeekableReadStream *_stream = nullptr;
379 int _line = 0;
380
381 friend class YackParser;
382};
383
385public:
386 YackParser() {}
388
389private:
390 bool match(const std::initializer_list<YackTokenId> &ids);
391 Common::SharedPtr<YLabel> parseLabel();
392 Common::SharedPtr<YStatement> parseStatement();
393 Common::SharedPtr<YCond> parseCondition();
394 Common::SharedPtr<YExp> parseExpression();
395 Common::SharedPtr<YSay> parseSayExpression();
396 Common::SharedPtr<YExp> parseWaitWhileExpression();
397 Common::SharedPtr<YExp> parseInstructionExpression();
398 Common::SharedPtr<YGoto> parseGotoExpression();
399 Common::SharedPtr<YCodeExp> parseCodeExpression();
400 Common::SharedPtr<YChoice> parseChoiceExpression();
401
402private:
403 YackTokenReader _reader;
405};
406
407class YackDump : public YackVisitor {
408public:
409 virtual ~YackDump() {}
410
411 virtual void visit(const YCompilationUnit &node) {
412 debug("CompilationUnit:");
413 for (const auto &cond : node._labels) {
414 cond->accept(*this);
415 }
416 }
417 virtual void visit(const YLabel &node) {
418 debug("Label: %s [%d]", node._name.c_str(), node._line);
419 for (const auto &stmt : node._stmts) {
420 stmt->accept(*this);
421 }
422 }
423 virtual void visit(const YStatement &node) {
424 debug("Statement:");
425 for (const auto &cond : node._conds) {
426 cond->accept(*this);
427 }
428 node._exp->accept(*this);
429 }
430 virtual void visit(const YWaitFor &node) { debug("WaifFor %s", node._actor.c_str()); }
431 virtual void visit(const YWaitWhile &node) { debug("WaitWhile %s", node._cond.c_str()); }
432 virtual void visit(const YLimit &node) { debug("Limit: %d", node._max); }
433 virtual void visit(const YAllowObjects &node) { debug("AllowObjects"); }
434 virtual void visit(const YShutup &node) { debug("Shutup"); }
435 virtual void visit(const YOverride &node) { defaultVisit(node); }
436 virtual void visit(const YDialog &node) { debug("Dialog: %s", node._actor.c_str()); }
437 virtual void visit(const YParrot &node) { debug("Parrot: %s", node._active ? "YES" : "NO"); }
438 virtual void visit(const YPause &node) { debug("Pause: %d", node._time); }
439 virtual void visit(const YSay &node) { debug("Say: actor: %s, text = %s", node._actor.c_str(), node._text.c_str()); }
440 virtual void visit(const YChoice &node) { debug("Choice %d: %s -> %s", node._number, node._text.c_str(), node._goto->_name.c_str()); }
441 virtual void visit(const YCodeExp &node) { debug("Code: %s", node._code.c_str()); }
442 virtual void visit(const YGoto &node) { debug("Goto: %s", node._name.c_str()); }
443 virtual void visit(const YTempOnce &node) { debug("TempOnce"); }
444 virtual void visit(const YOnceEver &node) { debug("OnceEver"); }
445 virtual void visit(const YShowOnce &node) { debug("ShowOnce"); }
446 virtual void visit(const YOnce &node) { debug("Once"); }
447 virtual void visit(const YCodeCond &node) { debug("Cond: %s", node._code.c_str()); }
448
449 virtual void defaultVisit(const YackNode &node) {}
450};
451
452} // namespace Twp
453
454#endif
Definition: array.h:52
Definition: stream.h:745
Definition: ptr.h:159
Definition: str.h:59
Definition: yack.h:212
Definition: yack.h:149
Definition: yack.h:84
Definition: yack.h:140
Definition: yack.h:273
Definition: yack.h:76
Definition: yack.h:188
Definition: yack.h:123
Definition: yack.h:129
Definition: yack.h:261
Definition: yack.h:221
Definition: yack.h:108
Definition: yack.h:94
Definition: yack.h:197
Definition: yack.h:179
Definition: yack.h:170
Definition: yack.h:160
Definition: yack.h:101
Definition: yack.h:206
Definition: yack.h:250
Definition: yack.h:115
Definition: yack.h:239
Definition: yack.h:230
Definition: yack.h:407
Definition: yack.h:68
Definition: yack.h:384
Definition: yack.h:322
Definition: yack.h:320
Definition: yack.h:282
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: yack.h:311