%{
#include "y.tab.h"
static int lineno = 1;

#define YYTEXTCOPY textcopy(yytext)
static char *textcopy(char *text);
static char *textcopystringval(char *text);

#define yyeraseunput() (yysptr = yysbuf)
/* The above macro is called by yyerror() to discard any unput() characters
   so the next call to yylex() will only deal with new characters from the new
   input file. It is specific to at&t lex. */

/* #define QQYY fprintf(stderr, "<%s>", yytext) */
#define QQYY 
%}

%%

\n		{ QQYY; lineno++; return '\n'; }

ACTIONLIST	{ QQYY; yylval.s = YYTEXTCOPY; return ACTIONLIST; }
BooleanInput	{ QQYY; yylval.s = YYTEXTCOPY; return BOOLEANINPUT0; }
BoxDisplay	{ QQYY; yylval.s = YYTEXTCOPY; return BOXDISPLAY0; }
CALCULATE	{ QQYY; yylval.s = YYTEXTCOPY; return CALCULATE; }
char		{ QQYY; yylval.s = YYTEXTCOPY; return CHAR; }
CHOICES		{ QQYY; yylval.s = YYTEXTCOPY; return CHOICES; }
COL		{ QQYY; yylval.s = YYTEXTCOPY; return COL; }
COLUMNS		{ QQYY; yylval.s = YYTEXTCOPY; return COLUMNS; }
DATA		{ QQYY; yylval.s = YYTEXTCOPY; return DATA; }
DEFAULTQUEUE	{ QQYY; yylval.s = YYTEXTCOPY; return DEFAULTQUEUE; }
DEFAULTVALUE	{ QQYY; yylval.s = YYTEXTCOPY; return DEFAULTVALUE; }
DEFAULTVALUES	{ QQYY; yylval.s = YYTEXTCOPY; return DEFAULTVALUES; }
DETAIL		{ QQYY; yylval.s = YYTEXTCOPY; return DETAIL; }
DIRECTION	{ QQYY; yylval.s = YYTEXTCOPY; return DIRECTION; }
DisplayField	{ QQYY; yylval.s = YYTEXTCOPY; return DISPLAYFIELD; }
DISPLAY		{ QQYY; yylval.s = YYTEXTCOPY; return DISPLAY0; }
DISTANCE	{ QQYY; yylval.s = YYTEXTCOPY; return DISTANCE; }
DOWN		{ QQYY; yylval.s = YYTEXTCOPY; return DOWN; }
exclusive	{ QQYY; yylval.s = YYTEXTCOPY; return EXCLUSIVE0; }
Field		{ QQYY; yylval.s = YYTEXTCOPY; return FIELD; }
Form		{ QQYY; yylval.s = YYTEXTCOPY; return FORM; }
FORMNAME	{ QQYY; yylval.s = YYTEXTCOPY; return FORMNAME; }
HEIGHT		{ QQYY; yylval.s = YYTEXTCOPY; return HEIGHT; }
HIDDENIF	{ QQYY; yylval.s = YYTEXTCOPY; return HIDDENIF; }
InputField	{ QQYY; yylval.s = YYTEXTCOPY; return INPUTFIELD; }
INPUTSOURCE	{ QQYY; yylval.s = YYTEXTCOPY; return INPUTSOURCE; }
LEFT		{ QQYY; yylval.s = YYTEXTCOPY; return LEFT; }
LENGTH		{ QQYY; yylval.s = YYTEXTCOPY; return LENGTH; }
LineDisplay	{ QQYY; yylval.s = YYTEXTCOPY; return LINEDISPLAY0; }
LOCKEDIF	{ QQYY; yylval.s = YYTEXTCOPY; return LOCKEDIF; }
NAME		{ QQYY; yylval.s = YYTEXTCOPY; return NAME; }
NODENUMBER	{ QQYY; yylval.s = YYTEXTCOPY; return NODENUMBER; }
nonexclusive	{ QQYY; yylval.s = YYTEXTCOPY; return NONEXCLUSIVE0; }
NumericInput	{ QQYY; yylval.s = YYTEXTCOPY; return NUMERICINPUT0; }
none		{ QQYY; yylval.s = YYTEXTCOPY; return NONE; }
NOTIFY		{ QQYY; yylval.s = YYTEXTCOPY; return NOTIFY; }
NUMLINES	{ QQYY; yylval.s = YYTEXTCOPY; return NUMLINES; }
PROMPT		{ QQYY; yylval.s = YYTEXTCOPY; return PROMPT; }
RIGHT		{ QQYY; yylval.s = YYTEXTCOPY; return RIGHT; }
Route		{ QQYY; yylval.s = YYTEXTCOPY; return ROUTE; }
ROW		{ QQYY; yylval.s = YYTEXTCOPY; return ROW; }
SCREEN		{ QQYY; yylval.s = YYTEXTCOPY; return SCREEN; }
SelectionInput	{ QQYY; yylval.s = YYTEXTCOPY; return SELECTIONINPUT0; }
STATUSSTRING	{ QQYY; yylval.s = YYTEXTCOPY; return STATUSSTRING; }
TERMINAL	{ QQYY; yylval.s = YYTEXTCOPY; return TERMINAL; }
TEXTATTRS	{ QQYY; yylval.s = YYTEXTCOPY; return TEXTATTRS; }
TextDisplay	{ QQYY; yylval.s = YYTEXTCOPY; return TEXTDISPLAY0; }
TextInput	{ QQYY; yylval.s = YYTEXTCOPY; return TEXTINPUT0; }
TYPE		{ QQYY; yylval.s = YYTEXTCOPY; return TYPE; }
UP		{ QQYY; yylval.s = YYTEXTCOPY; return UP; }
WIDTH		{ QQYY; yylval.s = YYTEXTCOPY; return WIDTH; }
word		{ QQYY; yylval.s = YYTEXTCOPY; return WORD; }
WRAP		{ QQYY; yylval.s = YYTEXTCOPY; return WRAP; }

