+template<typename T>
+RefPtr<T> Parser::parse_with_recovery(RefPtr<T> (Parser::*parse_func)())
+{
+ tokenizer.clear_progress_mark();
+ try
+ {
+ return (this->*parse_func)();
+ }
+ catch(const invalid_shader_source &exc)
+ {
+ errors.push_back(exc.what());
+ }
+
+ if(tokenizer.get_last_token()!=";" || !tokenizer.get_progress_mark())
+ {
+ unsigned scope_level = 0;
+ while(1)
+ {
+ if(tokenizer.peek_token()=="}" && scope_level==0)
+ {
+ if(!tokenizer.get_progress_mark())
+ tokenizer.parse_token();
+ break;
+ }
+
+ string token = tokenizer.parse_token();
+ if(token=="}")
+ {
+ --scope_level;
+ if(scope_level==0)
+ break;
+ }
+ else if(token=="{")
+ ++scope_level;
+ else if(token==";" && scope_level==0)
+ break;
+ else if(token.empty())
+ break;
+ }
+ }
+
+ return RefPtr<T>();
+}
+