ScummVM API documentation
parser.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 PHOENIXVR_PARSER_H
23#define PHOENIXVR_PARSER_H
24
25#include "common/array.h"
26#include "common/str.h"
27
28namespace PhoenixVR {
29class Parser {
30 const Common::String &_line;
31 uint _lineno;
32 uint _pos;
33
34public:
35 Parser(const Common::String &line, uint lineno) : _line(line), _lineno(lineno), _pos(0) {
36 skip();
37 }
38
39 void skip() {
40 // comment found in amerzone ",*****"
41 if (_pos == 0 && _line[_pos] == ',') {
42 _pos = _line.size();
43 return;
44 }
45 while (_pos < _line.size() && Common::isSpace(_line[_pos]))
46 ++_pos;
47 if (_pos < _line.size() && _line[_pos] == ';')
48 _pos = _line.size();
49 }
50
51 bool atEnd() const { return _pos >= _line.size(); }
52
53 int peek() const { return _pos < _line.size() ? _line[_pos] : 0; }
54 int next() { return _pos < _line.size() ? _line[_pos++] : 0; }
55
56 void expect(int expected) {
57 skip();
58 auto ch = next();
59 if (ch != expected)
60 error("expected '%c' at line %u, got %c in %s", expected, _lineno, ch, _line.c_str());
61 skip();
62 }
63
64 bool maybe(char ch) {
65 skip();
66 if (peek() == ch) {
67 next();
68 return true;
69 } else
70 return false;
71 }
72
73 bool peek(const Common::String &prefix) {
74 skip();
75 if (_pos + prefix.size() > _line.size())
76 return false;
77
78 auto n = prefix.size();
79 auto *ch0 = _line.c_str() + _pos;
80 auto *ch1 = prefix.c_str();
81 while (n--) {
82 if (tolower(*ch0++) != tolower(*ch1++))
83 return false;
84 }
85 return true;
86 }
87
88 bool maybe(const Common::String &prefix) {
89 if (peek(prefix)) {
90 _pos += prefix.size();
91 skip();
92 return true;
93 }
94 return false;
95 }
96
97 bool keyword(const Common::String &prefix) {
98 skip();
99 bool yes = peek(prefix);
100 // keywords ends either on non-alpha or eof
101 if (yes) {
102 auto end = _pos + prefix.size();
103 if (end >= _line.size() || !Common::isAlpha(_line[end])) {
104 _pos += prefix.size();
105 skip();
106 return true;
107 }
108 }
109 return false;
110 }
111
112 Common::String nextArg() {
113 skip();
114 auto begin = _pos;
115 while (_pos < _line.size() && _line[_pos] != ',' && _line[_pos] != ')')
116 ++_pos;
117 auto end = _pos;
118 while (end > begin && Common::isSpace(_line[end - 1]))
119 --end;
120 skip();
121 return _line.substr(begin, end - begin);
122 }
123
124 int nextInt() {
125 bool negative = false;
126 int value = 0;
127 if (maybe('-'))
128 negative = true;
129 do {
130 auto ch = next();
131 if (ch < '0' || ch > '9')
132 error("expected digit at %d, line: %u, %s", _pos, _lineno, _line.c_str());
133 value = value * 10 + (ch - '0');
134 } while (Common::isDigit(peek()));
135 return negative ? -value : value;
136 }
137
138 Common::String nextWord() {
139 skip();
140 auto begin = _pos;
141 while (_pos < _line.size() && !Common::isSpace(_line[_pos]) && _line[_pos] != ',' && _line[_pos] != '(' && _line[_pos] != '=' && _line[_pos] != ')')
142 ++_pos;
143 auto end = _pos;
144 skip();
145 return _line.substr(begin, end - begin);
146 }
147
148 Common::String nextString() {
149 skip();
150 expect('"');
151 Common::String str;
152 while (_pos < _line.size()) {
153 auto ch = _line[_pos++];
154 if (ch == '"')
155 break;
156 str += ch;
157 }
158 skip();
159 return str;
160 }
161
162 Common::Array<Common::String> readStringList() {
164 while (!atEnd() && peek() != ')') {
165 if (peek() == '"')
166 list.push_back(nextString());
167 else {
168 list.push_back(nextArg());
169 }
170 if (!atEnd() && peek() != ')')
171 expect(',');
172 }
173 return list;
174 }
175};
176} // namespace PhoenixVR
177
178#endif
void push_back(const T &element)
Definition: array.h:181
Definition: str.h:59
String substr(size_t pos=0, size_t len=npos) const
Definition: parser.h:29
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
bool isSpace(int c)
bool isAlpha(int c)
bool isDigit(int c)