1 %{ /* -*- C++ -*- */ 2 # include <cstdlib> 3 # include <cerrno> 4 # include <climits> 5 # include <string> 6 # include "calc++-driver.hh" 7 # include "calc++-parser.hh" 8 9 /* Work around an incompatibility in flex (at least versions 10 2.5.31 through 2.5.33): it generates code that does 11 not conform to C89. See Debian bug 333231 12 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */ 13 # undef yywrap 14 # define yywrap() 1 15 16 /* By default yylex returns int, we use token_type. 17 Unfortunately yyterminate by default returns 0, which is 18 not of token_type. */ 19 #define yyterminate() return token::END 20 %} 21 22 %option noyywrap nounput batch debug 23 24 id [a-zA-Z][a-zA-Z_0-9]* 25 int [0-9]+ 26 blank [ \t] 27 28 29 %{ 30 # define YY_USER_ACTION yylloc->columns (yyleng); 31 %} 32 33 %% 34 %{ 35 yylloc->step (); 36 %} 37 {blank}+ yylloc->step (); 38 [\n]+ yylloc->lines (yyleng); yylloc->step (); 39 40 %{ 41 typedef yy::calcxx_parser::token token; 42 %} 43 /* Convert ints to the actual type of tokens. */ 44 [-+*/] return yy::calcxx_parser::token_type (yytext[0]); 45 46 ":=" return token::ASSIGN; 47 48 49 {int} { 50 errno = 0; 51 long n = strtol (yytext, NULL, 10); 52 if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE)) 53 driver.error (*yylloc, "integer is out of range"); 54 yylval->ival = n; 55 return token::NUMBER; 56 } 57 58 59 60 {id} { 61 yylval->sval = new std::string (yytext); 62 return token::IDENTIFIER; 63 } 64 65 66 . driver.error (*yylloc, "invalid character"); 67 %% 68 69 70 void 71 calcxx_driver::scan_begin () 72 { 73 yy_flex_debug = trace_scanning; 74 if (file.empty () || file == "-") 75 yyin = stdin; 76 else if (!(yyin = fopen (file.c_str (), "r"))) 77 { 78 error ("cannot open " + file + ": " + strerror(errno)); 79 exit (EXIT_FAILURE); 80 } 81 } 82 83 84 85 void 86 calcxx_driver::scan_end () 87 { 88 fclose (yyin); 89 } 90 91