%{

/*
    definition of the lexical analyser used in xetal, 
    Copyright (C) 1991 Raphael Cerf (e-mail: cerf@ens.ens.fr)

    This file is part of xetal.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 1, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <search.h>
#include "proto.h"
#include "y.tab.h"
#include "stack.h"

static long nskip;	/* nb of \n in logical line */
int cmd;		/* token of command currently handled */

/*
 * macros for LEX actions
 */
#define R_C0 yylval.y_chr=yytext[0]; charpos++;
#define R_C1 yylval.y_chr=yytext[1]; charpos+=2;
#define R_C(c) yylval.y_chr=c; charpos++;
#define R_W yylval.y_str=yytext; charpos+=yyleng; 
#define RD_W yylval.y_str=strdup(yytext); charpos+=yyleng; 
#define CP charpos++;
#define CM charpos--;
#define CY charpos+=yyleng;
#define C(x) charpos+=x;
#define B(x) yyless(yyleng-x)

#ifdef FLEX_SCANNER

#undef YY_FATAL_ERROR
/* report a fatal error */
#define YY_FATAL_ERROR(msg) \
	{ \
	if (strcmp(msg, "NULL in input")!=0) {\
	fputs( msg, stderr ); \
	putc( '\n', stderr ); \
		exit( 1 ); \
	} }
#undef YY_INPUT
extern int yy_input1();
extern int yy_input2();
char *tmp_buf;
int (*yy_input)();
#define YY_INPUT(buf,result,max_size) \
	result=(*yy_input)(buf, max_size);

#undef YY_NEW_FILE
#define YY_NEW_FILE { yy_input=yy_input2; goto new_file; }

#endif

#undef yywrap

%}

%a 5000
%e 500
%k 500
%o 6500
%p 4000

