/* Copyright 1989-93 GROUPE BULL -- See license conditions in file COPYRIGHT */
/***************************\
*                           *
*  FLex generator for Klone *
*                           *
\***************************/
/* Note: this parser works on 8-bit chars and is faster than the old lex one,
 * TODO: guard the parser from jumping out of it
 */

%option 8bit
%option ecs meta-ecs
%option prefix="Klyy"
%option outfile="kllex.yy.c"

%{
#include "kly.tab.h"
/* #define YYLMAX 8192 */ /* 8192 is the default flex value */

/********************************************************** flex-dependences */
/* these lines shamelessly exploits internal implementation details of flex
 * v2.5.2. they may need tweaking for later releases, but I dont think so.
 */

/* we export the size from a documented macro to a shared variable. portable. */
int Klyy_buf_size = YY_BUF_SIZE;

/* we export the cursor position from static variables. 
 * uses undocumented var yy_c_buf_p
 */
char *Klyy_bufptr() {return yy_c_buf_p;}

/* set bufferization. uses undocumented field of buffer yy_is_interactive
 * if this changes, look at the definition of the function yy_set_interactive
 */
Klyy_set_bufferized(b, flag)
    YY_BUFFER_STATE b;
    int flag;
{
    if (!flag)
	b->yy_is_interactive = 1;
}

/* then, if the bufferisation is set read ONLY one char at a time.
   here is the code of the original 2.5.2 YY_INPUT:
   */
/* #define YY_INPUT(buf,result,max_size) \
	if ( yy_current_buffer->yy_is_interactive ) \
		{ \
		int c = '*', n; \
		for ( n = 0; n < max_size && \
			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
			buf[n] = (char) c; \
		if ( c == '\n' ) \
			buf[n++] = (char) c; \
		if ( c == EOF && ferror( yyin ) ) \
			YY_FATAL_ERROR( "input in flex scanner failed" ); \
		result = n; \
		} \
	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
		  && ferror( yyin ) ) \
		YY_FATAL_ERROR( "input in flex scanner failed" );
		*/

#define YY_INPUT(buf,result,max_size) \
	if ( yy_current_buffer->yy_is_interactive ) { \
		int c = getc( yyin ); \
		    if ( c == EOF )\
		       if (ferror( yyin ) ) \
			   YY_FATAL_ERROR( "input in flex scanner failed" ); \
                       else \
                           result = 0 ;\
                    else \
			   *(buf) = c, result = 1; \
	} else if ( ((result = fread( buf, (size_t) 1, (size_t) max_size,\
				      yyin )) == 0) \
		  && ferror( yyin ) ) \
		YY_FATAL_ERROR( "input in flex scanner failed" );



extern char *KlStripStringContents();

/*************************************************** end of flex-dependences */

#include "klone.h"
#include "kl_stream.h"
int
Klyylinenoget()
{
    /* only called if KlIsReadingFile returns something */
    int i, pos = ftell(KlStdyy->fd), lineno = 1;
    FILE *fd;
    if (pos == -1 
	|| !(fd = fopen(KlStdyy->name, "r")))
	return 0;			/* 0 is returned if something fails */
    /* hack to deduce real cursor despite the heavy bufferisation */
    pos -=  yy_current_buffer->yy_n_chars
	- (yy_current_buffer->yy_buf_pos - yy_current_buffer->yy_ch_buf);
    for (i = 0; i < pos; i++) {
	if (getc(fd) == '\n') {
	    lineno++;
	}
    }
    fclose(fd);
    return lineno;
}

%}
FNCP	[^-+ \t\014\015\036\n"'(){}\[\]0-9`,;]
FNC	[^ \t\014\015\036\n"'(){}\[\]0-9`,;]
NC	[^ \t\014\015\036\n"'(){}\[\]`,;]
SIGN	[-+]
PACKCHAR [%]

%x comment
%x string
%x string_end
%x rawstring
%x rawstring_end

%%
^\#![^\n]*\n    ;			        /* ignore shell exec lines */
.[\010]		;				/* handles backspacing */
.[\177]		;				/* handles deleting */
\036 		BEGIN(rawstring);
<rawstring>[^\036]*           {		/* ^^...^^ */
                    KlReadString = (KlO) KlStringMakeFromBytes(yyleng, yytext);
		    BEGIN(rawstring_end);
		}
<rawstring>\036 {   /* should be matched above, but doesnt, so... */
		    KlReadString=(KlO)KlStringMakeFromBytes(0,0);
		    BEGIN(INITIAL);
		    return(RAW_STRING);
		}
<rawstring_end>\036               BEGIN(INITIAL);return(RAW_STRING);
<rawstring_end><<EOF>>            BEGIN(INITIAL);return(NON_CLOSED_RAW_STRING);
\"              BEGIN(string);
<string>([^\\\"]|\\(.|\n))*      {int sslen;
		    char *ss = KlStripStringContents(yyleng, yytext, &sslen);
		    KlReadString = (KlO) KlStringMakeFromBytes(sslen, ss);
                    BEGIN(string_end);
		}
<string>\"      {   /* should be matched above, but doesnt, so... */
		    KlReadString=(KlO)KlStringMakeFromBytes(0,0);
		    BEGIN(INITIAL);
		    return(STRING);
		}
<string_end>\"		      BEGIN(INITIAL);return(STRING);
<string_end><<EOF>>	      BEGIN(INITIAL);return(NON_CLOSED_STRING);
[;] 			      BEGIN(comment);
<comment>[^\n]*		      ;			/* comments */
<comment>\n                   BEGIN(INITIAL);BEGIN(INITIAL);
<comment><<EOF>> 	      BEGIN(INITIAL);return(END_OF_FILE);
[-+]?[0-9]+	              return(NUMBER);			/* integers */
[#]x[0-9a-fA-F]+	      return(HEX_NUMBER);	/* hex integers */
[#]u[0-9]+	              return(UNSIGNED_NUMBER); /* unsigned integers */
[#]l[-+]?[0-9]+	              return(LONGLONG_NUMBER); /* long long integers */
0[xX][0-9a-fA-F]+	      return(HEX_NUMBER); /* hex integers OBSOLETE */
[-+]?[0-9]+[.][0-9]*[eE][-+]?[0-9][0-9]* return(REAL_NUMBER);
[-+]?[.][0-9]+[eE][-+]?[0-9][0-9]* 	 return(REAL_NUMBER);
[-+]?[0-9]+[.][0-9]*               	 return(REAL_NUMBER);
[-+]?[.][0-9]+               		 return(REAL_NUMBER);
[-+]?[0-9]+[eE][-+]?[0-9][0-9]*     	 return(REAL_NUMBER);
"("		return(LEFTPAR); 		/* start of list */
[)][.]      	return(RIGHTPARDOT);	        /* accessor on expr */
")"		return(RIGHTPAR);    		/* end of list */
"{"		return(LEFTBRA); 		/* start of read-obj */
"}"		return(RIGHTBRA);    		/* end of read-obj */
"["      	return(LEFTSQUARE);	        /* begin locator */
"#""["          return(LEFTSHARPSQUARE); 
"]"             return(RIGHTSQUARE); 		/*  end locator  */
"#("            return(LEFTPARVECTOR);          /* start of vector, CL compat */
"'"		return(QUOTECHAR);		/* quoting */
"`"		return(BACKQUOTE);		/* backquoting */
","		return(UNQUOTE);		/* backquoting */
",@"		return(UNQUOTESPLICING);	/* backquoting */
{PACKCHAR}{FNC}{NC}* return(PACKNAME);		/* see KlPacknameMake */
[#]\\\^[@-~]	return(CTRLCHAR);		/* #\^A */
[#]\\{FNCP}{NC}{NC}* return(SYMBCHAR);		/* #\space etc... */
[#]\\.		return(CHAR);			/* #\A */
{FNCP}{NC}*	return (NAME);			/* identifier */
{SIGN}{FNC}{NC}*	return (NAME);		/* +foo */
{SIGN}		return (NAME);			/* + */
[ \t\014\015\n]		;			/* blanks */
<<EOF>>		return(END_OF_FILE);		/* pseudo-EOF handling */
%%

/*
;;; EMACS MODES
;;; Local Variables: ***
;;; mode:c ***
;;; End: ***
*/


syntax highlighted by Code2HTML, v. 0.9.1