|
|
1.1 ! root 1: /* scan.l - scanner for flex input */ ! 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: * Redistribution and use in source and binary forms are permitted provided ! 15: * that: (1) source distributions retain this entire copyright notice and ! 16: * comment, and (2) distributions including binaries display the following ! 17: * acknowledgement: ``This product includes software developed by the ! 18: * University of California, Berkeley and its contributors'' in the ! 19: * documentation or other materials provided with the distribution and in ! 20: * all advertising materials mentioning features or use of this software. ! 21: * Neither the name of the University nor the names of its contributors may ! 22: * be used to endorse or promote products derived from this software without ! 23: * specific prior written permission. ! 24: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 25: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 26: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 27: * ! 28: * @(#)scan.l 5.2 (Berkeley) 6/18/90 ! 29: */ ! 30: ! 31: %{ ! 32: #undef yywrap ! 33: ! 34: #include "flexdef.h" ! 35: #include "parse.h" ! 36: ! 37: #ifndef lint ! 38: static char copyright[] = ! 39: "@(#) Copyright (c) 1989 The Regents of the University of California.\n"; ! 40: static char CR_continuation[] = "@(#) All rights reserved.\n"; ! 41: ! 42: static char rcsid[] = ! 43: "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/scan.l,v 2.8 90/05/26 16:53:23 vern Exp $ (LBL)"; ! 44: #endif ! 45: ! 46: #define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) ! 47: #define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); ! 48: ! 49: #undef YY_DECL ! 50: #define YY_DECL \ ! 51: int flexscan() ! 52: ! 53: #define RETURNCHAR \ ! 54: yylval = yytext[0]; \ ! 55: return ( CHAR ); ! 56: ! 57: #define RETURNNAME \ ! 58: (void) strcpy( nmstr, (char *) yytext ); \ ! 59: return ( NAME ); ! 60: ! 61: #define PUT_BACK_STRING(str, start) \ ! 62: for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ ! 63: unput((str)[i]) ! 64: ! 65: #define CHECK_REJECT(str) \ ! 66: if ( all_upper( str ) ) \ ! 67: reject = true; ! 68: ! 69: #define CHECK_YYMORE(str) \ ! 70: if ( all_lower( str ) ) \ ! 71: yymore_used = true; ! 72: %} ! 73: ! 74: %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE ! 75: %x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT ! 76: %x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION ! 77: ! 78: WS [ \t\f]+ ! 79: OPTWS [ \t\f]* ! 80: NOT_WS [^ \t\f\n] ! 81: ! 82: NAME [a-z_][a-z_0-9-]* ! 83: NOT_NAME [^a-z_\n]+ ! 84: ! 85: SCNAME {NAME} ! 86: ! 87: ESCSEQ \\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2}) ! 88: ! 89: %% ! 90: static int bracelevel, didadef; ! 91: int i, indented_code, checking_used, new_xlation; ! 92: int doing_codeblock = false; ! 93: Char nmdef[MAXLINE], myesc(); ! 94: ! 95: ^{WS} indented_code = true; BEGIN(CODEBLOCK); ! 96: ^#.*\n ++linenum; /* treat as a comment */ ! 97: ^"/*" ECHO; BEGIN(C_COMMENT); ! 98: ^"%s"{NAME}? return ( SCDECL ); ! 99: ^"%x"{NAME}? return ( XSCDECL ); ! 100: ^"%{".*\n { ! 101: ++linenum; ! 102: line_directive_out( stdout ); ! 103: indented_code = false; ! 104: BEGIN(CODEBLOCK); ! 105: } ! 106: ! 107: {WS} return ( WHITESPACE ); ! 108: ! 109: ^"%%".* { ! 110: sectnum = 2; ! 111: line_directive_out( stdout ); ! 112: BEGIN(SECT2PROLOG); ! 113: return ( SECTEND ); ! 114: } ! 115: ! 116: ^"%used" { ! 117: pinpoint_message( "warning - %%used/%%unused have been deprecated" ); ! 118: checking_used = REALLY_USED; BEGIN(USED_LIST); ! 119: } ! 120: ^"%unused" { ! 121: checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); ! 122: pinpoint_message( "warning - %%used/%%unused have been deprecated" ); ! 123: checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); ! 124: } ! 125: ! 126: ! 127: ^"%"[aeknopt]" ".*\n { ! 128: #ifdef NOTDEF ! 129: fprintf( stderr, ! 130: "old-style lex command at line %d ignored:\n\t%s", ! 131: linenum, yytext ); ! 132: #endif ! 133: ++linenum; ! 134: } ! 135: ! 136: ^"%"[cr]{OPTWS} /* ignore old lex directive */ ! 137: ! 138: %t{OPTWS}\n { ! 139: ++linenum; ! 140: xlation = ! 141: (int *) malloc( sizeof( int ) * (unsigned) csize ); ! 142: ! 143: if ( ! xlation ) ! 144: flexfatal( ! 145: "dynamic memory failure building %t table" ); ! 146: ! 147: for ( i = 0; i < csize; ++i ) ! 148: xlation[i] = 0; ! 149: ! 150: num_xlations = 0; ! 151: ! 152: BEGIN(XLATION); ! 153: } ! 154: ! 155: ^"%"[^sxanpekotcru{}]{OPTWS} synerr( "unrecognized '%' directive" ); ! 156: ! 157: ^{NAME} { ! 158: (void) strcpy( nmstr, (char *) yytext ); ! 159: didadef = false; ! 160: BEGIN(PICKUPDEF); ! 161: } ! 162: ! 163: {SCNAME} RETURNNAME; ! 164: ^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */ ! 165: {OPTWS}\n ++linenum; return ( '\n' ); ! 166: . synerr( "illegal character" ); BEGIN(RECOVER); ! 167: ! 168: ! 169: <C_COMMENT>"*/" ECHO; BEGIN(INITIAL); ! 170: <C_COMMENT>"*/".*\n ++linenum; ECHO; BEGIN(INITIAL); ! 171: <C_COMMENT>[^*\n]+ ECHO; ! 172: <C_COMMENT>"*" ECHO; ! 173: <C_COMMENT>\n ++linenum; ECHO; ! 174: ! 175: ! 176: <CODEBLOCK>^"%}".*\n ++linenum; BEGIN(INITIAL); ! 177: <CODEBLOCK>"reject" ECHO; CHECK_REJECT(yytext); ! 178: <CODEBLOCK>"yymore" ECHO; CHECK_YYMORE(yytext); ! 179: <CODEBLOCK>{NAME}|{NOT_NAME}|. ECHO; ! 180: <CODEBLOCK>\n { ! 181: ++linenum; ! 182: ECHO; ! 183: if ( indented_code ) ! 184: BEGIN(INITIAL); ! 185: } ! 186: ! 187: ! 188: <PICKUPDEF>{WS} /* separates name and definition */ ! 189: ! 190: <PICKUPDEF>{NOT_WS}.* { ! 191: (void) strcpy( (char *) nmdef, (char *) yytext ); ! 192: ! 193: for ( i = strlen( (char *) nmdef ) - 1; ! 194: i >= 0 && ! 195: nmdef[i] == ' ' || nmdef[i] == '\t'; ! 196: --i ) ! 197: ; ! 198: ! 199: nmdef[i + 1] = '\0'; ! 200: ! 201: ndinstal( nmstr, nmdef ); ! 202: didadef = true; ! 203: } ! 204: ! 205: <PICKUPDEF>\n { ! 206: if ( ! didadef ) ! 207: synerr( "incomplete name definition" ); ! 208: BEGIN(INITIAL); ! 209: ++linenum; ! 210: } ! 211: ! 212: <RECOVER>.*\n ++linenum; BEGIN(INITIAL); RETURNNAME; ! 213: ! 214: ! 215: <USED_LIST>\n ++linenum; BEGIN(INITIAL); ! 216: <USED_LIST>{WS} ! 217: <USED_LIST>"reject" { ! 218: if ( all_upper( yytext ) ) ! 219: reject_really_used = checking_used; ! 220: else ! 221: synerr( "unrecognized %used/%unused construct" ); ! 222: } ! 223: <USED_LIST>"yymore" { ! 224: if ( all_lower( yytext ) ) ! 225: yymore_really_used = checking_used; ! 226: else ! 227: synerr( "unrecognized %used/%unused construct" ); ! 228: } ! 229: <USED_LIST>{NOT_WS}+ synerr( "unrecognized %used/%unused construct" ); ! 230: ! 231: ! 232: <XLATION>"%t"{OPTWS}\n ++linenum; BEGIN(INITIAL); ! 233: <XLATION>^{OPTWS}[0-9]+ ++num_xlations; new_xlation = true; ! 234: <XLATION>^. synerr( "bad row in translation table" ); ! 235: <XLATION>{WS} /* ignore whitespace */ ! 236: ! 237: <XLATION>{ESCSEQ} { ! 238: xlation[myesc( yytext )] = ! 239: (new_xlation ? num_xlations : -num_xlations); ! 240: new_xlation = false; ! 241: } ! 242: <XLATION>. { ! 243: xlation[yytext[0]] = ! 244: (new_xlation ? num_xlations : -num_xlations); ! 245: new_xlation = false; ! 246: } ! 247: ! 248: <XLATION>\n ++linenum; ! 249: ! 250: ! 251: <SECT2PROLOG>.*\n/{NOT_WS} { ! 252: ++linenum; ! 253: ACTION_ECHO; ! 254: MARK_END_OF_PROLOG; ! 255: BEGIN(SECT2); ! 256: } ! 257: ! 258: <SECT2PROLOG>.*\n ++linenum; ACTION_ECHO; ! 259: ! 260: <SECT2PROLOG><<EOF>> MARK_END_OF_PROLOG; yyterminate(); ! 261: ! 262: <SECT2>^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */ ! 263: ! 264: <SECT2>^({WS}|"%{") { ! 265: indented_code = (yytext[0] != '%'); ! 266: doing_codeblock = true; ! 267: bracelevel = 1; ! 268: ! 269: if ( indented_code ) ! 270: ACTION_ECHO; ! 271: ! 272: BEGIN(CODEBLOCK_2); ! 273: } ! 274: ! 275: <SECT2>"<" BEGIN(SC); return ( '<' ); ! 276: <SECT2>^"^" return ( '^' ); ! 277: <SECT2>\" BEGIN(QUOTE); return ( '"' ); ! 278: <SECT2>"{"/[0-9] BEGIN(NUM); return ( '{' ); ! 279: <SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR); ! 280: <SECT2>"$"/[ \t\n] return ( '$' ); ! 281: ! 282: <SECT2>{WS}"%{" { ! 283: bracelevel = 1; ! 284: BEGIN(PERCENT_BRACE_ACTION); ! 285: return ( '\n' ); ! 286: } ! 287: <SECT2>{WS}"|".*\n continued_action = true; ++linenum; return ( '\n' ); ! 288: ! 289: <SECT2>{WS} { ! 290: /* this rule is separate from the one below because ! 291: * otherwise we get variable trailing context, so ! 292: * we can't build the scanner using -{f,F} ! 293: */ ! 294: bracelevel = 0; ! 295: continued_action = false; ! 296: BEGIN(ACTION); ! 297: return ( '\n' ); ! 298: } ! 299: ! 300: <SECT2>{OPTWS}/\n { ! 301: bracelevel = 0; ! 302: continued_action = false; ! 303: BEGIN(ACTION); ! 304: return ( '\n' ); ! 305: } ! 306: ! 307: <SECT2>^{OPTWS}\n ++linenum; return ( '\n' ); ! 308: ! 309: <SECT2>"<<EOF>>" return ( EOF_OP ); ! 310: ! 311: <SECT2>^"%%".* { ! 312: sectnum = 3; ! 313: BEGIN(SECT3); ! 314: return ( EOF ); /* to stop the parser */ ! 315: } ! 316: ! 317: <SECT2>"["([^\\\]\n]|{ESCSEQ})+"]" { ! 318: int cclval; ! 319: ! 320: (void) strcpy( nmstr, (char *) yytext ); ! 321: ! 322: /* check to see if we've already encountered this ccl */ ! 323: if ( (cclval = ccllookup( (Char *) nmstr )) ) ! 324: { ! 325: yylval = cclval; ! 326: ++cclreuse; ! 327: return ( PREVCCL ); ! 328: } ! 329: else ! 330: { ! 331: /* we fudge a bit. We know that this ccl will ! 332: * soon be numbered as lastccl + 1 by cclinit ! 333: */ ! 334: cclinstal( (Char *) nmstr, lastccl + 1 ); ! 335: ! 336: /* push back everything but the leading bracket ! 337: * so the ccl can be rescanned ! 338: */ ! 339: PUT_BACK_STRING((Char *) nmstr, 1); ! 340: ! 341: BEGIN(FIRSTCCL); ! 342: return ( '[' ); ! 343: } ! 344: } ! 345: ! 346: <SECT2>"{"{NAME}"}" { ! 347: register Char *nmdefptr; ! 348: Char *ndlookup(); ! 349: ! 350: (void) strcpy( nmstr, (char *) yytext ); ! 351: nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ ! 352: ! 353: /* lookup from "nmstr + 1" to chop leading brace */ ! 354: if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) ! 355: synerr( "undefined {name}" ); ! 356: ! 357: else ! 358: { /* push back name surrounded by ()'s */ ! 359: unput(')'); ! 360: PUT_BACK_STRING(nmdefptr, 0); ! 361: unput('('); ! 362: } ! 363: } ! 364: ! 365: <SECT2>[/|*+?.()] return ( yytext[0] ); ! 366: <SECT2>. RETURNCHAR; ! 367: <SECT2>\n ++linenum; return ( '\n' ); ! 368: ! 369: ! 370: <SC>"," return ( ',' ); ! 371: <SC>">" BEGIN(SECT2); return ( '>' ); ! 372: <SC>">"/"^" BEGIN(CARETISBOL); return ( '>' ); ! 373: <SC>{SCNAME} RETURNNAME; ! 374: <SC>. synerr( "bad start condition name" ); ! 375: ! 376: <CARETISBOL>"^" BEGIN(SECT2); return ( '^' ); ! 377: ! 378: ! 379: <QUOTE>[^"\n] RETURNCHAR; ! 380: <QUOTE>\" BEGIN(SECT2); return ( '"' ); ! 381: ! 382: <QUOTE>\n { ! 383: synerr( "missing quote" ); ! 384: BEGIN(SECT2); ! 385: ++linenum; ! 386: return ( '"' ); ! 387: } ! 388: ! 389: ! 390: <FIRSTCCL>"^"/[^-\n] BEGIN(CCL); return ( '^' ); ! 391: <FIRSTCCL>"^"/- return ( '^' ); ! 392: <FIRSTCCL>- BEGIN(CCL); yylval = '-'; return ( CHAR ); ! 393: <FIRSTCCL>. BEGIN(CCL); RETURNCHAR; ! 394: ! 395: <CCL>-/[^\]\n] return ( '-' ); ! 396: <CCL>[^\]\n] RETURNCHAR; ! 397: <CCL>"]" BEGIN(SECT2); return ( ']' ); ! 398: ! 399: ! 400: <NUM>[0-9]+ { ! 401: yylval = myctoi( yytext ); ! 402: return ( NUMBER ); ! 403: } ! 404: ! 405: <NUM>"," return ( ',' ); ! 406: <NUM>"}" BEGIN(SECT2); return ( '}' ); ! 407: ! 408: <NUM>. { ! 409: synerr( "bad character inside {}'s" ); ! 410: BEGIN(SECT2); ! 411: return ( '}' ); ! 412: } ! 413: ! 414: <NUM>\n { ! 415: synerr( "missing }" ); ! 416: BEGIN(SECT2); ! 417: ++linenum; ! 418: return ( '}' ); ! 419: } ! 420: ! 421: ! 422: <BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2); ! 423: <BRACEERROR>\n synerr( "missing }" ); ++linenum; BEGIN(SECT2); ! 424: ! 425: ! 426: <PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".* bracelevel = 0; ! 427: <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject" { ! 428: ACTION_ECHO; ! 429: CHECK_REJECT(yytext); ! 430: } ! 431: <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore" { ! 432: ACTION_ECHO; ! 433: CHECK_YYMORE(yytext); ! 434: } ! 435: <PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|. ACTION_ECHO; ! 436: <PERCENT_BRACE_ACTION,CODEBLOCK_2>\n { ! 437: ++linenum; ! 438: ACTION_ECHO; ! 439: if ( bracelevel == 0 || ! 440: (doing_codeblock && indented_code) ) ! 441: { ! 442: if ( ! doing_codeblock ) ! 443: fputs( "\tYY_BREAK\n", temp_action_file ); ! 444: ! 445: doing_codeblock = false; ! 446: BEGIN(SECT2); ! 447: } ! 448: } ! 449: ! 450: ! 451: /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ ! 452: <ACTION>"{" ACTION_ECHO; ++bracelevel; ! 453: <ACTION>"}" ACTION_ECHO; --bracelevel; ! 454: <ACTION>[^a-z_{}"'/\n]+ ACTION_ECHO; ! 455: <ACTION>{NAME} ACTION_ECHO; ! 456: <ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT); ! 457: <ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */ ! 458: <ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING); ! 459: <ACTION>\n { ! 460: ++linenum; ! 461: ACTION_ECHO; ! 462: if ( bracelevel == 0 ) ! 463: { ! 464: fputs( "\tYY_BREAK\n", temp_action_file ); ! 465: BEGIN(SECT2); ! 466: } ! 467: } ! 468: <ACTION>. ACTION_ECHO; ! 469: ! 470: <ACTION_COMMENT>"*/" ACTION_ECHO; BEGIN(ACTION); ! 471: <ACTION_COMMENT>[^*\n]+ ACTION_ECHO; ! 472: <ACTION_COMMENT>"*" ACTION_ECHO; ! 473: <ACTION_COMMENT>\n ++linenum; ACTION_ECHO; ! 474: <ACTION_COMMENT>. ACTION_ECHO; ! 475: ! 476: <ACTION_STRING>[^"\\\n]+ ACTION_ECHO; ! 477: <ACTION_STRING>\\. ACTION_ECHO; ! 478: <ACTION_STRING>\n ++linenum; ACTION_ECHO; ! 479: <ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION); ! 480: <ACTION_STRING>. ACTION_ECHO; ! 481: ! 482: <ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>> { ! 483: synerr( "EOF encountered inside an action" ); ! 484: yyterminate(); ! 485: } ! 486: ! 487: ! 488: <SECT2,QUOTE,CCL>{ESCSEQ} { ! 489: yylval = myesc( yytext ); ! 490: return ( CHAR ); ! 491: } ! 492: ! 493: <FIRSTCCL>{ESCSEQ} { ! 494: yylval = myesc( yytext ); ! 495: BEGIN(CCL); ! 496: return ( CHAR ); ! 497: } ! 498: ! 499: ! 500: <SECT3>.*(\n?) ECHO; ! 501: %% ! 502: ! 503: ! 504: int yywrap() ! 505: ! 506: { ! 507: if ( --num_input_files > 0 ) ! 508: { ! 509: set_input_file( *++input_files ); ! 510: return ( 0 ); ! 511: } ! 512: ! 513: else ! 514: return ( 1 ); ! 515: } ! 516: ! 517: ! 518: /* set_input_file - open the given file (if NULL, stdin) for scanning */ ! 519: ! 520: void set_input_file( file ) ! 521: char *file; ! 522: ! 523: { ! 524: if ( file ) ! 525: { ! 526: infilename = file; ! 527: yyin = fopen( infilename, "r" ); ! 528: ! 529: if ( yyin == NULL ) ! 530: lerrsf( "can't open %s", file ); ! 531: } ! 532: ! 533: else ! 534: { ! 535: yyin = stdin; ! 536: infilename = "<stdin>"; ! 537: } ! 538: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.