Changeset b87a5ed for translator/Parser/lex.l
- Timestamp:
- May 16, 2015, 3:36:19 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- a32b204
- Parents:
- b8508a2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/Parser/lex.l
rb8508a2 rb87a5ed 1 /* -*- Mode: C -*-2 * 3 * CForall Lexer Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this4 * grammar and to use it within software systems. THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT5 * ANY EXPRESS OR IMPLIED WARRANTIES.1 /* 2 * Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 3 * 4 * The contents of this file are covered under the licence agreement in the 5 * file "LICENCE" distributed with Cforall. 6 6 * 7 7 * lex.l -- … … 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Jan 21 08:43:59201513 * Update Count : 3 2012 * Last Modified On : Sat May 16 12:14:18 2015 13 * Update Count : 330 14 14 */ 15 15 … … 17 17 18 18 %{ 19 // This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor 20 // directive have been performed and removed from the source. The only exceptions are preprocessor 21 // directives passed to the compiler (e.g., line-number directives) and C/C++ style comments, which 22 // are ignored. 19 // This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive 20 // have been performed and removed from the source. The only exceptions are preprocessor directives passed to 21 // the compiler (e.g., line-number directives) and C/C++ style comments, which are ignored. 23 22 24 23 //**************************** Includes and Defines **************************** … … 28 27 #include "lex.h" 29 28 #include "ParseNode.h" 30 #include "cfa.tab.h" 29 #include "cfa.tab.h" // YACC generated definitions based on C++ grammar 31 30 32 31 char *yyfilename; 33 std::string *strtext; // accumulate parts of character and string constant value34 35 #define WHITE_RETURN(x) // do nothing32 std::string *strtext; // accumulate parts of character and string constant value 33 34 #define WHITE_RETURN(x) // do nothing 36 35 #define NEWLINE_RETURN() WHITE_RETURN('\n') 37 36 #define RETURN_VAL(x) yylval.tok.str = new std::string(yytext); \ 38 39 40 37 yylval.tok.loc.file = yyfilename; \ 38 yylval.tok.loc.line = yylineno; \ 39 return(x) 41 40 #define RETURN_STR(x) yylval.tok.str = strtext; \ 42 43 44 45 46 #define KEYWORD_RETURN(x) RETURN_VAL(x) // keyword41 yylval.tok.loc.file = yyfilename; \ 42 yylval.tok.loc.line = yylineno; \ 43 return(x) 44 45 #define KEYWORD_RETURN(x) RETURN_VAL(x) // keyword 47 46 #define IDENTIFIER_RETURN() RETURN_VAL((typedefTable.isIdentifier(yytext) ? IDENTIFIER : typedefTable.isTypedef(yytext) ? TYPEDEFname : TYPEGENname)) 48 47 //#define ATTRIBUTE_RETURN() RETURN_VAL((typedefTable.isIdentifier(yytext) ? ATTR_IDENTIFIER : typedefTable.isTypedef(yytext) ? ATTR_TYPEDEFname : ATTR_TYPEGENname)) 49 48 #define ATTRIBUTE_RETURN() RETURN_VAL(ATTR_IDENTIFIER) 50 49 51 #define ASCIIOP_RETURN() RETURN_VAL((int)yytext[0]) 52 #define NAMEDOP_RETURN(x) RETURN_VAL(x) // multichar operator, with a name50 #define ASCIIOP_RETURN() RETURN_VAL((int)yytext[0]) // single character operator 51 #define NAMEDOP_RETURN(x) RETURN_VAL(x) // multichar operator, with a name 53 52 54 53 #define NUMERIC_RETURN(x) rm_underscore(); RETURN_VAL(x) // numeric constant 55 54 56 55 void rm_underscore() { 57 58 59 60 if ( yytext[i] != '_' ) {61 62 63 } // if64 65 66 56 // remove underscores in numeric constant 57 int j = 0; 58 for ( int i = 0; yytext[i] != '\0'; i += 1 ) { 59 if ( yytext[i] != '_' ) { 60 yytext[j] = yytext[i]; 61 j += 1; 62 } // if 63 } // for 64 yyleng = j; 65 yytext[yyleng] = '\0'; 67 66 } 68 67 … … 75 74 universal_char "\\"((u"_"?{hex_quad})|(U"_"?{hex_quad}{2})) 76 75 77 // identifier, GCC: $ in identifier76 // identifier, GCC: $ in identifier 78 77 identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})* 79 78 80 // quoted identifier79 // quoted identifier 81 80 quoted_identifier "`"{identifier}"`" 82 81 83 // attribute identifier, GCC: $ in identifier82 // attribute identifier, GCC: $ in identifier 84 83 attr_identifier "@"{identifier} 85 84 86 // numeric constants, CFA: '_' in constant85 // numeric constants, CFA: '_' in constant 87 86 hex_quad {hex}("_"?{hex}){3} 88 87 integer_suffix "_"?(([uU][lL]?)|([uU]("ll"|"LL")?)|([lL][uU]?)|("ll"|"LL")[uU]?) … … 109 108 hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix}? 110 109 111 // character escape sequence, GCC: \e => esc character110 // character escape sequence, GCC: \e => esc character 112 111 simple_escape "\\"[abefnrtv'"?\\] 113 // ' stop highlighting112 // ' stop highlighting 114 113 octal_escape "\\"{octal}("_"?{octal}){0,2} 115 114 hex_escape "\\""x""_"?{hex_digits} 116 115 escape_seq {simple_escape}|{octal_escape}|{hex_escape}|{universal_char} 117 116 118 // display/white-space characters117 // display/white-space characters 119 118 h_tab [\011] 120 119 form_feed [\014] … … 123 122 h_white [ ]|{h_tab} 124 123 125 // operators124 // operators 126 125 op_unary_only "~"|"!" 127 126 op_unary_binary "+"|"-"|"*" … … 140 139 141 140 %% 142 /* line directives */141 /* line directives */ 143 142 ^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["][^\n]*"\n" { 144 143 /* " stop highlighting */ … … 150 149 begin_string = strchr( end_num, '"' ); 151 150 if ( begin_string ) { 152 153 154 length = end_string - begin_string - 1;155 filename = new char[ length + 1 ];156 memcpy( filename, begin_string + 1, length );157 filename[ length ] = '\0';158 //std::cout << "file " << filename << " line " << lineno << std::endl;159 yylineno = lineno;160 yyfilename = filename;161 }162 } 151 end_string = strchr( begin_string + 1, '"' ); 152 if ( end_string ) { 153 length = end_string - begin_string - 1; 154 filename = new char[ length + 1 ]; 155 memcpy( filename, begin_string + 1, length ); 156 filename[ length ] = '\0'; 157 //std::cout << "file " << filename << " line " << lineno << std::endl; 158 yylineno = lineno; 159 yyfilename = filename; 160 } // if 161 } // if 163 162 } 164 163 165 /* ignore preprocessor directives (for now) */164 /* ignore preprocessor directives (for now) */ 166 165 ^{h_white}*"#"[^\n]*"\n" ; 167 166 168 /* ignore C style comments */167 /* ignore C style comments */ 169 168 "/*" { BEGIN COMMENT; } 170 169 <COMMENT>.|\n ; 171 170 <COMMENT>"*/" { BEGIN 0; } 172 171 173 /* ignore C++ style comments */172 /* ignore C++ style comments */ 174 173 "//"[^\n]*"\n" ; 175 174 176 /* ignore whitespace */175 /* ignore whitespace */ 177 176 {h_white}+ { WHITE_RETURN(' '); } 178 177 ({v_tab}|{c_return}|{form_feed})+ { WHITE_RETURN(' '); } 179 178 ({h_white}|{v_tab}|{c_return}|{form_feed})*"\n" { NEWLINE_RETURN(); } 180 179 181 /* keywords */182 _Alignas { KEYWORD_RETURN(ALIGNAS); } // C11183 _Alignof { KEYWORD_RETURN(ALIGNOF); } // C11184 __alignof { KEYWORD_RETURN(ALIGNOF); } // GCC185 __alignof__ { KEYWORD_RETURN(ALIGNOF); } // GCC186 asm { KEYWORD_RETURN(ASM); }187 __asm { KEYWORD_RETURN(ASM); } // GCC188 __asm__ { KEYWORD_RETURN(ASM); } // GCC189 _Atomic { KEYWORD_RETURN(ATOMIC); } // C11190 __attribute { KEYWORD_RETURN(ATTRIBUTE); } // GCC191 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); }// GCC180 /* keywords */ 181 _Alignas { KEYWORD_RETURN(ALIGNAS); } // C11 182 _Alignof { KEYWORD_RETURN(ALIGNOF); } // C11 183 __alignof { KEYWORD_RETURN(ALIGNOF); } // GCC 184 __alignof__ { KEYWORD_RETURN(ALIGNOF); } // GCC 185 asm { KEYWORD_RETURN(ASM); } 186 __asm { KEYWORD_RETURN(ASM); } // GCC 187 __asm__ { KEYWORD_RETURN(ASM); } // GCC 188 _Atomic { KEYWORD_RETURN(ATOMIC); } // C11 189 __attribute { KEYWORD_RETURN(ATTRIBUTE); } // GCC 190 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); } // GCC 192 191 auto { KEYWORD_RETURN(AUTO); } 193 _Bool { KEYWORD_RETURN(BOOL); } // C99192 _Bool { KEYWORD_RETURN(BOOL); } // C99 194 193 break { KEYWORD_RETURN(BREAK); } 195 194 case { KEYWORD_RETURN(CASE); } 196 catch { KEYWORD_RETURN(CATCH); } // CFA195 catch { KEYWORD_RETURN(CATCH); } // CFA 197 196 char { KEYWORD_RETURN(CHAR); } 198 choose { KEYWORD_RETURN(CHOOSE); } // CFA199 _Complex { KEYWORD_RETURN(COMPLEX); } // C99200 __complex { KEYWORD_RETURN(COMPLEX); } // GCC201 __complex__ { KEYWORD_RETURN(COMPLEX); } // GCC197 choose { KEYWORD_RETURN(CHOOSE); } // CFA 198 _Complex { KEYWORD_RETURN(COMPLEX); } // C99 199 __complex { KEYWORD_RETURN(COMPLEX); } // GCC 200 __complex__ { KEYWORD_RETURN(COMPLEX); } // GCC 202 201 const { KEYWORD_RETURN(CONST); } 203 __const { KEYWORD_RETURN(CONST); } // GCC204 __const__ { KEYWORD_RETURN(CONST); } // GCC205 context { KEYWORD_RETURN(CONTEXT); } // CFA202 __const { KEYWORD_RETURN(CONST); } // GCC 203 __const__ { KEYWORD_RETURN(CONST); } // GCC 204 context { KEYWORD_RETURN(CONTEXT); } // CFA 206 205 continue { KEYWORD_RETURN(CONTINUE); } 207 206 default { KEYWORD_RETURN(DEFAULT); } 208 do { KEYWORD_RETURN(DO); }207 do { KEYWORD_RETURN(DO); } 209 208 double { KEYWORD_RETURN(DOUBLE); } 210 dtype { KEYWORD_RETURN(DTYPE); } // CFA209 dtype { KEYWORD_RETURN(DTYPE); } // CFA 211 210 else { KEYWORD_RETURN(ELSE); } 212 211 enum { KEYWORD_RETURN(ENUM); } 213 __extension__ { KEYWORD_RETURN(EXTENSION); }// GCC212 __extension__ { KEYWORD_RETURN(EXTENSION); } // GCC 214 213 extern { KEYWORD_RETURN(EXTERN); } 215 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA216 finally { KEYWORD_RETURN(FINALLY); } // CFA214 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA 215 finally { KEYWORD_RETURN(FINALLY); } // CFA 217 216 float { KEYWORD_RETURN(FLOAT); } 218 __float128 { KEYWORD_RETURN(FLOAT); } // GCC219 for { KEYWORD_RETURN(FOR); }220 forall { KEYWORD_RETURN(FORALL); } // CFA217 __float128 { KEYWORD_RETURN(FLOAT); } // GCC 218 for { KEYWORD_RETURN(FOR); } 219 forall { KEYWORD_RETURN(FORALL); } // CFA 221 220 fortran { KEYWORD_RETURN(FORTRAN); } 222 ftype { KEYWORD_RETURN(FTYPE); } // CFA223 _Generic { KEYWORD_RETURN(GENERIC); } // C11221 ftype { KEYWORD_RETURN(FTYPE); } // CFA 222 _Generic { KEYWORD_RETURN(GENERIC); } // C11 224 223 goto { KEYWORD_RETURN(GOTO); } 225 if { KEYWORD_RETURN(IF); }226 _Imaginary { KEYWORD_RETURN(IMAGINARY); } // C99227 __imag { KEYWORD_RETURN(IMAGINARY); } // GCC228 __imag__ { KEYWORD_RETURN(IMAGINARY); } // GCC229 inline { KEYWORD_RETURN(INLINE); } // C99230 __inline { KEYWORD_RETURN(INLINE); } // GCC231 __inline__ { KEYWORD_RETURN(INLINE); } // GCC232 int { KEYWORD_RETURN(INT); }233 __int128 { KEYWORD_RETURN(INT); } // GCC234 __label__ { KEYWORD_RETURN(LABEL); } // GCC224 if { KEYWORD_RETURN(IF); } 225 _Imaginary { KEYWORD_RETURN(IMAGINARY); } // C99 226 __imag { KEYWORD_RETURN(IMAGINARY); } // GCC 227 __imag__ { KEYWORD_RETURN(IMAGINARY); } // GCC 228 inline { KEYWORD_RETURN(INLINE); } // C99 229 __inline { KEYWORD_RETURN(INLINE); } // GCC 230 __inline__ { KEYWORD_RETURN(INLINE); } // GCC 231 int { KEYWORD_RETURN(INT); } 232 __int128 { KEYWORD_RETURN(INT); } // GCC 233 __label__ { KEYWORD_RETURN(LABEL); } // GCC 235 234 long { KEYWORD_RETURN(LONG); } 236 lvalue { KEYWORD_RETURN(LVALUE); } // CFA237 _Noreturn { KEYWORD_RETURN(NORETURN); } // C11235 lvalue { KEYWORD_RETURN(LVALUE); } // CFA 236 _Noreturn { KEYWORD_RETURN(NORETURN); } // C11 238 237 register { KEYWORD_RETURN(REGISTER); } 239 restrict { KEYWORD_RETURN(RESTRICT); } // C99240 __restrict { KEYWORD_RETURN(RESTRICT); } // GCC241 __restrict__ { KEYWORD_RETURN(RESTRICT); }// GCC238 restrict { KEYWORD_RETURN(RESTRICT); } // C99 239 __restrict { KEYWORD_RETURN(RESTRICT); } // GCC 240 __restrict__ { KEYWORD_RETURN(RESTRICT); } // GCC 242 241 return { KEYWORD_RETURN(RETURN); } 243 242 short { KEYWORD_RETURN(SHORT); } 244 243 signed { KEYWORD_RETURN(SIGNED); } 245 __signed { KEYWORD_RETURN(SIGNED); } // GCC246 __signed__ { KEYWORD_RETURN(SIGNED); } // GCC244 __signed { KEYWORD_RETURN(SIGNED); } // GCC 245 __signed__ { KEYWORD_RETURN(SIGNED); } // GCC 247 246 sizeof { KEYWORD_RETURN(SIZEOF); } 248 247 static { KEYWORD_RETURN(STATIC); } 249 _Static_assert { KEYWORD_RETURN(STATICASSERT); }// C11248 _Static_assert { KEYWORD_RETURN(STATICASSERT); } // C11 250 249 struct { KEYWORD_RETURN(STRUCT); } 251 250 switch { KEYWORD_RETURN(SWITCH); } 252 _Thread_local { KEYWORD_RETURN(THREADLOCAL); }// C11253 throw { KEYWORD_RETURN(THROW); } // CFA254 try { KEYWORD_RETURN(TRY); }// CFA255 type { KEYWORD_RETURN(TYPE); } // CFA251 _Thread_local { KEYWORD_RETURN(THREADLOCAL); } // C11 252 throw { KEYWORD_RETURN(THROW); } // CFA 253 try { KEYWORD_RETURN(TRY); } // CFA 254 type { KEYWORD_RETURN(TYPE); } // CFA 256 255 typedef { KEYWORD_RETURN(TYPEDEF); } 257 typeof { KEYWORD_RETURN(TYPEOF); } // GCC258 __typeof { KEYWORD_RETURN(TYPEOF); } // GCC259 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC256 typeof { KEYWORD_RETURN(TYPEOF); } // GCC 257 __typeof { KEYWORD_RETURN(TYPEOF); } // GCC 258 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 260 259 union { KEYWORD_RETURN(UNION); } 261 260 unsigned { KEYWORD_RETURN(UNSIGNED); } 262 261 void { KEYWORD_RETURN(VOID); } 263 262 volatile { KEYWORD_RETURN(VOLATILE); } 264 __volatile { KEYWORD_RETURN(VOLATILE); } // GCC265 __volatile__ { KEYWORD_RETURN(VOLATILE); }// GCC263 __volatile { KEYWORD_RETURN(VOLATILE); } // GCC 264 __volatile__ { KEYWORD_RETURN(VOLATILE); } // GCC 266 265 while { KEYWORD_RETURN(WHILE); } 267 266 268 /* identifier */269 {identifier} 270 {attr_identifier} 267 /* identifier */ 268 {identifier} { IDENTIFIER_RETURN(); } 269 {attr_identifier} { ATTRIBUTE_RETURN(); } 271 270 "`" { BEGIN BKQUOTE; } 272 <BKQUOTE>{identifier} 273 <BKQUOTE>"`" 274 275 /* numeric constants */276 "0" { NUMERIC_RETURN(ZERO); }// CFA277 "1" { NUMERIC_RETURN(ONE); }// CFA271 <BKQUOTE>{identifier} { IDENTIFIER_RETURN(); } 272 <BKQUOTE>"`" { BEGIN 0; } 273 274 /* numeric constants */ 275 "0" { NUMERIC_RETURN(ZERO); } // CFA 276 "1" { NUMERIC_RETURN(ONE); } // CFA 278 277 {decimal_constant} { NUMERIC_RETURN(INTEGERconstant); } 279 278 {octal_constant} { NUMERIC_RETURN(INTEGERconstant); } … … 282 281 {hex_floating_constant} { NUMERIC_RETURN(FLOATINGconstant); } 283 282 284 /* character constant, allows empty value */283 /* character constant, allows empty value */ 285 284 "L"?"_"?['] { BEGIN QUOTE; rm_underscore(); strtext = new std::string; *strtext += std::string( yytext ); } 286 <QUOTE>[^'\\\n]* 287 <QUOTE>['\n] 288 /* ' stop highlighting */289 290 /* string constant */285 <QUOTE>[^'\\\n]* { *strtext += std::string( yytext ); } 286 <QUOTE>['\n] { BEGIN 0; *strtext += std::string( yytext); RETURN_STR(CHARACTERconstant); } 287 /* ' stop highlighting */ 288 289 /* string constant */ 291 290 "L"?"_"?["] { BEGIN STRING; rm_underscore(); strtext = new std::string; *strtext += std::string( yytext ); } 292 <STRING>[^"\\\n]* 293 <STRING>["\n] 294 /* " stop highlighting */291 <STRING>[^"\\\n]* { *strtext += std::string( yytext ); } 292 <STRING>["\n] { BEGIN 0; *strtext += std::string( yytext); RETURN_STR(STRINGliteral); } 293 /* " stop highlighting */ 295 294 296 295 <QUOTE,STRING>{escape_seq} { rm_underscore(); *strtext += std::string( yytext ); } 297 296 <QUOTE,STRING>[\\] { *strtext += std::string( yytext ); } // unknown escape character 298 297 299 /* punctuation */300 "[" { ASCIIOP_RETURN(); }301 "]" { ASCIIOP_RETURN(); }302 "(" { ASCIIOP_RETURN(); }303 ")" { ASCIIOP_RETURN(); }304 "{" { ASCIIOP_RETURN(); }305 "}" { ASCIIOP_RETURN(); }306 "," { ASCIIOP_RETURN(); }// also operator307 ":" { ASCIIOP_RETURN(); }308 ";" { ASCIIOP_RETURN(); }309 "." { ASCIIOP_RETURN(); }// also operator298 /* punctuation */ 299 "[" { ASCIIOP_RETURN(); } 300 "]" { ASCIIOP_RETURN(); } 301 "(" { ASCIIOP_RETURN(); } 302 ")" { ASCIIOP_RETURN(); } 303 "{" { ASCIIOP_RETURN(); } 304 "}" { ASCIIOP_RETURN(); } 305 "," { ASCIIOP_RETURN(); } // also operator 306 ":" { ASCIIOP_RETURN(); } 307 ";" { ASCIIOP_RETURN(); } 308 "." { ASCIIOP_RETURN(); } // also operator 310 309 "..." { NAMEDOP_RETURN(ELLIPSIS); } 311 310 312 /* alternative C99 brackets, "<:" & "<:<:" handled by preprocessor */311 /* alternative C99 brackets, "<:" & "<:<:" handled by preprocessor */ 313 312 "<:" { RETURN_VAL('['); } 314 313 ":>" { RETURN_VAL(']'); } … … 316 315 "%>" { RETURN_VAL('}'); } 317 316 318 /* operators */319 "!" { ASCIIOP_RETURN(); }320 "+" { ASCIIOP_RETURN(); }321 "-" { ASCIIOP_RETURN(); }322 "*" { ASCIIOP_RETURN(); }323 "/" { ASCIIOP_RETURN(); }324 "%" { ASCIIOP_RETURN(); }325 "^" { ASCIIOP_RETURN(); }326 "~" { ASCIIOP_RETURN(); }327 "&" { ASCIIOP_RETURN(); }328 "|" { ASCIIOP_RETURN(); }329 "<" { ASCIIOP_RETURN(); }330 ">" { ASCIIOP_RETURN(); }331 "=" { ASCIIOP_RETURN(); }332 "?" { ASCIIOP_RETURN(); }317 /* operators */ 318 "!" { ASCIIOP_RETURN(); } 319 "+" { ASCIIOP_RETURN(); } 320 "-" { ASCIIOP_RETURN(); } 321 "*" { ASCIIOP_RETURN(); } 322 "/" { ASCIIOP_RETURN(); } 323 "%" { ASCIIOP_RETURN(); } 324 "^" { ASCIIOP_RETURN(); } 325 "~" { ASCIIOP_RETURN(); } 326 "&" { ASCIIOP_RETURN(); } 327 "|" { ASCIIOP_RETURN(); } 328 "<" { ASCIIOP_RETURN(); } 329 ">" { ASCIIOP_RETURN(); } 330 "=" { ASCIIOP_RETURN(); } 331 "?" { ASCIIOP_RETURN(); } 333 332 334 333 "++" { NAMEDOP_RETURN(ICR); } … … 354 353 ">>=" { NAMEDOP_RETURN(RSassign); } 355 354 356 /* CFA, operator identifier */357 {op_unary}"?" { IDENTIFIER_RETURN(); }// unary355 /* CFA, operator identifier */ 356 {op_unary}"?" { IDENTIFIER_RETURN(); } // unary 358 357 "?"({op_unary_pre_post}|"()"|"[?]") { IDENTIFIER_RETURN(); } 359 "?"{op_binary_over}"?" { IDENTIFIER_RETURN(); } // binary358 "?"{op_binary_over}"?" { IDENTIFIER_RETURN(); } // binary 360 359 /* 361 This rule handles ambiguous cases with operator identifiers, e.g., "int *?*?()", where the 362 string "*?*?" can be lexed as "*"/"?*?" or "*?"/"*?". Since it is common practise to put 363 a unary operator juxtaposed to an identifier, e.g., "*i", users will be annoyed if they 364 cannot do this with respect to operator identifiers. Even with this special hack, there 365 are 5 general cases that cannot be handled. The first case is for the function-call 366 identifier "?()": 360 This rule handles ambiguous cases with operator identifiers, e.g., "int *?*?()", where the string "*?*?" 361 can be lexed as "*"/"?*?" or "*?"/"*?". Since it is common practise to put a unary operator juxtaposed 362 to an identifier, e.g., "*i", users will be annoyed if they cannot do this with respect to operator 363 identifiers. Even with this special hack, there are 5 general cases that cannot be handled. The first 364 case is for the function-call identifier "?()": 367 365 368 366 int * ?()(); // declaration: space required after '*' 369 367 * ?()(); // expression: space required after '*' 370 368 371 Without the space, the string "*?()" is ambiguous without N character look ahead; it 372 requires scanning ahead to determine if there is a '(', which is the start of an 373 argument/parameter list. 369 Without the space, the string "*?()" is ambiguous without N character look ahead; it requires scanning 370 ahead to determine if there is a '(', which is the start of an argument/parameter list. 374 371 375 372 The 4 remaining cases occur in expressions: … … 380 377 i?--i:0; // space required after '?' 381 378 382 In the first two cases, the string "i++?" is ambiguous, where this string can be lexed as 383 "i "/"++?" or "i++"/"?"; it requires scanning ahead to determine if there is a '(', which384 is the start of an argument list. In the second two cases, the string "?++x" is385 ambiguous, where this string can be lexed as "?++"/"x" or "?"/"++x"; it requires scanning386 a head to determine if there is a '(', which is the start of an argument list.379 In the first two cases, the string "i++?" is ambiguous, where this string can be lexed as "i"/"++?" or 380 "i++"/"?"; it requires scanning ahead to determine if there is a '(', which is the start of an argument 381 list. In the second two cases, the string "?++x" is ambiguous, where this string can be lexed as 382 "?++"/"x" or "?"/"++x"; it requires scanning ahead to determine if there is a '(', which is the start of 383 an argument list. 387 384 */ 388 385 {op_unary}"?"(({op_unary_pre_post}|"[?]")|({op_binary_over}"?")) { 389 390 391 392 393 394 395 396 397 398 399 /* unknown characters */386 // 1 or 2 character unary operator ? 387 int i = yytext[1] == '?' ? 1 : 2; 388 yyless( i ); // put back characters up to first '?' 389 if ( i > 1 ) { 390 NAMEDOP_RETURN( yytext[0] == '+' ? ICR : DECR ); 391 } else { 392 ASCIIOP_RETURN(); 393 } // if 394 } 395 396 /* unknown characters */ 400 397 . { printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); } 401 398 402 399 %% 403 400 404 405 // Local Variables: 406 // fill-column: 100 407 // compile-command: "make" 408 // End: 401 // Local Variables: // 402 // fill-column: 110 // 403 // tab-width: 4 // 404 // mode: c++ // 405 // compile-command: "make install" // 406 // End: //
Note: See TracChangeset
for help on using the changeset viewer.