Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

parser.cpp

Go to the documentation of this file.
00001 // parser.cpp
00002 //
00003 // Copyright (C) 2001 Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include "parser.h"
00011 
00012 
00013 /****** Value method implementations *******/
00014 
00015 Value::Value(double d)
00016 {
00017     type = NumberType;
00018     data.d = d;
00019 }
00020 
00021 Value::Value(string s)
00022 {
00023     type = StringType;
00024     data.s = new string(s);
00025 }
00026 
00027 Value::Value(Array* a)
00028 {
00029     type = ArrayType;
00030     data.a = a;
00031 }
00032 
00033 Value::Value(Hash* h)
00034 {
00035     type = HashType;
00036     data.h = h;
00037 }
00038 
00039 Value::Value(bool b)
00040 {
00041     type = BooleanType;
00042     data.d = b ? 1.0 : 0.0;
00043 }
00044 
00045 Value::~Value()
00046 {
00047     if (type == StringType)
00048     {
00049         delete data.s;
00050     }
00051     else if (type == ArrayType)
00052     {
00053         if (data.a != NULL)
00054         {
00055             for (unsigned int i = 0; i < data.a->size(); i++)
00056                 delete (*data.a)[i];
00057             delete data.a;
00058         }
00059     }
00060     else if (type == HashType)
00061     {
00062         if (data.h != NULL)
00063         {
00064 #if 0
00065             Hash::iterator iter = data.h->begin();
00066             while (iter != data.h->end())
00067             {
00068                 delete iter->second;
00069                 iter++;
00070             }
00071 #endif
00072             delete data.h;
00073         }
00074     }
00075 }
00076 
00077 Value::ValueType Value::getType() const
00078 {
00079     return type;
00080 }
00081 
00082 double Value::getNumber() const
00083 {
00084     // ASSERT(type == NumberType);
00085     return data.d;
00086 }
00087 
00088 string Value::getString() const
00089 {
00090     // ASSERT(type == StringType);
00091     return *data.s;
00092 }
00093 
00094 Array* Value::getArray() const
00095 {
00096     // ASSERT(type == ArrayType);
00097     return data.a;
00098 }
00099 
00100 Hash* Value::getHash() const
00101 {
00102     // ASSERT(type == HashType);
00103     return data.h;
00104 }
00105 
00106 bool Value::getBoolean() const
00107 {
00108     // ASSERT(type == BooleanType);
00109     return (data.d != 0.0);
00110 }
00111 
00112 
00113 /****** Parser method implementation ******/
00114 
00115 Parser::Parser(Tokenizer* _tokenizer) :
00116     tokenizer(_tokenizer)
00117 {
00118 }
00119 
00120 
00121 Array* Parser::readArray()
00122 {
00123     Tokenizer::TokenType tok = tokenizer->nextToken();
00124     if (tok != Tokenizer::TokenBeginArray)
00125     {
00126         tokenizer->pushBack();
00127         return NULL;
00128     }
00129 
00130     Array* array = new Array();
00131 
00132     Value* v = readValue();
00133     while (v != NULL)
00134     {
00135         array->insert(array->end(), v);
00136         v = readValue();
00137     }
00138     
00139     tok = tokenizer->nextToken();
00140     if (tok != Tokenizer::TokenEndArray)
00141     {
00142         tokenizer->pushBack();
00143         delete array;
00144         return NULL;
00145     }
00146 
00147     return array;
00148 }
00149 
00150 
00151 Hash* Parser::readHash()
00152 {
00153     Tokenizer::TokenType tok = tokenizer->nextToken();
00154     if (tok != Tokenizer::TokenBeginGroup)
00155     {
00156         tokenizer->pushBack();
00157         return NULL;
00158     }
00159 
00160     Hash* hash = new Hash();
00161 
00162     tok = tokenizer->nextToken();
00163     while (tok != Tokenizer::TokenEndGroup)
00164     {
00165         if (tok != Tokenizer::TokenName)
00166         {
00167             tokenizer->pushBack();
00168             delete hash;
00169             return NULL;
00170         }
00171         string name = tokenizer->getNameValue();
00172 
00173         Value* value = readValue();
00174         if (value == NULL)
00175         {
00176             delete hash;
00177             return NULL;
00178         }
00179         
00180         hash->addValue(name, *value);
00181 
00182         tok = tokenizer->nextToken();
00183     }
00184 
00185     return hash;
00186 }
00187 
00188 
00189 Value* Parser::readValue()
00190 {
00191     Tokenizer::TokenType tok = tokenizer->nextToken();
00192     switch (tok)
00193     {
00194     case Tokenizer::TokenNumber:
00195         return new Value(tokenizer->getNumberValue());
00196 
00197     case Tokenizer::TokenString:
00198         return new Value(tokenizer->getStringValue());
00199 
00200     case Tokenizer::TokenName:
00201         if (tokenizer->getNameValue() == "false")
00202             return new Value(false);
00203         else if (tokenizer->getNameValue() == "true")
00204             return new Value(true);
00205         else
00206         {
00207             tokenizer->pushBack();
00208             return NULL;
00209         }
00210 
00211     case Tokenizer::TokenBeginArray:
00212         tokenizer->pushBack();
00213         {
00214             Array* array = readArray();
00215             if (array == NULL)
00216                 return NULL;
00217             else
00218                 return new Value(array);
00219         }
00220 
00221     case Tokenizer::TokenBeginGroup:
00222         tokenizer->pushBack();
00223         {
00224             Hash* hash = readHash();
00225             if (hash == NULL)
00226                 return NULL;
00227             else
00228                 return new Value(hash);
00229         }
00230 
00231     default:
00232         tokenizer->pushBack();
00233         return NULL;
00234     }
00235 }
00236 
00237 
00238 AssociativeArray::AssociativeArray()
00239 {
00240 }
00241 
00242 AssociativeArray::~AssociativeArray()
00243 {
00244 #if 0
00245     Hash::iterator iter = data.h->begin();
00246     while (iter != data.h->end())
00247     {
00248         delete iter->second;
00249         iter++;
00250     }
00251 #endif
00252     for (map<string, Value*>::iterator iter = assoc.begin(); iter != assoc.end(); iter++)
00253         delete iter->second;
00254 }
00255 
00256 Value* AssociativeArray::getValue(string key) const
00257 {
00258     map<string, Value*>::const_iterator iter = assoc.find(key);
00259     if (iter == assoc.end())
00260         return NULL;
00261     else
00262         return iter->second;
00263 }
00264 
00265 void AssociativeArray::addValue(string key, Value& val)
00266 {
00267     assoc.insert(map<string, Value*>::value_type(key, &val));
00268 }
00269 
00270 bool AssociativeArray::getNumber(const string& key, double& val) const
00271 {
00272     Value* v = getValue(key);
00273     if (v == NULL || v->getType() != Value::NumberType)
00274         return false;
00275 
00276     val = v->getNumber();
00277 
00278     return true;
00279 }
00280 
00281 bool AssociativeArray::getNumber(const string& key, float& val) const
00282 {
00283     double dval;
00284 
00285     if (!getNumber(key, dval))
00286     {
00287         return false;
00288     }
00289     else
00290     {
00291         val = (float) dval;
00292         return true;
00293     }
00294 }
00295 
00296 bool AssociativeArray::getNumber(const string& key, int& val) const
00297 {
00298     double ival;
00299 
00300     if (!getNumber(key, ival))
00301     {
00302         return false;
00303     }
00304     else
00305     {
00306         val = (int) ival;
00307         return true;
00308     }
00309 }
00310 
00311 bool AssociativeArray::getString(const string& key, string& val) const
00312 {
00313     Value* v = getValue(key);
00314     if (v == NULL || v->getType() != Value::StringType)
00315         return false;
00316 
00317     val = v->getString();
00318 
00319     return true;
00320 }
00321 
00322 bool AssociativeArray::getBoolean(const string& key, bool& val) const
00323 {
00324     Value* v = getValue(key);
00325     if (v == NULL || v->getType() != Value::BooleanType)
00326         return false;
00327 
00328     val = v->getBoolean();
00329 
00330     return true;
00331 }
00332 
00333 bool AssociativeArray::getVector(const string& key, Vec3d& val) const
00334 {
00335     Value* v = getValue(key);
00336     if (v == NULL || v->getType() != Value::ArrayType)
00337         return false;
00338 
00339     Array* arr = v->getArray();
00340     if (arr->size() != 3)
00341         return false;
00342 
00343     Value* x = (*arr)[0];
00344     Value* y = (*arr)[1];
00345     Value* z = (*arr)[2];
00346 
00347     if (x->getType() != Value::NumberType ||
00348         y->getType() != Value::NumberType ||
00349         z->getType() != Value::NumberType)
00350         return false;
00351 
00352     val = Vec3d(x->getNumber(), y->getNumber(), z->getNumber());
00353 
00354     return true;
00355 }
00356 
00357 bool AssociativeArray::getVector(const string& key, Vec3f& val) const
00358 {
00359     Vec3d vecVal;
00360 
00361     if (!getVector(key, vecVal))
00362         return false;
00363 
00364     val = Vec3f((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
00365 
00366     return true;
00367 }
00368 
00369 
00370 bool AssociativeArray::getRotation(const string& key, Quatf& val) const
00371 {
00372     Value* v = getValue(key);
00373     if (v == NULL || v->getType() != Value::ArrayType)
00374         return false;
00375 
00376     Array* arr = v->getArray();
00377     if (arr->size() != 4)
00378         return false;
00379 
00380     Value* w = (*arr)[0];
00381     Value* x = (*arr)[1];
00382     Value* y = (*arr)[2];
00383     Value* z = (*arr)[3];
00384 
00385     if (w->getType() != Value::NumberType ||
00386         x->getType() != Value::NumberType ||
00387         y->getType() != Value::NumberType ||
00388         z->getType() != Value::NumberType)
00389         return false;
00390 
00391     Vec3f axis((float) x->getNumber(),
00392                (float) y->getNumber(),
00393                (float) z->getNumber());
00394     axis.normalize();
00395     float angle = degToRad((float) w->getNumber());
00396     val.setAxisAngle(axis, angle);
00397 
00398     return true;
00399 }
00400 
00401 bool AssociativeArray::getColor(const string& key, Color& val) const
00402 {
00403     Vec3d vecVal;
00404 
00405     if (!getVector(key, vecVal))
00406         return false;
00407 
00408     val = Color((float) vecVal.x, (float) vecVal.y, (float) vecVal.z);
00409 
00410     return true;
00411 }

Generated on Sat Jan 14 22:30:28 2006 for Celestia by  doxygen 1.4.1