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 #include <lestes/lang/cplus/lex/preprocessor.hh>
00029 #include <lestes/lang/cplus/syn/prefixer.hh>
00030 #include <lestes/lang/cplus/syn/syn.hh>
00031 #include <lestes/lang/cplus/syn/token.hh>
00032 #include <lestes/msg/logger.hh>
00033
00034 #include <iostream>
00035
00036 package(lestes);
00037 package(lang);
00038 package(cplus);
00039 package(syn);
00040
00041 declare_logger( prl );
00042 initialize_logger( prl, "prefixer", syn_logger );
00043
00044 prefixer::mode_type prefixer::mode;
00045
00046 ptr<prefixer::preprocessor> prefixer::pp;
00047
00048 void prefixer::init( mode_type a_mode, ptr<preprocessor> a_pp )
00049 {
00050 mode = a_mode;
00051 pp = a_pp;
00052 }
00053
00054 prefixer::mode_type prefixer::mode_get()
00055 {
00056 return mode;
00057 }
00058
00059 ptr<bison_token> prefixer::internal_yylex()
00060 {
00061 return bison_token::create( pp->read() );
00062 }
00063
00064
00065 static struct prefix2hint_map_item {
00066 const ucn_string value;
00067 const bison_token::hint_type hint;
00068 } prefix2hint_map[] = {
00069 { "_hint_templ_nontype",bison_token::HINT_TEMPL_NONTYPE },
00070 { "_hint_templ_type", bison_token::HINT_TEMPL_TYPE },
00071 { "_hint_nontype", bison_token::HINT_NONTYPE },
00072 { "_hint_class", bison_token::HINT_CLASS },
00073 { "_hint_enum", bison_token::HINT_ENUM },
00074 { "_hint_typedef", bison_token::HINT_TYPEDEF },
00075 { "_hint_namespace", bison_token::HINT_NAMESPACE },
00076 { "_hint_unknown", bison_token::HINT_UNKNOWN },
00077
00078 { "_hint_ctor", bison_token::HINT_CTOR },
00079 { "_hint_no_ctor", bison_token::HINT_NO_CTOR },
00080 { "_hint_bitfield", bison_token::HINT_BITFIELD },
00081 { "_hint_no_bitfield", bison_token::HINT_NO_BITFIELD },
00082
00083 { "", bison_token::HINT_NONE }
00084 };
00085
00086 bison_token::hint_type prefixer::prefix2hint( const ucn_string & str )
00087 {
00088 const struct prefix2hint_map_item * it = prefix2hint_map;
00089
00090 while (!(it->value.empty()) && str != it->value)
00091 ++it;
00092 return it->hint;
00093 }
00094
00095 ptr<bison_token> prefixer::yylex()
00096 {
00097 ptr<bison_token> tok1 = internal_yylex();
00098
00099 if (mode == PREFIX_OFF)
00100 return tok1;
00101 bison_token::hint_type hint;
00102 ptr<bison_token> tok2;
00103 do {
00104
00105 if (tok1->type_get() != bison_token::TOK_IDENT)
00106 return tok1;
00107 hint = prefix2hint( tok1->value_get() );
00108 if (hint == bison_token::HINT_NONE)
00109 return tok1;
00110 tok2 = internal_yylex();
00111
00112
00113
00114
00115 if (hint == bison_token::HINT_CTOR ||
00116 hint == bison_token::HINT_NO_CTOR) {
00117 if (tok2->type_get() == bison_token::TOK_LEFT_PAR)
00118 break;
00119 } else if (hint == bison_token::HINT_BITFIELD ||
00120 hint == bison_token::HINT_NO_BITFIELD) {
00121 if (tok2->type_get() == bison_token::TOK_COLON)
00122 break;
00123 } else if (tok2->type_get() == bison_token::TOK_IDENT) {
00124 if (prefix2hint(tok2->value_get()) == bison_token::HINT_NONE)
00125 break;
00126 else
00127 ;
00128 }
00129 llog(prl) << "user-specified hint (\"" << tok1->value_get() <<
00130 "\") irrelevant, discarding\n";
00131 tok1 = tok2;
00132 } while (true);
00133
00134 tok2->user_hint_set(hint);
00135 return tok2;
00136 }
00137
00138 end_package(syn);
00139 end_package(cplus);
00140 end_package(lang);
00141 end_package(lestes);