diff options
author | Mike Buland <eichlan@xagasoft.com> | 2013-02-10 21:53:22 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2013-02-10 21:53:22 +0000 |
commit | 1538ef47d1d4cc08e5f9c5894350bfa225866d40 (patch) | |
tree | caacdbe75db8a134a14074229892af2dbebf1ad1 | |
parent | 058caf24d2b48ab6b49ae8efe5e1eb1ed246eff1 (diff) | |
download | libgats-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.bld | 1 | ||||
-rw-r--r-- | c++-libbu++/src/object.cpp | 27 | ||||
-rw-r--r-- | 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" | |||
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 | ||
83 | void Gats::Object::skipWs( Bu::String::const_iterator &i ) | 83 | void 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 | ||
88 | Bu::String Gats::Object::token( Bu::String::const_iterator &i ) | 88 | Bu::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 | ||
114 | Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | 114 | Bu::String::FormatProxy Gats::Object::posError( Gats::Object::StrPos &i, const Bu::String &msg ) |
115 | { | ||
116 | return msg.format( new Thrower(i) ); | ||
117 | } | ||
118 | |||
119 | Gats::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 | ||
278 | Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) | 287 | Gats::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 ); |