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