00001 %{
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026 #include <lib/message/message.h>
00027
00028 #include <lib/lex/test-scanner.h>
00029
00030 #include <lib/lex/test-grammar.h>
00031
00032
00033 #define YY_EXTRA_TYPE class TestScanner*
00034
00035
00036 #include "scannerbase.cc"
00037
00038
00039 #define TOK() ((TestScanner::TestToken*)(yyextra->_tok_ptr()))
00040
00041 %}
00042
00043
00044
00045
00046 %pointer
00047 %option 8bit
00048 %option reentrant
00049
00050
00051
00052
00053
00054 %option nodefault
00055 %option noyywrap
00056 %option stack
00058 %option prefix="TEST_"
00059 %option outfile="test-scanner.cc"
00060
00061
00062
00063
00064 %x IN_CMT
00065 %x IN_CPPCMT
00066
00067 identifier [[:alpha:]_][[:alnum:]_]*
00068 ninteger [[:digit:]]+
00069 xinteger (0?[[:digit:]]+)|(0x[[:xdigit:]]+)
00070
00071 %%
00072
00073 "//" {
00074 PI_TOK();
00075 yy_push_state(IN_CPPCMT,yyscanner);
00076 }
00077 <IN_CPPCMT>.*\n {
00078 PI_LINE();
00079 PI_START();
00080 yy_pop_state(yyscanner);
00081 }
00082 <IN_CPPCMT><<EOF>> {
00083 PI_EOF();
00084 PI_TOK();
00085 PI_START();
00086 yy_pop_state(yyscanner);
00087 return(0);
00088 }
00089
00090 <IN_CPPCMT>. {
00091 PI_CHAR(yytext[0]);
00092 }
00093
00094 "/*" {
00095 PI_TOK();
00096 yy_push_state(IN_CMT,yyscanner);
00097 yyextra->nested_comment_warned=0;
00098 yyextra->newlines_in_ccomment=0;
00099 }
00100 <IN_CMT>"*/" {
00101 PI_TOK();
00102 PI_START();
00103 yy_pop_state(yyscanner);
00104 }
00105 <IN_CMT>"/*" {
00106 PI_START();
00107 PI_TOK();
00108 if(yyextra->allow_nested_comments)
00109 {
00110 if(yyextra->allow_nested_comments>=2 &&
00111 !yyextra->nested_comment_warned)
00112 {
00113 Warning(yyextra->_MakeCurrLoc(),"nested C-style comment\n");
00114 ++yyextra->nested_comment_warned;
00115 }
00116 yy_push_state(IN_CMT,yyscanner);
00117 }
00118 PI_START();
00119 }
00120 <IN_CMT>[^\n/\*]*\n { PI_LINE(); ++yyextra->newlines_in_ccomment; }
00121 <IN_CMT>[^\n\r\t/\*]* { PI_TOK(); }
00122
00123
00124 <IN_CMT>\t { PI_TAB(); }
00125 <IN_CMT><<EOF>> {
00126 PI_EOF();
00127 PI_TOK();
00128
00129 Error(yyextra->_MakeCurrEndLoc(),"unterminated C-style comment\n");
00130 ++yyextra->n_errors;
00131 while(YY_START==IN_CMT)
00132 { yy_pop_state(yyscanner); }
00133 return(0);
00134 }
00135 <IN_CMT>. { PI_TOK(); }
00136
00137
00138 [ \t]+ {
00139 PI_STR(yytext,yyleng);
00140
00141 PI_START();
00142 }
00143 \n { PI_LINE(); PI_START(); }
00144
00145
00146 "if" { PI_TOK(); return(TS_IF); }
00147 "else" { PI_TOK(); return(TS_ELSE); }
00148
00149 {xinteger} {
00150 PI_TOK();
00151
00152 int ival=strtol(yytext,NULL,0);
00153
00154 TOK()->lval.int_val=ival;
00155
00156 return(TS_INTEGER);
00157 }
00158 {identifier} {
00159 PI_TOK();
00160
00161 TOK()->lval.string_val=ALLOC<char>(yyleng+1);
00162 strncpy(TOK()->lval.string_val,yytext,yyleng);
00163 TOK()->lval.string_val[yyleng]='\0';
00164 return(TS_IDENTIFIER);
00165 }
00166
00167 <<EOF>> {
00168
00169
00170
00171
00172 PI_EOF();
00173 return(0);
00174 }
00175
00176 . { PI_TOK(); return(yytext[0]); }
00177
00178 %%
00179
00180
00181 #define PREFIX_FlexScannerBase TEST_FlexScannerBase
00182 #define PREFIX_lex TEST_lex
00183 #define PREFIX_lex_init TEST_lex_init
00184 #define PREFIX_lex_destroy TEST_lex_destroy
00185 #define PREFIX_pop_buffer_state TEST_pop_buffer_state
00186 #define PREFIX_push_buffer_state TEST_push_buffer_state
00187 #define PREFIX_create_buffer TEST__create_buffer
00188 #define PREFIX_switch_to_buffer TEST__switch_to_buffer
00189 inline void PREFIX_set_extra(PREFIX_FlexScannerBase *arg,yyscan_t scanner)
00190 { yyset_extra((TestScanner*)arg,scanner); }
00191 #define FLEX_BOTTOM_PART
00192 #include "scannerbase.cc"
00193
00194
00195 void TestScanner::reset()
00196 {
00197 nested_comment_warned=0;
00198 newlines_in_ccomment=0;
00199 }
00200
00201
00202 TestScanner::TestScanner() :
00203 TEST_FlexScannerBase()
00204 {
00205 nested_comment_warned=0;
00206 newlines_in_ccomment=0;
00207
00208 allow_nested_comments=1;
00209 }
00210
00211 TestScanner::~TestScanner()
00212 {
00213
00214 }
00215
00216
00217
00218 bool TestScanner::TestToken::MayBeCleared() const
00219 {
00220 if(token!=TS_IDENTIFIER) return(1);
00221
00222 if(!lval.string_val || *lval.string_val=='\0') return(1);
00223 return(0);
00224 }
00225
00226 void TestScanner::TestToken::clear(bool force)
00227 {
00228
00229
00230 if(!force)
00231 { Assert(MayBeCleared()); }
00232 if(token==TS_IDENTIFIER)
00233 { lval.string_val=FREE(lval.string_val); }
00234
00235
00236 TokenEntry::clear();
00237 }