letter		[a-zA-Z]
letterA		[a-zA-Z@]
letterS		[a-zA-Z\*]
letterAS	[a-zA-Z@\*]
digit		[0-9]
letter_or_digit	[a-zA-Z_0-9]
letter_or_digit_or_punct [a-zA-Z_0-9\.\,\`\'\"\;\:]
fln_car		[^ \t\n\}\]\{\[]

reel		[0-9]+|[0-9]+\.[0-9]*|[0-9]*\.[0-9]+
nombre		[0-9]+
lettres		{letter_or_digit}+
caracteres	{letter_or_digit_or_punct}+
filename	{fln_car}+

white_space	[ \t\n]+
bl		[ \t]
bls		[ \t]+
obls		[ \t]*
nl		[\n]
blsnl		[ \t]*[\n][ \t]*
blsorblsnl	([ \t]*[\n][ \t]*|[ \t]+)

accent		[\`\^\~\=\'\"\.]
slashed		\\[^\`\^\~\=\'\"\.btHudvc\n\t\ ]

anything	.*
any_not_slash	[^\\\n]*
argument	{letterS}+
command		\\{letterAS}+|\\{accent}
ctlseq0		[^=]*
ctlseq1		[^{=]*
ctlseq2		[^{]*
ctlseq3		[^{=][^{=\\]*
comment		\%[^\n]*\n

%START		BE_ARG O_ARG
%START		S_ARG S_LET S_NB S_CAR S_REEL
%START		S_FLN SQ0 SQ1 SQ2 SQ3
%START		S_VRB0 S_VRBA S_END

%%

		{ nskip=0L; oldlpos=linepos; }

<S_END>{anything}	{ char *p; R_W; p=yytext; return ANYTHING; }

<S_VRB0>\}		{ R_C0; BEGIN S_VRBA; return yytext[0]; }
<S_VRBA>{any_not_slash} { R_W; return ANY_NOT_SLASH; }
<S_VRBA>\\end\{verbatim { yyless(0); verbatim=-1; start_N(); }

<BE_ARG>{argument}	{ R_W; start_N(); cmd=s_lookup(yytext);
			switch(cmd) {
			case VERBATIM:
				if (verbatim==0) {
					BEGIN S_VRB0;
					verbatim=1;
				} else {
				verbatim=0; }
				break;
			}
			return(cmd);
		    }

{bls}		{ R_W;  return BLS; }
{blsnl}		{ R_W;  nskip++; linepos=charpos; return BLSNL; }

<S_ARG>{letter_or_digit} { R_C0; return LETTER; }
<SQ0>{ctlseq0}	{ R_W; return CTLSEQ0; }
<SQ1>{ctlseq1}	{ R_W; return CTLSEQ1; }
<SQ2>{ctlseq2}	{ R_W; return CTLSEQ2; }
<SQ3>{ctlseq3}	{ R_W; return CTLSEQ3; }
<S_NB>{nombre}	{ R_W; return NOMBRE; }
<S_REEL>{reel}	{ R_W; return REEL; }
<S_NB,S_CAR,S_FLN,S_LET,O_ARG>{lettres}	{ R_W; return LETTRES; }
<S_CAR>{caracteres}	{ R_W; return CARACTERES; }
<S_FLN>{filename}	{ R_W; return FILENAME; }

\$		{ R_W; return (mode!=-1 ? DOLLAR : LETTRES); }
\$\$		{ R_W; return (mode!=-1 ? DDOLLAR : LETTRES); }
\\\(		{ R_W; return (mode!=-1 ? OPARE : LETTRES); }
\\\)		{ R_W; return (mode!=-1 ? CPARE : LETTRES); }
\\\[		{ R_W; return (mode!=-1 ? OBRAC : LETTRES); }
\\\]		{ R_W; return (mode!=-1 ? CBRAC : LETTRES); }
<O_ARG>"["	{ R_W; return OBRAC; }
<O_ARG>"]"	{ R_W; return CBRAC; }
"]"		{ if (is_S_in_stack(O_ARG)) {
			R_W; return CBRAC;
		  } else {
		  	R_C0; return yytext[0];
		  }
		}

"\\"		{ R_C0; return SLASH; }

-{1,3}		{ R_C('-'); CY; CM; return '-'; }
\\[ /]		{ yylval.y_str=strcpy(yytext, " "); 
		  C(2); return BLS; }
\\@		{ C(2); }
\\-		{ C(2); }
~		{ yylval.y_str=strcpy(yytext, " "); 
		  C(1); return BLS; }

\\oe		{ R_C('o'); CP; B(1); return(LETTER); }
\\OE		{ R_C('O'); CP; B(1); return(LETTER); }
\\ae		{ R_C('a'); CP; B(1); return(LETTER); }
\\AE		{ R_C('A'); CP; B(1); return(LETTER); }
\\aa		{ R_C('a'); C(2); return(LETTER); }
\\AA		{ R_C('A'); C(2); return(LETTER); }
\\[lL]		{ R_C1; return(LETTER); }
\\[oO]		{ R_C('0'); return(LETTER); }
\\ss		{ R_C('s'); C(2); return(LETTER); }
\?\`		{ R_C('?'); CP; return(LETTER); }
\!\`		{ R_C('!'); CP; return(LETTER); }

{slashed}	{ R_C1; return SLASHED; }

{command}	{ R_W;
		  if (mode==-1) cmd=LETTRES;
		  else if (verbatim==1) cmd=ANY_NOT_SLASH;
		  else cmd=s_lookup(yytext); 
		  switch (cmd) {
			case VERB:
				{ 
				char sch;/* flag character for verb */
				char *p;/* current character */
				int l;/* nb of added characters */

				l=yyleng; p=yytext+l;

			/* verb command : reading text until verb flag */
#ifdef FLEX_SCANNER
				*yy_cp=yy_hold_char;
				sch=*(p++);l++;
				while((*(p++))!=sch) {
					l++;
    					if ( *p == YY_END_OF_BUFFER_CHAR ) {
					/* input needed */
					yy_hold_char = *p;
					yy_c_buf_p=p+1;
					yy_get_next_buffer();
					p=yytext+l;
					} }
				yy_cp=p;
				yy_hold_char=*yy_cp;
				*yy_cp='\0';
				yy_c_buf_p=yy_cp;
#else
				*(p++)=sch=input();
				while ((*(p++)=input())!=sch) l++;
				*p='\0';
#endif
				yylval.y_str=yytext;charpos+=l;
				} break;
		  }
		  return cmd; }

{comment}	{ R_W;  nskip++; return COMMENT; }

[\40-\176]	{ R_C0; return yytext[0]; }

[\14]		{ R_C0; return FFEED; }

.		{ R_C0; return OTHER; }

%%

/*
 * functions called by parser to change lex state
 */

start_O()
{
	S_push(0);
	BEGIN 0;
}

start_END()
{
	S_push(S_END);
	BEGIN S_END;
}

start_N()
{
	if (!is_S_stack_empty()) { S_pop(); }

	if (is_S_stack_empty()) {
		BEGIN S_LET;
	} else {
		BEGIN S_read();
	}
}

start_O_ARG()
{
	S_push(O_ARG);
	BEGIN O_ARG;
}

start_BE_ARG()
{
	S_push(BE_ARG);
	BEGIN BE_ARG;
}

start_ARG()
{
	S_push(S_ARG);
	BEGIN S_ARG;
}

start_NB()
{
	S_push(S_NB);
	BEGIN S_NB;
}

start_REEL()
{
	S_push(S_REEL);
	BEGIN S_REEL;
}

start_CAR()
{
	S_push(S_CAR);
	BEGIN S_CAR;
}

start_FLN()
{
	S_push(S_FLN);
	BEGIN S_FLN;
}

start_SQ0()
{
	S_push(SQ0);
	BEGIN SQ0;
}

start_SQ1()
{
	S_push(SQ1);
	BEGIN SQ1;
}

start_SQ2()
{
	S_push(SQ2);
	BEGIN SQ2;
}

start_SQ3()
{
	S_push(SQ3);
	BEGIN SQ3;
}

start_STATE(s)
int s;
{
	S_push(s);
	BEGIN s;
}

/*
 * lex initialization
 */
init_lex()
{
	f_in=&yyin;
#ifdef FLEX_SCANNER
	yy_input=yy_input1;
	yy_init=1;
#endif
}

#define NAME symbol[n].name
#define TOKEN symbol[n++].token

/*
 * compare two symbol_names
 */
int symbol_tcmp(s1, s2)
symbol_t *s1, *s2;
{
	return (strcmp(s1->name, s2->name));
}

/*
 * initialization of symbol list
 */
int init_symbol(envrt, n_envrt)
char *envrt[];
int n_envrt;
{
	int i, n=0;
	symbol_t s_fake, *r;

	start_N();

	NAME="\\`";			TOKEN=ACCENT;
	NAME="\\^";			TOKEN=ACCENT;
	NAME="\\~";			TOKEN=ACCENT;
	NAME="\\=";			TOKEN=ACCENT;
	NAME="\\'";			TOKEN=ACCENT;
	NAME="\\\"";			TOKEN=ACCENT;
	NAME="\\.";			TOKEN=ACCENT;

	NAME="\\b";			TOKEN=ACCENT;
	NAME="\\t";			TOKEN=ACCENT;
	NAME="\\H";			TOKEN=ACCENT;
	NAME="\\u";			TOKEN=ACCENT;
	NAME="\\d";			TOKEN=ACCENT;
	NAME="\\v";			TOKEN=ACCENT;
	NAME="\\c";			TOKEN=ACCENT;

	NAME="\\def";			TOKEN=DEF;
	NAME="\\gdef";			TOKEN=DEF;
	NAME="\\edef";			TOKEN=DEF;
	NAME="\\xdef";			TOKEN=DEF;

	NAME="\\toksdef";		TOKEN=ASSIGN;

	NAME="\\catcode";		TOKEN=CATCODE;
	NAME="\\mathcode";		TOKEN=CATCODE;
	NAME="\\delcode";		TOKEN=CATCODE;
	NAME="\\sfcode";		TOKEN=CATCODE;

	NAME="\\let";			TOKEN=ASSIGN;
	NAME="\\chardef";		TOKEN=ASSIGN;
	NAME="\\mathchardef";		TOKEN=ASSIGN;
	NAME="\\countdef";		TOKEN=ASSIGN;
	NAME="\\dimendef";		TOKEN=ASSIGN;
	NAME="\\skipdef";		TOKEN=ASSIGN;
	NAME="\\muskipdef";		TOKEN=ASSIGN;

	NAME="\\read";			TOKEN=READ;
	NAME="\\setbox";		TOKEN=SETBOX;
	NAME="\\font";			TOKEN=FONT;

	NAME="\\count";			TOKEN=REGISTER;
	NAME="\\dimen";			TOKEN=REGISTER;
	NAME="\\skip";			TOKEN=REGISTER;
	NAME="\\muskip";		TOKEN=REGISTER;
	NAME="\\toks";			TOKEN=REGISTER;

	NAME="\\advance";		TOKEN=OPERATION;
	NAME="\\multiply";		TOKEN=OPERATION;
	NAME="\\divide";		TOKEN=OPERATION;

	NAME="\\pretolerance";		TOKEN=INT_PAR;
	NAME="\\tolerance";		TOKEN=INT_PAR;
	NAME="\\hbadness";		TOKEN=INT_PAR;
	NAME="\\vbadness";		TOKEN=INT_PAR;
	NAME="\\linepenalty";		TOKEN=INT_PAR;
	NAME="\\hyphenpenalty";		TOKEN=INT_PAR;
	NAME="\\exhyphenpenalty";	TOKEN=INT_PAR;
	NAME="\\binoppenalty";		TOKEN=INT_PAR;
	NAME="\\relpenalty";		TOKEN=INT_PAR;
	NAME="\\clubpenalty";		TOKEN=INT_PAR;
	NAME="\\widowpenalty";		TOKEN=INT_PAR;
	NAME="\\displaywidowpenalty";	TOKEN=INT_PAR;
	NAME="\\brokenpenalty";		TOKEN=INT_PAR;
	NAME="\\predisplaypenalty";	TOKEN=INT_PAR;
	NAME="\\postdisplaypenalty";	TOKEN=INT_PAR;
	NAME="\\interlinepenalty";	TOKEN=INT_PAR;
	NAME="\\floatingpenalty";	TOKEN=INT_PAR;
	NAME="\\outputpenalty";		TOKEN=INT_PAR;
	NAME="\\doublehyphendemerits";	TOKEN=INT_PAR;
	NAME="\\finalhyphendemerits";	TOKEN=INT_PAR;
	NAME="\\adjdemerits";		TOKEN=INT_PAR;
	NAME="\\looseness";		TOKEN=INT_PAR;
	NAME="\\pausing";		TOKEN=INT_PAR;
	NAME="\\tracingonline";		TOKEN=INT_PAR;
	NAME="\\tracingmacros";		TOKEN=INT_PAR;
	NAME="\\tracingstats";		TOKEN=INT_PAR;
	NAME="\\tracingparagraphs";	TOKEN=INT_PAR;
	NAME="\\tracingpages";		TOKEN=INT_PAR;
	NAME="\\tracingoutput";		TOKEN=INT_PAR;
	NAME="\\tracinglostchars";	TOKEN=INT_PAR;
	NAME="\\tracingcommands";	TOKEN=INT_PAR;
	NAME="\\tracingrestores";	TOKEN=INT_PAR;
	NAME="\\uchyph";		TOKEN=INT_PAR;
	NAME="\\globaldefs";		TOKEN=INT_PAR;
	NAME="\\defaulthyphenchar";	TOKEN=INT_PAR;
	NAME="\\defaultskewchar";	TOKEN=INT_PAR;
	NAME="\\escapechar";		TOKEN=INT_PAR;
	NAME="\\endlinechar";		TOKEN=INT_PAR;
	NAME="\\newlinechar";		TOKEN=INT_PAR;
	NAME="\\maxdeadcycles";		TOKEN=INT_PAR;
	NAME="\\hangafter";		TOKEN=INT_PAR;
	NAME="\\fam";			TOKEN=INT_PAR;
	NAME="\\mag";			TOKEN=INT_PAR;
	NAME="\\delimiterfactor";	TOKEN=INT_PAR;
	NAME="\\time";			TOKEN=INT_PAR;
	NAME="\\day";			TOKEN=INT_PAR;
	NAME="\\month";			TOKEN=INT_PAR;
	NAME="\\year";			TOKEN=INT_PAR;
	NAME="\\showboxbreadth";	TOKEN=INT_PAR;
	NAME="\\showboxdepth";		TOKEN=INT_PAR;

	NAME="\\hfuzz";			TOKEN=DIMEN_PAR;
	NAME="\\vfuzz";			TOKEN=DIMEN_PAR;
	NAME="\\overfullrule";		TOKEN=DIMEN_PAR;
	NAME="\\hsize";			TOKEN=DIMEN_PAR;
	NAME="\\vsize";			TOKEN=DIMEN_PAR;
	NAME="\\maxdepth";		TOKEN=DIMEN_PAR;
	NAME="\\splitmaxdepth";		TOKEN=DIMEN_PAR;
	NAME="\\boxmaxdepth";		TOKEN=DIMEN_PAR;
	NAME="\\lineskiplimit";		TOKEN=DIMEN_PAR;
	NAME="\\delimitershortfall";	TOKEN=DIMEN_PAR;
	NAME="\\nulldelimiterspace";	TOKEN=DIMEN_PAR;
	NAME="\\scriptspace";		TOKEN=DIMEN_PAR;
	NAME="\\mathsurround";		TOKEN=DIMEN_PAR;
	NAME="\\predisplaysize";	TOKEN=DIMEN_PAR;
	NAME="\\displaywidth";		TOKEN=DIMEN_PAR;
	NAME="\\displayindent";		TOKEN=DIMEN_PAR;
	NAME="\\parindent";		TOKEN=DIMEN_PAR;
	NAME="\\hangindent";		TOKEN=DIMEN_PAR;
	NAME="\\hoffset";		TOKEN=DIMEN_PAR;
	NAME="\\voffset";		TOKEN=DIMEN_PAR;

	NAME="\\baselineskip";		TOKEN=GLUE_PAR;
	NAME="\\lineskip";		TOKEN=GLUE_PAR;
	NAME="\\parskip";		TOKEN=GLUE_PAR;
	NAME="\\abovedisplayskip";	TOKEN=GLUE_PAR;
	NAME="\\abovedisplayshortskip";	TOKEN=GLUE_PAR;
	NAME="\\belowdisplayskip";	TOKEN=GLUE_PAR;
	NAME="\\belowdisplayshortskip";	TOKEN=GLUE_PAR;
	NAME="\\leftskip";		TOKEN=GLUE_PAR;
	NAME="\\rightskip";		TOKEN=GLUE_PAR;
	NAME="\\topskip";		TOKEN=GLUE_PAR;
	NAME="\\splittoskip";		TOKEN=GLUE_PAR;
	NAME="\\tabskip";		TOKEN=GLUE_PAR;
	NAME="\\spaceskip";		TOKEN=GLUE_PAR;
	NAME="\\xspaceskip";		TOKEN=GLUE_PAR;
	NAME="\\parfillskip";		TOKEN=GLUE_PAR;

	NAME="\\thinmuskip";		TOKEN=MUGLUE_PAR;
	NAME="\\medmuskip";		TOKEN=MUGLUE_PAR;
	NAME="\\thickmuskip";		TOKEN=MUGLUE_PAR;

	NAME="\\output";		TOKEN=TOKEN_PAR;
	NAME="\\everypar";		TOKEN=TOKEN_PAR;
	NAME="\\everymath";		TOKEN=TOKEN_PAR;
	NAME="\\everydisplay";		TOKEN=TOKEN_PAR;
	NAME="\\everyhbox";		TOKEN=TOKEN_PAR;
	NAME="\\everyvbox";		TOKEN=TOKEN_PAR;
	NAME="\\everyjob";		TOKEN=TOKEN_PAR;
	NAME="\\everycr";		TOKEN=TOKEN_PAR;
	NAME="\\errhelp";		TOKEN=TOKEN_PAR;

	NAME="\\TeX";			TOKEN=H_COMMAND;
	NAME="\\LaTeX";			TOKEN=H_COMMAND;

	NAME="\\dag";			TOKEN=H_COMMAND;
	NAME="\\ddag";			TOKEN=H_COMMAND;
	NAME="\\S";			TOKEN=H_COMMAND;
	NAME="\\P";			TOKEN=H_COMMAND;
	NAME="\\copyright";		TOKEN=H_COMMAND;
	NAME="\\pounds";		TOKEN=H_COMMAND;

	NAME="\\begin";			TOKEN=BGIN;
	NAME="\\end";			TOKEN=END;

	NAME="\\input";			TOKEN=INCLUSION;
	NAME="\\include";		TOKEN=INCLUSION;
	NAME="\\includeonly";		TOKEN=INCLUDEONLY;

	NAME="math";			TOKEN=MATHENV;
	NAME="math*";			TOKEN=MATHENV;
	NAME="displaymath";		TOKEN=MATHENV;
	NAME="displaymath*";		TOKEN=MATHENV;
	NAME="equation";		TOKEN=MATHENV;
	NAME="equation*";		TOKEN=MATHENV;
	NAME="eqnarray";		TOKEN=MATHENV;
	NAME="eqnarray*";		TOKEN=MATHENV;

	NAME="\\\\";			TOKEN=HO_COMMAND;
	NAME="\\\\*";			TOKEN=HO_COMMAND;

	NAME="\\today";			TOKEN=H_COMMAND;

	NAME="\\noindent";		TOKEN=H_COMMAND;
	NAME="\\indent";		TOKEN=H_COMMAND;
	NAME="\\par";			TOKEN=H_COMMAND;
	NAME="\\linewidth";		TOKEN=LATEX_PAR;
	NAME="\\baselinestretch";	TOKEN=LATEX_PAR;

	NAME="\\footnote";		TOKEN=KO1_COMMAND;
	NAME="\\footnotemark";		TOKEN=HO_COMMAND;
	NAME="\\footnotetext";		TOKEN=KO1_COMMAND;
	NAME="\\footnotesep";		TOKEN=H_COMMAND;
	NAME="\\footnoterule";		TOKEN=H_COMMAND;

	NAME="\\part";			TOKEN=KO1_COMMAND;
	NAME="\\chapter";		TOKEN=KO1_COMMAND;
	NAME="\\section";		TOKEN=KO1_COMMAND;
	NAME="\\subsection";		TOKEN=KO1_COMMAND;
	NAME="\\subsubsection";		TOKEN=KO1_COMMAND;
	NAME="\\paragraph";		TOKEN=KO1_COMMAND;
	NAME="\\subparagraph";		TOKEN=KO1_COMMAND;

	NAME="\\part*";			TOKEN=K1_COMMAND;
	NAME="\\chapter*";		TOKEN=K1_COMMAND;
	NAME="\\section*";		TOKEN=K1_COMMAND;
	NAME="\\subsection*";		TOKEN=K1_COMMAND;
	NAME="\\subsubsection*";	TOKEN=K1_COMMAND;
	NAME="\\paragraph*";		TOKEN=K1_COMMAND;
	NAME="\\subparagraph*";		TOKEN=K1_COMMAND;

	NAME="\\appendix";		TOKEN=H_COMMAND;
	NAME="\\tableofcontents";	TOKEN=H_COMMAND;
	NAME="\\listoffigures";		TOKEN=H_COMMAND;
	NAME="\\listoftables";		TOKEN=H_COMMAND;

	NAME="\\addcontentsline";	TOKEN=H3_COMMAND;
	NAME="\\addtocontents";		TOKEN=H2_COMMAND;

	NAME="\\documentstyle";		TOKEN=HO1_COMMAND;
	NAME="\\bibindent";		TOKEN=LATEX_PAR;
	NAME="\\columnsep";		TOKEN=LATEX_PAR;
	NAME="\\columnseprule";		TOKEN=LATEX_PAR;
	NAME="\\mathindent";		TOKEN=LATEX_PAR;

	NAME="\\pagestyle";		TOKEN=H1_COMMAND;
	NAME="\\thispagestyle";		TOKEN=H_COMMAND;
	NAME="\\markright";		TOKEN=H1_COMMAND;
	NAME="\\markboth";		TOKEN=H2_COMMAND;
	NAME="\\pagenumbering";		TOKEN=H1_COMMAND;
	NAME="\\twocolumn";		TOKEN=HO_COMMAND;
	NAME="\\onecolumn";		TOKEN=H_COMMAND;
	NAME="\\oddsidemargin";		TOKEN=LATEX_PAR;
	NAME="\\evensidemargin";	TOKEN=LATEX_PAR;
	NAME="\\topmargin";		TOKEN=LATEX_PAR;
	NAME="\\headheight";		TOKEN=LATEX_PAR;
	NAME="\\headsep";		TOKEN=LATEX_PAR;
	NAME="\\textheight";		TOKEN=LATEX_PAR;
	NAME="\\textwidth";		TOKEN=LATEX_PAR;
	NAME="\\footheight";		TOKEN=LATEX_PAR;
	NAME="\\footskip";		TOKEN=LATEX_PAR;

	NAME="\\maketitle";		TOKEN=H_COMMAND;
	NAME="\\title";			TOKEN=K1_COMMAND;
	NAME="\\author";		TOKEN=K1_COMMAND;
	NAME="\\date";			TOKEN=K1_COMMAND;
	NAME="\\thanks";		TOKEN=K1_COMMAND;

	NAME="document";		TOKEN=TEXTENV;
	NAME="abstract";		TOKEN=TEXTENV;
	NAME="titlepage";		TOKEN=TEXTENV;
	NAME="quote";			TOKEN=TEXTENV;
	NAME="quotation";		TOKEN=TEXTENV;
	NAME="verse";			TOKEN=TEXTENV;
	NAME="itemize";			TOKEN=TEXTENV;
	NAME="enumerate";		TOKEN=TEXTENV;
	NAME="description";		TOKEN=TEXTENV;
	NAME="em";			TOKEN=TEXTENV;

	NAME="\\item";			TOKEN=HO_COMMAND;

	NAME="list";			TOKEN=LISTENV;
	NAME="\\topsep";		TOKEN=LATEX_PAR;
	NAME="\\partopsep";		TOKEN=LATEX_PAR;
	NAME="\\itemsep";		TOKEN=LATEX_PAR;
	NAME="\\parsep";		TOKEN=LATEX_PAR;
	NAME="\\leftmargin";		TOKEN=LATEX_PAR;
	NAME="\\rightmargin";		TOKEN=LATEX_PAR;
	NAME="\\listparindent";		TOKEN=LATEX_PAR;
	NAME="\\itemindent";		TOKEN=LATEX_PAR;
	NAME="\\labelsep";		TOKEN=LATEX_PAR;
	NAME="\\labelwidth";		TOKEN=LATEX_PAR;
	NAME="\\makelabel";		TOKEN=H1_COMMAND;
	NAME="\\usecounter";		TOKEN=H1_COMMAND;
	NAME="trivlist";		TOKEN=LISTENV;

	NAME="\\verb";			TOKEN=VERB;
	NAME="\\verb*";			TOKEN=VERB;
	NAME="verbatim";		TOKEN=VERBATIM;
	NAME="verbatim*";		TOKEN=VERBATIM;

	NAME="\\newcommand";		TOKEN=LATEX_DEF;
	NAME="\\renewcommand";		TOKEN=LATEX_DEF;

	NAME="\\newenvironment";	TOKEN=LATEX_DEFENV;
	NAME="\\renewenvironment";	TOKEN=LATEX_DEFENV;

	NAME="\\newtheorem";		TOKEN=H2O_COMMAND;
	NAME="\\renewtheorem";		TOKEN=H1O1_COMMAND;

	NAME="\\newcounter";		TOKEN=H1O_COMMAND;
	NAME="\\setcounter";		TOKEN=H2_COMMAND;
	NAME="\\addtocounter";		TOKEN=H2_COMMAND;

	NAME="\\value";			TOKEN=H1_COMMAND;
	NAME="\\arabic";		TOKEN=H1_COMMAND;
	NAME="\\roman";			TOKEN=H1_COMMAND;
	NAME="\\Roman";			TOKEN=H1_COMMAND;
	NAME="\\alph";			TOKEN=H1_COMMAND;
	NAME="\\Alph";			TOKEN=H1_COMMAND;
	NAME="\\fnsymbol";		TOKEN=H1_COMMAND;
	NAME="\\stepcounter";		TOKEN=H1_COMMAND;
	NAME="\\refstepcounter";	TOKEN=H1_COMMAND;

	NAME="figure";			TOKEN=FIGENV;
	NAME="figure*";			TOKEN=FIGENV;
	NAME="table";			TOKEN=FIGENV;
	NAME="table*";			TOKEN=FIGENV;

	NAME="\\caption";		TOKEN=KO1_COMMAND;

	NAME="\\topfraction";		TOKEN=LATEX_PAR;
	NAME="\\bottomfraction";	TOKEN=LATEX_PAR;
	NAME="\\textfraction";		TOKEN=LATEX_PAR;
	NAME="\\floatpagefraction";	TOKEN=LATEX_PAR;
	NAME="\\dbltopfraction";	TOKEN=LATEX_PAR;
	NAME="\\dblfloatpagefraction";	TOKEN=LATEX_PAR;
	NAME="\\floatsep";		TOKEN=LATEX_PAR;
	NAME="\\textfloatsep";		TOKEN=LATEX_PAR;
	NAME="\\intextsep";		TOKEN=LATEX_PAR;
	NAME="\\dblfloatsep";		TOKEN=LATEX_PAR;
	NAME="\\dbltextfloatsep";	TOKEN=LATEX_PAR;

	NAME="\\marginpar";		TOKEN=HO1_COMMAND;
	NAME="\\reversemarginpar";	TOKEN=H_COMMAND;
	NAME="\\normalmarginpar";	TOKEN=H_COMMAND;
	NAME="\\marginparwidth";	TOKEN=H_COMMAND;
	NAME="\\marginparsep";		TOKEN=H_COMMAND;
	NAME="\\marginparpush";		TOKEN=H_COMMAND;

	NAME="tabbing";			TOKEN=TABBENV;

	NAME="array";			TOKEN=TABUENV;
	NAME="array*";			TOKEN=TABUENV;
	NAME="tabular";			TOKEN=TABUENV;
	NAME="tabular*";		TOKEN=TABUENV;

	NAME="\\multicolumn";		TOKEN=H3_COMMAND;
	NAME="\\vline";			TOKEN=H_COMMAND;
	NAME="\\hline";			TOKEN=H_COMMAND;
	NAME="\\cline";			TOKEN=H1_COMMAND;

	NAME="\\arraycolsep";		TOKEN=LATEX_PAR;
	NAME="\\tabcolsep";		TOKEN=LATEX_PAR;
	NAME="\\arrayrulewidth";	TOKEN=LATEX_PAR;
	NAME="\\doublerulesep";		TOKEN=LATEX_PAR;
	NAME="\\arraystretch";		TOKEN=LATEX_PAR;

	NAME="\\label";			TOKEN=H1_COMMAND;
	NAME="\\ref";			TOKEN=H1_COMMAND;
	NAME="\\pageref";		TOKEN=H1_COMMAND;

	NAME="\\bibliography";		TOKEN=H1_COMMAND;
	NAME="thebibliography";		TOKEN=BIBLENV;
	NAME="\\bibitem";		TOKEN=HO1_COMMAND;
	NAME="\\cite";			TOKEN=HO1_COMMAND;
	NAME="\\nocite";		TOKEN=H1_COMMAND;

	NAME="theindex";		TOKEN=INDENV;
	NAME="\\makeindex";		TOKEN=H_COMMAND;
	NAME="\\makeglossary";		TOKEN=H_COMMAND;
	NAME="\\index";			TOKEN=K1_COMMAND;
	NAME="\\glossary";		TOKEN=K1_COMMAND;

	NAME="\\typeout";		TOKEN=H1_COMMAND;
	NAME="\\typein";		TOKEN=HO1_COMMAND;

	NAME="\\linebreak";		TOKEN=HO_COMMAND;
	NAME="\\nolinebreak";		TOKEN=HO_COMMAND;

	NAME="\\newline";		TOKEN=H_COMMAND;
	NAME="\\hyphenation";		TOKEN=H1_COMMAND;
	NAME="\\sloppy";		TOKEN=H_COMMAND;
	NAME="\\fussy";			TOKEN=H_COMMAND;

	NAME="sloppypar";		TOKEN=SLOPENV;

	NAME="\\pagebreak";		TOKEN=HO_COMMAND;
	NAME="\\nopagebreak";		TOKEN=HO_COMMAND;
	NAME="\\samepage";		TOKEN=H_COMMAND;
	NAME="\\newpage";		TOKEN=H_COMMAND;
	NAME="\\clearpage";		TOKEN=H_COMMAND;
	NAME="\\cleardoublepage";	TOKEN=H_COMMAND;

	NAME="\\fill";			TOKEN=H_COMMAND;
	NAME="\\stretch";		TOKEN=H1_COMMAND;
	NAME="\\newlength";		TOKEN=H1_COMMAND;
	NAME="\\setlength";		TOKEN=H2_COMMAND;
	NAME="\\addtolength";		TOKEN=H2_COMMAND;
	NAME="\\settowidth";		TOKEN=H2_COMMAND;

	NAME="\\hspace";		TOKEN=H1_COMMAND;
	NAME="\\hspace*";		TOKEN=H1_COMMAND;
	NAME="\\vspace";		TOKEN=H1_COMMAND;
	NAME="\\vspace*";		TOKEN=H1_COMMAND;
	NAME="\\bigskip";		TOKEN=H_COMMAND;
	NAME="\\medskip";		TOKEN=H_COMMAND;
	NAME="\\smallskip";		TOKEN=H_COMMAND;
	NAME="\\addvspace";		TOKEN=H1_COMMAND;

	NAME="\\mbox";			TOKEN=BOX;
	NAME="\\hbox";			TOKEN=BOX;
	NAME="\\vbox";			TOKEN=BOX;
	NAME="\\htop";			TOKEN=BOX;
	NAME="\\fbox";			TOKEN=BOX;

	NAME="\\makebox";		TOKEN=HOO1_COMMAND;
	NAME="\\framebox";		TOKEN=HOO1_COMMAND;
	NAME="\\newsavebox";		TOKEN=H1_COMMAND;
	NAME="\\sbox";			TOKEN=H2_COMMAND;
	NAME="\\savebox";		TOKEN=H1OO1_COMMAND;
	NAME="\\usebox";		TOKEN=H1_COMMAND;
	NAME="\\parbox";		TOKEN=HO2_COMMAND;

	NAME="minipage";		TOKEN=MINIENV;
	NAME="\\rule";			TOKEN=HO2_COMMAND;
	NAME="\\raisebox";		TOKEN=H1O1O_COMMAND;

	NAME="\\fboxrule";		TOKEN=LATEX_PAR;
	NAME="\\fboxsep";		TOKEN=LATEX_PAR;

	NAME="picture";			TOKEN=PICTENV;
	
	NAME="\\rm";			TOKEN=H_COMMAND;
	NAME="\\em";			TOKEN=H_COMMAND;
	NAME="\\bf";			TOKEN=H_COMMAND;
	NAME="\\it";			TOKEN=H_COMMAND;
	NAME="\\sl";			TOKEN=H_COMMAND;
	NAME="\\sf";			TOKEN=H_COMMAND;
	NAME="\\sc";			TOKEN=H_COMMAND;
	NAME="\\tt";			TOKEN=H_COMMAND;

	NAME="\\tiny";			TOKEN=H_COMMAND;
	NAME="\\small";			TOKEN=H_COMMAND;
	NAME="\\large";			TOKEN=H_COMMAND;
	NAME="\\huge";			TOKEN=H_COMMAND;
	NAME="\\scriptsize";		TOKEN=H_COMMAND;
	NAME="\\normalsize";		TOKEN=H_COMMAND;
	NAME="\\Large";			TOKEN=H_COMMAND;
	NAME="\\Huge";			TOKEN=H_COMMAND;
	NAME="\\footnotesize";		TOKEN=H_COMMAND;
	NAME="\\LARGE";			TOKEN=H_COMMAND;

	NAME="\\quad";			TOKEN=H_COMMAND;
	NAME="\\qquad";			TOKEN=H_COMMAND;
	NAME="\\dots";			TOKEN=H_COMMAND;
	NAME="\\ldots";			TOKEN=H_COMMAND;
	NAME="\\centering";		TOKEN=H_COMMAND;
	NAME="\\raggedright";		TOKEN=H_COMMAND;
	NAME="\\raggedleft";		TOKEN=H_COMMAND;
	NAME="\\break";			TOKEN=H_COMMAND;
	NAME="\\kill";			TOKEN=H_COMMAND;

	NAME="\\newfont";		TOKEN=H2_COMMAND;
	NAME="\\symbol";		TOKEN=H1_COMMAND;
	NAME="\\load";			TOKEN=H2_COMMAND;

	NAME="\\displaystyle";		TOKEN=H_COMMAND;
	NAME="\\textstyle";		TOKEN=H_COMMAND;
	NAME="\\scriptstyle";		TOKEN=H_COMMAND;
	NAME="\\scriptscriptstyle";	TOKEN=H_COMMAND;
	NAME="\\boldmath";		TOKEN=H_COMMAND;
	NAME="\\unboldmath";		TOKEN=H_COMMAND;

	NAME="\\dotfill";		TOKEN=H_COMMAND;

	NAME="\\line";			TOKEN=H1_COMMAND;
	NAME="\\hfil";			TOKEN=H_COMMAND;
	NAME="\\hfill";			TOKEN=H_COMMAND;
	NAME="\\vfil";			TOKEN=H_COMMAND;
	NAME="\\vfill";			TOKEN=H_COMMAND;
	NAME="\\vskip";			TOKEN=H1_COMMAND;
	NAME="\\eject";			TOKEN=H_COMMAND;
	NAME="\\bye";			TOKEN=H_COMMAND;
	NAME="\\centerline";		TOKEN=H1_COMMAND;
	NAME="\\nopagenumbers";		TOKEN=H_COMMAND;

	NAME="$";			TOKEN=DOLLAR;
	NAME="$$";			TOKEN=DDOLLAR;
	NAME="\\(";			TOKEN=OPARE;
	NAME="\\)";			TOKEN=CPARE;
	NAME="\\[";			TOKEN=OBRAC;
	NAME="\\]";			TOKEN=CBRAC;

	n_symbol=n;
	/* sort list */
	qsort((char *)symbol, n_symbol, sizeof(symbol_t), symbol_tcmp);

	/* envrt names given with -e option */

	/* search for already existing names */
	for (i=0; i<n_envrt; i++) {
		s_fake.name=envrt[i];
		s_fake.token=UNKNOWN;
		r=(symbol_t *)
bsearch(&s_fake, symbol, n_symbol, sizeof(symbol_t), symbol_tcmp);
		if (r!=(symbol_t *)NULL) {
			r->token=MATHENV;
			envrt[i]=(char *)NULL;	
		}
	}

	/* add new names */
	n_adsymbol=0;
	for (i=0; i<n_envrt; i++) {
		if (envrt[i]!=(char *)NULL) {
			symbol[n].name=strdup(envrt[i]);
			symbol[n++].token=MATHENV;

			adsymbol[n_adsymbol].name=symbol[n].name;
			adsymbol[n_adsymbol++].token=MATHENV;
		}
	}
	n_symbol=n;
	qsort((char *)symbol, n_symbol, sizeof(symbol_t), symbol_tcmp);
}

