From 1538ef47d1d4cc08e5f9c5894350bfa225866d40 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 10 Feb 2013 21:53:22 +0000 Subject: Made the gats text parser much more robust. --- c++-libbu++/default.bld | 1 + c++-libbu++/src/object.cpp | 27 ++++++++++++------- c++-libbu++/src/object.h | 66 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/c++-libbu++/default.bld b/c++-libbu++/default.bld index 5a09a55..e6d1380 100644 --- a/c++-libbu++/default.bld +++ b/c++-libbu++/default.bld @@ -52,6 +52,7 @@ target "gatsc" { rule "exe"; input files("src/gatsc/*.cpp"); + requires "libgats.a"; CXXFLAGS += "-I. -Ilibbu++"; LDFLAGS += "-L. -lgats -lbu++"; } diff --git a/c++-libbu++/src/object.cpp b/c++-libbu++/src/object.cpp index db7b80b..faeca16 100644 --- a/c++-libbu++/src/object.cpp +++ b/c++-libbu++/src/object.cpp @@ -80,12 +80,12 @@ Gats::Object *Gats::Object::read( Bu::Stream &rIn ) return pObj; } -void Gats::Object::skipWs( Bu::String::const_iterator &i ) +void Gats::Object::skipWs( Gats::Object::StrPos &i ) { for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { } } -Bu::String Gats::Object::token( Bu::String::const_iterator &i ) +Bu::String Gats::Object::token( Gats::Object::StrPos &i ) { Bu::String sRet; if( *i == '\"' ) @@ -111,7 +111,12 @@ Bu::String Gats::Object::token( Bu::String::const_iterator &i ) return sRet; } -Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) +Bu::String::FormatProxy Gats::Object::posError( Gats::Object::StrPos &i, const Bu::String &msg ) +{ + return msg.format( new Thrower(i) ); +} + +Gats::Object *Gats::Object::strToGats( Gats::Object::StrPos &i ) { skipWs( i ); @@ -145,7 +150,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) return pLst; default: - throw Bu::ExceptionBase("Invalid character found."); + posError(i, "Expected ',' or ']' but found '%1'."). + arg( *i ); } } } @@ -164,16 +170,18 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) return pDict; } if( *i != '\"' ) - throw Bu::ExceptionBase("Keys must be quoted strings."); + posError(i, "Dictionary keys must be quoted strings."); Bu::String sKey = token( i ); skipWs( i ); if( *i != ':' ) - throw Bu::ExceptionBase("Keys and values must be " + posError(i, "Dictionary keys and values must be " "seperated with colons."); + StrPos ih( i ); i++; + skipWs( i ); Gats::Object *pObj = strToGats( i ); if( !pObj ) - throw Bu::ExceptionBase("No value object found."); + posError(ih, "Dictionary key has no value."); pDict->insert( sKey, pObj ); skipWs( i ); switch( *i ) @@ -187,7 +195,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) return pDict; default: - throw Bu::ExceptionBase("Invalid character found."); + posError(i, "Expected ',' or '}' but found '%1'.") + .arg( *i ); } } } @@ -277,7 +286,7 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) { - Bu::String::const_iterator i = sStr.begin(); + StrPos i( sStr.begin() ); return strToGats( i ); } diff --git a/c++-libbu++/src/object.h b/c++-libbu++/src/object.h index e4da8de..a876061 100644 --- a/c++-libbu++/src/object.h +++ b/c++-libbu++/src/object.h @@ -48,9 +48,69 @@ namespace Gats static Object *strToGats( const Bu::String &sStr ); private: - static Object *strToGats( Bu::String::const_iterator &i ); - static Bu::String token( Bu::String::const_iterator &i ); - static void skipWs( Bu::String::const_iterator &i ); + class StrPos + { + public: + StrPos( const Bu::String::const_iterator &i ) : + i( i ), iLine( 1 ), iChar( 1 ) + { } + Bu::String::const_iterator i; + int iLine; + int iChar; + + char operator*() + { + return *i; + } + StrPos &operator++(int) + { + i++; + if( i ) + { + if( *i == '\n' ) + { + iLine++; + iChar = 0; + } + else + iChar++; + } + return *this; + } + operator bool() + { + return i; + } + }; + + class Thrower : public Bu::String::FormatProxyEndAction + { + public: + Thrower( Gats::Object::StrPos &i ) : + i( i ) + { + } + + virtual ~Thrower() + { + } + + virtual void operator()( const Bu::String &sFinal ) + { + throw Bu::ExceptionBase( + (Bu::String("%1: %2: ").arg(i.iLine).arg(i.iChar).end() + sFinal) + .getStr() + ); + } + + private: + Gats::Object::StrPos &i; + }; + + static Bu::String::FormatProxy posError( Gats::Object::StrPos &i, const Bu::String &msg ); + static Object *strToGats( Gats::Object::StrPos &i ); + static Bu::String token( Gats::Object::StrPos &i ); + static void skipWs( Gats::Object::StrPos &i ); }; const char *typeToStr( Type t ); -- cgit v1.2.3