%{
	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>
	#include <malloc.h>
	#include "scanner.h"
	char *stringconst;
	int VarType;
	int n;
	char *keyword[] = {"ACCESS", "ALIAS", "ANY", "APPEND", "AS", "BASE",
                   "BINARY", "BYVAL", "CALL", "CALLS", "CASE", "CDEL",
                   "COMMON", "CONST", "DATA", "DECLARE", "DEF FN", "DEFDBL",
                   "DEFINT", "DEFLNG", "DEFSNG", "DEFSTR", "DIM", "DO",
                   "DOUBLE", "$DYNAMIC", "ELSE", "ELSEIF", "END", "EXIT",
                   "FIELD", "FOR", "FUNCTION", "GOSUB", "GOTO", "IF", "SEG",
                   "$INCLUDE", "INTEGER", "IS", "LET", "LOCAL", "LONG",
                   "LOOP", "NEXT", "OPTION", "OUTPUT", "RESUME", "RETURN",
                   "SELECT", "SHARED", "SIGNAL", "SINGLE", "STATIC",
                   "$STATIC", "STEP", "STRING", "SUB", "THEN", "TO", "DEF",
                   "TYPE", "UNTIL", "USING", "WEND", "WHILE", "REDIM","EndKeywords"};
%}
digit	[0-9]
letter	[A-Za-z_]
suffix	[!#\$%&]

%%
	/* Rules */
{digit}+	{
		return TK_NUMBER;
		}
{digit}+"&"	{
		return TK_NUMBER;
		}
{digit}+"."{digit}+ {
		return TK_NUMBER;
		}

	/* Comments */
"REM"	{
		return TK_COMMENT;
	}
"'"	{
		return TK_COMMENT;
	}

	/* Highest Important Operators */
"AND"	return TK_OPERATOR;
"OR"	return TK_OPERATOR;
"XOR"	return TK_OPERATOR;
"NOT"	return TK_OPERATOR;
"MOD"	return TK_OPERATOR;
"IMP"	return TK_OPERATOR;
"EQV"	return TK_OPERATOR;

	/* Continue Line */
"_"$	return TK_CONTLINE;

	/* The dot between types and members */
"."	return TK_DOT;

"#"{letter}({letter}|{digit})*	{
				VarType = VAR_FILE;
				return TK_UNKNOWN;
				}
"#"{digit}*	{
				return TK_NUMBER;
				}

"&H"({letter}|{digit})*	{
				return TK_HEX;
				}

"&H"({letter}|{digit})*"&"	{
				return TK_HEX;
				}

	/* Keyword (normal) */
{letter}({letter}|{digit})*{suffix}*	{
				n=0;
				while(strcmp(keyword[n],"EndKeywords") != 0)
				{
					if(strcmp(keyword[n],yytext) == 0)
						return TK_KEYWORD;
					n++;
				}

				/* Unknown Variable or Function */
				VarType = VAR_DEFAULT;
				return TK_UNKNOWN;
				}

	/* Keyword (pre-processor) */
"$"{letter}({letter}|{digit})*	{
				n=0;
				while(strcmp(keyword[n],"EndKeywords") != 0)
				{
					if(stricmp(keyword[n],yytext) == 0)
						return TK_METACOMMAND;
					n++;
				}
				}

">="	return TK_OPERATOR;
"<="	return TK_OPERATOR;
"<>"	return TK_OPERATOR;
[-+/*=><\\^]	return TK_OPERATOR;

[ ]	return TK_SPACE;
[\t]	return TK_TAB;
[\n]	return TK_NEWLINE;

\"[^"\n]*["\n]	{
			stringconst = strdup(yytext);
			if(stringconst[yyleng-1] != '"')
				return 254;
			return TK_STRINGCONSTANT;
			}

[().,;]	return TK_SYMBOL;

":"	return TK_SOFTLINE;

^{letter}({letter}|{digit})*":"$	return TK_LABEL;

<<EOF>> {
		
	return TK_EOF;
}

.	return TK_UNRECOGNIZE;

%%

int yywrap(void) {
	return 1;
}

YY_BUFFER_STATE GetCurrentBuffer(void)
{
	return YY_CURRENT_BUFFER;
}