/*
 * add a new symbol to list
 */
int add_symbol(s)
symbol_t *s;
{
	int i;

	symbol[n_symbol].name=strdup(s->name);
	symbol[n_symbol++].token=s->token;
	adsymbol[n_adsymbol].name=symbol[n_symbol-1].name;
	adsymbol[n_adsymbol++].token=s->token;

	qsort((char *)symbol, n_symbol, sizeof(symbol_t), symbol_tcmp);
	return(n_symbol);
}

/*
 * search command s in list
 */
int s_lookup(s)
char *s;
{
	int i, t;
	symbol_t s_fake, *r;

	s_fake.name=s;
	s_fake.token=UNKNOWN;

	r=(symbol_t *)
bsearch(&s_fake, symbol, n_symbol, sizeof(symbol_t), symbol_tcmp);

	if (r!=(symbol_t *)NULL) {
		t=r->token;
	} else {
		t=UNKNOWN;
		if (mode!=1) {
			add_symbol(&s_fake);
			if (d_unknown) {
				if (s[0]=='\\')
				fprintf(stderr, "unknown command: %s\n", s);
				else
				fprintf(stderr, "unknown keyword: %s\n", s);
			}
	}	}

	return (t);
}

/*
 * supplied yywrap function
 */
int yywrap()
{
	char *last_string;
	char last_char;

	fclose(*f_in);
	total_lines+=lineno;
	if (d_report) {
	if (strcmp("", f_name)!=0) {
		fprintf(stderr, "%s: %d lines\n", f_name, lineno);
	} }
	if (strcmp("", f_name)!=0)
		str_destroy(fich_name(f_read()));
#ifdef FLEX_SCANNER
	last_string=(f_read())->last_string;
#else
	last_char=(f_read())->last_char;
#endif
	lineno=fich_line(f_pop());
	if (d_fname==0) d_fname=-1;
	if (is_f_stack_empty()) {
		return(1);
	} else {
		*f_in=fich_fd(f_read());
		f_name=fich_name(f_read());
#ifdef FLEX_SCANNER
		if (last_string!=(char *)NULL) {
			tmp_buf=strdup(last_string);
			free(last_string);
		}
#else
		if (last_char!=(char)NULL) unput(last_char);
#endif
		/*yy_ch_buf[0]=last_char;*/
		/*lineno=fich_line(f_read());*/
		return(0);
	}
}



