00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <cstring>
00034 #include <iostream>
00035
00036 using std::cout ;
00037 using std::endl ;
00038
00039 #include "BESTokenizer.h"
00040 #include "BESSyntaxUserError.h"
00041
00042 BESTokenizer::BESTokenizer( )
00043 : _counter( -1 ) {}
00044
00045 BESTokenizer::~BESTokenizer() {}
00046
00059 void
00060 BESTokenizer::parse_error( const string &s ) {
00061 string error = "Parse error." ;
00062 string where = "" ;
00063 if( _counter >= 0 ) {
00064 for( int w = 0; w < _counter+1; w++ )
00065 where += tokens[w] + " " ;
00066 where += "<----HERE IS THE ERROR" ;
00067 error += "\n" + where ;
00068 }
00069 if( s != "" )
00070 error += "\n" + s ;
00071 throw BESSyntaxUserError( error, __FILE__, __LINE__ ) ;
00072 }
00073
00082 string &
00083 BESTokenizer::get_first_token() {
00084 _counter = 0 ;
00085 return tokens[_counter] ;
00086 }
00087
00097 string &
00098 BESTokenizer::get_current_token() {
00099 if( _counter == -1 ) {
00100 parse_error( "incomplete expression!" ) ;
00101 }
00102
00103 if( _counter > _number_tokens-1 ) {
00104 parse_error( "incomplete expression!" ) ;
00105 }
00106
00107 return tokens[_counter] ;
00108 }
00109
00119 string &
00120 BESTokenizer::get_next_token() {
00121 if( _counter == -1 ) {
00122 parse_error( "incomplete expression!" ) ;
00123 }
00124
00125 if( _counter >= _number_tokens-1 ) {
00126 parse_error( "incomplete expression!" ) ;
00127 }
00128
00129 return tokens[++_counter] ;
00130 }
00131
00158 void
00159 BESTokenizer::tokenize( const char *p ) {
00160 size_t len = strlen( p ) ;
00161 string s = "" ;
00162 bool passing_raw = false ;
00163 bool escaped = false ;
00164
00165
00166
00167 for( unsigned int j = 0; j < len; j++ ) {
00168
00169
00170 if( !escaped && p[j] == '\"') {
00171
00172 if( s != "" ) {
00173 if( passing_raw ) {
00174 s += "\"" ;
00175 tokens.push_back( s ) ;
00176 s = "" ;
00177 } else {
00178 tokens.push_back( s ) ;
00179 s = "\"" ;
00180 }
00181 } else {
00182 s += "\"" ;
00183 }
00184 passing_raw =! passing_raw ;
00185
00186 } else if( passing_raw ) {
00187
00188 if(!escaped && p[j] == '\\' ){
00189 escaped = true;
00190 } else {
00191 s += p[j] ;
00192
00193 if(escaped)
00194 escaped = false;
00195 }
00196
00197 } else {
00198 if( ( p[j] == ' ' ) ||
00199 ( p[j] == '\n' ) ||
00200 ( p[j] == 0x0D ) ||
00201 ( p[j] == 0x0A ) ) {
00202 if( s != "" ) {
00203 tokens.push_back( s ) ;
00204 s = "" ;
00205 }
00206 } else if( ( p[j] == ',' ) || ( p[j] == ';' ) ) {
00207 if( s!= "" ) {
00208 tokens.push_back( s ) ;
00209 s = "" ;
00210 }
00211 switch( p[j] ) {
00212 case ',':
00213 tokens.push_back( "," ) ;
00214 break;
00215 case ';':
00216 tokens.push_back( ";" ) ;
00217 break;
00218 }
00219 } else
00220 s += p[j] ;
00221 }
00222 }
00223
00224
00225 if( s != "" )
00226 tokens.push_back( s ) ;
00227 _number_tokens = tokens.size() ;
00228 if( passing_raw )
00229 parse_error( "Unclose quote found.(\")" ) ;
00230 if( _number_tokens < 2 )
00231 parse_error( "Unknown command: '" + (string)p + (string)"'") ;
00232 if( tokens[_number_tokens - 1] != ";" )
00233 parse_error( "The request must be terminated by a semicolon (;)" ) ;
00234 }
00235
00256 string
00257 BESTokenizer::parse_container_name( const string &s, unsigned int &type ) {
00258 string::size_type where = s.rfind( ".constraint=", s.size() ) ;
00259 if( where == string::npos ) {
00260 where = s.rfind( ".attributes=", s.size() ) ;
00261 if( where == string::npos ) {
00262 parse_error( "Expected property declaration." ) ;
00263 } else {
00264 type = 2 ;
00265 }
00266 } else {
00267 type = 1 ;
00268 }
00269 string valid = s.substr( where, s.size() ) ;
00270 if( (valid != ".constraint=") && (valid != ".attributes=") ) {
00271 string err = (string)"Invalid container property "
00272 + valid
00273 + " for container "
00274 + s.substr( 0, where )
00275 + ". constraint expressions and attribute lists "
00276 + "must be wrapped in quotes" ;
00277 parse_error( err ) ;
00278 }
00279 return s.substr( 0, where ) ;
00280 }
00281
00293 string
00294 BESTokenizer::remove_quotes( const string &s ) {
00295 if( (s[0] != '"' ) || (s[s.size() - 1] != '"' ) ) {
00296 parse_error( "item " + s + " must be enclosed by quotes" ) ;
00297 }
00298 return s.substr( 1, s.size() - 2 ) ;
00299 }
00300
00309 void
00310 BESTokenizer::dump_tokens() {
00311 tokens_citerator i = tokens.begin() ;
00312 tokens_citerator ie = tokens.end() ;
00313 for( ; i != ie; i++ ) {
00314 cout << "\"" << (*i) << "\"" << endl ;
00315 }
00316 }
00317
00324 void
00325 BESTokenizer::dump( ostream &strm ) const {
00326 strm << BESIndent::LMarg << "BESTokenizer::dump - ("
00327 << (void *)this << ")" << endl ;
00328 BESIndent::Indent() ;
00329 tokens_citerator i = tokens.begin() ;
00330 tokens_citerator ie = tokens.end() ;
00331 for( ; i != ie; i++ ) {
00332 strm << BESIndent::LMarg << "\"" << (*i) << "\"" << endl ;
00333 }
00334 BESIndent::UnIndent() ;
00335 }
00336