%{
/*
 * Copyright (c) 1991, 1992 Brad Eacker,
 *              (Music, Intuition, Software, and Computers)
 * All Rights Reserved
 */
/*
 *	tokenizer for dbf
 */
#ifdef DEBUG		/* debugging version */
main()
{
	char	*p;

	while (p = (char *)yylex())
		printf("%-10.10s is \"%s\"\n", p, yytext);
}

s_lookup() {}
yymark() {}

int yynerrrs = 0;

#define	token(x)	(int) "x"

#else /* ! DEBUG (ie production version) */

#include "gram.tab.h"
#define token(x)	x

#endif /* DEBUG */

#define	END_OF(v)	(v-1 + sizeof v / sizeof v[0])
static int screen();
%}

letter			[a-zA-Z_]
digit			[0-9]
letter_or_digit		[a-zA-Z0-9_]
car_ret			[\n]
blank			[ \t]
slash			[/]
double_quote		["]
single_quote		[']
not_d_quote		[^"]
not_s_quote		[^']
other			.
period			[.]

%%

";"{car_ret}		;
{car_ret}		return token(CR);

^{blank}*"*".*\n	;
"&&".*\n		return token(CR);

{period}		return token(PERIOD);

{double_quote}{not_d_quote}*{double_quote}		return token(STRING);
{single_quote}{not_s_quote}*{single_quote}		return token(STRING);

"("			return token(L_PAREN);
")"			return token(R_PAREN);
"@"			return token(AT);
"?"			return token(QUEST);
"??"			return token(QUEST);
"&"			return token(AMPER);

"*"			return token(MULT);
"/"			return token(DIVIDE);

"+"			return token(PLUS);
"-"			return token(MINUS);

","			return token(COMMA);
";"			;
":"			return token(COLON);
"!"			return token(BANG);

"="			return token(EQUAL);
"<>"			return token(NOT_EQUAL);
">"			return token(GREATER);
">="			return token(GREATER_EQUAL);
"<"			return token(LESS);
"<="			return token(LESS_EQUAL);
"$"			return token(DOLLAR);
"->"			return token(PTR);

"\.OR\."		return token(OR);
"\.AND\."		return token(AND);
"\.NOT\."		return token(NOT);

{letter}{letter_or_digit}*	{
#ifdef DEBUG
				return screen();
#else
				int retval;
				if ((retval = screen()) == token(Identifier)){
					s_lookup(token(Identifier));
				}
				return retval;
#endif
				}
{digit}+			{ s_lookup(token(Constant));
				  return token(Constant);
				}
{period}{digit}+		{ s_lookup(token(Constant));
				  return token(Constant);
				}
{digit}+{period}{digit}+	{ s_lookup(token(Constant));
				  return token(Constant);
				}

{blank}+			;

{other}				return token(yytext[0]);

%%

static struct rwtable {		/* reserved word table */
	char	*rw_name;	/* representations */
	int	rw_yylex;	/* yylex(value) */
} rwtable[] = {			/* sorted */
	"ACCE",		token(ACCEPT),
	"ACCEPT",	token(ACCEPT),
	"ALIA",		token(ALIAS),
	"ALIAS",	token(ALIAS),
	"ALL",		token(ALL),
	"APPE",		token(APPEND),
	"APPEND",	token(APPEND),
	"ASSI",		token(ASSIST),
	"ASSIST",	token(ASSIST),
	"AVER",		token(AVERAGE),
	"AVERAGE",	token(AVERAGE),
	"BLAN",		token(BLANK),
	"BLANK",	token(BLANK),
	"BOTTOM",	token(BOTTOM),
	"BROW",		token(BROWSE),
	"BROWSE",	token(BROWSE),
	"CALL",		token(CALL),
	"CANC",		token(CANCEL),
	"CANCEL",	token(CANCEL),
	"CASE",		token(CASE),
	"CHANGE",	token(CHANGE),
	"CLEA",		token(CLEAR),
	"CLEAR",	token(CLEAR),
	"CLOS",		token(CLOSE),
	"CLOSE",	token(CLOSE),
	"CONT",		token(CONTINUE),
	"CONTINUE",	token(CONTINUE),
	"COPY",		token(COPY),
	"COUNT",	token(COUNT),
	"DATABASES",	token(DATABASES),
	"DELETE",	token(DELETE),
	"DELI",		token(DELIMITED),
	"DELIMITED",	token(DELIMITED),
	"DISP",		token(DISPLAY),
	"DISPLAY",	token(DISPLAY),
	"DO",		token(DO),
	"EDIT",		token(EDIT),
	"EJEC",		token(EJECT),
	"EJECT",	token(EJECT),
	"ELSE",		token(ELSE),
	"ENDC",		token(ENDCASE),
	"ENDCASE",	token(ENDCASE),
	"ENDD",		token(ENDDO),
	"ENDDO",	token(ENDDO),
	"ENDI",		token(ENDIF),
	"ENDIF",	token(ENDIF),
	"ENDTEXT",	token(ENDTEXT),
	"ERASE",	token(ERASE),
	"EXCL",		token(EXCLUSIVE),
	"EXCLUSIVE",	token(EXCLUSIVE),
	"EXIT",		token(EXIT),
	"EXPO",		token(EXPORT),
	"EXPORT",	token(EXPORT),
	"FIEL",		token(FIELDS),
	"FIELDS",	token(FIELDS),
	"FILE",		token(FILE_T),
	"FIND",		token(FIND),
	"FOR",		token(FOR),
	"FORM",		token(FORM),
	"FROM",		token(FROM),
	"GET",		token(GET),
	"GO",		token(GO),
	"GOTO",		token(GO),
	"HEAD",		token(HEADING),
	"HEADING",	token(HEADING),
	"HELP",		token(HELP),
	"IF",		token(IF),
	"INDE",		token(INDEX),
	"INDEX",	token(INDEX),
	"INPU",		token(INPUT),
	"INPUT",	token(INPUT),
	"INSE",		token(INSERT),
	"INSERT",	token(INSERT),
	"JOIN",		token(JOIN),
	"LABE",		token(LABEL),
	"LABEL",	token(LABEL),
	"LIST",		token(LIST),
	"LOAD",		token(LOAD),
	"LOCA",		token(LOCATE),
	"LOCATE",	token(LOCATE),
	"LOCK",		token(LOCK),
	"LOGO",		token(LOGOUT),
	"LOGOUT",	token(LOGOUT),
	"LOOP",		token(LOOP),
	"MENU",		token(MENU),
	"MODI",		token(MODIFY),
	"MODIFY",	token(MODIFY),
	"NEXT",		token(NEXT),
	"NOEJ",		token(NOEJECT),
	"NOEJECT",	token(NOEJECT),
	"NOTE",		token(NOTE),
	"OFF",		token(OFF),
	"ON",		token(ON),
	"OTHE",		token(OTHERWISE),
	"OTHERWISE",	token(OTHERWISE),
	"PACK",		token(PACK),
	"PARA",		token(PARAMETERS),
	"PARAMETERS",	token(PARAMETERS),
	"PICT",		token(PICTURE),
	"PICTURE",	token(PICTURE),
	"PLAIN",	token(PLAIN),
	"PLAI",		token(PLAIN),
	"PRIN",		token(PRINT),
	"PRINT",	token(PRINT),
	"PRIV",		token(PRIVATE),
	"PRIVATE",	token(PRIVATE),
	"PROC",		token(PROCEDURE),
	"PROCEDURE",	token(PROCEDURE),
	"PROM",		token(PROMPT),
	"PROMPT",	token(PROMPT),
	"PUBL",		token(PUBLIC),
	"PUBLIC",	token(PUBLIC),
	"QUIT",		token(QUIT),
	"RANGE",	token(RANGE),
	"READ",		token(READ),
	"RECA",		token(RECALL),
	"RECALL",	token(RECALL),
	"RECO",		token(RECORD),
	"RECORD",	token(RECORD),
	"REIN",		token(REINDEX),
	"REINDEX",	token(REINDEX),
	"RELE",		token(RELEASE),
	"RELEASE",	token(RELEASE),
	"RENA",		token(RENAME),
	"RENAME",	token(RENAME),
	"REPL",		token(REPLACE),
	"REPLACE",	token(REPLACE),
	"REPO",		token(REPORT),
	"REPORT",	token(REPORT),
	"RESTORE",	token(RESTORE),
	"REST",		token(REST),
	"RESU",		token(RESUME),
	"RESUME",	token(RESUME),
	"RETR",		token(RETRY),
	"RETRY",	token(RETRY),
	"RETU",		token(RETURN),
	"RETURN",	token(RETURN),
	"RUN",		token(RUN),
	"SAY",		token(SAY),
	"SEEK",		token(SEEK),
	"SELE",		token(SELECT),
	"SELECT",	token(SELECT),
	"SET",		token(SET),
	"SKIP",		token(SKIP),
	"SORT",		token(SORT),
	"STORE",	token(STORE),
	"STRU",		token(STRUCTURE),
	"STRUCTURE",	token(STRUCTURE),
	"SUM",		token(SUM),
	"SUMM",		token(SUMMARY),
	"SUMMARY",	token(SUMMARY),
	"SUSP",		token(SUSPEND),
	"SUSPEND",	token(SUSPEND),
	"TEXT",		token(TEXT),
	"TO",		token(TO),
	"TOP",		token(TOP),
	"TOTAL",	token(TOTAL),
	"TYPE",		token(TYPE),
	"UNLO",		token(UNLOCK),
	"UNLOCK",	token(UNLOCK),
	"UNIQ",		token(UNIQUE),
	"UNIQUE",	token(UNIQUE),
	"USE",		token(USE),
	"VIEW",		token(VIEW),
	"WAIT",		token(WAIT),
	"WHIL",		token(WHILE),
	"WHILE",	token(WHILE),
	"WITH",		token(WITH),
	"ZAP",		token(ZAP),
	};

static int screen()
{
	struct rwtable	*low = rwtable,
			*high = END_OF(rwtable),
			*mid;
	char	*yptr, *op, ochar[100];
	int c;

	op = ochar;
	for (yptr = yytext; *yptr; yptr++)
		*op++ = toupper(*yptr);
	*op = 0;
	op = ochar;
	while (low <= high) {
		mid = low + (high - low)/2;
		if ((c = strcmp(mid->rw_name, op)) == 0)
			return mid->rw_yylex;
		else if (c < 0)
			low = mid + 1;
		else
			high = mid - 1;
	}
	s_lookup(token(Identifier));
	return token(Identifier);
}
