pp_token.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 /*! \file
00029   \brief Preprocessor token.
00030 
00031   Definition of pp_token class representing preprocessor token.
00032   \author pt
00033 */
00034 #include <lestes/common.hh>
00035 #include <lestes/equality.hh>
00036 #include <lestes/std/source_location.hh>
00037 #include <lestes/std/ucn_string.hh>
00038 #include <lestes/lang/cplus/lex/pp_token.hh>
00039 #include <lestes/lang/cplus/lex/basic_token.hh>
00040 #include <lestes/lang/cplus/lex/token_value.hh>
00041 #include <lestes/lang/cplus/lex/taboo_macros.hh>
00042 
00043 #include <iostream>
00044 
00045 package(lestes);
00046 package(lang);
00047 package(cplus);
00048 package(lex);
00049 
00050 using namespace ::std;
00051 
00052 /*!
00053   Creates new token, initializes with location, token type, token value and flags.
00054   \pre a_taboo != NULL
00055   \post is_equal(location_get(),a_location)
00056   \post is_equal(type_get(),a_type)
00057   \post is_equal(value_get(),a_value)
00058   \param a_location  The initial location.
00059   \param a_type  The type.
00060   \param a_value  The value.
00061   \param a_alternative  The alternative spelling flag.
00062   \param a_taboo  The taboo.
00063 */
00064 pp_token::pp_token(const location_type &a_location, const type_type &a_type,
00065         const value_type &a_value, bool a_alternative, const ptr<taboo_macros> &a_taboo):
00066         basic_pp_token(a_location,a_type,a_value),
00067         alternative(a_alternative),
00068         taboo(checked(a_taboo))
00069 {
00070 }
00071 
00072 /*!
00073   Tests if token is name, that is identifier, keyword, true or false.
00074   \return true  If token is a name.
00075 */
00076 bool pp_token::is_name(void) const
00077 {
00078         return the_flags[type_get()] & FLG_NAME;
00079 }
00080 
00081 /*!
00082   Tests if token has alternative spelling.
00083   \return true  If token has alternative spelling.
00084 */
00085 bool pp_token::is_alternative(void) const
00086 {
00087         return alternative;
00088 }
00089 
00090 /*!
00091   Tests if token has value.
00092   \return true  If token has alternative spelling.
00093 */
00094 bool pp_token::is_valued(void) const
00095 {
00096         return the_flags[type_get()] & (FLG_EXTERNAL | FLG_INTERNAL);
00097 }
00098 
00099 /*!
00100   Returns internal token description dependent on token type, for debugging.
00101   \return  The token description.
00102 */
00103 lstring pp_token::description_get(void) const
00104 {
00105         return the_description[type_get()];
00106 }
00107 
00108 /*!
00109   Returns token spelling, reflecting the source.
00110   \return  String representation of the token.
00111 */
00112 ucn_string pp_token::spelling_get(void) const
00113 {
00114         pp_token_type ptt = type_get();
00115   
00116         switch (ptt) {
00117                 case pp_token::TOK_STRING_LIT:
00118                         {
00119                                 ucn_string us = "\"";
00120                                 us += value_get()->content_get();
00121                                 us += character::create_from_host('"');
00122                                 return us;
00123                         }
00124                 case pp_token::TOK_CHAR_LIT:
00125                         {
00126                                 ucn_string us = "'";
00127                                 us += value_get()->content_get();
00128                                 us += character::create_from_host('\'');
00129                                 return us;
00130                         }
00131                 case pp_token::TOK_WSTRING_LIT:
00132                         {
00133                                 ucn_string us = "L\"";
00134                                 us += value_get()->content_get();
00135                                 us += character::create_from_host('"');
00136                                 return us;
00137                         }
00138                 case pp_token::TOK_WCHAR_LIT:
00139                         {
00140                                 ucn_string us = "L'";
00141                                 us += value_get()->content_get();
00142                                 us += character::create_from_host('\'');
00143                                 return us;
00144                         }
00145                 default:
00146                         break;
00147         }
00148 
00149         if (is_valued()) {
00150                 /* TODO pt remove
00151                 if (is_name()) {
00152                         ucn_string u;
00153                         u += value_get()->content_get();
00154                         u += taboo_get()->names_get();
00155                         return u;
00156                 }
00157                 */
00158                 
00159                 return value_get()->content_get();
00160         }
00161 
00162         return the_spelling[is_alternative()][ptt];
00163 }
00164 
00165 /*!
00166   Returns taboo macros for the token.
00167   \return The taboo macros for the token.
00168 */
00169 ptr<taboo_macros> pp_token::taboo_get(void) const
00170 {
00171         return taboo;
00172 }
00173 
00174 /*!
00175   Tests congruence of the token, that is equivalence considering
00176   only type, value and spelling.
00177   \param other  The token to compare with.
00178   \return true  If both tokens are congruent.
00179 */
00180 bool pp_token::congruent(const ptr<pp_token> &other) const
00181 {
00182         return other &&
00183                 is_equal(type_get(),other->type_get()) &&
00184                 is_equal(is_alternative(),other->is_alternative()) &&
00185                 is_equal(value_get(),other->value_get());
00186 }
00187 
00188 /*!
00189   Tests equality of the token.
00190   \param other  The token to compare with.
00191   \return true  If both tokens are equal.
00192 */
00193 bool pp_token::equals(const ptr<pp_token> &other) const
00194 {
00195         // TODO pt taboo
00196         return other &&
00197                 is_equal(type_get(),other->type_get()) &&
00198                 is_equal(is_alternative(),other->is_alternative()) &&
00199                 is_equal(location_get(),other->location_get()) &&
00200                 is_equal(value_get(),other->value_get());
00201 }
00202 
00203 /*!
00204   Returns copy of this token, with different location.
00205   \pre a_location != NULL
00206   \param a_location  The new location 
00207   \return  New token which holds the same values and new location.
00208 */
00209 ptr<pp_token> pp_token::clone(const location_type &a_location) const
00210 {
00211         lassert(a_location);
00212         return new pp_token(a_location,type_get(),value_get(),is_alternative(),taboo_get());
00213 }
00214 
00215 /*!
00216   Returns copy of this token, with different taboo macros.
00217   \pre a_taboo != NULL
00218   \pre The token is name.
00219   \param a_taboo  The new taboo macros. 
00220   \return  New token which holds the same values and new taboo macros.
00221 */
00222 ptr<pp_token> pp_token::clone(const ptr<taboo_macros> &a_taboo) const
00223 {
00224         lassert(a_taboo);
00225         lassert(is_name());
00226         return new pp_token(location_get(),type_get(),value_get(),is_alternative(),a_taboo);
00227 }
00228 
00229 /*!
00230   Returns new token, initializes with location, token type.
00231   \pre The type does not need value or value is initialized internally.
00232   \post is_equal(location_get(),a_location)
00233   \post is_equal(type_get(),a_type)
00234   \param a_location  The location.
00235   \param a_type  The token type.
00236   \return  New token initialized with location and token type.
00237 */
00238 ptr<pp_token> pp_token::create(const location_type &a_location, const type_type &a_type)
00239 {
00240         initialize();
00241         lassert(!(the_flags[a_type] & FLG_EXTERNAL));
00242         return new pp_token(a_location,a_type,the_value[a_type],false,taboo_macros::create());
00243 }
00244 
00245 /*!
00246   Returns new token with alternative spelling, initializes with location and token type.
00247   \pre The type does not need value or value is initialized internally.
00248   \pre Alternative spelling is used only when available.
00249   \post is_equal(location_get(),a_location)
00250   \post is_equal(type_get(),a_type)
00251   \param a_location  The location.
00252   \param a_type  The token type.
00253   \return  New token initialized with location and token type.
00254 */
00255 ptr<pp_token> pp_token::create_alternative(const location_type &a_location, const type_type &a_type)
00256 {
00257         initialize();
00258         lassert(!(the_flags[a_type] & FLG_EXTERNAL));
00259         lassert(the_flags[a_type] & FLG_VARIANT);
00260         return new pp_token(a_location,a_type,the_value[a_type],true,taboo_macros::create());
00261 }
00262 
00263 /*!
00264   Returns new token, initializes with location, token type and token value.
00265   \pre The token type needs an external value.
00266   \post is_equal(location_get(),a_location)
00267   \post is_equal(type_get(),a_type)
00268   \post is_equal(value_get(),a_value)
00269   \param a_location  The initial location.
00270   \param a_type  The initial token type.
00271   \param a_value  The initial token value.
00272   \return  New token initialized with location, token type and token value.
00273 */
00274 ptr<pp_token> pp_token::create(const location_type &a_location, const type_type &a_type,
00275         const value_type &a_value)
00276 {
00277         initialize();
00278         lassert(the_flags[a_type] & FLG_EXTERNAL);
00279         return new pp_token(a_location,a_type,a_value,false,taboo_macros::create());
00280 }
00281 
00282 ptr<pp_token> pp_token::terminator(void)
00283 {
00284         if (!terminator_instance) {
00285                 terminator_instance = pp_token::create(source_location::zero(),pp_token::TOK_TERMINATOR);
00286         }
00287         return terminator_instance;
00288 }
00289 
00290 /*!
00291   Marks the object.
00292 */
00293 void pp_token::gc_mark(void)
00294 {
00295         taboo.gc_mark();
00296         basic_pp_token::gc_mark();
00297 }
00298 
00299 /*!
00300   Initializes helper static structures containing properties of existing token types.
00301   The initialization is invoked automatically prior to use of any instance.
00302 */
00303 void pp_token::initialize(void)
00304 {
00305         if (initialized) return;
00306         
00307         ulint i;
00308 
00309         i = 0;
00310 #undef DEF_PP_TOKEN
00311 #define DEF_PP_TOKEN(x,y,z,w) \
00312         the_description[i++] = #x;
00313         PP_TOKENS_LIST
00314 
00315         i = 0;
00316 #undef DEF_PP_TOKEN
00317 #define DEF_PP_TOKEN(x,y,z,w) \
00318         the_spelling[0][i] = y; the_spelling[1][i++] = z;
00319         PP_TOKENS_LIST
00320 
00321         i = 0;
00322 #undef DEF_PP_TOKEN
00323 #define DEF_PP_TOKEN(x,y,z,w) \
00324         the_value[i++] = ((w) & FLG_INTERNAL) ? token_value::create(ucn_string(y)) : ptr<token_value>(NULL);
00325         PP_TOKENS_LIST
00326 
00327         i = 0;
00328 #undef DEF_PP_TOKEN
00329 #define DEF_PP_TOKEN(x,y,z,w) \
00330         the_flags[i++] = w;
00331         PP_TOKENS_LIST
00332 
00333         initialized = true;
00334 }
00335 
00336 /*!
00337   Multiple initialization guard.
00338 */
00339 bool pp_token::initialized;
00340 
00341 /*!
00342   List of token internally initialized values.
00343 */
00344 ptr<token_value> pp_token::the_value[TOKEN_TYPE_COUNT];
00345 
00346 /*!
00347   List of token descriptions.
00348 */
00349 lstring pp_token::the_description[TOKEN_TYPE_COUNT];
00350 
00351 /*!
00352   List of token spellings.
00353 */
00354 ucn_string pp_token::the_spelling[2][TOKEN_TYPE_COUNT];
00355 
00356 /*!
00357   List of token flags.
00358 */
00359 pp_token::flags_type pp_token::the_flags[TOKEN_TYPE_COUNT];
00360 
00361 /*!
00362   Terminator token instance.
00363 */
00364 ptr<pp_token> pp_token::terminator_instance = terminator_instance;
00365 
00366 end_package(lex);
00367 end_package(cplus);
00368 end_package(lang);
00369 end_package(lestes);
00370 
00371 /* vim: set ft=lestes : */

Generated on Mon Feb 12 18:23:10 2007 for lestes by doxygen 1.5.1-20070107