1 // parser.cpp
2 //
3 // Copyright (C) 2001 Chris Laurel <claurel@shatters.net>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9
10 #include "parser.h"
11
12
13 /****** Value method implementations *******/
14
Value(double d)15 Value::Value(double d)
16 {
17 type = NumberType;
18 data.d = d;
19 }
20
Value(string s)21 Value::Value(string s)
22 {
23 type = StringType;
24 data.s = new string(s);
25 }
26
Value(Array * a)27 Value::Value(Array* a)
28 {
29 type = ArrayType;
30 data.a = a;
31 }
32
Value(Hash * h)33 Value::Value(Hash* h)
34 {
35 type = HashType;
36 data.h = h;
37 }
38
Value(bool b)39 Value::Value(bool b)
40 {
41 type = BooleanType;
42 data.d = b ? 1.0 : 0.0;
43 }
44
~Value()45 Value::~Value()
46 {
47 if (type == StringType)
48 {
49 delete data.s;
50 }
51 else if (type == ArrayType)
52 {
53 if (data.a != NULL)
54 {
55 for (unsigned int i = 0; i < data.a->size(); i++)
56 delete (*data.a)[i];
57 delete data.a;
58 }
59 }
60 else if (type == HashType)
61 {
62 if (data.h != NULL)
63 {
64 #if 0
65 Hash::iterator iter = data.h->begin();
66 while (iter != data.h->end())
67 {
68 delete iter->second;
69 iter++;
70 }
71 #endif
72 delete data.h;
73 }
74 }
75 }
76
getType() const77 Value::ValueType Value::getType() const
78 {
79 return type;
80 }
81
getNumber() const82 double Value::getNumber() const
83 {
84 // ASSERT(type == NumberType);
85 return data.d;
86 }
87
getString() const88 string Value::getString() const
89 {
90 // ASSERT(type == StringType);
91 return *data.s;
92 }
93
getArray() const94 Array* Value::getArray() const
95 {
96 // ASSERT(type == ArrayType);
97 return data.a;
98 }
99
getHash() const100 Hash* Value::getHash() const
101 {
102 // ASSERT(type == HashType);
103 return data.h;
104 }
105
getBoolean() const106 bool Value::getBoolean() const
107 {
108 // ASSERT(type == BooleanType);
109 return (data.d != 0.0);
110 }
111
112
113 /****** Parser method implementation ******/
114
Parser(Tokenizer * _tokenizer)115 Parser::Parser(Tokenizer* _tokenizer) :
116 tokenizer(_tokenizer)
117 {
118 }
119
120
readArray()121 Array* Parser::readArray()
122 {
123 Tokenizer::TokenType tok = tokenizer->nextToken();
124 if (tok != Tokenizer::TokenBeginArray)
125 {
126 tokenizer->pushBack();
127 return NULL;
128 }
129
130 Array* array = new Array();
131
132 Value* v = readValue();
133 while (v != NULL)
134 {
135 array->insert(array->end(), v);
136 v = readValue();
137 }
138
139 tok = tokenizer->nextToken();
140 if (tok != Tokenizer::TokenEndArray)
141 {
142 tokenizer->pushBack();
143 delete array;
144 return NULL;
145 }
146
147 return array;
148 }
149
150
readHash()151 Hash* Parser::readHash()
152 {
153 Tokenizer::TokenType tok = tokenizer->nextToken();
154 if (tok != Tokenizer::TokenBeginGroup)
155 {
156 tokenizer->pushBack();
157 return NULL;
158 }
159
160 Hash* hash = new Hash();
161
162 tok = tokenizer->nextToken();
163 while (tok != Tokenizer::TokenEndGroup)
164 {
165 if (tok != Tokenizer::TokenName)
166 {
167 tokenizer->pushBack();
168 delete hash;
169 return NULL;
170 }
171 string name = tokenizer->getNameValue();
172
173 Value* value = readValue();
174 if (value == NULL)
175 {
176 delete hash;
177 return NULL;
178 }
179
180 hash->addValue(name, *value);
181
182 tok = tokenizer->nextToken();
183 }
184
185 return hash;
186 }
187
188
readValue()189 Value* Parser::readValue()
190 {
191 Tokenizer::TokenType tok = tokenizer->nextToken();
192 switch (tok)
193 {
194 case Tokenizer::TokenNumber:
195 return new Value(tokenizer->getNumberValue());
196
197 case Tokenizer::TokenString:
198 return new Value(tokenizer->getStringValue());
199
200 case Tokenizer::TokenName:
201 if (tokenizer->getNameValue() == "false")
202 return new Value(false);
203 else if (tokenizer->getNameValue() == "true")
204 return new Value(true);
205 else
206 {
207 tokenizer->pushBack();
208 return NULL;
209 }
210
211 case Tokenizer::TokenBeginArray:
212 tokenizer->pushBack();
213 {
214 Array* array = readArray();
215 if (array == NULL)
216 return NULL;
217 else
218 return new Value(array);
219 }
220
221 case Tokenizer::TokenBeginGroup:
222 tokenizer->pushBack();
223 {
224 Hash* hash = readHash();
225 if (hash == NULL)
226 return NULL;
227 else
228 return new Value(hash);
229 }
230
231 default:
232 tokenizer->pushBack();
233 return NULL;
234 }
235 }
236
237
AssociativeArray()238 AssociativeArray::AssociativeArray()
239 {
240 }
241
~AssociativeArray()242 AssociativeArray::~AssociativeArray()
243 {
244 #if 0
245 Hash::iterator iter = data.h->begin();
246 while (iter != data.h->end())
247 {
248 delete iter->second;
249 iter++;
250 }
251 #endif
252 for (map<string, Value*>::iterator iter = assoc.begin(); iter != assoc.end(); iter++)
253 delete iter->second;
254 }
255
getValue(string key) const256 Value* AssociativeArray::getValue(string key) const
257 {
258 map<string, Value*>::const_iterator iter = assoc.find(key);
259 if (iter == assoc.end())
260 return NULL;
261 else
262 return iter->second;
263 }
264
addValue(string key,Value & val)265 void AssociativeArray::addValue(string key, Value& val)
266 {
267 assoc.insert(map<string, Value*>::value_type(key, &val));
268 }
269
getNumber(const string & key,double & val) const270 bool AssociativeArray::getNumber(const string& key, double& val) const
271 {
272 Value* v = getValue(key);
273 if (v == NULL || v->getType() != Value::NumberType)
274 return false;
275
276 val = v->getNumber();
277
278 return true;
279 }
280
getNumber(const string & key,float & val) const281 bool AssociativeArray::getNumber(const string& key, float& val) const
282 {
283 double dval;
284
285 if (!getNumber(key, dval))
286 {
287 return false;
288 }
289 else
290 {
291 val = (float) dval;
292 return true;
293 }
294 }
295
getNumber(const string & key,int & val) const296 bool AssociativeArray::getNumber(const string& key, int& val) const
297 {
298 double ival;
299
300 if (!getNumber(key, ival))
301 {
302 return false;
303 }
304 else
305 {
306 val = (int) ival;
307 return true;
308 }
309 }
310
getNumber(const string & key,uint32 & val) const311 bool AssociativeArray::getNumber(const string& key, uint32& val) const
312 {
313 double ival;
314
315 if (!getNumber(key, ival))
316 {
317 return false;
318 }
319 else
320 {
321 val = (uint32) ival;
322 return true;
323 }
324 }
325
getString(const string & key,string & val) const326 bool AssociativeArray::getString(const string& key, string& val) const
327 {
328 Value* v = getValue(key);
329 if (v == NULL || v->getType() != Value::StringType)
330 return false;
331
332 val = v->getString();
333
334 return true;
335 }
336
getBoolean(const string & key,bool & val) const337 bool AssociativeArray::getBoolean(const string& key, bool& val) const
338 {
339 Value* v = getValue(key);
340 if (v == NULL || v->getType() != Value::BooleanType)
341 return false;
342
343 val = v->getBoolean();
344
345 return true;
346 }
347
getVector(const string & key,Vec3d & val) const348 bool AssociativeArray::getVector(const string& key, Vec3d& val) const
349 {
350 Value* v = getValue(key);
351 if (v == NULL || v->getType() != Value::ArrayType)
352 return false;
353
354 Array* arr = v->getArray();
355 if (arr->size() != 3)
356 return false;
357
358 Value* x = (*arr)[0];
359 Value* y = (*arr)[1];
360 Value* z = (*arr)[2];
361
362 if (x->getType() != Value::NumberType ||
363 y->getType() != Value::NumberType ||
364 z->getType() != Value::NumberType)
365 return false;
366
367 val = Vec3d(x->getNumber(), y->getNumber(), z->getNumber());
368
369 return true;
370 }
371
getVector(const string & key,Vec3f & val) const372 bool AssociativeArray::getVector(const string& key, Vec3f& val) const
373 {
374 Vec3d vecVal;
375
376 if (!getVector(key, vecVal))
377 return false;
378
379 val = Vec3f((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
380
381 return true;
382 }
383
384
getRotation(const string & key,Quatf & val) const385 bool AssociativeArray::getRotation(const string& key, Quatf& val) const
386 {
387 Value* v = getValue(key);
388 if (v == NULL || v->getType() != Value::ArrayType)
389 return false;
390
391 Array* arr = v->getArray();
392 if (arr->size() != 4)
393 return false;
394
395 Value* w = (*arr)[0];
396 Value* x = (*arr)[1];
397 Value* y = (*arr)[2];
398 Value* z = (*arr)[3];
399
400 if (w->getType() != Value::NumberType ||
401 x->getType() != Value::NumberType ||
402 y->getType() != Value::NumberType ||
403 z->getType() != Value::NumberType)
404 return false;
405
406 Vec3f axis((float) x->getNumber(),
407 (float) y->getNumber(),
408 (float) z->getNumber());
409 axis.normalize();
410 float angle = degToRad((float) w->getNumber());
411 val.setAxisAngle(axis, angle);
412
413 return true;
414 }
415
getColor(const string & key,Color & val) const416 bool AssociativeArray::getColor(const string& key, Color& val) const
417 {
418 Vec3d vecVal;
419
420 if (!getVector(key, vecVal))
421 return false;
422
423 val = Color((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
424
425 return true;
426 }
427
428
429 HashIterator
begin()430 AssociativeArray::begin()
431 {
432 return assoc.begin();
433 }
434
435
436 HashIterator
end()437 AssociativeArray::end()
438 {
439 return assoc.end();
440 }
441