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
00034 #include <lestes/common.hh>
00035 #include <lestes/std/source_location.hh>
00036 #include <lestes/std/file_info.hh>
00037 #include <lestes/lang/cplus/lex/token_sequence.hh>
00038 #include <lestes/lang/cplus/lex/pp_token.hh>
00039 #include <lestes/lang/cplus/lex/pp_token.hh>
00040 #include <lestes/lang/cplus/lex/taboo_macros.hh>
00041 #include <lestes/lang/cplus/lex/macro.hh>
00042 #include <lestes/lang/cplus/lex/macro_storage.hh>
00043 #include <lestes/lang/cplus/lex/token_value.hh>
00044
00045 #include <iterator>
00046 #include <iostream>
00047
00048 package(lestes);
00049 package(lang);
00050 package(cplus);
00051 package(lex);
00052
00053 using namespace ::std;
00054
00055
00056
00057
00058
00059 token_sequence::token_sequence(void):
00060 sequence(sequence_type::create())
00061 {
00062 }
00063
00064
00065
00066
00067
00068 ptr<pp_token> token_sequence::read(void)
00069 {
00070 if (length() == 0) return pp_token::terminator();
00071 ptr<pp_token> t = sequence->front();
00072 sequence->pop_front();
00073 return t;
00074 }
00075
00076
00077
00078
00079
00080 ptr<pp_token> token_sequence::peek_front(void)
00081 {
00082 if (length() != 0) return sequence->front();
00083 return pp_token::terminator();
00084 }
00085
00086
00087
00088
00089
00090 ptr<pp_token> token_sequence::peek_back(void)
00091 {
00092 if (length() == 0) return pp_token::terminator();
00093 return sequence->back();
00094 }
00095
00096
00097
00098
00099
00100 ptr<pp_token> token_sequence::read_front(void)
00101 {
00102 ulint len = length();
00103 if (!len) return pp_token::terminator();
00104
00105 ptr<pp_token> t = sequence->front();
00106 sequence->pop_front();
00107 len--;
00108
00109 if (t->type_get() == pp_token::TOK_BLANK) {
00110 ptr<pp_token> u;
00111 while (len--) {
00112 u = sequence->front();
00113 if (u->type_get() != pp_token::TOK_BLANK) break;
00114 sequence->pop_front();
00115 }
00116 }
00117
00118 return t;
00119 }
00120
00121
00122
00123
00124
00125 ptr<pp_token> token_sequence::read_front_skip_ws(void)
00126 {
00127 ptr<pp_token> t;
00128 ulint len = length();
00129
00130 while (len--) {
00131 t = sequence->front();
00132 sequence->pop_front();
00133 if (t->type_get() != pp_token::TOK_BLANK)
00134 return t;
00135 }
00136
00137 return pp_token::terminator();
00138 }
00139
00140
00141
00142
00143
00144 ptr<pp_token> token_sequence::read_back(void)
00145 {
00146 ulint len = length();
00147
00148 if (!len) return pp_token::terminator();
00149
00150 ptr<pp_token> t = sequence->back();
00151 sequence->pop_back();
00152 len--;
00153
00154 if (t->type_get() == pp_token::TOK_BLANK) {
00155 ptr<pp_token> u;
00156 while (len--) {
00157 u = sequence->back();
00158 if (u->type_get() != pp_token::TOK_BLANK) break;
00159 sequence->pop_back();
00160 }
00161 }
00162
00163 return t;
00164 }
00165
00166
00167
00168
00169
00170
00171 ptr<pp_token> token_sequence::read_back_skip_ws(void)
00172 {
00173 ptr<pp_token> t;
00174 ulint len = length();
00175
00176 while (len--) {
00177 t = sequence->back();
00178 sequence->pop_back();
00179 if (t->type_get() != pp_token::TOK_BLANK)
00180 return t;
00181 }
00182
00183 return pp_token::terminator();
00184 }
00185
00186
00187
00188
00189
00190 bool token_sequence::skip_front_ws(void)
00191 {
00192 sequence_type::size_type len = sequence->size();
00193 while (len && sequence->front()->type_get() == pp_token::TOK_BLANK) {
00194 sequence->pop_front();
00195 len--;
00196 }
00197 return len;
00198 }
00199
00200
00201
00202
00203
00204 bool token_sequence::skip_back_ws(void)
00205 {
00206 sequence_type::size_type len = sequence->size();
00207 while (len && sequence->back()->type_get() == pp_token::TOK_BLANK) {
00208 sequence->pop_back();
00209 len--;
00210 }
00211 return len;
00212 }
00213
00214
00215
00216
00217
00218
00219 void token_sequence::add_back(const ptr<pp_token> &a_token)
00220 {
00221 lassert(a_token);
00222 sequence->push_back(a_token);
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232 ptr<token_sequence> token_sequence::expand_all(const ptr<macro_storage> ¯os)
00233 {
00234 lassert(macros);
00235
00236 ptr<token_sequence> result = token_sequence::create();
00237
00238 if (!length()) return result;
00239
00240 ptr<pp_token> t = sequence->front();
00241 pp_token_type ptt = t->type_get();
00242
00243 ptr<macro> mac;
00244 ptr<token_sequence> expanded;
00245
00246 while (length()) {
00247 t = sequence->front();
00248 sequence->pop_front();
00249
00250 ptt = t->type_get();
00251
00252
00253
00254
00255 if (t->is_name() &&
00256 (mac = macros->lookup(t->value_get())) &&
00257 !t->taboo_get()->contains(mac) &&
00258 (!mac->funlike_get() || peek_front()->type_get() == pp_token::TOK_LEFT_PAR)) {
00259
00260 ptr<token_sequence> expanded = mac->expand(t,this,macros);
00261
00262 expanded->taboo_extend(t->taboo_get()->extend(mac),macros);
00263
00264
00265 prepend(expanded);
00266 } else {
00267 result->add_back(t);
00268 }
00269 }
00270 return result;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280 void token_sequence::taboo_extend(const ptr<taboo_macros> &tm, const ptr<macro_storage> ¯os)
00281 {
00282 lassert(tm);
00283 lassert(macros);
00284
00285 ptr<pp_token> t;
00286
00287 for (sequence_type::iterator it = sequence->begin(),
00288 end = sequence->end(); it != end; ++it) {
00289 t = *it;
00290
00291
00292 if (t->is_name() &&
00293 macros->lookup(t->value_get())) {
00294
00295
00296 *it = t->clone(tm);
00297 }
00298 }
00299 }
00300
00301
00302
00303
00304
00305
00306 ptr<token_sequence> token_sequence::clone(void) const
00307 {
00308 ptr<token_sequence> nju = token_sequence::create();
00309 copy(sequence->begin(),sequence->end(),back_inserter(*(nju->sequence)));
00310 return nju;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 ptr<token_sequence> token_sequence::clone(const ptr<source_location> &a_location) const
00320 {
00321 lassert(a_location);
00322
00323 ptr<pp_token> t;
00324 ptr<token_sequence> nju = token_sequence::create();
00325
00326 sequence_type::iterator it = sequence->begin();
00327 sequence_type::iterator end = sequence->end();
00328
00329 for (; it != end; ++it) {
00330 t = *it;
00331 nju->add_back(t->clone(a_location));
00332 }
00333
00334 return nju;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 void token_sequence::prepend(const ptr<token_sequence> &inserted)
00344 {
00345 lassert(inserted);
00346 sequence->splice(sequence->begin(),*(inserted->sequence));
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 void token_sequence::append(const ptr<token_sequence> &inserted)
00356 {
00357 lassert(inserted);
00358 sequence->splice(sequence->end(),*(inserted->sequence));
00359 }
00360
00361
00362
00363
00364
00365 token_sequence::size_type token_sequence::length(void) const
00366 {
00367 return sequence->size();
00368 }
00369
00370
00371
00372
00373
00374 ptr<token_sequence> token_sequence::create(void)
00375 {
00376 return new token_sequence();
00377 }
00378
00379
00380
00381
00382
00383
00384 bool token_sequence::equals(const ptr<token_sequence> &other) const
00385 {
00386 if (!other || length() != other->length()) return false;
00387
00388 sequence_type::iterator it = sequence->begin();
00389 sequence_type::iterator end = sequence->end();
00390
00391 sequence_type::iterator ot = other->sequence->begin();
00392
00393 for (; it != end; ++it, ++ot) {
00394 ptr<pp_token> pt = *it;
00395 ptr<pp_token> qt = *ot;
00396
00397 if (!is_equal(pt,qt)) return false;
00398 }
00399
00400 return true;
00401 }
00402
00403
00404
00405
00406
00407
00408 bool token_sequence::congruent(const ptr<token_sequence> &other) const
00409 {
00410
00411
00412
00413
00414 if (!other || length() != other->length()) return false;
00415
00416
00417
00418 sequence_type::iterator it = sequence->begin();
00419 sequence_type::iterator end = sequence->end();
00420
00421 sequence_type::iterator ot = other->sequence->begin();
00422
00423 for (; it != end; ++it, ++ot) {
00424 ptr<pp_token> pt = *it;
00425 ptr<pp_token> qt = *ot;
00426
00427 if (!pt->congruent(qt)) return false;
00428
00429 }
00430
00431 return true;
00432 }
00433
00434
00435
00436
00437 void token_sequence::gc_mark(void)
00438 {
00439 sequence.gc_mark();
00440 token_input::gc_mark();
00441 }
00442
00443
00444
00445
00446
00447 void token_sequence::debug_print(ostream &o) const
00448 {
00449 bool next = false;
00450
00451 for (sequence_type::iterator it = sequence->begin(), end = sequence->end();
00452 it != end; ++it) {
00453 if (next) o << ' '; else next = true;
00454 o << (*it)->spelling_get();
00455 }
00456 }
00457
00458
00459
00460
00461
00462
00463 ::std::ostream &operator<<(::std::ostream &o, const ptr<token_sequence> &ts) {
00464 ts->debug_print(o);
00465 return o;
00466 }
00467
00468 end_package(lex);
00469 end_package(cplus);
00470 end_package(lang);
00471 end_package(lestes);
00472