CVMTGroupNode *Parse() { CToken *Token; CVMTGroupNode *Group = 0; // Consume all newlines. Token = this->Tokenizer->Next(); while (Token->GetToken() == TOKEN_NEWLINE) { Token = this->Tokenizer->Next(); } if (Token->GetToken() == TOKEN_STRING || Token->GetToken() == TOKEN_QUOTED_STRING) { Group = new CVMTGroupNode(Token->GetString()); } else { throw "expected shader name"; } // We *may* have a group, parse it. this->Parse(Group); if (uiVMTParseMode == PARSE_MODE_LOOSE) { while (vlTrue) { // Consume all newlines. while (this->Tokenizer->Peek()->GetToken() == TOKEN_NEWLINE) { Token = this->Tokenizer->Next(); } CToken *Peek = this->Tokenizer->Peek(); if (Peek->GetToken() == TOKEN_EOF) { break; } else if (Peek->GetToken() == TOKEN_OPEN_BRACE) { CVMTGroupNode *NextGroup = 0; try{ NextGroup = new CVMTGroupNode(""); this->Parse(NextGroup); }catch (char *cErrorMessage) { delete NextGroup; throw cErrorMessage; } for (vlUInt i = 0; i < NextGroup->GetNodeCount(); i++) { Group->AddNode(NextGroup->GetNode(i)->Clone()); } delete NextGroup; } else { throw "expected end of file"; } } } else { // Consume all newlines. Token = this->Tokenizer->Next(); while (Token->GetToken() == TOKEN_NEWLINE) { Token = this->Tokenizer->Next(); } if (Token->GetToken() != TOKEN_EOF) { throw "expected end of file"; } } return Group; }