+Literal *Parser::ParseScript() {
+ std::string msg("error parsing script");
+ Token t(GetToken());
+ AssertTokenType(t.type, Token::SCRIPT_BEGIN, msg);
+
+ t = GetToken();
+ vector<ScriptToken *> script;
+ try {
+ while (t.type != Token::SCRIPT_END) {
+ if (BeginningOfPrimitiveLiteral(t)) {
+ tok.Putback(t);
+ script.push_back(new ScriptToken(ParseLiteral()));
+ } else {
+ switch (t.type) {
+ case Token::COMMAND: {
+ Token t2(GetToken());
+ AssertTokenType(t2.type, Token::IDENTIFIER, msg);
+ script.push_back(new ScriptToken(t2.str, ScriptToken::COMMAND));
+ break;
+ }
+ case Token::IDENTIFIER: {
+ Token t2(GetToken());
+ if (t2.type == Token::COLON) {
+ script.push_back(new ScriptToken(t.str, ScriptToken::LABEL));
+ } else {
+ tok.Putback(t2);
+ script.push_back(new ScriptToken(t.str, ScriptToken::IDENTIFIER));
+ }
+ break;
+ }
+ case Token::REGISTER: {
+ Token t2(GetToken());
+ AssertTokenType(t2.type, Token::IDENTIFIER, msg);
+ script.push_back(new ScriptToken(t2.str, ScriptToken::REGISTER));
+ break;
+ }
+ default:
+ throw Error(file, tok.Line(), string("unexpected token in script: ") + TokenTypeToString(t.type));
+ }
+ }
+ t = GetToken();
+ }
+ } catch (...) {
+ for (vector<ScriptToken *>::const_iterator i(script.begin()), end(script.end()); i != end; ++i) {
+ delete *i;
+ }
+ throw;
+ }
+ return new Literal(script);
+}
+
+
+void Parser::AssertTokenType(Token::Type actual, Token::Type expected) {