aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2013-02-10 21:53:22 +0000
committerMike Buland <eichlan@xagasoft.com>2013-02-10 21:53:22 +0000
commit1538ef47d1d4cc08e5f9c5894350bfa225866d40 (patch)
treecaacdbe75db8a134a14074229892af2dbebf1ad1
parent058caf24d2b48ab6b49ae8efe5e1eb1ed246eff1 (diff)
downloadlibgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.gz
libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.bz2
libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.xz
libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.zip
Made the gats text parser much more robust.
-rw-r--r--c++-libbu++/default.bld1
-rw-r--r--c++-libbu++/src/object.cpp27
-rw-r--r--c++-libbu++/src/object.h66
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"
52{ 52{
53 rule "exe"; 53 rule "exe";
54 input files("src/gatsc/*.cpp"); 54 input files("src/gatsc/*.cpp");
55 requires "libgats.a";
55 CXXFLAGS += "-I. -Ilibbu++"; 56 CXXFLAGS += "-I. -Ilibbu++";
56 LDFLAGS += "-L. -lgats -lbu++"; 57 LDFLAGS += "-L. -lgats -lbu++";
57} 58}
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 )
80 return pObj; 80 return pObj;
81} 81}
82 82
83void Gats::Object::skipWs( Bu::String::const_iterator &i ) 83void Gats::Object::skipWs( Gats::Object::StrPos &i )
84{ 84{
85 for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { } 85 for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { }
86} 86}
87 87
88Bu::String Gats::Object::token( Bu::String::const_iterator &i ) 88Bu::String Gats::Object::token( Gats::Object::StrPos &i )
89{ 89{
90 Bu::String sRet; 90 Bu::String sRet;
91 if( *i == '\"' ) 91 if( *i == '\"' )
@@ -111,7 +111,12 @@ Bu::String Gats::Object::token( Bu::String::const_iterator &i )
111 return sRet; 111 return sRet;
112} 112}
113 113
114Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) 114Bu::String::FormatProxy Gats::Object::posError( Gats::Object::StrPos &i, const Bu::String &msg )
115{
116 return msg.format( new Thrower(i) );
117}
118
119Gats::Object *Gats::Object::strToGats( Gats::Object::StrPos &i )
115{ 120{
116 skipWs( i ); 121 skipWs( i );
117 122
@@ -145,7 +150,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i )
145 return pLst; 150 return pLst;
146 151
147 default: 152 default:
148 throw Bu::ExceptionBase("Invalid character found."); 153 posError(i, "Expected ',' or ']' but found '%1'.").
154 arg( *i );
149 } 155 }
150 } 156 }
151 } 157 }
@@ -164,16 +170,18 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i )
164 return pDict; 170 return pDict;
165 } 171 }
166 if( *i != '\"' ) 172 if( *i != '\"' )
167 throw Bu::ExceptionBase("Keys must be quoted strings."); 173 posError(i, "Dictionary keys must be quoted strings.");
168 Bu::String sKey = token( i ); 174 Bu::String sKey = token( i );
169 skipWs( i ); 175 skipWs( i );
170 if( *i != ':' ) 176 if( *i != ':' )
171 throw Bu::ExceptionBase("Keys and values must be " 177 posError(i, "Dictionary keys and values must be "
172 "seperated with colons."); 178 "seperated with colons.");
179 StrPos ih( i );
173 i++; 180 i++;
181 skipWs( i );
174 Gats::Object *pObj = strToGats( i ); 182 Gats::Object *pObj = strToGats( i );
175 if( !pObj ) 183 if( !pObj )
176 throw Bu::ExceptionBase("No value object found."); 184 posError(ih, "Dictionary key has no value.");
177 pDict->insert( sKey, pObj ); 185 pDict->insert( sKey, pObj );
178 skipWs( i ); 186 skipWs( i );
179 switch( *i ) 187 switch( *i )
@@ -187,7 +195,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i )
187 return pDict; 195 return pDict;
188 196
189 default: 197 default:
190 throw Bu::ExceptionBase("Invalid character found."); 198 posError(i, "Expected ',' or '}' but found '%1'.")
199 .arg( *i );
191 } 200 }
192 } 201 }
193 } 202 }
@@ -277,7 +286,7 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i )
277 286
278Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) 287Gats::Object *Gats::Object::strToGats( const Bu::String &sStr )
279{ 288{
280 Bu::String::const_iterator i = sStr.begin(); 289 StrPos i( sStr.begin() );
281 290
282 return strToGats( i ); 291 return strToGats( i );
283} 292}
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
48 static Object *strToGats( const Bu::String &sStr ); 48 static Object *strToGats( const Bu::String &sStr );
49 49
50 private: 50 private:
51 static Object *strToGats( Bu::String::const_iterator &i ); 51 class StrPos
52 static Bu::String token( Bu::String::const_iterator &i ); 52 {
53 static void skipWs( Bu::String::const_iterator &i ); 53 public:
54 StrPos( const Bu::String::const_iterator &i ) :
55 i( i ), iLine( 1 ), iChar( 1 )
56 { }
57 Bu::String::const_iterator i;
58 int iLine;
59 int iChar;
60
61 char operator*()
62 {
63 return *i;
64 }
65 StrPos &operator++(int)
66 {
67 i++;
68 if( i )
69 {
70 if( *i == '\n' )
71 {
72 iLine++;
73 iChar = 0;
74 }
75 else
76 iChar++;
77 }
78 return *this;
79 }
80 operator bool()
81 {
82 return i;
83 }
84 };
85
86 class Thrower : public Bu::String::FormatProxyEndAction
87 {
88 public:
89 Thrower( Gats::Object::StrPos &i ) :
90 i( i )
91 {
92 }
93
94 virtual ~Thrower()
95 {
96 }
97
98 virtual void operator()( const Bu::String &sFinal )
99 {
100 throw Bu::ExceptionBase(
101 (Bu::String("%1: %2: ").arg(i.iLine).arg(i.iChar).end() + sFinal)
102 .getStr()
103 );
104 }
105
106 private:
107 Gats::Object::StrPos &i;
108 };
109
110 static Bu::String::FormatProxy posError( Gats::Object::StrPos &i, const Bu::String &msg );
111 static Object *strToGats( Gats::Object::StrPos &i );
112 static Bu::String token( Gats::Object::StrPos &i );
113 static void skipWs( Gats::Object::StrPos &i );
54 }; 114 };
55 115
56 const char *typeToStr( Type t ); 116 const char *typeToStr( Type t );