scan.l revision 250869
1/* scan.l - scanner for flex input -*-C-*- */ 2 3%{ 4/* Copyright (c) 1990 The Regents of the University of California. */ 5/* All rights reserved. */ 6 7/* This code is derived from software contributed to Berkeley by */ 8/* Vern Paxson. */ 9 10/* The United States Government has rights in this work pursuant */ 11/* to contract no. DE-AC03-76SF00098 between the United States */ 12/* Department of Energy and the University of California. */ 13 14/* This file is part of flex. */ 15 16/* Redistribution and use in source and binary forms, with or without */ 17/* modification, are permitted provided that the following conditions */ 18/* are met: */ 19 20/* 1. Redistributions of source code must retain the above copyright */ 21/* notice, this list of conditions and the following disclaimer. */ 22/* 2. Redistributions in binary form must reproduce the above copyright */ 23/* notice, this list of conditions and the following disclaimer in the */ 24/* documentation and/or other materials provided with the distribution. */ 25 26/* Neither the name of the University nor the names of its contributors */ 27/* may be used to endorse or promote products derived from this software */ 28/* without specific prior written permission. */ 29 30/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ 31/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 32/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ 33/* PURPOSE. */ 34 35#include "flexdef.h" 36#include "parse.h" 37extern bool tablesverify, tablesext; 38extern int trlcontxt; /* Set in parse.y for each rule. */ 39extern const char *escaped_qstart, *escaped_qend; 40 41#define ACTION_ECHO add_action( yytext ) 42#define ACTION_IFDEF(def, should_define) \ 43 { \ 44 if ( should_define ) \ 45 action_define( def, 1 ); \ 46 } 47 48#define ACTION_ECHO_QSTART add_action (escaped_qstart) 49#define ACTION_ECHO_QEND add_action (escaped_qend) 50 51#define ACTION_M4_IFDEF(def, should_define) \ 52 do{ \ 53 if ( should_define ) \ 54 buf_m4_define( &m4defs_buf, def, NULL);\ 55 else \ 56 buf_m4_undefine( &m4defs_buf, def);\ 57 } while(0) 58 59#define MARK_END_OF_PROLOG mark_prolog(); 60 61#define YY_DECL \ 62 int flexscan() 63 64#define RETURNCHAR \ 65 yylval = (unsigned char) yytext[0]; \ 66 return CHAR; 67 68#define RETURNNAME \ 69 if(yyleng < MAXLINE) \ 70 { \ 71 strcpy( nmstr, yytext ); \ 72 } \ 73 else \ 74 { \ 75 synerr(_("Input line too long\n")); \ 76 FLEX_EXIT(EXIT_FAILURE); \ 77 } \ 78 return NAME; 79 80#define PUT_BACK_STRING(str, start) \ 81 for ( i = strlen( str ) - 1; i >= start; --i ) \ 82 unput((str)[i]) 83 84#define CHECK_REJECT(str) \ 85 if ( all_upper( str ) ) \ 86 reject = true; 87 88#define CHECK_YYMORE(str) \ 89 if ( all_lower( str ) ) \ 90 yymore_used = true; 91 92#define YY_USER_INIT \ 93 if ( getenv("POSIXLY_CORRECT") ) \ 94 posix_compat = true; 95 96%} 97 98%option caseless nodefault stack noyy_top_state 99%option nostdinit 100 101%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE 102%x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION 103%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE 104%x GROUP_WITH_PARAMS 105%x GROUP_MINUS_PARAMS 106%x EXTENDED_COMMENT 107%x COMMENT_DISCARD 108 109WS [[:blank:]]+ 110OPTWS [[:blank:]]* 111NOT_WS [^[:blank:]\r\n] 112 113NL \r?\n 114 115NAME ([[:alpha:]_][[:alnum:]_-]*) 116NOT_NAME [^[:alpha:]_*\n]+ 117 118SCNAME {NAME} 119 120ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2})) 121 122FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ}) 123CCL_CHAR ([^\\\n\]]|{ESCSEQ}) 124CCL_EXPR ("[:"^?[[:alpha:]]+":]") 125 126LEXOPT [aceknopr] 127 128M4QSTART "[[" 129M4QEND "]]" 130 131%% 132 static int bracelevel, didadef, indented_code; 133 static int doing_rule_action = false; 134 static int option_sense; 135 136 int doing_codeblock = false; 137 int i, brace_depth=0, brace_start_line=0; 138 Char nmdef[MAXLINE]; 139 140 141<INITIAL>{ 142 ^{WS} indented_code = true; BEGIN(CODEBLOCK); 143 ^"/*" ACTION_ECHO; yy_push_state( COMMENT ); 144 ^#{OPTWS}line{WS} yy_push_state( LINEDIR ); 145 ^"%s"{NAME}? return SCDECL; 146 ^"%x"{NAME}? return XSCDECL; 147 ^"%{".*{NL} { 148 ++linenum; 149 line_directive_out( (FILE *) 0, 1 ); 150 indented_code = false; 151 BEGIN(CODEBLOCK); 152 } 153 ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL} { 154 brace_start_line = linenum; 155 ++linenum; 156 buf_linedir( &top_buf, infilename?infilename:"<stdin>", linenum); 157 brace_depth = 1; 158 yy_push_state(CODEBLOCK_MATCH_BRACE); 159 } 160 161 ^"%top".* synerr( _("malformed '%top' directive") ); 162 163 {WS} /* discard */ 164 165 ^"%%".* { 166 sectnum = 2; 167 bracelevel = 0; 168 mark_defs1(); 169 line_directive_out( (FILE *) 0, 1 ); 170 BEGIN(SECT2PROLOG); 171 return SECTEND; 172 } 173 174 ^"%pointer".*{NL} yytext_is_array = false; ++linenum; 175 ^"%array".*{NL} yytext_is_array = true; ++linenum; 176 177 ^"%option" BEGIN(OPTION); return OPTION_OP; 178 179 ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */ 180 ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */ 181 182 /* xgettext: no-c-format */ 183 ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) ); 184 185 ^{NAME} { 186 if(yyleng < MAXLINE) 187 { 188 strcpy( nmstr, yytext ); 189 } 190 else 191 { 192 synerr( _("Definition name too long\n")); 193 FLEX_EXIT(EXIT_FAILURE); 194 } 195 196 didadef = false; 197 BEGIN(PICKUPDEF); 198 } 199 200 {SCNAME} RETURNNAME; 201 ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */ 202 {OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */ 203} 204 205 206<COMMENT>{ 207 "*/" ACTION_ECHO; yy_pop_state(); 208 "*" ACTION_ECHO; 209 {M4QSTART} ACTION_ECHO_QSTART; 210 {M4QEND} ACTION_ECHO_QEND; 211 [^*\n] ACTION_ECHO; 212 {NL} ++linenum; ACTION_ECHO; 213} 214 215<COMMENT_DISCARD>{ 216 /* This is the same as COMMENT, but is discarded rather than output. */ 217 "*/" yy_pop_state(); 218 "*" ; 219 [^*\n] ; 220 {NL} ++linenum; 221} 222 223<EXTENDED_COMMENT>{ 224 ")" yy_pop_state(); 225 [^\n\)]+ ; 226 {NL} ++linenum; 227} 228 229<LINEDIR>{ 230 \n yy_pop_state(); 231 [[:digit:]]+ linenum = myctoi( yytext ); 232 233 \"[^"\n]*\" { 234 flex_free( (void *) infilename ); 235 infilename = copy_string( yytext + 1 ); 236 infilename[strlen( infilename ) - 1] = '\0'; 237 } 238 . /* ignore spurious characters */ 239} 240 241<CODEBLOCK>{ 242 ^"%}".*{NL} ++linenum; BEGIN(INITIAL); 243 244 {M4QSTART} ACTION_ECHO_QSTART; 245 {M4QEND} ACTION_ECHO_QEND; 246 . ACTION_ECHO; 247 248 {NL} { 249 ++linenum; 250 ACTION_ECHO; 251 if ( indented_code ) 252 BEGIN(INITIAL); 253 } 254} 255 256<CODEBLOCK_MATCH_BRACE>{ 257 "}" { 258 if( --brace_depth == 0){ 259 /* TODO: Matched. */ 260 yy_pop_state(); 261 }else 262 buf_strnappend(&top_buf, yytext, yyleng); 263 } 264 265 "{" { 266 brace_depth++; 267 buf_strnappend(&top_buf, yytext, yyleng); 268 } 269 270 {NL} { 271 ++linenum; 272 buf_strnappend(&top_buf, yytext, yyleng); 273 } 274 275 {M4QSTART} buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart)); 276 {M4QEND} buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend)); 277 278 [^{}\r\n] { 279 buf_strnappend(&top_buf, yytext, yyleng); 280 } 281 282 <<EOF>> { 283 linenum = brace_start_line; 284 synerr(_("Unmatched '{'")); 285 yyterminate(); 286 } 287} 288 289 290<PICKUPDEF>{ 291 {WS} /* separates name and definition */ 292 293 {NOT_WS}[^\r\n]* { 294 if(yyleng < MAXLINE) 295 { 296 strcpy( (char *) nmdef, yytext ); 297 } 298 else 299 { 300 format_synerr( _("Definition value for {%s} too long\n"), nmstr); 301 FLEX_EXIT(EXIT_FAILURE); 302 } 303 /* Skip trailing whitespace. */ 304 for ( i = strlen( (char *) nmdef ) - 1; 305 i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t'); 306 --i ) 307 ; 308 309 nmdef[i + 1] = '\0'; 310 311 ndinstal( nmstr, nmdef ); 312 didadef = true; 313 } 314 315 {NL} { 316 if ( ! didadef ) 317 synerr( _( "incomplete name definition" ) ); 318 BEGIN(INITIAL); 319 ++linenum; 320 } 321} 322 323 324<OPTION>{ 325 {NL} ++linenum; BEGIN(INITIAL); 326 {WS} option_sense = true; 327 328 "=" return '='; 329 330 no option_sense = ! option_sense; 331 332 7bit csize = option_sense ? 128 : 256; 333 8bit csize = option_sense ? 256 : 128; 334 335 align long_align = option_sense; 336 always-interactive { 337 ACTION_M4_IFDEF( "M4""_YY_ALWAYS_INTERACTIVE", option_sense ); 338 interactive = option_sense; 339 } 340 array yytext_is_array = option_sense; 341 ansi-definitions ansi_func_defs = option_sense; 342 ansi-prototypes ansi_func_protos = option_sense; 343 backup backing_up_report = option_sense; 344 batch interactive = ! option_sense; 345 bison-bridge bison_bridge_lval = option_sense; 346 bison-locations { if((bison_bridge_lloc = option_sense)) 347 bison_bridge_lval = true; 348 } 349 "c++" C_plus_plus = option_sense; 350 caseful|case-sensitive sf_set_case_ins(!option_sense); 351 caseless|case-insensitive sf_set_case_ins(option_sense); 352 debug ddebug = option_sense; 353 default spprdflt = ! option_sense; 354 ecs useecs = option_sense; 355 fast { 356 useecs = usemecs = false; 357 use_read = fullspd = true; 358 } 359 full { 360 useecs = usemecs = false; 361 use_read = fulltbl = true; 362 } 363 input ACTION_IFDEF("YY_NO_INPUT", ! option_sense); 364 interactive interactive = option_sense; 365 lex-compat lex_compat = option_sense; 366 posix-compat posix_compat = option_sense; 367 main { 368 ACTION_M4_IFDEF( "M4""_YY_MAIN", option_sense); 369 /* Override yywrap */ 370 if( option_sense == true ) 371 do_yywrap = false; 372 } 373 meta-ecs usemecs = option_sense; 374 never-interactive { 375 ACTION_M4_IFDEF( "M4""_YY_NEVER_INTERACTIVE", option_sense ); 376 interactive = !option_sense; 377 } 378 perf-report performance_report += option_sense ? 1 : -1; 379 pointer yytext_is_array = ! option_sense; 380 read use_read = option_sense; 381 reentrant reentrant = option_sense; 382 reject reject_really_used = option_sense; 383 stack ACTION_M4_IFDEF( "M4""_YY_STACK_USED", option_sense ); 384 stdinit do_stdinit = option_sense; 385 stdout use_stdout = option_sense; 386 unistd ACTION_IFDEF("YY_NO_UNISTD_H", ! option_sense); 387 unput ACTION_M4_IFDEF("M4""_YY_NO_UNPUT", ! option_sense); 388 verbose printstats = option_sense; 389 warn nowarn = ! option_sense; 390 yylineno do_yylineno = option_sense; ACTION_M4_IFDEF("M4""_YY_USE_LINENO", option_sense); 391 yymore yymore_really_used = option_sense; 392 yywrap do_yywrap = option_sense; 393 394 yy_push_state ACTION_M4_IFDEF("M4""_YY_NO_PUSH_STATE", ! option_sense); 395 yy_pop_state ACTION_M4_IFDEF("M4""_YY_NO_POP_STATE", ! option_sense); 396 yy_top_state ACTION_M4_IFDEF("M4""_YY_NO_TOP_STATE", ! option_sense); 397 398 yy_scan_buffer ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BUFFER", ! option_sense); 399 yy_scan_bytes ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BYTES", ! option_sense); 400 yy_scan_string ACTION_M4_IFDEF("M4""_YY_NO_SCAN_STRING", ! option_sense); 401 402 yyalloc ACTION_M4_IFDEF("M4""_YY_NO_FLEX_ALLOC", ! option_sense); 403 yyrealloc ACTION_M4_IFDEF("M4""_YY_NO_FLEX_REALLOC", ! option_sense); 404 yyfree ACTION_M4_IFDEF("M4""_YY_NO_FLEX_FREE", ! option_sense); 405 406 yyget_debug ACTION_M4_IFDEF("M4""_YY_NO_GET_DEBUG", ! option_sense); 407 yyset_debug ACTION_M4_IFDEF("M4""_YY_NO_SET_DEBUG", ! option_sense); 408 yyget_extra ACTION_M4_IFDEF("M4""_YY_NO_GET_EXTRA", ! option_sense); 409 yyset_extra ACTION_M4_IFDEF("M4""_YY_NO_SET_EXTRA", ! option_sense); 410 yyget_leng ACTION_M4_IFDEF("M4""_YY_NO_GET_LENG", ! option_sense); 411 yyget_text ACTION_M4_IFDEF("M4""_YY_NO_GET_TEXT", ! option_sense); 412 yyget_lineno ACTION_M4_IFDEF("M4""_YY_NO_GET_LINENO", ! option_sense); 413 yyset_lineno ACTION_M4_IFDEF("M4""_YY_NO_SET_LINENO", ! option_sense); 414 yyget_in ACTION_M4_IFDEF("M4""_YY_NO_GET_IN", ! option_sense); 415 yyset_in ACTION_M4_IFDEF("M4""_YY_NO_SET_IN", ! option_sense); 416 yyget_out ACTION_M4_IFDEF("M4""_YY_NO_GET_OUT", ! option_sense); 417 yyset_out ACTION_M4_IFDEF("M4""_YY_NO_SET_OUT", ! option_sense); 418 yyget_lval ACTION_M4_IFDEF("M4""_YY_NO_GET_LVAL", ! option_sense); 419 yyset_lval ACTION_M4_IFDEF("M4""_YY_NO_SET_LVAL", ! option_sense); 420 yyget_lloc ACTION_M4_IFDEF("M4""_YY_NO_GET_LLOC", ! option_sense); 421 yyset_lloc ACTION_M4_IFDEF("M4""_YY_NO_SET_LLOC", ! option_sense); 422 423 extra-type return OPT_EXTRA_TYPE; 424 outfile return OPT_OUTFILE; 425 prefix return OPT_PREFIX; 426 yyclass return OPT_YYCLASS; 427 header(-file)? return OPT_HEADER; 428 tables-file return OPT_TABLES; 429 tables-verify { 430 tablesverify = option_sense; 431 if(!tablesext && option_sense) 432 tablesext = true; 433 } 434 435 436 \"[^"\n]*\" { 437 if(yyleng-1 < MAXLINE) 438 { 439 strcpy( nmstr, yytext + 1 ); 440 } 441 else 442 { 443 synerr( _("Option line too long\n")); 444 FLEX_EXIT(EXIT_FAILURE); 445 } 446 nmstr[strlen( nmstr ) - 1] = '\0'; 447 return NAME; 448 } 449 450 (([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|. { 451 format_synerr( _( "unrecognized %%option: %s" ), 452 yytext ); 453 BEGIN(RECOVER); 454 } 455} 456 457<RECOVER>.*{NL} ++linenum; BEGIN(INITIAL); 458 459 460<SECT2PROLOG>{ 461 ^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */ 462 ^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */ 463 464 ^{WS}.* ACTION_ECHO; /* indented code in prolog */ 465 466 ^{NOT_WS}.* { /* non-indented code */ 467 if ( bracelevel <= 0 ) 468 { /* not in %{ ... %} */ 469 yyless( 0 ); /* put it all back */ 470 yy_set_bol( 1 ); 471 mark_prolog(); 472 BEGIN(SECT2); 473 } 474 else 475 ACTION_ECHO; 476 } 477 478 . ACTION_ECHO; 479 {NL} ++linenum; ACTION_ECHO; 480 481 <<EOF>> { 482 mark_prolog(); 483 sectnum = 0; 484 yyterminate(); /* to stop the parser */ 485 } 486} 487 488<SECT2>{ 489 ^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */ 490 491 ^{OPTWS}"%{" { 492 indented_code = false; 493 doing_codeblock = true; 494 bracelevel = 1; 495 BEGIN(PERCENT_BRACE_ACTION); 496 } 497 498 ^{OPTWS}"<" { 499 /* Allow "<" to appear in (?x) patterns. */ 500 if (!sf_skip_ws()) 501 BEGIN(SC); 502 return '<'; 503 } 504 ^{OPTWS}"^" return '^'; 505 \" BEGIN(QUOTE); return '"'; 506 "{"/[[:digit:]] { 507 BEGIN(NUM); 508 if ( lex_compat || posix_compat ) 509 return BEGIN_REPEAT_POSIX; 510 else 511 return BEGIN_REPEAT_FLEX; 512 } 513 "$"/([[:blank:]]|{NL}) return '$'; 514 515 {WS}"%{" { 516 bracelevel = 1; 517 BEGIN(PERCENT_BRACE_ACTION); 518 519 if ( in_rule ) 520 { 521 doing_rule_action = true; 522 in_rule = false; 523 return '\n'; 524 } 525 } 526 {WS}"|".*{NL} { 527 if (sf_skip_ws()){ 528 /* We're in the middle of a (?x: ) pattern. */ 529 /* Push back everything starting at the "|" */ 530 size_t amt; 531 amt = strchr (yytext, '|') - yytext; 532 yyless(amt); 533 } 534 else { 535 continued_action = true; 536 ++linenum; 537 return '\n'; 538 } 539 } 540 541 ^{WS}"/*" { 542 543 if (sf_skip_ws()){ 544 /* We're in the middle of a (?x: ) pattern. */ 545 yy_push_state(COMMENT_DISCARD); 546 } 547 else{ 548 yyless( yyleng - 2 ); /* put back '/', '*' */ 549 bracelevel = 0; 550 continued_action = false; 551 BEGIN(ACTION); 552 } 553 } 554 555 ^{WS} /* allow indented rules */ ; 556 557 {WS} { 558 if (sf_skip_ws()){ 559 /* We're in the middle of a (?x: ) pattern. */ 560 } 561 else{ 562 /* This rule is separate from the one below because 563 * otherwise we get variable trailing context, so 564 * we can't build the scanner using -{f,F}. 565 */ 566 bracelevel = 0; 567 continued_action = false; 568 BEGIN(ACTION); 569 570 if ( in_rule ) 571 { 572 doing_rule_action = true; 573 in_rule = false; 574 return '\n'; 575 } 576 } 577 } 578 579 {OPTWS}{NL} { 580 if (sf_skip_ws()){ 581 /* We're in the middle of a (?x: ) pattern. */ 582 ++linenum; 583 } 584 else{ 585 bracelevel = 0; 586 continued_action = false; 587 BEGIN(ACTION); 588 unput( '\n' ); /* so <ACTION> sees it */ 589 590 if ( in_rule ) 591 { 592 doing_rule_action = true; 593 in_rule = false; 594 return '\n'; 595 } 596 } 597 } 598 599 ^{OPTWS}"<<EOF>>" | 600 "<<EOF>>" return EOF_OP; 601 602 ^"%%".* { 603 sectnum = 3; 604 BEGIN(SECT3); 605 outn("/* Begin user sect3 */"); 606 yyterminate(); /* to stop the parser */ 607 } 608 609 "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})* { 610 int cclval; 611 612 if(yyleng < MAXLINE) 613 { 614 strcpy( nmstr, yytext ); 615 } 616 else 617 { 618 synerr( _("Input line too long\n")); 619 FLEX_EXIT(EXIT_FAILURE); 620 } 621 622 /* Check to see if we've already encountered this 623 * ccl. 624 */ 625 if (0 /* <--- This "0" effectively disables the reuse of a 626 * character class (purely based on its source text). 627 * The reason it was disabled is so yacc/bison can parse 628 * ccl operations, such as ccl difference and union. 629 */ 630 && (cclval = ccllookup( (Char *) nmstr )) != 0 ) 631 { 632 if ( input() != ']' ) 633 synerr( _( "bad character class" ) ); 634 635 yylval = cclval; 636 ++cclreuse; 637 return PREVCCL; 638 } 639 else 640 { 641 /* We fudge a bit. We know that this ccl will 642 * soon be numbered as lastccl + 1 by cclinit. 643 */ 644 cclinstal( (Char *) nmstr, lastccl + 1 ); 645 646 /* Push back everything but the leading bracket 647 * so the ccl can be rescanned. 648 */ 649 yyless( 1 ); 650 651 BEGIN(FIRSTCCL); 652 return '['; 653 } 654 } 655 "{-}" return CCL_OP_DIFF; 656 "{+}" return CCL_OP_UNION; 657 658 659 /* Check for :space: at the end of the rule so we don't 660 * wrap the expanded regex in '(' ')' -- breaking trailing 661 * context. 662 */ 663 "{"{NAME}"}"[[:space:]]? { 664 register Char *nmdefptr; 665 int end_is_ws, end_ch; 666 667 end_ch = yytext[yyleng-1]; 668 end_is_ws = end_ch != '}' ? 1 : 0; 669 670 if(yyleng-1 < MAXLINE) 671 { 672 strcpy( nmstr, yytext + 1 ); 673 } 674 else 675 { 676 synerr( _("Input line too long\n")); 677 FLEX_EXIT(EXIT_FAILURE); 678 } 679nmstr[yyleng - 2 - end_is_ws] = '\0'; /* chop trailing brace */ 680 681 if ( (nmdefptr = ndlookup( nmstr )) == 0 ) 682 format_synerr( 683 _( "undefined definition {%s}" ), 684 nmstr ); 685 686 else 687 { /* push back name surrounded by ()'s */ 688 int len = strlen( (char *) nmdefptr ); 689 if (end_is_ws) 690 unput(end_ch); 691 692 if ( lex_compat || nmdefptr[0] == '^' || 693 (len > 0 && nmdefptr[len - 1] == '$') 694 || (end_is_ws && trlcontxt && !sf_skip_ws())) 695 { /* don't use ()'s after all */ 696 PUT_BACK_STRING((char *) nmdefptr, 0); 697 698 if ( nmdefptr[0] == '^' ) 699 BEGIN(CARETISBOL); 700 } 701 702 else 703 { 704 unput(')'); 705 PUT_BACK_STRING((char *) nmdefptr, 0); 706 unput('('); 707 } 708 } 709 } 710 711 "/*" { 712 if (sf_skip_ws()) 713 yy_push_state(COMMENT_DISCARD); 714 else{ 715 /* Push back the "*" and return "/" as usual. */ 716 yyless(1); 717 return '/'; 718 } 719 } 720 721 "(?#" { 722 if (lex_compat || posix_compat){ 723 /* Push back the "?#" and treat it like a normal parens. */ 724 yyless(1); 725 sf_push(); 726 return '('; 727 } 728 else 729 yy_push_state(EXTENDED_COMMENT); 730 } 731 "(?" { 732 sf_push(); 733 if (lex_compat || posix_compat) 734 /* Push back the "?" and treat it like a normal parens. */ 735 yyless(1); 736 else 737 BEGIN(GROUP_WITH_PARAMS); 738 return '('; 739 } 740 "(" sf_push(); return '('; 741 ")" sf_pop(); return ')'; 742 743 [/|*+?.(){}] return (unsigned char) yytext[0]; 744 . RETURNCHAR; 745} 746 747 748<SC>{ 749 {OPTWS}{NL}{OPTWS} ++linenum; /* Allow blank lines & continuations */ 750 [,*] return (unsigned char) yytext[0]; 751 ">" BEGIN(SECT2); return '>'; 752 ">"/^ BEGIN(CARETISBOL); return '>'; 753 {SCNAME} RETURNNAME; 754 . { 755 format_synerr( _( "bad <start condition>: %s" ), 756 yytext ); 757 } 758} 759 760<CARETISBOL>"^" BEGIN(SECT2); return '^'; 761 762 763<QUOTE>{ 764 [^"\n] RETURNCHAR; 765 \" BEGIN(SECT2); return '"'; 766 767 {NL} { 768 synerr( _( "missing quote" ) ); 769 BEGIN(SECT2); 770 ++linenum; 771 return '"'; 772 } 773} 774 775<GROUP_WITH_PARAMS>{ 776 ":" BEGIN(SECT2); 777 "-" BEGIN(GROUP_MINUS_PARAMS); 778 i sf_set_case_ins(1); 779 s sf_set_dot_all(1); 780 x sf_set_skip_ws(1); 781} 782<GROUP_MINUS_PARAMS>{ 783 ":" BEGIN(SECT2); 784 i sf_set_case_ins(0); 785 s sf_set_dot_all(0); 786 x sf_set_skip_ws(0); 787} 788 789<FIRSTCCL>{ 790 "^"/[^-\]\n] BEGIN(CCL); return '^'; 791 "^"/("-"|"]") return '^'; 792 . BEGIN(CCL); RETURNCHAR; 793} 794 795<CCL>{ 796 -/[^\]\n] return '-'; 797 [^\]\n] RETURNCHAR; 798 "]" BEGIN(SECT2); return ']'; 799 .|{NL} { 800 synerr( _( "bad character class" ) ); 801 BEGIN(SECT2); 802 return ']'; 803 } 804} 805 806<FIRSTCCL,CCL>{ 807 "[:alnum:]" BEGIN(CCL); return CCE_ALNUM; 808 "[:alpha:]" BEGIN(CCL); return CCE_ALPHA; 809 "[:blank:]" BEGIN(CCL); return CCE_BLANK; 810 "[:cntrl:]" BEGIN(CCL); return CCE_CNTRL; 811 "[:digit:]" BEGIN(CCL); return CCE_DIGIT; 812 "[:graph:]" BEGIN(CCL); return CCE_GRAPH; 813 "[:lower:]" BEGIN(CCL); return CCE_LOWER; 814 "[:print:]" BEGIN(CCL); return CCE_PRINT; 815 "[:punct:]" BEGIN(CCL); return CCE_PUNCT; 816 "[:space:]" BEGIN(CCL); return CCE_SPACE; 817 "[:upper:]" BEGIN(CCL); return CCE_UPPER; 818 "[:xdigit:]" BEGIN(CCL); return CCE_XDIGIT; 819 820 "[:^alnum:]" BEGIN(CCL); return CCE_NEG_ALNUM; 821 "[:^alpha:]" BEGIN(CCL); return CCE_NEG_ALPHA; 822 "[:^blank:]" BEGIN(CCL); return CCE_NEG_BLANK; 823 "[:^cntrl:]" BEGIN(CCL); return CCE_NEG_CNTRL; 824 "[:^digit:]" BEGIN(CCL); return CCE_NEG_DIGIT; 825 "[:^graph:]" BEGIN(CCL); return CCE_NEG_GRAPH; 826 "[:^lower:]" BEGIN(CCL); return CCE_NEG_LOWER; 827 "[:^print:]" BEGIN(CCL); return CCE_NEG_PRINT; 828 "[:^punct:]" BEGIN(CCL); return CCE_NEG_PUNCT; 829 "[:^space:]" BEGIN(CCL); return CCE_NEG_SPACE; 830 "[:^upper:]" BEGIN(CCL); return CCE_NEG_UPPER; 831 "[:^xdigit:]" BEGIN(CCL); return CCE_NEG_XDIGIT; 832 {CCL_EXPR} { 833 format_synerr( 834 _( "bad character class expression: %s" ), 835 yytext ); 836 BEGIN(CCL); return CCE_ALNUM; 837 } 838} 839 840<NUM>{ 841 [[:digit:]]+ { 842 yylval = myctoi( yytext ); 843 return NUMBER; 844 } 845 846 "," return ','; 847 "}" { 848 BEGIN(SECT2); 849 if ( lex_compat || posix_compat ) 850 return END_REPEAT_POSIX; 851 else 852 return END_REPEAT_FLEX; 853 } 854 855 . { 856 synerr( _( "bad character inside {}'s" ) ); 857 BEGIN(SECT2); 858 return '}'; 859 } 860 861 {NL} { 862 synerr( _( "missing }" ) ); 863 BEGIN(SECT2); 864 ++linenum; 865 return '}'; 866 } 867} 868 869 870<PERCENT_BRACE_ACTION>{ 871 {OPTWS}"%}".* bracelevel = 0; 872 873 <ACTION>"/*" ACTION_ECHO; yy_push_state( COMMENT ); 874 875 <CODEBLOCK,ACTION>{ 876 "reject" { 877 ACTION_ECHO; 878 CHECK_REJECT(yytext); 879 } 880 "yymore" { 881 ACTION_ECHO; 882 CHECK_YYMORE(yytext); 883 } 884 } 885 886 {M4QSTART} ACTION_ECHO_QSTART; 887 {M4QEND} ACTION_ECHO_QEND; 888 . ACTION_ECHO; 889 {NL} { 890 ++linenum; 891 ACTION_ECHO; 892 if ( bracelevel == 0 || 893 (doing_codeblock && indented_code) ) 894 { 895 if ( doing_rule_action ) 896 add_action( "\tYY_BREAK\n" ); 897 898 doing_rule_action = doing_codeblock = false; 899 BEGIN(SECT2); 900 } 901 } 902} 903 904 905 /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ 906<ACTION>{ 907 "{" ACTION_ECHO; ++bracelevel; 908 "}" ACTION_ECHO; --bracelevel; 909 {M4QSTART} ACTION_ECHO_QSTART; 910 {M4QEND} ACTION_ECHO_QEND; 911 [^[:alpha:]_{}"'/\n\[\]]+ ACTION_ECHO; 912 [\[\]] ACTION_ECHO; 913 {NAME} ACTION_ECHO; 914 "'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */ 915 \" ACTION_ECHO; BEGIN(ACTION_STRING); 916 {NL} { 917 ++linenum; 918 ACTION_ECHO; 919 if ( bracelevel == 0 ) 920 { 921 if ( doing_rule_action ) 922 add_action( "\tYY_BREAK\n" ); 923 924 doing_rule_action = false; 925 BEGIN(SECT2); 926 } 927 } 928 . ACTION_ECHO; 929} 930 931<ACTION_STRING>{ 932 [^"\\\n]+ ACTION_ECHO; 933 \\. ACTION_ECHO; 934 {NL} ++linenum; ACTION_ECHO; BEGIN(ACTION); 935 \" ACTION_ECHO; BEGIN(ACTION); 936 . ACTION_ECHO; 937} 938 939<COMMENT,COMMENT_DISCARD,ACTION,ACTION_STRING><<EOF>> { 940 synerr( _( "EOF encountered inside an action" ) ); 941 yyterminate(); 942 } 943 944<EXTENDED_COMMENT,GROUP_WITH_PARAMS,GROUP_MINUS_PARAMS><<EOF>> { 945 synerr( _( "EOF encountered inside pattern" ) ); 946 yyterminate(); 947 } 948 949<SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ} { 950 yylval = myesc( (Char *) yytext ); 951 952 if ( YY_START == FIRSTCCL ) 953 BEGIN(CCL); 954 955 return CHAR; 956 } 957 958 959<SECT3>{ 960 {M4QSTART} fwrite (escaped_qstart, 1, strlen(escaped_qstart), yyout); 961 {M4QEND} fwrite (escaped_qend, 1, strlen(escaped_qend), yyout); 962 [^\[\]\n]*(\n?) ECHO; 963 (.|\n) ECHO; 964 <<EOF>> sectnum = 0; yyterminate(); 965} 966 967<*>.|\n format_synerr( _( "bad character: %s" ), yytext ); 968 969%% 970 971 972int yywrap() 973 { 974 if ( --num_input_files > 0 ) 975 { 976 set_input_file( *++input_files ); 977 return 0; 978 } 979 980 else 981 return 1; 982 } 983 984 985/* set_input_file - open the given file (if NULL, stdin) for scanning */ 986 987void set_input_file( file ) 988char *file; 989 { 990 if ( file && strcmp( file, "-" ) ) 991 { 992 infilename = copy_string( file ); 993 yyin = fopen( infilename, "r" ); 994 995 if ( yyin == NULL ) 996 lerrsf( _( "can't open %s" ), file ); 997 } 998 999 else 1000 { 1001 yyin = stdin; 1002 infilename = copy_string( "<stdin>" ); 1003 } 1004 1005 linenum = 1; 1006 } 1007 1008 1009/* Wrapper routines for accessing the scanner's malloc routines. */ 1010 1011void *flex_alloc( size ) 1012size_t size; 1013 { 1014 return (void *) malloc( size ); 1015 } 1016 1017void *flex_realloc( ptr, size ) 1018void *ptr; 1019size_t size; 1020 { 1021 return (void *) realloc( ptr, size ); 1022 } 1023 1024void flex_free( ptr ) 1025void *ptr; 1026 { 1027 if ( ptr ) 1028 free( ptr ); 1029 } 1030