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 
31 namespace Twp {
32 
33 enum 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
53 enum 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 
67 class YackVisitor;
68 class YackNode {
69 public:
70  virtual ~YackNode() {}
71 
72  virtual void accept(YackVisitor &v) = 0;
73 };
74 
75 // Represents a condition
76 class YCond : public YackNode {
77 public:
78  virtual ~YCond() {}
79 
80 public:
81  int _line;
82 };
83 
84 class YCodeCond : public YCond {
85 public:
86  YCodeCond(int line) { _line = line; }
87  virtual ~YCodeCond() {}
88  virtual void accept(YackVisitor &v) override;
89 
90 public:
91  Common::String _code;
92 };
93 
94 class YOnce : public YCond {
95 public:
96  YOnce(int line) { _line = line; }
97  virtual ~YOnce() {}
98  virtual void accept(YackVisitor &v) override;
99 };
100 
101 class YShowOnce : public YCond {
102 public:
103  YShowOnce(int line) { _line = line; }
104  virtual ~YShowOnce() {}
105  virtual void accept(YackVisitor &v) override;
106 };
107 
108 class YOnceEver : public YCond {
109 public:
110  YOnceEver(int line) { _line = line; }
111  virtual ~YOnceEver() {}
112  virtual void accept(YackVisitor &v) override;
113 };
114 
115 class YTempOnce : public YCond {
116 public:
117  YTempOnce(int line) { _line = line; }
118  virtual ~YTempOnce() {}
119  virtual void accept(YackVisitor &v) override;
120 };
121 
122 // Expression
123 class YExp : public YackNode {
124 public:
125  YExp() {}
126  virtual ~YExp() {}
127 };
128 
129 class YGoto : public YExp {
130 public:
131  YGoto(int line) { _line = line; }
132  virtual ~YGoto() {}
133  virtual void accept(YackVisitor &v) override;
134 
135 public:
136  Common::String _name;
137  int _line = 0;
138 };
139 
140 class YCodeExp : public YExp {
141 public:
142  virtual ~YCodeExp() {}
143  virtual void accept(YackVisitor &v) override;
144 
145 public:
146  Common::String _code;
147 };
148 
149 class YChoice : public YExp {
150 public:
151  virtual ~YChoice() {}
152  virtual void accept(YackVisitor &v) override;
153 
154 public:
155  int _number = 0;
156  Common::String _text;
158 };
159 
160 class YSay : public YExp {
161 public:
162  virtual ~YSay() {}
163  virtual void accept(YackVisitor &v) override;
164 
165 public:
166  Common::String _actor;
167  Common::String _text;
168 };
169 
170 class YPause : public YExp {
171 public:
172  virtual ~YPause() {}
173  virtual void accept(YackVisitor &v) override;
174 
175 public:
176  int _time = 0;
177 };
178 
179 class YParrot : public YExp {
180 public:
181  virtual ~YParrot() {}
182  virtual void accept(YackVisitor &v) override;
183 
184 public:
185  bool _active = true;
186 };
187 
188 class YDialog : public YExp {
189 public:
190  virtual ~YDialog() {}
191  virtual void accept(YackVisitor &v) override;
192 
193 public:
194  Common::String _actor;
195 };
196 
197 class YOverride : public YExp {
198 public:
199  virtual ~YOverride() {}
200  virtual void accept(YackVisitor &v) override;
201 
202 public:
203  Common::String _node;
204 };
205 
206 class YShutup : public YExp {
207 public:
208  virtual ~YShutup() {}
209  virtual void accept(YackVisitor &v) override;
210 };
211 
212 class YAllowObjects : public YExp {
213 public:
214  virtual ~YAllowObjects() {}
215  virtual void accept(YackVisitor &v) override;
216 
217 public:
218  bool _active = true;
219 };
220 
221 class YLimit : public YExp {
222 public:
223  virtual ~YLimit() {}
224  virtual void accept(YackVisitor &v) override;
225 
226 public:
227  int _max = 8;
228 };
229 
230 class YWaitWhile : public YExp {
231 public:
232  virtual ~YWaitWhile() {}
233  virtual void accept(YackVisitor &v) override;
234 
235 public:
236  Common::String _cond;
237 };
238 
239 class YWaitFor : public YExp {
240 public:
241  virtual ~YWaitFor() {}
242  virtual void accept(YackVisitor &v) override;
243 
244 public:
245  Common::String _actor;
246 };
247 
248 //
249 
250 class YStatement : public YackNode {
251 public:
252  virtual ~YStatement() override {}
253 
254  virtual void accept(YackVisitor &v) override;
255 
256 public:
259 };
260 
261 class YLabel : public YackNode {
262 public:
263  YLabel(int line);
264  virtual ~YLabel() override;
265  virtual void accept(YackVisitor &v) override;
266 
267 public:
268  Common::String _name;
270  int _line = 0;
271 };
272 
273 class YCompilationUnit : public YackNode {
274 public:
275  virtual ~YCompilationUnit() override;
276  virtual void accept(YackVisitor &v) override;
277 
278 public:
280 };
281 
282 class YackVisitor {
283 public:
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 
311 struct 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 
321 public:
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 
356 public:
357  void open(Common::SeekableReadStream *stream);
358 
359  iterator begin();
360  iterator end();
361  Common::String readText(const YackToken &YackToken);
362 
363 private:
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 
377 private:
378  Common::SeekableReadStream *_stream = nullptr;
379  int _line = 0;
380 
381  friend class YackParser;
382 };
383 
384 class YackParser {
385 public:
386  YackParser() {}
388 
389 private:
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 
402 private:
403  YackTokenReader _reader;
405 };
406 
407 class YackDump : public YackVisitor {
408 public:
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: yack.h:261
Definition: yack.h:140
Definition: yack.h:197
Definition: str.h:59
Definition: yack.h:160
Definition: yack.h:84
Definition: array.h:52
Definition: yack.h:76
Definition: yack.h:170
Definition: yack.h:282
Definition: yack.h:123
Definition: stream.h:745
Definition: yack.h:179
Definition: yack.h:101
Definition: yack.h:221
Definition: yack.h:407
Definition: yack.h:322
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: yack.h:149
Definition: yack.h:212
Definition: yack.h:250
Definition: yack.h:206
Definition: yack.h:273
Definition: yack.h:239
Definition: yack.h:94
Definition: yack.h:320
Definition: yack.h:384
Definition: yack.h:115
Definition: yack.h:68
Definition: ptr.h:159
Definition: yack.h:188
Definition: yack.h:230
Definition: yack.h:129
Definition: yack.h:311
Definition: achievements_tables.h:27
Definition: yack.h:108