
%{
/*
	> FLEX -d -i -I lex.l
	> Dcc lex.yy.c -mD -c
**
    21-08-94 - added FLAG, REFERENCE
    25-09-94 * rewritten

*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include "Dyn.h"
#include "node.h"
#include "y.tab.h"
extern FILE *nextfile(void);

#define _ESC  "\\"
#define _KET  "%}"
#define _EKET "%]"

#define STORE(x) yylval = (int)strdup((x))

int  lineno   = 0;
DSTR value    = EmptyDyn;
char linebuffer[1000];

/* jeder txt muss mit "" eingesclossen sein!; "\\" werden gestrippt */
char * Strip (const char *txt, int embedded)
{
    char *dest = linebuffer;
    char c = 0;

    if (embedded)
	if (*txt == '"')
	    ++txt;

    while (c = *(txt ++)) {
	if (c == '\\')
	    c = *(txt++);
	*(dest++) = c;
    } /* while */

    if (embedded)
	if (*(--dest) != '"')
	    ++dest;
    *dest = 0;
    return linebuffer;
} /* Strip */


/* int read(FILE *, char *, int); */
%}

ROL  ("%%")
RBRA ("%{")
RKET ("%}")
EBRA ("%[")
EKET ("%]")
ESC  "\\"
SAFECHAR	    [^\]\[\t \n%}{;+=\\"/]
LEGALC		    [^\]\[\t \n%}{;,+=\\"/]
LEGALS		    {LEGALC}+(([\][\n]{LEGALC}*)|([/]{LEGALC}+))*

ALNUM		   [A-Za-z0-9]
LABEL		   [A-Za-z_][A-Za-z_0-9]*

STARTLINE	   [\n][#]if(def)*[\t ]+{LABEL}
ENDLINE 	   [\n][#]endif



%start ASSIGN INFRA INTRA INFR2

%%

[\n]		    { ++ lineno; REJECT; }

<ASSIGN>PROJECT     {		    return PROJECT;   }
<ASSIGN>GLOBAL	    {		    return GLOBAL;    }
<ASSIGN>CONST	    {		    return CONST;     }
<ASSIGN>HIDDEN	    {		    return HIDDEN;    }
<ASSIGN>INTERNAL    {		    return INTERNAL;  }
<ASSIGN>GENERIC     {		    return GENERIC;   }

<ASSIGN>__TYPES     {		    return TYPES;   }
<ASSIGN>__NEEDED    {		    return NEEDED;  }
<ASSIGN>__DEFAULT   {		    return DEFAULT; }
<ASSIGN>{LABEL}     { STORE(yytext); return (NODE_IsType((void*)yylval)) ? GENTYPE : LABEL; }

<ASSIGN>[;]	    {		    return SEMI;  }
<ASSIGN>[,]	    {		    return KOMMA; }
<ASSIGN>[=]	    {		    return ASS;   }
<ASSIGN>[+][=]	    {		    return ADD;   }
<ASSIGN>{RBRA}	    {		    return RBRA;  }
<ASSIGN>{RKET}	    {		    return RKET;  }
<ASSIGN>[{]	    {		    return SBRA;  }
<ASSIGN>[}]	    {		    return SKET;  }

<ASSIGN>{EBRA}	    { BEGIN INFRA;  DynClear(&value); return EBRA; }
<ASSIGN>{EKET}	    {				      return EKET; }
<INFRA>{ESC}{ESC}   |
<INFRA>{ESC}{EKET}  {		    DynCat (&value, yytext + 1); }
<INFRA>{EKET}	    { BEGIN ASSIGN; STORE(DynValue(&value)); yyless(0); return VALUE;  }
<INFRA>[\n]	    {		   yymore(); }
<INFRA>{SAFECHAR}+  |
<INFRA>.	    |
<INFRA>[\t ]+	    {		    DynCat (&value, yytext); }

<ASSIGN>[{][{]	    { BEGIN INFR2;  DynClear(&value); return SSBRA; }
<ASSIGN>[}][}]	    {				      return SSKET; }
<INFR2>{ESC}{ESC}   |
<INFR2>{ESC}[}]     {		    DynCat (&value, yytext + 1); }
<INFR2>[}][}]	    { BEGIN ASSIGN; STORE(DynValue(&value)); yyless(0); return VALUE;  }
<INFR2>[\n]	    {		   yymore(); }
<INFR2>{SAFECHAR}+  |
<INFR2>.	    |
<INFR2>[\t ]+	    {		    DynCat (&value, yytext); }

<ASSIGN>{ROL}	    { BEGIN INTRA;				}
<ASSIGN>["](([^\\"\n]*)([\\]["\\])*)*["] { STORE(Strip(yytext,1)); return VALUE; }
<INTRA>[^\n]*	    { BEGIN ASSIGN; STORE(yytext);          return VALUE; }
<ASSIGN>{LEGALS}    {		    STORE(Strip(yytext,0)); return VALUE; }

{STARTLINE}	    { extern char *inittext; if (!strstr(yytext, inittext)) REJECT;
			BEGIN ASSIGN; return BLOCKSTART;  /* Parseblock START */ }
<ASSIGN>{ENDLINE}   {		BEGIN 0;		  /* Parseblock END   */ }
[/][/][^\n]*	    {					  /* Kommentare       */ }
[ \t]+		    {					  /* Whitespace       */ }
[\n]		    {					  /* Newlines	      */ }
<ASSIGN>.	    {			    return -1;	  /* Unmatched Chars  */ }
<INFRA>.	    {			    return -1;	  /* Unmatched Chars  */ }
<INTRA>.	    {			    return -1;	  /* Unmatched Chars  */ }
.		    {					  /* App Source - NOP */ }
<ASSIGN><<EOF>>     { extern char *filename; BEGIN 0; fprintf (stderr, "unexpected EOF in `%s',%d\n",filename, lineno); REJECT; }
<<EOF>> 	    { BEGIN 0; if ((yyin = nextfile())) { lineno = 0; YY_NEW_FILE; } else return 0; }

%%



