Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef VLXParserVLT_INCLUDE_ONCE
00033 #define VLXParserVLT_INCLUDE_ONCE
00034
00035 #include <vlCore/VLXParser.hpp>
00036 #include <vlCore/VLTTokenizer.hpp>
00037 #include <cstdlib>
00038
00039 #ifdef _MSC_VER
00040 #define atoll _atoi64
00041 #endif
00042
00043 namespace vl
00044 {
00046 class VLXParserVLT: public VLXParser
00047 {
00048 VL_INSTRUMENT_CLASS(vl::VLXParserVLT, VLXParser)
00049
00050 public:
00051 VLXParserVLT()
00052 {
00053 mTokenizer = new VLTTokenizer;
00054 mVersion = 0;
00055 }
00056
00057 bool getToken(VLTToken& token) { return mTokenizer->getToken(token); }
00058
00059 bool parseHeader()
00060 {
00061 mVersion = 0;
00062 mEncoding.clear();
00063
00064
00065 if (!getToken(mToken) || mToken.mType != VLTToken::Identifier || mToken.mString != "VLX")
00066 {
00067 Log::error("'VLX' header not found!\n");
00068 return false;
00069 }
00070
00071
00072 if (!getToken(mToken) || mToken.mType != VLTToken::Identifier || mToken.mString != "version")
00073 return false;
00074
00075 if (!getToken(mToken) || mToken.mType != VLTToken::Equals)
00076 return false;
00077
00078 if (!getToken(mToken) || mToken.mType != VLTToken::Integer || mToken.mString != "100")
00079 return false;
00080 else
00081 mVersion = (unsigned short)atoi( mToken.mString.c_str() );
00082
00083
00084 if (!getToken(mToken) || mToken.mType != VLTToken::Identifier || mToken.mString != "encoding")
00085 return false;
00086
00087 if (!getToken(mToken) || mToken.mType != VLTToken::Equals)
00088 return false;
00089
00090 if (!getToken(mToken) || mToken.mType != VLTToken::Identifier || mToken.mString != "ascii")
00091 return false;
00092 else
00093 mEncoding = mToken.mString;
00094
00095 return true;
00096 }
00097
00098 bool parse()
00099 {
00100 class CloseFileClass
00101 {
00102 public:
00103 CloseFileClass(VirtualFile* f): mFile(f) {}
00104 ~CloseFileClass()
00105 {
00106 if (mFile)
00107 mFile->close();
00108 }
00109 private:
00110 ref<VirtualFile> mFile;
00111 } CloseFile(tokenizer()->inputFile());
00112
00113
00114 mMetadata.clear();
00115
00116
00117 if (!parseHeader())
00118 {
00119 Log::error( Say("Line %n : error parsing VLT header at '%s'.\n") << tokenizer()->lineNumber() << mToken.mString );
00120 return false;
00121 }
00122
00123 if (mVersion != 100)
00124 {
00125 Log::error("VLX version not supported.\n");
00126 return false;
00127 }
00128
00129 if (mEncoding != "ascii")
00130 {
00131 Log::error("Encoding not supported.\n");
00132 return false;
00133 }
00134
00135 while(getToken(mToken) && mToken.mType != VLTToken::TOKEN_EOF)
00136 {
00137 if(mToken.mType == VLTToken::TagHeader)
00138 {
00139 mLastTag = mToken.mString;
00140
00141 if(getToken(mToken) && mToken.mType == VLTToken::LeftCurlyBracket)
00142 {
00143 ref<VLXStructure> st = new VLXStructure;
00144 st->setLineNumber( tokenizer()->lineNumber() );
00145
00146 if (!parseStructure(st.get()))
00147 {
00148 if (mToken.mString.length())
00149 Log::error( Say("Line %n : parse error at '%s'.\n") << mTokenizer->lineNumber() << mToken.mString.c_str() );
00150 else
00151 Log::error( Say("Line %n : parse error.\n") << mTokenizer->lineNumber() );
00152 return false;
00153 }
00154
00155 mStructures.push_back(st);
00156 }
00157 else
00158 {
00159 Log::error( Say("Line %n : parse error at '%s'.\n") << mTokenizer->lineNumber() << mToken.mString.c_str() );
00160 return false;
00161 }
00162 }
00163 else
00164 {
00165 Log::error( Say("Line %n : parse error at '%s'.\n") << mTokenizer->lineNumber() << mToken.mString.c_str() );
00166 return false;
00167 }
00168 }
00169
00170 parseMetadata();
00171
00172 VL_CHECK(mToken.mType == VLTToken::TOKEN_EOF)
00173 return mToken.mType == VLTToken::TOKEN_EOF;
00174 }
00175
00176 bool parseStructure(VLXStructure* object)
00177 {
00178
00179 if (!mLastTag.empty())
00180 {
00181 object->setTag(mLastTag.c_str());
00182 mLastTag.clear();
00183 }
00184
00185 while(getToken(mToken))
00186 {
00187 if (mToken.mType == VLTToken::RightCurlyBracket)
00188 {
00189 return true;
00190 }
00191 else
00192 if (mToken.mType == VLTToken::Identifier)
00193 {
00194
00195 if (mToken.mString.length() == 2)
00196 {
00197 if (mToken.mString == "ID")
00198 {
00199
00200 if (!object->uid().empty() && object->uid() != "#NULL")
00201 {
00202 Log::error("ID already set.\n");
00203 return false;
00204 }
00205
00206
00207 if (!getToken(mToken) || mToken.mType != VLTToken::Equals)
00208 return false;
00209
00210
00211 if (getToken(mToken) && mToken.mType == VLTToken::ID)
00212 {
00213 object->setID(mToken.mString.c_str());
00214 continue;
00215 }
00216 else
00217 return false;
00218 }
00219 else
00220
00221 if (mToken.mString == "Id" || mToken.mString == "iD" || mToken.mString == "id")
00222 return false;
00223 }
00224
00225
00226 object->value().push_back( VLXStructure::Value() );
00227 VLXStructure::Value& name_value = object->value().back();
00228
00229
00230 name_value.setKey( mToken.mString.c_str() );
00231
00232
00233 if (!getToken(mToken) || mToken.mType != VLTToken::Equals)
00234 return false;
00235
00236
00237 if (getToken(mToken))
00238 {
00239 name_value.value().setLineNumber( tokenizer()->lineNumber() );
00240
00241
00242 if (mToken.mType == VLTToken::TagHeader)
00243 {
00244 if (mLastTag.empty())
00245 {
00246 mLastTag = mToken.mString;
00247 if (!getToken(mToken))
00248 return false;
00249 }
00250 else
00251 return false;
00252 }
00253
00254
00255 if (mToken.mType == VLTToken::LeftCurlyBracket)
00256 {
00257 ref<VLXStructure> object = new VLXStructure;
00258 object->setLineNumber( tokenizer()->lineNumber() );
00259 name_value.value().setStructure(object.get());
00260 if (!parseStructure( object.get() ) )
00261 return false;
00262 }
00263 else
00264
00265 if (mToken.mType == VLTToken::LeftSquareBracket)
00266 {
00267 ref<VLXList> list = new VLXList;
00268 list->setLineNumber( tokenizer()->lineNumber() );
00269 name_value.value().setList(list.get());
00270 if ( !parseList( list.get() ) )
00271 return false;
00272 }
00273 else
00274
00275 if (mToken.mType == VLTToken::LeftRoundBracket)
00276 {
00277 ref<VLXArray> arr;
00278 if ( parseArray( arr ) )
00279 name_value.value().setArray(arr.get());
00280 else
00281 return false;
00282 }
00283 else
00284
00285 if (mToken.mType == VLTToken::LeftFancyBracket)
00286 {
00287 if(!getToken(mToken) || mToken.mType != VLTToken::RawtextBlock)
00288 return false;
00289 name_value.value().setRawtextBlock( new VLXRawtextBlock(mLastTag.c_str()) );
00290 name_value.value().getRawtextBlock()->setValue( mToken.mString.c_str() );
00291
00292 mLastTag.clear();
00293 if(!getToken(mToken) || mToken.mType != VLTToken::RightFancyBracket)
00294 return false;
00295 }
00296 else
00297
00298 if (mToken.mType == VLTToken::String)
00299 {
00300 if (!mLastTag.empty())
00301 return false;
00302 name_value.value().setString(mToken.mString.c_str());
00303 }
00304 else
00305
00306 if (mToken.mType == VLTToken::Identifier)
00307 {
00308 if (!mLastTag.empty())
00309 return false;
00310 name_value.value().setIdentifier(mToken.mString.c_str());
00311 }
00312 else
00313
00314 if (mToken.mType == VLTToken::ID)
00315 {
00316 if (!mLastTag.empty())
00317 return false;
00318 name_value.value().setID(mToken.mString.c_str());
00319 }
00320 else
00321
00322 if (mToken.mType == VLTToken::Boolean)
00323 {
00324 if (!mLastTag.empty())
00325 return false;
00326 name_value.value().setBool(mToken.mString == "true");
00327 }
00328 else
00329
00330 if (mToken.mType == VLTToken::Integer)
00331 {
00332 if (!mLastTag.empty())
00333 return false;
00334 name_value.value().setInteger( atoll(mToken.mString.c_str()) );
00335 }
00336 else
00337
00338 if (mToken.mType == VLTToken::real)
00339 {
00340 if (!mLastTag.empty())
00341 return false;
00342 name_value.value().setReal( atof(mToken.mString.c_str()) );
00343 }
00344 else
00345 return false;
00346 }
00347 }
00348 else
00349 return false;
00350 }
00351 return false;
00352 }
00353
00354 bool parseList(VLXList* list)
00355 {
00356
00357 if (!mLastTag.empty())
00358 {
00359 list->setTag(mLastTag.c_str());
00360 mLastTag.clear();
00361 }
00362
00363 while(getToken(mToken))
00364 {
00365 if (mToken.mType == VLTToken::RightSquareBracket)
00366 return true;
00367 else
00368 {
00369 VLXValue value;
00370 value.setLineNumber( tokenizer()->lineNumber() );
00371 switch( mToken.mType )
00372 {
00373
00374 case VLTToken::TagHeader:
00375 {
00376 if (mLastTag.empty())
00377 mLastTag = mToken.mString;
00378 else
00379 return false;
00380 break;
00381 }
00382
00383
00384 case VLTToken::LeftCurlyBracket:
00385 {
00386 ref<VLXStructure> object = new VLXStructure;
00387 object->setLineNumber( tokenizer()->lineNumber() );
00388 if ( parseStructure( object.get() ) )
00389 {
00390 value.setStructure(object.get());
00391 list->value().push_back( value );
00392 }
00393 else
00394 return false;
00395 break;
00396 }
00397
00398
00399 case VLTToken::LeftSquareBracket:
00400 {
00401 ref<VLXList> sub_list = new VLXList;
00402 sub_list->setLineNumber( tokenizer()->lineNumber() );
00403 if ( parseList( sub_list.get() ) )
00404 {
00405 value.setList( sub_list.get() );
00406 list->value().push_back( value );
00407 }
00408 else
00409 return false;
00410 break;
00411 }
00412
00413
00414 case VLTToken::LeftRoundBracket:
00415 {
00416 ref<VLXArray> arr;
00417 if (parseArray(arr))
00418 {
00419 value.setArray(arr.get());
00420 list->value().push_back(value);
00421 }
00422 else
00423 return false;
00424 break;
00425 }
00426
00427
00428 case VLTToken::String:
00429 if (!mLastTag.empty())
00430 return false;
00431 value.setString( mToken.mString.c_str() ); list->value().push_back( value );
00432 break;
00433
00434
00435 case VLTToken::Identifier:
00436 if (!mLastTag.empty())
00437 return false;
00438 value.setIdentifier( mToken.mString.c_str() ); list->value().push_back( value );
00439 break;
00440
00441
00442 case VLTToken::LeftFancyBracket:
00443 {
00444 if(!getToken(mToken) || mToken.mType != VLTToken::RawtextBlock)
00445 return false;
00446
00447 value.setRawtextBlock( new VLXRawtextBlock(mLastTag.c_str()) );
00448 value.getRawtextBlock()->setValue( mToken.mString.c_str() );
00449 list->value().push_back( value );
00450
00451 mLastTag.clear();
00452
00453 if(!getToken(mToken) || mToken.mType != VLTToken::RightFancyBracket)
00454 return false;
00455 break;
00456 }
00457
00458
00459 case VLTToken::ID:
00460 if (!mLastTag.empty())
00461 return false;
00462 value.setID( mToken.mString.c_str() ); list->value().push_back( value );
00463 break;
00464
00465
00466 case VLTToken::Boolean:
00467 if (!mLastTag.empty())
00468 return false;
00469 value.setBool( mToken.mString == "true" ); list->value().push_back( value );
00470 break;
00471
00472
00473 case VLTToken::Integer:
00474 if (!mLastTag.empty())
00475 return false;
00476 value.setInteger( atoll(mToken.mString.c_str()) ); list->value().push_back( value );
00477 break;
00478
00479
00480 case VLTToken::real:
00481 if (!mLastTag.empty())
00482 return false;
00483 value.setReal( atof(mToken.mString.c_str()) ); list->value().push_back( value );
00484 break;
00485
00486 default:
00487 return false;
00488 }
00489 }
00490 }
00491 return false;
00492 }
00493
00494 bool parseArray(ref<VLXArray>& arr)
00495 {
00496
00497 struct struct_consume_tag
00498 {
00499 struct_consume_tag(ref<VLXArray>* p1, std::string* p2): p_arr(p1), p_tag(p2) {}
00500
00501 ~struct_consume_tag()
00502 {
00503 if ((*p_arr).get() && !p_tag->empty())
00504 {
00505 (*p_arr)->setTag(p_tag->c_str());
00506 p_tag->clear();
00507 }
00508 }
00509
00510 ref<VLXArray>* p_arr;
00511 std::string* p_tag;
00512 } consume_tag(&arr, &mLastTag);
00513
00514 if(getToken(mToken))
00515 {
00516
00517
00518
00519 if (mToken.mType == VLTToken::RightRoundBracket)
00520 {
00521 arr = new VLXArrayInteger;
00522 return true;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 else
00557 if (mToken.mType == VLTToken::Integer)
00558 {
00559 ref<VLXArrayInteger> arr_integer;
00560 arr = arr_integer = new VLXArrayInteger;
00561 do
00562 {
00563 switch(mToken.mType)
00564 {
00565 case VLTToken::Integer: arr_integer->value().push_back( atoll( mToken.mString.c_str() ) ); break;
00566 case VLTToken::RightRoundBracket: return true;
00567 default:
00568 return false;
00569 }
00570 }
00571 while(getToken(mToken));
00572 return false;
00573 }
00574 else
00575 if (mToken.mType == VLTToken::real)
00576 {
00577 ref<VLXArrayReal> arr_floating;
00578 arr = arr_floating = new VLXArrayReal;
00579 arr_floating->value().reserve(1024);
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 do
00590 {
00591 switch(mToken.mType)
00592 {
00593 case VLTToken::Integer:
00594 case VLTToken::real: arr_floating->value().push_back( atof( mToken.mString.c_str() ) ); break;
00595 case VLTToken::RightRoundBracket: return true;
00596 default:
00597 return false;
00598 }
00599 }
00600 while(getToken(mToken));
00601 return false;
00602 }
00603 else
00604 return false;
00605 }
00606
00607 return false;
00608 }
00609
00610
00611 void listTokens()
00612 {
00613 while(getToken(mToken) && mToken.mType != VLTToken::TOKEN_EOF)
00614 {
00615 switch(mToken.mType)
00616 {
00617 case VLTToken::LeftRoundBracket: printf("LeftSquareBracket (\n"); break;
00618 case VLTToken::RightRoundBracket: printf("RightSquareBracket )\n"); break;
00619 case VLTToken::LeftSquareBracket: printf("LeftSquareBracket [\n"); break;
00620 case VLTToken::RightSquareBracket: printf("RightSquareBracket ]\n"); break;
00621 case VLTToken::LeftCurlyBracket: printf("LeftCurlyBracket {\n"); break;
00622 case VLTToken::RightCurlyBracket: printf("RightCurlyBracket } \n"); break;
00623 case VLTToken::LeftFancyBracket: printf("LeftFancyBracket >}\n"); break;
00624 case VLTToken::RightFancyBracket: printf("RightFancyBracket {< \n"); break;
00625 case VLTToken::Equals: printf("Equals =\n"); break;
00626 case VLTToken::String: printf("String = %s\n", mToken.mString.c_str()); break;
00627 case VLTToken::ID: printf("ID = %s\n", mToken.mString.c_str()); break;
00628 case VLTToken::Identifier: printf("Identifier = %s\n", mToken.mString.c_str()); break;
00629 case VLTToken::RawtextBlock: printf("RawtextBlock = %s\n", mToken.mString.c_str()); break;
00630 case VLTToken::real: printf("real = %s\n", mToken.mString.c_str()); break;
00631 case VLTToken::Integer: printf("Integer = %s\n", mToken.mString.c_str()); break;
00632 case VLTToken::TagHeader: printf("TagHeader = %s\n", mToken.mString.c_str()); break;
00633 default:
00634 break;
00635 }
00636 }
00637 if (mToken.mType != VLTToken::TOKEN_EOF)
00638 {
00639 printf("Line %d: syntax error : '%s'.\n", mTokenizer->lineNumber(), mToken.mString.c_str());
00640 }
00641 }
00642
00643 VLTTokenizer* tokenizer() { return mTokenizer.get(); }
00644
00645 const VLTTokenizer* tokenizer() const { return mTokenizer.get(); }
00646
00647 private:
00648 std::string mLastTag;
00649 ref<VLTTokenizer> mTokenizer;
00650 VLTToken mToken;
00651 };
00652 }
00653
00654 #ifdef _MSC_VER
00655 #undef atoll
00656 #endif
00657
00658 #endif