X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fparser.cpp;h=1d225cb21d243c670dec03b29e5a4724cc47bd00;hb=cbd0ddd6ee033e46646bfb85d19232c816ea1eda;hp=c9ad188868a0bed69087879472b2741b67e07f46;hpb=98f563736e0837a429714b98656215503c607710;p=libs%2Fdatafile.git diff --git a/source/parser.cpp b/source/parser.cpp index c9ad188..1d225cb 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -1,349 +1,71 @@ -/* -This file is part of libmspparser +/* $Id$ + +This file is part of libmspdatafile Copyright © 2006 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ -#include -#include -#include +#include +#include "binaryparser.h" #include "parser.h" #include "statement.h" -#include "token.h" +#include "textparser.h" using namespace std; namespace Msp { -namespace Parser { +namespace DataFile { -Parser::Parser(istream &i, const string &s): +Parser::Parser(IO::Base &i, const string &s): in(i), + main_src(s), src(s), - good(true) + good(true), + mode(new TextParser(in, src)) { } +Parser::~Parser() +{ + delete mode; +} + Statement Parser::parse() { if(!good) throw Exception("Parser is not good"); - - try - { - return parse_(0); - } - catch(const Exception &e) - { - good=false; - throw; - } -} -Statement Parser::parse_(const Token *t) -{ - Statement result; - bool sub=false; - bool finish=false; - - while(in) + try { - Token token; - if(t) - { - token=*t; - t=0; - } - else - token=parse_token(); - - if(result.keyword.empty()) + while(1) { - if(token.str.empty()) - break; - else if(token.type!=Token::IDENTIFIER) - throw DataError(get_location()+": Syntax error at token '"+token.str+"' (expected an identifier)"); - result.keyword=token.str; - result.valid=true; - result.source=src; - result.line=in.get_line_number(); - } - else if(sub) - { - if(token.str=="}") + Statement st = mode->parse(); + if(st.keyword=="__bin") { - sub=false; - finish=true; + delete mode; + mode = new BinaryParser(in, src); } - else + else if(st.keyword=="__text") { - Statement ss=parse_(&token); - result.sub.push_back(ss); + delete mode; + mode = new TextParser(in, src); + } + else if(st.keyword=="__src") + { + string s = st.args[0].get(); + if(s.empty()) + src = main_src; + else + src = format("%s[%s]", main_src, s); } - } - else if(finish) - { - if(token.str!=";") - throw DataError(get_location()+": Syntax error at token '"+token.str+"' (Expected a ';')"); - break; - } - else if(token.str=="{") - sub=true; - else if(token.str==";") - break; - else if(token.type==Token::INTEGER) - result.args.push_back(Value(Value::INTEGER, token.str)); - else if(token.type==Token::FLOAT) - result.args.push_back(Value(Value::FLOAT, token.str)); - else if(token.type==Token::STRING) - result.args.push_back(Value(Value::STRING, token.str)); - else if(token.type==Token::IDENTIFIER) - { - if(token.str=="true") - result.args.push_back(Value(Value::BOOLEAN, "1")); - else if(token.str=="false") - result.args.push_back(Value(Value::BOOLEAN, "0")); - else - result.args.push_back(Value(Value::ENUM, token.str)); - //result.args.push_back(resolve_identifiertoken.str); - } - else if(token.str=="") - throw DataError(src+": Unexcepted EOF"); - else - throw DataError(get_location()+": Syntax error"); - } - - return result; -} - -Token Parser::parse_token() -{ - int c; - unsigned comment=0; - while(in) - { - c=in.get(); - int next=in.peek(); - - //cout<=ACCEPT) - return Token(token_type[state], buf); } - - return Token(Token::SPECIAL, ""); -} - -bool Parser::is_delimiter(int c) -{ - return (isspace(c) || c=='{' || c=='}' || c==';' || c=='/'); -} - -bool Parser::isodigit(int c) -{ - return (c>='0' && c<='7'); -} - -string Parser::unescape_string(const string &str) -{ - string result; - bool escape=false; - unsigned hexcape=0; - for(string::const_iterator i=str.begin()+1; i!=str.end()-1; ++i) + catch(const Exception &e) { - if(escape) - { - if(*i=='n') - result+='\n'; - else if(*i=='t') - result+='\t'; - else if(*i=='\\') - result+='\\'; - else if(*i=='"') - result+='"'; - else if(*i=='x') - hexcape=0x100; - else - throw DataError("Invalid escape"); - escape=false; - } - else if(hexcape) - { - unsigned digit=0; - if(*i>='0' && *i<='9') - digit=*i-'0'; - else if(*i>='a' && *i<='f') - digit=*i-'a'+10; - else if(*i>='A' && *i<='F') - digit=*i-'A'+10; - else - throw DataError("Invalid hex digit"); - - hexcape=(hexcape<<4)|digit; - if(hexcape&0x10000) - { - result+=hexcape&0xFF; - hexcape=0; - } - } - else if(*i=='\\') - escape=true; - else - result+=*i; + good = false; + throw; } - - return result; -} - -string Parser::get_location() -{ - ostringstream ss; - ss<