X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftextparser.cpp;h=0f17d3f3cc79808a7659e291e406f6b7bb814137;hb=256f7238bc60d6dcc31a564988f5cc02a60c4537;hp=78d2f1df6334b32dbf67a7871975deda4dafb0a4;hpb=2f79370bffe0bac865dc97c5114dc87c1936fbb4;p=libs%2Fdatafile.git diff --git a/source/textparser.cpp b/source/textparser.cpp index 78d2f1d..0f17d3f 100644 --- a/source/textparser.cpp +++ b/source/textparser.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspdatafile -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -47,7 +47,7 @@ Statement TextParser::parse_statement(const Token *t) if(token.str.empty()) break; else if(token.type!=Token::IDENTIFIER) - throw ParseError(format("%s: Syntax error at token '%s' (expected an identifier)", get_location(), token.str), src, in.get_line_number()); + throw_at(ParseError(format("Syntax error at token '%s' (expected an identifier)", token.str)), get_location()); result.keyword=token.str; result.valid=true; result.source=src; @@ -69,7 +69,7 @@ Statement TextParser::parse_statement(const Token *t) else if(finish) { if(token.str!=";") - throw ParseError(format("%s: Syntax error at token '%s' (Expected a ';')", get_location(), token.str), src, in.get_line_number()); + throw_at(ParseError(format("Syntax error at token '%s' (Expected a ';')", token.str)), get_location()); break; } else if(token.str=="{") @@ -93,9 +93,9 @@ Statement TextParser::parse_statement(const Token *t) //result.args.push_back(resolve_identifiertoken.str); } else if(token.str=="") - throw ParseError(src+": Unexcepted end of input", src, in.get_line_number()); + throw_at(ParseError("Unexcepted end of input"), get_location()); else - throw ParseError(get_location()+": Syntax error", src, in.get_line_number()); + throw_at(ParseError("Syntax error"), get_location()); } return result; @@ -104,10 +104,10 @@ Statement TextParser::parse_statement(const Token *t) Token TextParser::parse_token() { int c=0; - unsigned comment=0; + int comment=0; // Skip over comments and whitespace - while(in) + while(in && comment>=0) { c=in.get(); int next=in.peek(); @@ -123,11 +123,13 @@ Token TextParser::parse_token() else if(comment==3) // Skip the second character of block comment end comment=0; else if(!isspace(c) && !comment) - break; + comment=-1; } - if(comment) // Didn't hit any non-whitespace - throw ParseError(src+": Unfinished comment at end of input", src, in.get_line_number()); + if(comment>0) // EOF while in comment + throw_at(ParseError("Unfinished comment at end of input"), get_location()); + else if(comment==0) // Didn't hit any non-whitespace + return Token(Token::SPECIAL, ""); enum ParseState { @@ -167,7 +169,7 @@ Token TextParser::parse_token() string buf; bool escape=false; - while(in) + while(in || state==INIT) { if(state!=INIT) c=in.get(); @@ -193,7 +195,7 @@ Token TextParser::parse_token() else if(isalpha(c) || c=='_') state=IDENTIFIER; else - parse_error(c, state); + parse_error(c, "0-9A-Za-z_.\"{};+-"); break; case SIGN: @@ -204,7 +206,7 @@ Token TextParser::parse_token() else if(c=='.') state=FLOAT; else - parse_error(c, state); + parse_error(c, "0-9."); break; case ZERO: @@ -215,31 +217,31 @@ Token TextParser::parse_token() else if(c=='.') state=FLOAT; else - parse_error(c, state); + parse_error(c, "0-9A-Fa-f."); break; case DECIMAL: if(c=='.') state=FLOAT; else if(!isdigit(c)) - parse_error(c, state); + parse_error(c, "0-9."); break; case HEXADECIMAL: if(!isxdigit(c)) - parse_error(c, state); + parse_error(c, "0-9A-Fa-f"); break; case OCTAL: if(!isodigit(c)) - parse_error(c, state); + parse_error(c, "0-7"); break; case FLOAT: if(c=='e' || c=='E') state=FLOATEXPINIT; else if(!isdigit(c)) - parse_error(c, state); + parse_error(c, "0-9Ee"); break; case FLOATEXPINIT: @@ -248,19 +250,19 @@ Token TextParser::parse_token() else if(isdigit(c)) state=FLOATEXP; else - parse_error(c, state); + parse_error(c, "0-9+-"); break; case FLOATEXPSIGN: if(isdigit(c)) state=FLOATEXP; else - parse_error(c, state); + parse_error(c, "0-9"); break; case FLOATEXP: if(!isdigit(c)) - parse_error(c, state); + parse_error(c, "0-9"); break; case STRING: @@ -272,9 +274,10 @@ Token TextParser::parse_token() { return Token(Token::STRING, c_unescape(buf.substr(1, buf.size()-2))); } - catch(const Exception &e) + catch(Exception &e) { - throw ParseError(format("%s: %s", get_location(), e.what()), src, in.get_line_number()); + e.at(get_location()); + throw; } } else @@ -283,11 +286,11 @@ Token TextParser::parse_token() case IDENTIFIER: if(!isalpha(c) && !isdigit(c) && c!='_') - parse_error(c, state); + parse_error(c, "0-9A-Za-z_"); break; default: - throw Exception(get_location()+": Internal error (bad state)"); + throw_at(InvalidState("Internal error (bad state)"), get_location()); } if(is_delimiter(next) && state>=ACCEPT) @@ -314,9 +317,9 @@ string TextParser::get_location() return ss.str(); } -void TextParser::parse_error(int c, int state) +void TextParser::parse_error(int c, const char *e) { - throw ParseError(format("%s: Parse error at '%c' (state %d)", get_location(), static_cast(c), state), src, in.get_line_number()); + throw_at(ParseError(format("Parse error at '%c', expected one of \"%s\"", static_cast(c), e)), get_location()); } } // namespace DataFile