|
|
1.1 ! root 1: /* scan.l - scanner for flex input */ ! 2: ! 3: /* ! 4: * Copyright (c) 1989 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 to ! 11: * contract no. DE-AC03-76SF00098 between the United States Department of ! 12: * Energy and the University of California. ! 13: * ! 14: * Redistribution and use in source and binary forms are permitted ! 15: * provided that the above copyright notice and this paragraph are ! 16: * duplicated in all such forms and that any documentation, ! 17: * advertising materials, and other materials related to such ! 18: * distribution and use acknowledge that the software was developed ! 19: * by the University of California, Berkeley. The name of the ! 20: * University may not be used to endorse or promote products derived ! 21: * from this software without specific prior written permission. ! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 23: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 24: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 25: */ ! 26: ! 27: %{ ! 28: #include "flexdef.h" ! 29: #include "parse.h" ! 30: ! 31: #ifndef lint ! 32: static char copyright[] = ! 33: "@(#) Copyright (c) 1989 The Regents of the University of California.\n"; ! 34: static char CR_continuation[] = "@(#) All rights reserved.\n"; ! 35: ! 36: static char rcsid[] = ! 37: "@(#) $Header: scan.l,v 2.1 89/06/20 17:24:13 vern Exp $ (LBL)"; ! 38: #endif ! 39: ! 40: #define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) ! 41: #define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); ! 42: ! 43: #undef YY_DECL ! 44: #define YY_DECL \ ! 45: int flexscan() ! 46: ! 47: #define RETURNCHAR \ ! 48: yylval = yytext[0]; \ ! 49: return ( CHAR ); ! 50: ! 51: #define RETURNNAME \ ! 52: (void) strcpy( nmstr, yytext ); \ ! 53: return ( NAME ); ! 54: ! 55: #define PUT_BACK_STRING(str, start) \ ! 56: for ( i = strlen( str ) - 1; i >= start; --i ) \ ! 57: unput(str[i]) ! 58: ! 59: #define CHECK_REJECT(str) \ ! 60: if ( all_upper( str ) ) \ ! 61: reject = true; ! 62: ! 63: #define CHECK_YYMORE(str) \ ! 64: if ( all_lower( str ) ) \ ! 65: yymore_used = true; ! 66: %} ! 67: ! 68: %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE ! 69: %x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT C_COMMENT_2 ACTION_COMMENT ! 70: %x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST ! 71: ! 72: WS [ \t\f]+ ! 73: OPTWS [ \t\f]* ! 74: NOT_WS [^ \t\f\n] ! 75: ! 76: NAME [a-z_][a-z_0-9-]* ! 77: NOT_NAME [^a-z_\n]+ ! 78: ! 79: SCNAME {NAME} ! 80: ! 81: ESCSEQ \\([^\n]|[0-9]{1,3}) ! 82: ! 83: %% ! 84: static int bracelevel, didadef; ! 85: int i, indented_code, checking_used; ! 86: char nmdef[MAXLINE], myesc(); ! 87: ! 88: ^{WS} indented_code = true; BEGIN(CODEBLOCK); ! 89: ^#.*\n ++linenum; ECHO; /* treat as a comment */ ! 90: ^"/*" ECHO; BEGIN(C_COMMENT); ! 91: ^"%s"(tart)? return ( SCDECL ); ! 92: ^"%x" return ( XSCDECL ); ! 93: ^"%{".*\n { ! 94: ++linenum; ! 95: line_directive_out( stdout ); ! 96: indented_code = false; ! 97: BEGIN(CODEBLOCK); ! 98: } ! 99: ! 100: {WS} return ( WHITESPACE ); ! 101: ! 102: ^"%%".* { ! 103: sectnum = 2; ! 104: line_directive_out( stdout ); ! 105: BEGIN(SECT2PROLOG); ! 106: return ( SECTEND ); ! 107: } ! 108: ! 109: ^"%used" checking_used = REALLY_USED; BEGIN(USED_LIST); ! 110: ^"%unused" checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); ! 111: ! 112: ! 113: ^"%"[^sx]" ".*\n { ! 114: fprintf( stderr, ! 115: "old-style lex command at line %d ignored:\n\t%s", ! 116: linenum, yytext ); ! 117: ++linenum; ! 118: } ! 119: ! 120: ^{NAME} { ! 121: (void) strcpy( nmstr, yytext ); ! 122: didadef = false; ! 123: BEGIN(PICKUPDEF); ! 124: } ! 125: ! 126: {SCNAME} RETURNNAME; ! 127: ^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */ ! 128: \n ++linenum; return ( '\n' ); ! 129: . synerr( "illegal character" ); BEGIN(RECOVER); ! 130: ! 131: ! 132: <C_COMMENT>"*/" ECHO; BEGIN(0); ! 133: <C_COMMENT>"*/".*\n ++linenum; ECHO; BEGIN(0); ! 134: <C_COMMENT>[^*\n]+ ECHO; ! 135: <C_COMMENT>"*" ECHO; ! 136: <C_COMMENT>\n ++linenum; ECHO; ! 137: ! 138: ! 139: <CODEBLOCK>^"%}".*\n ++linenum; BEGIN(0); ! 140: <CODEBLOCK>"reject" ECHO; CHECK_REJECT(yytext); ! 141: <CODEBLOCK>"yymore" ECHO; CHECK_YYMORE(yytext); ! 142: <CODEBLOCK>{NAME}|{NOT_NAME}|. ECHO; ! 143: <CODEBLOCK>\n { ! 144: ++linenum; ! 145: ECHO; ! 146: if ( indented_code ) ! 147: BEGIN(0); ! 148: } ! 149: ! 150: ! 151: <PICKUPDEF>{WS} /* separates name and definition */ ! 152: ! 153: <PICKUPDEF>{NOT_WS}.* { ! 154: (void) strcpy( nmdef, yytext ); ! 155: ! 156: for ( i = strlen( nmdef ) - 1; ! 157: i >= 0 && ! 158: nmdef[i] == ' ' || nmdef[i] == '\t'; ! 159: --i ) ! 160: ; ! 161: ! 162: nmdef[i + 1] = '\0'; ! 163: ! 164: ndinstal( nmstr, nmdef ); ! 165: didadef = true; ! 166: } ! 167: ! 168: <PICKUPDEF>\n { ! 169: if ( ! didadef ) ! 170: synerr( "incomplete name definition" ); ! 171: BEGIN(0); ! 172: ++linenum; ! 173: } ! 174: ! 175: <RECOVER>.*\n ++linenum; BEGIN(0); RETURNNAME; ! 176: ! 177: ! 178: <USED_LIST>\n ++linenum; BEGIN(0); ! 179: <USED_LIST>{WS} ! 180: <USED_LIST>"reject" { ! 181: if ( all_upper( yytext ) ) ! 182: reject_really_used = checking_used; ! 183: else ! 184: synerr( "unrecognized %used/%unused construct" ); ! 185: } ! 186: <USED_LIST>"yymore" { ! 187: if ( all_lower( yytext ) ) ! 188: yymore_really_used = checking_used; ! 189: else ! 190: synerr( "unrecognized %used/%unused construct" ); ! 191: } ! 192: <USED_LIST>{NOT_WS}+ synerr( "unrecognized %used/%unused construct" ); ! 193: ! 194: ! 195: <SECT2PROLOG>.*\n/{NOT_WS} { ! 196: ++linenum; ! 197: ACTION_ECHO; ! 198: MARK_END_OF_PROLOG; ! 199: BEGIN(SECT2); ! 200: } ! 201: ! 202: <SECT2PROLOG>.*\n ++linenum; ACTION_ECHO; ! 203: ! 204: <SECT2PROLOG><<EOF>> MARK_END_OF_PROLOG; yyterminate(); ! 205: ! 206: <SECT2>^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */ ! 207: ! 208: /* this horrible mess of a rule matches indented lines which ! 209: * do not contain "/*". We need to make the distinction because ! 210: * otherwise this rule will be taken instead of the rule which ! 211: * matches the beginning of comments like this one ! 212: */ ! 213: <SECT2>^{WS}([^/\n]|"/"[^*\n])*("/"?)\n { ! 214: synerr( "indented code found outside of action" ); ! 215: ++linenum; ! 216: } ! 217: ! 218: <SECT2>"<" BEGIN(SC); return ( '<' ); ! 219: <SECT2>^"^" return ( '^' ); ! 220: <SECT2>\" BEGIN(QUOTE); return ( '"' ); ! 221: <SECT2>"{"/[0-9] BEGIN(NUM); return ( '{' ); ! 222: <SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR); ! 223: <SECT2>"$"/[ \t\n] return ( '$' ); ! 224: ! 225: <SECT2>{WS}"%{" { ! 226: bracelevel = 1; ! 227: BEGIN(PERCENT_BRACE_ACTION); ! 228: return ( '\n' ); ! 229: } ! 230: <SECT2>{WS}"|".*\n continued_action = true; ++linenum; return ( '\n' ); ! 231: ! 232: <SECT2>^{OPTWS}"/*" ACTION_ECHO; BEGIN(C_COMMENT_2); ! 233: ! 234: <SECT2>{WS} { ! 235: /* this rule is separate from the one below because ! 236: * otherwise we get variable trailing context, so ! 237: * we can't build the scanner using -{f,F} ! 238: */ ! 239: bracelevel = 0; ! 240: continued_action = false; ! 241: BEGIN(ACTION); ! 242: return ( '\n' ); ! 243: } ! 244: ! 245: <SECT2>{OPTWS}/\n { ! 246: bracelevel = 0; ! 247: continued_action = false; ! 248: BEGIN(ACTION); ! 249: return ( '\n' ); ! 250: } ! 251: ! 252: <SECT2>^{OPTWS}\n ++linenum; return ( '\n' ); ! 253: ! 254: <SECT2>"<<EOF>>" return ( EOF_OP ); ! 255: ! 256: <SECT2>^"%%".* { ! 257: sectnum = 3; ! 258: BEGIN(SECT3); ! 259: return ( EOF ); /* to stop the parser */ ! 260: } ! 261: ! 262: <SECT2>"["([^\\\]\n]|{ESCSEQ})+"]" { ! 263: int cclval; ! 264: ! 265: (void) strcpy( nmstr, yytext ); ! 266: ! 267: /* check to see if we've already encountered this ccl */ ! 268: if ( (cclval = ccllookup( nmstr )) ) ! 269: { ! 270: yylval = cclval; ! 271: ++cclreuse; ! 272: return ( PREVCCL ); ! 273: } ! 274: else ! 275: { ! 276: /* we fudge a bit. We know that this ccl will ! 277: * soon be numbered as lastccl + 1 by cclinit ! 278: */ ! 279: cclinstal( nmstr, lastccl + 1 ); ! 280: ! 281: /* push back everything but the leading bracket ! 282: * so the ccl can be rescanned ! 283: */ ! 284: PUT_BACK_STRING(nmstr, 1); ! 285: ! 286: BEGIN(FIRSTCCL); ! 287: return ( '[' ); ! 288: } ! 289: } ! 290: ! 291: <SECT2>"{"{NAME}"}" { ! 292: register char *nmdefptr; ! 293: char *ndlookup(); ! 294: ! 295: (void) strcpy( nmstr, yytext ); ! 296: nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ ! 297: ! 298: /* lookup from "nmstr + 1" to chop leading brace */ ! 299: if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) ! 300: synerr( "undefined {name}" ); ! 301: ! 302: else ! 303: { /* push back name surrounded by ()'s */ ! 304: unput(')'); ! 305: PUT_BACK_STRING(nmdefptr, 0); ! 306: unput('('); ! 307: } ! 308: } ! 309: ! 310: <SECT2>[/|*+?.()] return ( yytext[0] ); ! 311: <SECT2>. RETURNCHAR; ! 312: <SECT2>\n ++linenum; return ( '\n' ); ! 313: ! 314: ! 315: <SC>"," return ( ',' ); ! 316: <SC>">" BEGIN(SECT2); return ( '>' ); ! 317: <SC>">"/"^" BEGIN(CARETISBOL); return ( '>' ); ! 318: <SC>{SCNAME} RETURNNAME; ! 319: <SC>. synerr( "bad start condition name" ); ! 320: ! 321: <CARETISBOL>"^" BEGIN(SECT2); return ( '^' ); ! 322: ! 323: ! 324: <QUOTE>[^"\n] RETURNCHAR; ! 325: <QUOTE>\" BEGIN(SECT2); return ( '"' ); ! 326: ! 327: <QUOTE>\n { ! 328: synerr( "missing quote" ); ! 329: BEGIN(SECT2); ! 330: ++linenum; ! 331: return ( '"' ); ! 332: } ! 333: ! 334: ! 335: <FIRSTCCL>"^"/[^-\n] BEGIN(CCL); return ( '^' ); ! 336: <FIRSTCCL>"^"/- return ( '^' ); ! 337: <FIRSTCCL>- BEGIN(CCL); yylval = '-'; return ( CHAR ); ! 338: <FIRSTCCL>. BEGIN(CCL); RETURNCHAR; ! 339: ! 340: <CCL>-/[^\]\n] return ( '-' ); ! 341: <CCL>[^\]\n] RETURNCHAR; ! 342: <CCL>"]" BEGIN(SECT2); return ( ']' ); ! 343: ! 344: ! 345: <NUM>[0-9]+ { ! 346: yylval = myctoi( yytext ); ! 347: return ( NUMBER ); ! 348: } ! 349: ! 350: <NUM>"," return ( ',' ); ! 351: <NUM>"}" BEGIN(SECT2); return ( '}' ); ! 352: ! 353: <NUM>. { ! 354: synerr( "bad character inside {}'s" ); ! 355: BEGIN(SECT2); ! 356: return ( '}' ); ! 357: } ! 358: ! 359: <NUM>\n { ! 360: synerr( "missing }" ); ! 361: BEGIN(SECT2); ! 362: ++linenum; ! 363: return ( '}' ); ! 364: } ! 365: ! 366: ! 367: <BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2); ! 368: <BRACEERROR>\n synerr( "missing }" ); ++linenum; BEGIN(SECT2); ! 369: ! 370: ! 371: <PERCENT_BRACE_ACTION>{OPTWS}"%}".* bracelevel = 0; ! 372: <PERCENT_BRACE_ACTION,ACTION>"reject" ACTION_ECHO; CHECK_REJECT(yytext); ! 373: <PERCENT_BRACE_ACTION,ACTION>"yymore" ACTION_ECHO; CHECK_YYMORE(yytext); ! 374: <PERCENT_BRACE_ACTION>{NAME}|{NOT_NAME}|. ACTION_ECHO; ! 375: <PERCENT_BRACE_ACTION>\n { ! 376: ++linenum; ! 377: ACTION_ECHO; ! 378: if ( bracelevel == 0 ) ! 379: { ! 380: fputs( "\tYY_BREAK\n", temp_action_file ); ! 381: BEGIN(SECT2); ! 382: } ! 383: } ! 384: ! 385: /* REJECT and yymore() are checked for above, in PERCENT_BRACE_ACTION */ ! 386: <ACTION>"{" ACTION_ECHO; ++bracelevel; ! 387: <ACTION>"}" ACTION_ECHO; --bracelevel; ! 388: <ACTION>[^a-z_{}"'/\n]+ ACTION_ECHO; ! 389: <ACTION>{NAME} ACTION_ECHO; ! 390: <ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT); ! 391: <ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */ ! 392: <ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING); ! 393: <ACTION>\n { ! 394: ++linenum; ! 395: ACTION_ECHO; ! 396: if ( bracelevel == 0 ) ! 397: { ! 398: fputs( "\tYY_BREAK\n", temp_action_file ); ! 399: BEGIN(SECT2); ! 400: } ! 401: } ! 402: <ACTION>. ACTION_ECHO; ! 403: ! 404: <ACTION_COMMENT>"*/" ACTION_ECHO; BEGIN(ACTION); ! 405: <ACTION_COMMENT>[^*\n]+ ACTION_ECHO; ! 406: <ACTION_COMMENT>"*" ACTION_ECHO; ! 407: <ACTION_COMMENT>\n ++linenum; ACTION_ECHO; ! 408: <ACTION_COMMENT>. ACTION_ECHO; ! 409: ! 410: <C_COMMENT_2>"*/" ACTION_ECHO; BEGIN(SECT2); ! 411: <C_COMMENT_2>"*/".*\n ++linenum; ACTION_ECHO; BEGIN(SECT2); ! 412: <C_COMMENT_2>[^*\n]+ ACTION_ECHO; ! 413: <C_COMMENT_2>"*" ACTION_ECHO; ! 414: <C_COMMENT_2>\n ++linenum; ACTION_ECHO; ! 415: ! 416: <ACTION_STRING>[^"\\\n]+ ACTION_ECHO; ! 417: <ACTION_STRING>\\. ACTION_ECHO; ! 418: <ACTION_STRING>\n ++linenum; ACTION_ECHO; ! 419: <ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION); ! 420: <ACTION_STRING>. ACTION_ECHO; ! 421: ! 422: ! 423: <SECT2,QUOTE,CCL>{ESCSEQ} { ! 424: yylval = myesc( yytext ); ! 425: return ( CHAR ); ! 426: } ! 427: ! 428: <FIRSTCCL>{ESCSEQ} { ! 429: yylval = myesc( yytext ); ! 430: BEGIN(CCL); ! 431: return ( CHAR ); ! 432: } ! 433: ! 434: ! 435: <SECT3>.*(\n?) ECHO; ! 436: %%
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.