#ifdef FLEX_SCANNER
char *Input() {
	char *r;

	*yy_c_buf_p=yy_hold_char;
	r=strdup(yy_c_buf_p);	
	*yy_c_buf_p='\0';
	return(r);
}

/*
 * input function normally used with flex
 * yy_input1 is not a macro, but with flex input is bufferized
 */
int yy_input1(buf, max_size)
char *buf;
int max_size;
{
	int result;

	if ( (result = read( fileno(yyin), buf, max_size )) < 0 ) {
		perror((char *)NULL);
	    YY_FATAL_ERROR( "read() in flex scanner failed" );
	}
	return (result);
}

/*
 * input function used when, having finished to read an included
 * file, flex come back and retrieve the precedent file
 */
int yy_input2(buf, max_size)
char *buf;
int max_size;
{
	int l;

	l=strlen(tmp_buf);
	if (l>0) strcpy(buf, tmp_buf);
	free(tmp_buf);
	yy_input=yy_input1;
	return(l);
}

/*
 * this procedure is a portion of the lex.yy.c program generated by flex
 * its aim is to initialize the buffer before starting reading a new file
 * (it corresponds to action done by YY_NEW_FILE)
 */
inclusion_file()
{
	/* this is where we enter upon encountering an end-of-file and
	 * yywrap() indicating that we should continue processing
	 */

	/* we put in the '\n' and start reading from [1] so that an
	 * initial match-at-newline will be true.
	 */

	yy_ch_buf[0] = '\n';
	yy_n_chars = 1;

	/* we always need two end-of-buffer characters.  The first causes
	 * a transition to the end-of-buffer state.  The second causes
	 * a jam in that state.
	 */
	yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
	yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;

	yy_eof_has_been_seen = 0;

	yytext = yy_c_buf_p = &yy_ch_buf[1];
	yy_hold_char = *yy_c_buf_p;
	yy_init = 0;
}

#else

/*
 * read next input character
 */
char Input() {
	return input();
}

inclusion_file()
{}

#endif