"/*"			{ char c, l;
			  for (c = '!'; c != EOF; c = input()) {
			    if (c == '/' && l == '*') break;
			    l = c;
			    if (c == '\n') lineno++;
			  }
			}
[ \t]+			{ }
\"([^"]*(\\\")?)*\"	{ QQYY; yylval.s = textcopystringval(yytext); return STRING; }
[a-zA-Z_][a-zA-Z_0-9]*	{ QQYY; yylval.s = YYTEXTCOPY; return ID; }
[-+]?[0-9]+		{ QQYY; yylval.i = strtol(yytext, NULL, 0); return INTEGER; }
.			{ QQYY; return yytext[0]; }

%%

yywrap() { return(1); }

char *yylexany(void) {
  static char buf[BUFSIZ];
  char *trav = buf, reading = 0, c = 0;
  int left = BUFSIZ - 1;
  while (c != EOF && c != '\n' && left) {
    c = input();
    reading |= !isspace(c);
    if (reading) *trav++ = c, left--;
  }
  if (c == '\n') {
    unput('\n');
    trav--;
  }
  *trav = 0;
  return buf;
}

static char *textcopy(char *text) {
  static int curbuf = 0;
  static char yyextrabuf[2][BUFSIZ];
  strcpy(yyextrabuf[curbuf], text);
  curbuf = !curbuf;
  return yyextrabuf[!curbuf];
}

static char *textcopystringval(char *text) {
  char stuff[BUFSIZ], *trav = stuff;
  text++;
  while (*text != '\"') {
    if (*text == '\\') {
      text++;
      if (*text == 'n') *trav = '\n';
      else if (*text == 'r') *trav = '\r';
      else *trav = *text;
    } else *trav = *text;
    trav++, text++;
  }
  *trav = 0;
  return textcopy(stuff);
}

void yyerror(char *s) {
  fprintf(stderr, "Oops... %s on line number %d!\n", s, lineno);
}

void yybegin(void) {
  yyeraseunput();
  lineno = 1;
}
