X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Ftextparser.cpp;h=7dc4bde7e46ed659368498798bf0b6b3b62fa246;hp=225425b4e23166eea05fe0697f16974c327ab1c0;hb=cd3de49e76305a50ae61696210ce10804a59cef1;hpb=6653c7d83dbe1fe81a541a125be8bb808b234eb7 diff --git a/source/textparser.cpp b/source/textparser.cpp index 225425b..7dc4bde 100644 --- a/source/textparser.cpp +++ b/source/textparser.cpp @@ -1,5 +1,6 @@ #include #include +#include "except.h" #include "input.h" #include "textparser.h" #include "token.h" @@ -9,33 +10,11 @@ using namespace std; namespace Msp { namespace DataFile { -class parse_error: public runtime_error -{ -public: - parse_error(const std::string &t): - runtime_error(t.empty() ? "at end of input" : format("after '%s'", t)) - { } - - virtual ~parse_error() throw() { } -}; - - -class syntax_error: public runtime_error -{ -public: - syntax_error(const std::string &t): - runtime_error(t.empty() ? "at end of input" : format("at '%s'", t)) - { } - - virtual ~syntax_error() throw() { } -}; - - TextParser::TextParser(Input &i, const string &s): ParserMode(i, s) { } -Statement TextParser::parse(bool) +Statement TextParser::parse() { return parse_statement(0); } @@ -43,8 +22,7 @@ Statement TextParser::parse(bool) Statement TextParser::parse_statement(const Token *t) { Statement result; - bool sub = false; - bool finish = false; + unsigned sub = 0; while(in) { @@ -68,44 +46,28 @@ Statement TextParser::parse_statement(const Token *t) result.source = src; result.line = in.get_line_number(); } - else if(sub) + else if(sub==1) { if(token.str=="}") - { - sub = false; - finish = true; - } + sub = 2; else { Statement ss = parse_statement(&token); result.sub.push_back(ss); } } - else if(finish) + else if(sub==2) { if(token.str!=";") throw syntax_error(token.str); break; } else if(token.str=="{") - sub = true; + sub = 1; else if(token.str==";") break; - else if(token.type==Token::INTEGER) - result.append(lexical_cast(token.str)); - else if(token.type==Token::FLOAT) - result.append(lexical_cast(token.str)); - else if(token.type==Token::STRING) - result.append(token.str); - else if(token.type==Token::IDENTIFIER) - { - if(token.str=="true") - result.append(true); - else if(token.str=="false") - result.append(false); - else - result.append(Symbol(token.str)); - } + else if(token.type!=Token::SPECIAL) + result.append_from_token(token); else throw syntax_error(token.str); } @@ -124,9 +86,9 @@ Token TextParser::parse_token() c = in.get(); int next = in.peek(); - if(c=='/' && next=='/') + if(c=='/' && next=='/' && !comment) comment = 1; - else if(c=='/' && next=='*') + else if(c=='/' && next=='*' && !comment) comment = 2; else if(c=='\n' && comment==1) comment = 0; @@ -150,6 +112,7 @@ Token TextParser::parse_token() FLOATEXPINIT, FLOATEXPSIGN, STRING, + STRING_ESCAPE, ACCEPT, ZERO, DECIMAL, @@ -169,6 +132,7 @@ Token TextParser::parse_token() Token::SPECIAL, Token::SPECIAL, Token::SPECIAL, + Token::SPECIAL, Token::INTEGER, Token::INTEGER, Token::INTEGER, @@ -181,7 +145,6 @@ Token TextParser::parse_token() ParseState state = INIT; string buf; - bool escape = false; while(in || state==INIT) { @@ -283,11 +246,13 @@ Token TextParser::parse_token() case STRING: if(c=='\\') - escape = !escape; - else if(c=='"' && !escape) + state = STRING_ESCAPE; + else if(c=='"') state = STRING_END; - else - escape = false; + break; + + case STRING_ESCAPE: + state = STRING; break; case IDENTIFIER: