00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_datafilescanner.hpp"
00012
00013 #include <iostream>
00014
00015 #include "xrb_datafilelocation.hpp"
00016 #include "xrb_datafilevalue.hpp"
00017 #include "xrb_math.hpp"
00018 #include "xrb_util.hpp"
00019
00020 #undef FL
00021 #define FL DataFileLocation(m_input_path, m_line_number)
00022
00023 namespace Xrb
00024 {
00025
00026 inline bool IsWhitespace (char c) { return c == ' ' || c == '\t'; }
00027 inline bool IsOperator (char c) { return c == '{' || c == '}' || c == '[' || c == ']' || c == ';' || c == ','; }
00028 inline bool IsAlpha (char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
00029 inline bool IsBinaryDigit (char c) { return c == '0' || c == '1'; }
00030 inline bool IsOctalDigit (char c) { return c >= '0' && c <= '7'; }
00031 inline bool IsDecimalDigit (char c) { return c >= '0' && c <= '9'; }
00032 inline bool IsHexadecimalDigit (char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
00033
00034 Uint32 HexadecimalDigitValue (char c)
00035 {
00036 ASSERT1(IsHexadecimalDigit(c));
00037 if (c >= '0' && c <= '9')
00038 return c - '0';
00039 if (c >= 'a' && c <= 'f')
00040 return c - 'a' + 10;
00041 if (c >= 'A' && c <= 'F')
00042 return c - 'A' + 10;
00043 return 0;
00044 }
00045
00046 DataFileScanner::DataFileScanner ()
00047 {
00048 m_line_number = 0;
00049 m_were_warnings_encountered = false;
00050 m_were_errors_encountered = false;
00051 }
00052
00053 DataFileScanner::~DataFileScanner ()
00054 {
00055 Close();
00056 }
00057
00058 bool DataFileScanner::Open (std::string const &input_path)
00059 {
00060 ASSERT1(!m_input.is_open() && "you must call Close() first");
00061
00062 m_input.open(input_path.c_str());
00063 m_input.unsetf(std::ios_base::skipws);
00064 if (m_input.is_open())
00065 m_input_path = input_path;
00066 else
00067 m_input_path.clear();
00068 m_text.clear();
00069 m_line_number = 1;
00070 m_were_warnings_encountered = false;
00071 m_were_errors_encountered = false;
00072 return m_input.is_open();
00073 }
00074
00075 void DataFileScanner::Close ()
00076 {
00077 m_input_path.clear();
00078 if (m_input.is_open())
00079 m_input.close();
00080 m_text.clear();
00081 m_line_number = 0;
00082 }
00083
00084 void DataFileScanner::EmitWarning (std::string const &message)
00085 {
00086 ASSERT1(!m_input_path.empty());
00087 ASSERT1(m_input.is_open());
00088 std::cerr << m_input_path << ": warning: " << message << std::endl;
00089 m_were_warnings_encountered = true;
00090 }
00091
00092 void DataFileScanner::EmitWarning (DataFileLocation const &file_location, std::string const &message)
00093 {
00094 ASSERT1(!m_input_path.empty());
00095 ASSERT1(m_input.is_open());
00096 std::cerr << file_location << ": warning: " << message << std::endl;
00097 m_were_warnings_encountered = true;
00098 }
00099
00100 void DataFileScanner::EmitError (std::string const &message)
00101 {
00102 ASSERT1(!m_input_path.empty());
00103 ASSERT1(m_input.is_open());
00104 std::cerr << m_input_path << ": error: " << message << std::endl;
00105 m_were_errors_encountered = true;
00106 }
00107
00108 void DataFileScanner::EmitError (DataFileLocation const &file_location, std::string const &message)
00109 {
00110 ASSERT1(!m_input_path.empty());
00111 ASSERT1(m_input.is_open());
00112 std::cerr << file_location << ": error: " << message << std::endl;
00113 m_were_errors_encountered = true;
00114 }
00115
00116 DataFileParser::Token::Type DataFileScanner::Scan (DataFileValue **const scanned_token)
00117 {
00118 ASSERT1(!m_input_path.empty());
00119 ASSERT1(m_input.is_open());
00120 ASSERT1(m_line_number > 0);
00121
00122 ASSERT1(scanned_token != NULL);
00123 ASSERT1(*scanned_token == NULL);
00124
00125 while (true)
00126 {
00127 m_text.clear();
00128
00129 char c;
00130
00131 while (!IsNextCharEOF(&c) && IsWhitespace(c))
00132 m_input >> c;
00133
00134 m_input >> c;
00135 if (m_input.eof())
00136 return DataFileParser::Token::END_;
00137 m_text += c;
00138
00139 if (IsAlpha(c) || c == '_')
00140 return ScanIdentifier(scanned_token);
00141 else if (IsOperator(c))
00142 return ScanOperator(scanned_token);
00143 else if (IsDecimalDigit(c) || c == '+' || c == '-')
00144 return ScanNumeric(scanned_token);
00145 else switch (c)
00146 {
00147 case '\'': return ScanCharacterLiteral(scanned_token);
00148 case '"': return ScanStringLiteral(scanned_token);
00149 case '\n': ++m_line_number; break;
00150 case '/':
00151 try
00152 {
00153 ScanComment();
00154 }
00155 catch (DataFileParser::Token::Type token_type)
00156 {
00157 if (token_type == DataFileParser::Token::END_)
00158 EmitWarning(FL, "unterminated comment");
00159 return token_type;
00160 }
00161 break;
00162 default:
00163 return DataFileParser::Token::BAD_TOKEN;
00164 }
00165 }
00166 }
00167
00168 DataFileParser::Token::Type DataFileScanner::ScanIdentifier (DataFileValue **const scanned_token)
00169 {
00170 ASSERT1(scanned_token != NULL);
00171 ASSERT1(*scanned_token == NULL);
00172 ASSERT1(!m_input.eof());
00173
00174 char c;
00175
00176 while (!IsNextCharEOF(&c) && (IsAlpha(c) || IsDecimalDigit(c) || c == '_'))
00177 {
00178 m_input >> c;
00179 m_text += c;
00180 }
00181
00182
00183 std::string lowercase_text(m_text);
00184 Util::MakeLowercase(&lowercase_text);
00185 if (lowercase_text == "true")
00186 {
00187 *scanned_token = new DataFileBoolean(true);
00188 return DataFileParser::Token::BOOLEAN;
00189 }
00190 else if (lowercase_text == "false")
00191 {
00192 *scanned_token = new DataFileBoolean(false);
00193 return DataFileParser::Token::BOOLEAN;
00194 }
00195
00196 *scanned_token = new DataFileString(m_text);
00197 return DataFileParser::Token::IDENTIFIER;
00198 }
00199
00200 DataFileParser::Token::Type DataFileScanner::ScanOperator (DataFileValue **const scanned_token)
00201 {
00202 ASSERT1(scanned_token != NULL);
00203 ASSERT1(*scanned_token == NULL);
00204 ASSERT1(!m_input.eof());
00205
00206 return static_cast<DataFileParser::Token::Type>(m_text[0]);
00207 }
00208
00209 DataFileParser::Token::Type DataFileScanner::ScanNumeric (DataFileValue **const scanned_token)
00210 {
00211 ASSERT1(scanned_token != NULL);
00212 ASSERT1(*scanned_token == NULL);
00213 ASSERT1(!m_input.eof());
00214
00215 char c = m_text[0];
00216
00217 ASSERT1(IsDecimalDigit(c) || c == '+' || c == '-');
00218
00219 bool is_signed = false;
00220 bool is_positive = true;
00221 if (c == '+' || c == '-')
00222 {
00223 is_signed = true;
00224 is_positive = c == '+';
00225
00226 if (IsNextCharEOF(&c) || !IsDecimalDigit(c))
00227 {
00228 ASSERT1(m_text.length() == 1);
00229 if (m_text[0] == '+')
00230 return static_cast<DataFileParser::Token::Type>('+');
00231
00232 EmitError(FL, "malformed numeric value");
00233 return DataFileParser::Token::BAD_TOKEN;
00234 }
00235
00236 m_input >> c;
00237 m_text += c;
00238 }
00239
00240 if (c == '0')
00241 {
00242
00243 if (IsNextCharEOF(&c) || (c != 'b' && !IsDecimalDigit(c) && c != 'x' && c != '.' && c != 'e' && c != 'E'))
00244 {
00245 if (is_signed)
00246 {
00247 *scanned_token = new DataFileSint32(0);
00248 return DataFileParser::Token::SINT32;
00249 }
00250 else
00251 {
00252 *scanned_token = new DataFileUint32(0);
00253 return DataFileParser::Token::UINT32;
00254 }
00255 }
00256
00257 m_input >> c;
00258 m_text += c;
00259
00260 if (c == 'b')
00261 return ScanBinaryNumeric(scanned_token, is_signed, is_positive);
00262 else if (IsOctalDigit(c))
00263 return ScanOctalNumeric(scanned_token, is_signed, is_positive, c);
00264 else if (c == 'x')
00265 return ScanHexadecimalNumeric(scanned_token, is_signed, is_positive);
00266 else if (c == '.' || c == 'e' || c == 'E')
00267 return ScanFloatingPointNumeric(scanned_token);
00268 else
00269 return DataFileParser::Token::BAD_TOKEN;
00270 }
00271 else
00272 return ScanDecimalNumeric(scanned_token, is_signed, is_positive, c);
00273 }
00274
00275 DataFileParser::Token::Type DataFileScanner::ScanBinaryNumeric (
00276 DataFileValue **const scanned_token,
00277 bool const is_signed,
00278 bool const is_positive)
00279 {
00280 ASSERT1(scanned_token != NULL);
00281 ASSERT1(*scanned_token == NULL);
00282 ASSERT1(!m_input.eof());
00283
00284 char c;
00285 bool actually_read_digits = false;
00286 bool overflow = false;
00287 Uint32 value = 0;
00288 while (!IsNextCharEOF(&c) && IsBinaryDigit(c))
00289 {
00290 actually_read_digits = true;
00291 m_input >> c;
00292 m_text += c;
00293
00294
00295 if ((value&0x80000000) != 0)
00296 overflow = true;
00297 value = (value << 1) + (c - '0');
00298 }
00299
00300 if (!actually_read_digits)
00301 {
00302 EmitError(FL, std::string("malformed ") + (is_signed ? "signed" : "unsigned") + " binary value " + m_text);
00303 return DataFileParser::Token::BAD_TOKEN;
00304 }
00305
00306
00307 if (is_signed &&
00308 ((is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND))
00309 ||
00310 (!is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND)+1)))
00311 {
00312 overflow = true;
00313 }
00314
00315
00316 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00317 return DataFileParser::Token::BAD_TOKEN;
00318
00319 if (overflow)
00320 EmitError(FL, std::string("overflow in ") + (is_signed ? "signed" : "unsigned") + " binary value " + m_text);
00321
00322 if (is_signed)
00323 {
00324 *scanned_token = new DataFileSint32(is_positive ? static_cast<Sint32>(value) : -static_cast<Sint32>(value));
00325 return DataFileParser::Token::SINT32;
00326 }
00327 else
00328 {
00329 *scanned_token = new DataFileUint32(value);
00330 return DataFileParser::Token::UINT32;
00331 }
00332 }
00333
00334 DataFileParser::Token::Type DataFileScanner::ScanOctalNumeric (
00335 DataFileValue **const scanned_token,
00336 bool const is_signed,
00337 bool const is_positive,
00338 char const first_char)
00339 {
00340 ASSERT1(scanned_token != NULL);
00341 ASSERT1(*scanned_token == NULL);
00342 ASSERT1(!m_input.eof());
00343
00344 char c;
00345 bool overflow = false;
00346 ASSERT1(first_char >= '0');
00347 Uint32 value = first_char - '0';
00348 while (!IsNextCharEOF(&c) && IsOctalDigit(c))
00349 {
00350 m_input >> c;
00351 m_text += c;
00352
00353
00354 if ((value&0xE0000000) != 0)
00355 overflow = true;
00356 value = (value << 3) + (c - '0');
00357 }
00358
00359
00360 if (is_signed &&
00361 ((is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND))
00362 ||
00363 (!is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND)+1)))
00364 {
00365 overflow = true;
00366 }
00367
00368
00369 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00370 return DataFileParser::Token::BAD_TOKEN;
00371
00372 if (overflow)
00373 EmitError(FL, std::string("overflow in ") + (is_signed ? "signed" : "unsigned") + " octal value " + m_text);
00374
00375 if (is_signed)
00376 {
00377 *scanned_token = new DataFileSint32(is_positive ? static_cast<Sint32>(value) : -static_cast<Sint32>(value));
00378 return DataFileParser::Token::SINT32;
00379 }
00380 else
00381 {
00382 *scanned_token = new DataFileUint32(value);
00383 return DataFileParser::Token::UINT32;
00384 }
00385 }
00386
00387 DataFileParser::Token::Type DataFileScanner::ScanDecimalNumeric (
00388 DataFileValue **const scanned_token,
00389 bool const is_signed,
00390 bool const is_positive,
00391 char const first_char)
00392 {
00393 ASSERT1(scanned_token != NULL);
00394 ASSERT1(*scanned_token == NULL);
00395 ASSERT1(!m_input.eof());
00396
00397 char c;
00398 bool overflow = false;
00399 ASSERT1(first_char >= '0');
00400 Uint32 value = first_char - '0';
00401 while (!IsNextCharEOF(&c) && IsDecimalDigit(c))
00402 {
00403 m_input >> c;
00404 m_text += c;
00405
00406
00407
00408
00409 if (value > 429496729 || (value == 429496729 && c > '5'))
00410 overflow = true;
00411 value = 10 * value + (c - '0');
00412 }
00413
00414 if (c == '.' || c == 'e' || c == 'E')
00415 {
00416 m_input >> c;
00417 m_text += c;
00418 return ScanFloatingPointNumeric(scanned_token);
00419 }
00420
00421
00422 if (is_signed &&
00423 ((is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND))
00424 ||
00425 (!is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND)+1)))
00426 {
00427 overflow = true;
00428 }
00429
00430
00431 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00432 return DataFileParser::Token::BAD_TOKEN;
00433
00434 if (overflow)
00435 EmitError(FL, std::string("overflow in ") + (is_signed ? "signed" : "unsigned") + " decimal value " + m_text);
00436
00437 if (is_signed)
00438 {
00439 *scanned_token = new DataFileSint32(is_positive ? static_cast<Sint32>(value) : -static_cast<Sint32>(value));
00440 return DataFileParser::Token::SINT32;
00441 }
00442 else
00443 {
00444 *scanned_token = new DataFileUint32(value);
00445 return DataFileParser::Token::UINT32;
00446 }
00447 }
00448
00449 DataFileParser::Token::Type DataFileScanner::ScanHexadecimalNumeric (
00450 DataFileValue **const scanned_token,
00451 bool const is_signed,
00452 bool const is_positive)
00453 {
00454 ASSERT1(scanned_token != NULL);
00455 ASSERT1(*scanned_token == NULL);
00456 ASSERT1(!m_input.eof());
00457
00458 char c;
00459 bool actually_read_digits = false;
00460 bool overflow = false;
00461 Uint32 value = 0;
00462 while (!IsNextCharEOF(&c) && IsHexadecimalDigit(c))
00463 {
00464 actually_read_digits = true;
00465 m_input >> c;
00466 m_text += c;
00467 if ((value&0xF0000000) != 0)
00468 overflow = true;
00469 value = (value << 4) + HexadecimalDigitValue(c);
00470 }
00471
00472 if (!actually_read_digits)
00473 {
00474 EmitError(FL, std::string("malformed ") + (is_signed ? "signed" : "unsigned") + " binary value " + m_text);
00475 return DataFileParser::Token::BAD_TOKEN;
00476 }
00477
00478
00479 if (is_signed &&
00480 ((is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND))
00481 ||
00482 (!is_positive && value > static_cast<Uint32>(SINT32_UPPER_BOUND)+1)))
00483 {
00484 overflow = true;
00485 }
00486
00487
00488 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00489 return DataFileParser::Token::BAD_TOKEN;
00490
00491 if (overflow)
00492 EmitError(FL, std::string("overflow in ") + (is_signed ? "signed" : "unsigned") + " hexadecimal value " + m_text);
00493
00494 if (is_signed)
00495 {
00496 *scanned_token = new DataFileSint32(is_positive ? static_cast<Sint32>(value) : -static_cast<Sint32>(value));
00497 return DataFileParser::Token::SINT32;
00498 }
00499 else
00500 {
00501 *scanned_token = new DataFileUint32(value);
00502 return DataFileParser::Token::UINT32;
00503 }
00504 }
00505
00506 DataFileParser::Token::Type DataFileScanner::ScanFloatingPointNumeric (DataFileValue **const scanned_token)
00507 {
00508 ASSERT1(scanned_token != NULL);
00509 ASSERT1(*scanned_token == NULL);
00510 ASSERT1(!m_input.eof());
00511
00512 char c = *m_text.rbegin();
00513 ASSERT1(c == '.' || c == 'e' || c == 'E');
00514
00515 if (c == '.')
00516 {
00517
00518 if (!IsNextCharEOF(&c) && IsDecimalDigit(c))
00519 {
00520 m_input >> c;
00521 m_text += c;
00522 }
00523
00524 if (m_input.eof() || !IsDecimalDigit(c))
00525 return DataFileParser::Token::BAD_TOKEN;
00526
00527 while (!IsNextCharEOF(&c) && IsDecimalDigit(c))
00528 {
00529 m_input >> c;
00530 m_text += c;
00531 }
00532
00533 if (!IsNextCharEOF(&c) && (c == 'e' || c == 'E'))
00534 {
00535 m_input >> c;
00536 m_text += c;
00537 }
00538 }
00539
00540 if (c == 'e' || c == 'E')
00541 {
00542
00543 if (!IsNextCharEOF(&c) && (c == '+' || c == '-'))
00544 {
00545 m_input >> c;
00546 m_text += c;
00547 }
00548
00549 if (m_input.eof() || (c != '+' && c != '-' && !IsDecimalDigit(c)))
00550 return DataFileParser::Token::BAD_TOKEN;
00551
00552 if (!IsNextCharEOF(&c) && IsDecimalDigit(c))
00553 {
00554 m_input >> c;
00555 m_text += c;
00556 }
00557
00558 if (m_input.eof() || !IsDecimalDigit(c))
00559 return DataFileParser::Token::BAD_TOKEN;
00560
00561 while (!IsNextCharEOF(&c) && IsDecimalDigit(c))
00562 {
00563 m_input >> c;
00564 m_text += c;
00565 }
00566 }
00567
00568
00569 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00570 return DataFileParser::Token::BAD_TOKEN;
00571
00572 Float value = Util::TextToFloat(m_text.c_str());
00573 if (!Math::IsFinite(value))
00574 EmitError(FL, std::string("overflow/underflow in floating point value ") + m_text);
00575
00576 *scanned_token = new DataFileFloat(value);
00577 return DataFileParser::Token::FLOAT;
00578 }
00579
00580 DataFileParser::Token::Type DataFileScanner::ScanCharacterLiteral (DataFileValue **const scanned_token)
00581 {
00582 ASSERT1(scanned_token != NULL);
00583 ASSERT1(*scanned_token == NULL);
00584 ASSERT1(!m_input.eof());
00585
00586 m_text.clear();
00587 m_text += '\'';
00588
00589 char c;
00590 bool escaped_char = false;
00591
00592 if (IsNextCharEOF(&c))
00593 {
00594 EmitError(FL, "unexpected end of file");
00595 return DataFileParser::Token::BAD_TOKEN;
00596 }
00597
00598 if (c == '\\')
00599 {
00600 m_input >> c;
00601 m_text += c;
00602 escaped_char = true;
00603
00604 if (IsNextCharEOF(&c))
00605 {
00606 EmitError(FL, "unexpected end of file");
00607 return DataFileParser::Token::BAD_TOKEN;
00608 }
00609 }
00610
00611 m_input >> c;
00612 m_text += c;
00613
00614 if (c == '\n' || (!escaped_char && c == '\''))
00615 {
00616 if (c == '\n')
00617 ++m_line_number;
00618 if (!escaped_char && c == '\'')
00619 {
00620 if (!IsNextCharEOF(&c) && c == '\'')
00621 {
00622 m_input >> c;
00623 m_text += c;
00624 }
00625 }
00626
00627 EmitError(FL, "malformed character literal");
00628 return DataFileParser::Token::BAD_TOKEN;
00629 }
00630
00631 if (IsNextCharEOF(&c))
00632 {
00633 EmitError(FL, "unexpected end of file");
00634 return DataFileParser::Token::BAD_TOKEN;
00635 }
00636
00637 if (c == '\'')
00638 {
00639 m_input >> c;
00640 m_text += c;
00641
00642
00643 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00644 return DataFileParser::Token::BAD_TOKEN;
00645
00646 if (escaped_char)
00647 *scanned_token = new DataFileCharacter(Util::EscapedChar(m_text[m_text.length()-2]));
00648 else
00649 *scanned_token = new DataFileCharacter(m_text[m_text.length()-2]);
00650 return DataFileParser::Token::CHARACTER;
00651 }
00652 else
00653 {
00654 EmitError(FL, "malformed character literal");
00655 return DataFileParser::Token::BAD_TOKEN;
00656 }
00657 }
00658
00659 DataFileParser::Token::Type DataFileScanner::ScanStringLiteral (DataFileValue **const scanned_token)
00660 {
00661 ASSERT1(scanned_token != NULL);
00662 ASSERT1(*scanned_token == NULL);
00663 ASSERT1(!m_input.eof());
00664
00665 char c;
00666 Uint32 starting_line = m_line_number;
00667
00668 m_text.clear();
00669
00670 while (!IsNextCharEOF(&c) && c != '"')
00671 {
00672 m_input >> c;
00673
00674 if (c == '\\')
00675 {
00676 if (IsNextCharEOF(&c))
00677 {
00678 EmitError(DataFileLocation(m_input_path, starting_line), "unterminated string");
00679 return DataFileParser::Token::BAD_TOKEN;
00680 }
00681 else if (c == '\n')
00682 {
00683 ++m_line_number;
00684
00685 m_input >> c;
00686 }
00687 else
00688 {
00689 m_input >> c;
00690 m_text += Util::EscapedChar(c);
00691 }
00692 }
00693 else
00694 {
00695 if (c == '\n')
00696 ++m_line_number;
00697
00698 m_text += c;
00699 }
00700 }
00701
00702 if (c == '"')
00703 {
00704 m_input >> c;
00705
00706
00707 if (!IsNextCharEOF(&c) && !IsOperator(c) && !IsWhitespace(c) && c != '\n' && c != '/')
00708 return DataFileParser::Token::BAD_TOKEN;
00709
00710 *scanned_token = new DataFileString(m_text);
00711 return DataFileParser::Token::STRING_FRAGMENT;
00712 }
00713 else
00714 {
00715 EmitError(DataFileLocation(m_input_path, starting_line), "unterminated string");
00716 return DataFileParser::Token::BAD_TOKEN;
00717 }
00718 }
00719
00720 void DataFileScanner::ScanComment ()
00721 {
00722 ASSERT1(!m_input.eof());
00723
00724 char c;
00725
00726 if (IsNextCharEOF(&c))
00727 throw DataFileParser::Token::BAD_TOKEN;
00728 else if (c == '*')
00729 {
00730 m_input >> c;
00731 m_text += c;
00732 while (!IsNextCharEOF(&c))
00733 {
00734 m_input >> c;
00735 m_text += c;
00736 if (c == '*')
00737 {
00738 if (IsNextCharEOF(&c))
00739 throw DataFileParser::Token::END_;
00740 else if (c == '/')
00741 {
00742 m_input >> c;
00743 m_text += c;
00744 break;
00745 }
00746 }
00747 else if (c == '\n')
00748 ++m_line_number;
00749 }
00750
00751 if (IsNextCharEOF())
00752 throw DataFileParser::Token::END_;
00753 }
00754 else if (c == '/')
00755 {
00756 m_input >> c;
00757 m_text += c;
00758 while (!IsNextCharEOF(&c) && c != '\n')
00759 {
00760 m_input >> c;
00761 m_text += c;
00762 }
00763
00764 if (IsNextCharEOF())
00765 throw DataFileParser::Token::END_;
00766
00767 m_input >> c;
00768 m_text += c;
00769 ++m_line_number;
00770 }
00771 else
00772 throw DataFileParser::Token::BAD_TOKEN;
00773 }
00774
00775 }