home *** CD-ROM | disk | FTP | other *** search
- /* scan.l - scanner for flex input */
-
- %{
- /*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Vern Paxson.
- *
- * The United States Government has rights in this work pursuant
- * to contract no. DE-AC03-76SF00098 between the United States
- * Department of Energy and the University of California.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement: ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* $Header: scan.l,v 1.2 94/01/04 14:33:09 vern Exp $ */
-
- #include "flexdef.h"
- #include "parse.h"
-
- #define ACTION_ECHO add_action( yytext )
- #define MARK_END_OF_PROLOG mark_prolog();
-
- #define YY_DECL \
- int flexscan()
-
- #define RETURNCHAR \
- yylval = (unsigned char) yytext[0]; \
- return CHAR;
-
- #define RETURNNAME \
- strcpy( nmstr, yytext ); \
- return NAME;
-
- #define PUT_BACK_STRING(str, start) \
- for ( i = strlen( str ) - 1; i >= start; --i ) \
- unput((str)[i])
-
- #define CHECK_REJECT(str) \
- if ( all_upper( str ) ) \
- reject = true;
-
- #define CHECK_YYMORE(str) \
- if ( all_lower( str ) ) \
- yymore_used = true;
- %}
-
- %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
- %x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT
- %x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2
-
- WS [ \t]+
- OPTWS [ \t]*
- NOT_WS [^ \t\n]
-
- NL (\n|\r\n|\n\r)
-
- NAME ([a-z_][a-z_0-9-]*)
- NOT_NAME [^a-z_*\n]+
-
- SCNAME {NAME}
-
- ESCSEQ (\\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2}))
-
- FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ})
- CCL_CHAR ([^\\\n\]]|{ESCSEQ})
-
- %%
- static int bracelevel, didadef, indented_code, checking_used;
-
- int doing_codeblock = false;
- int i;
- Char nmdef[MAXLINE], myesc();
-
-
- ^{WS} indented_code = true; BEGIN(CODEBLOCK);
- ^"/*" ACTION_ECHO; BEGIN(C_COMMENT);
- ^"%s"{NAME}? return SCDECL;
- ^"%x"{NAME}? return XSCDECL;
- ^"%{".*{NL} {
- ++linenum;
- line_directive_out( (FILE *) 0 );
- indented_code = false;
- BEGIN(CODEBLOCK);
- }
-
- {WS} return WHITESPACE;
-
- ^"%%".* {
- sectnum = 2;
- bracelevel = 0;
- mark_defs1();
- line_directive_out( (FILE *) 0 );
- BEGIN(SECT2PROLOG);
- return SECTEND;
- }
-
- ^"%pointer".*{NL} {
- if ( lex_compat )
- warn( "%pointer incompatible with -l option" );
- else
- yytext_is_array = false;
- ++linenum;
- }
- ^"%array".*{NL} {
- if ( C_plus_plus )
- warn( "%array incompatible with -+ option" );
- else
- yytext_is_array = true;
- ++linenum;
- }
-
- ^"%used" {
- warn( "%used/%unused have been deprecated" );
- checking_used = REALLY_USED; BEGIN(USED_LIST);
- }
- ^"%unused" {
- warn( "%used/%unused have been deprecated" );
- checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
- }
-
-
- ^"%"[aceknopr]{OPTWS}[0-9]*{OPTWS}{NL} ++linenum; /* ignore */
-
- ^"%"[^sxanpekotcru{}].* synerr( "unrecognized '%' directive" );
-
- ^{NAME} {
- strcpy( nmstr, yytext );
- didadef = false;
- BEGIN(PICKUPDEF);
- }
-
- {SCNAME} RETURNNAME;
- ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */
- {OPTWS}{NL} ++linenum; return '\n';
-
-
- <C_COMMENT>"*/" ACTION_ECHO; BEGIN(INITIAL);
- <C_COMMENT>"*/".*{NL} ++linenum; ACTION_ECHO; BEGIN(INITIAL);
- <C_COMMENT>[^*\n]+ ACTION_ECHO;
- <C_COMMENT>"*" ACTION_ECHO;
- <C_COMMENT>{NL} ++linenum; ACTION_ECHO;
-
-
- <CODEBLOCK>^"%}".*{NL} ++linenum; BEGIN(INITIAL);
- <CODEBLOCK>"reject" ACTION_ECHO; CHECK_REJECT(yytext);
- <CODEBLOCK>"yymore" ACTION_ECHO; CHECK_YYMORE(yytext);
- <CODEBLOCK>{NAME}|{NOT_NAME}|. ACTION_ECHO;
- <CODEBLOCK>{NL} {
- ++linenum;
- ACTION_ECHO;
- if ( indented_code )
- BEGIN(INITIAL);
- }
-
-
- <PICKUPDEF>{WS} /* separates name and definition */
-
- <PICKUPDEF>{NOT_WS}.* {
- strcpy( (char *) nmdef, yytext );
-
- /* Skip trailing whitespace. */
- for ( i = strlen( (char *) nmdef ) - 1;
- i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
- --i )
- ;
-
- nmdef[i + 1] = '\0';
-
- ndinstal( nmstr, nmdef );
- didadef = true;
- }
-
- <PICKUPDEF>{NL} {
- if ( ! didadef )
- synerr( "incomplete name definition" );
- BEGIN(INITIAL);
- ++linenum;
- }
-
- <RECOVER>.*{NL} ++linenum; BEGIN(INITIAL); RETURNNAME;
-
-
- <USED_LIST>{NL} ++linenum; BEGIN(INITIAL);
- <USED_LIST>{WS}
- <USED_LIST>"reject" {
- if ( all_upper( yytext ) )
- reject_really_used = checking_used;
- else
- synerr(
- "unrecognized %used/%unused construct" );
- }
- <USED_LIST>"yymore" {
- if ( all_lower( yytext ) )
- yymore_really_used = checking_used;
- else
- synerr(
- "unrecognized %used/%unused construct" );
- }
- <USED_LIST>{NOT_WS}+ synerr( "unrecognized %used/%unused construct" );
-
-
- <SECT2PROLOG>^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
- <SECT2PROLOG>^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
-
- <SECT2PROLOG>^{WS}.* ACTION_ECHO; /* indented code in prolog */
-
- <SECT2PROLOG>^{NOT_WS}.* { /* non-indented code */
- if ( bracelevel <= 0 )
- { /* not in %{ ... %} */
- yyless( 0 ); /* put it all back */
- mark_prolog();
- BEGIN(SECT2);
- }
- else
- ACTION_ECHO;
- }
-
- <SECT2PROLOG>.* ACTION_ECHO;
- <SECT2PROLOG>{NL} ++linenum; ACTION_ECHO;
-
- <SECT2PROLOG><<EOF>> {
- mark_prolog();
- sectnum = 0;
- yyterminate(); /* to stop the parser */
- }
-
- <SECT2>^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */
-
- <SECT2>^({WS}|"%{") {
- indented_code = (yytext[0] != '%');
- doing_codeblock = true;
- bracelevel = 1;
-
- if ( indented_code )
- ACTION_ECHO;
-
- BEGIN(CODEBLOCK_2);
- }
-
- <SECT2>^"<" BEGIN(SC); return '<';
- <SECT2>^"^" return '^';
- <SECT2>\" BEGIN(QUOTE); return '"';
- <SECT2>"{"/[0-9] BEGIN(NUM); return '{';
- <SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR);
- <SECT2>"$"/([ \t]|{NL}) return '$';
-
- <SECT2>{WS}"%{" {
- bracelevel = 1;
- BEGIN(PERCENT_BRACE_ACTION);
- return '\n';
- }
- <SECT2>{WS}"|".*{NL} continued_action = true; ++linenum; return '\n';
-
- <SECT2>{WS} {
- /* This rule is separate from the one below because
- * otherwise we get variable trailing context, so
- * we can't build the scanner using -{f,F}.
- */
- bracelevel = 0;
- continued_action = false;
- BEGIN(ACTION);
- return '\n';
- }
-
- <SECT2>{OPTWS}{NL} {
- bracelevel = 0;
- continued_action = false;
- BEGIN(ACTION);
- unput( '\n' ); /* so <ACTION> sees it */
- return '\n';
- }
-
- <SECT2>"<<EOF>>" return EOF_OP;
-
- <SECT2>^"%%".* {
- sectnum = 3;
- BEGIN(SECT3);
- yyterminate(); /* to stop the parser */
- }
-
- <SECT2>"["{FIRST_CCL_CHAR}{CCL_CHAR}* {
- int cclval;
-
- strcpy( nmstr, yytext );
-
- /* Check to see if we've already encountered this
- * ccl.
- */
- if ( (cclval = ccllookup( (Char *) nmstr )) )
- {
- if ( input() != ']' )
- synerr( "bad character class" );
-
- yylval = cclval;
- ++cclreuse;
- return PREVCCL;
- }
- else
- {
- /* We fudge a bit. We know that this ccl will
- * soon be numbered as lastccl + 1 by cclinit.
- */
- cclinstal( (Char *) nmstr, lastccl + 1 );
-
- /* Push back everything but the leading bracket
- * so the ccl can be rescanned.
- */
- yyless( 1 );
-
- BEGIN(FIRSTCCL);
- return '[';
- }
- }
-
- <SECT2>"{"{NAME}"}" {
- register Char *nmdefptr;
- Char *ndlookup();
-
- strcpy( nmstr, yytext + 1 );
- nmstr[yyleng - 2] = '\0'; /* chop trailing brace */
-
- if ( ! (nmdefptr = ndlookup( nmstr )) )
- format_synerr( "undefined definition {%s}",
- nmstr );
-
- else
- { /* push back name surrounded by ()'s */
- int len = strlen( (char *) nmdefptr );
-
- if ( lex_compat || nmdefptr[0] == '^' ||
- (len > 0 && nmdefptr[len - 1] == '$') )
- { /* don't use ()'s after all */
- PUT_BACK_STRING((char *) nmdefptr, 0);
-
- if ( nmdefptr[0] == '^' )
- BEGIN(CARETISBOL);
- }
-
- else
- {
- unput(')');
- PUT_BACK_STRING((char *) nmdefptr, 0);
- unput('(');
- }
- }
- }
-
- <SECT2>[/|*+?.()] return (unsigned char) yytext[0];
- <SECT2>. RETURNCHAR;
-
-
- <SC>[,*] return (unsigned char) yytext[0];
- <SC>">" BEGIN(SECT2); return '>';
- <SC>">"/^ BEGIN(CARETISBOL); return '>';
- <SC>{SCNAME} RETURNNAME;
- <SC>. {
- format_synerr( "bad <start condition>: %s", yytext );
- }
-
- <CARETISBOL>"^" BEGIN(SECT2); return '^';
-
-
- <QUOTE>[^"\n] RETURNCHAR;
- <QUOTE>\" BEGIN(SECT2); return '"';
-
- <QUOTE>{NL} {
- synerr( "missing quote" );
- BEGIN(SECT2);
- ++linenum;
- return '"';
- }
-
-
- <FIRSTCCL>"^"/[^-\]\n] BEGIN(CCL); return '^';
- <FIRSTCCL>"^"/("-"|"]") return '^';
- <FIRSTCCL>. BEGIN(CCL); RETURNCHAR;
-
- <CCL>-/[^\]\n] return '-';
- <CCL>[^\]\n] RETURNCHAR;
- <CCL>"]" BEGIN(SECT2); return ']';
- <CCL>.|{NL} {
- synerr( "bad character class" );
- BEGIN(SECT2);
- return ']';
- }
-
-
- <NUM>[0-9]+ {
- yylval = myctoi( yytext );
- return NUMBER;
- }
-
- <NUM>"," return ',';
- <NUM>"}" BEGIN(SECT2); return '}';
-
- <NUM>. {
- synerr( "bad character inside {}'s" );
- BEGIN(SECT2);
- return '}';
- }
-
- <NUM>{NL} {
- synerr( "missing }" );
- BEGIN(SECT2);
- ++linenum;
- return '}';
- }
-
-
- <BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2);
- <BRACEERROR>{NL} synerr( "missing }" ); ++linenum; BEGIN(SECT2);
-
-
- <CODEBLOCK_2>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT);
- <PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".* bracelevel = 0;
- <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject" {
- ACTION_ECHO;
- CHECK_REJECT(yytext);
- }
- <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore" {
- ACTION_ECHO;
- CHECK_YYMORE(yytext);
- }
- <PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|. ACTION_ECHO;
- <PERCENT_BRACE_ACTION,CODEBLOCK_2>{NL} {
- ++linenum;
- ACTION_ECHO;
- if ( bracelevel == 0 ||
- (doing_codeblock && indented_code) )
- {
- if ( ! doing_codeblock )
- add_action( "\tYY_BREAK\n" );
-
- doing_codeblock = false;
- BEGIN(SECT2);
- }
- }
-
-
- /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
- <ACTION>"{" ACTION_ECHO; ++bracelevel;
- <ACTION>"}" ACTION_ECHO; --bracelevel;
- <ACTION>[^a-z_{}"'/\n]+ ACTION_ECHO;
- <ACTION>{NAME} ACTION_ECHO;
- <ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT);
- <ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
- <ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING);
- <ACTION>{NL} {
- ++linenum;
- ACTION_ECHO;
- if ( bracelevel == 0 )
- {
- add_action( "\tYY_BREAK\n" );
- BEGIN(SECT2);
- }
- }
- <ACTION>. ACTION_ECHO;
-
- <ACTION_COMMENT>"*/" {
- ACTION_ECHO;
- if ( doing_codeblock )
- BEGIN(CODEBLOCK_2);
- else
- BEGIN(ACTION);
- }
-
- <ACTION_COMMENT>"*" ACTION_ECHO;
- <ACTION_COMMENT>[^*\n]+ ACTION_ECHO;
- <ACTION_COMMENT>[^*\n]*{NL} ++linenum; ACTION_ECHO;
-
- <ACTION_STRING>[^"\\\n]+ ACTION_ECHO;
- <ACTION_STRING>\\. ACTION_ECHO;
- <ACTION_STRING>{NL} ++linenum; ACTION_ECHO;
- <ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION);
- <ACTION_STRING>. ACTION_ECHO;
-
- <ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>> {
- synerr( "EOF encountered inside an action" );
- yyterminate();
- }
-
-
- <SECT2,QUOTE,CCL>{ESCSEQ} {
- yylval = myesc( (Char *) yytext );
- return CHAR;
- }
-
- <FIRSTCCL>{ESCSEQ} {
- yylval = myesc( (Char *) yytext );
- BEGIN(CCL);
- return CHAR;
- }
-
-
- <SECT3>.*(\n?) ECHO;
- <SECT3><<EOF>> sectnum = 0; yyterminate();
-
- <*>.|\n format_synerr( "bad character: %s", yytext );
-
- %%
-
-
- int yywrap()
- {
- if ( --num_input_files > 0 )
- {
- set_input_file( *++input_files );
- return 0;
- }
-
- else
- return 1;
- }
-
-
- /* set_input_file - open the given file (if NULL, stdin) for scanning */
-
- void set_input_file( file )
- char *file;
- {
- if ( file )
- {
- infilename = file;
- yyin = fopen( infilename, "r" );
-
- if ( yyin == NULL )
- lerrsf( "can't open %s", file );
- }
-
- else
- {
- yyin = stdin;
- infilename = "<stdin>";
- }
- }
-
-
- /* Wrapper routines for accessing the scanner's malloc routines. */
-
- void *flex_alloc( size )
- unsigned int size;
- {
- return yy_flex_alloc( size );
- }
-
- void *flex_realloc( ptr, size )
- void *ptr;
- unsigned int size;
- {
- return yy_flex_realloc( ptr, size );
- }
-
- void flex_free( ptr )
- void *ptr;
- {
- yy_flex_free( ptr );
- }
-