/
CVS/
boards/CVS/
clans/
gmc/CVS/
help/CVS/
include/CVS/
players/
progs/CVS/
races/CVS/
system/CVS/
text/
text/CVS/
todo/
todo/CVS/
units/CVS/
{$I-}

unit LexLib;

(* Standard Lex library unit for TP Lex Version 3.0.
   2-11-91 AG *)

interface

uses
    fsys;

var

yyoutput : Text;        (* input and output file *)
yyfname : String;
yyline            : String;      (* current input line *)
yylineno, yycolno : Integer;     (* current input position *)
yytext            : String;      (* matched text (should be considered r/o) *)

function get_char : Char;
  (* obtain one character from the input file (null character at end-of-
     file) *)

procedure unget_char ( c : Char );
  (* return one character to the input file to be reread in subsequent calls
     to get_char *)

procedure put_char ( c : Char );
  (* write one character to the output file *)

procedure yyopen(fname : string);

(* Utility routines: *)

procedure echo;
  (* echoes the current match to the output stream *)

procedure yymore;
  (* append the next match to the current one *)

procedure yyless ( n : Integer );
  (* truncate yytext to size n and return the remaining characters to the
     input stream *)

procedure reject;
  (* reject the current match and execute the next one *)

  (* reject does not actually cause the input to be rescanned; instead,
     internal state information is used to find the next match. Hence
     you should not try to modify the input stream or the yytext variable
     when rejecting a match. *)

procedure return ( n : Integer );
procedure returnc ( c : Char );
  (* sets the return value of yylex *)

procedure start ( state : Integer );
  (* puts the lexical analyzer in the given start state; state=0 denotes
     the default start state, other values are user-defined *)

(* yywrap:

   The yywrap function is called by yylex at end-of-file (unless you have
   specified a rule matching end-of-file). You may redefine this routine
   in your Lex program to do application-dependent processing at end of
   file. In particular, yywrap may arrange for more input and return false
   in which case the yylex routine resumes lexical analysis. *)

function yywrap : Boolean;
  (* The default yywrap routine supplied here closes input and output files
     and returns true (causing yylex to terminate). *)

(* The following are the internal data structures and routines used by the
   lexical analyzer routine yylex; they should not be used directly. *)

var

yystate    : Integer; (* current state of lexical analyzer *)
yyactchar  : Char;    (* current character *)
yylastchar : Char;    (* last matched character (#0 if none) *)
yyrule     : Integer; (* matched rule *)
yyreject   : Boolean; (* current match rejected? *)
yydone     : Boolean; (* yylex return value set? *)
yyretval   : Integer; (* yylex return value *)

procedure yynew;
  (* starts next match; initializes state information of the lexical
     analyzer *)

procedure yyscan;
  (* gets next character from the input stream and updates yytext and
     yyactchar accordingly *)

procedure yymark ( n : Integer );
  (* marks position for rule no. n *)

procedure yymatch ( n : Integer );
  (* declares a match for rule number n *)

function yyfind ( var n : Integer ) : Boolean;
  (* finds the last match and the corresponding marked position and adjusts
     the matched string accordingly; returns:
     - true if a rule has been matched, false otherwise
     - n: the number of the matched rule *)

function yydefault : Boolean;
  (* executes the default action (copy character); returns true unless
     at end-of-file *)

procedure yyclear;
  (* reinitializes state information after lexical analysis has been
     finished *)

implementation

procedure fatal ( msg : String );
  (* writes a fatal error message and halts program *)
  begin
    writeln('LexLib: ', msg);
    halt(1);
  end(*fatal*);

(* I/O routines: *)

const nl = #10;  (* newline character *)
      max_chars = 32768;
      max_inputs = 16;
      max_matches = 1024;
      max_rules   = 256;

var
  bufptr : Integer;
  buf    : array [1..max_chars] of Char;
  iptr : Integer;
  inputStack : array[1..max_inputs] of GFileReader;

function get_char : Char;
  var i : Integer;
  begin
    if (bufptr=0) and (not inputStack[iptr].eof()) then
      begin
      yylineno := inputStack[iptr].line;
      yyline := inputStack[iptr].readLine();

      yycolno := 1;
      buf[1] := nl;
      for i := 1 to length(yyline) do
        buf[i+1] := yyline[length(yyline)-i+1];
      inc(bufptr, length(yyline)+1);
      end;

    if bufptr>0 then
      begin
        get_char := buf[bufptr];
        dec(bufptr);
        inc(yycolno);
      end
    else
      get_char := #0;
  end(*get_char*);

procedure unget_char ( c : Char );
  begin
    if bufptr=max_chars then fatal('input buffer overflow');
    inc(bufptr);
    dec(yycolno);
    buf[bufptr] := c;
  end(*unget_char*);

procedure put_char ( c : Char );
  begin
    (* if c=#0 then
      { ignore }
    else if c=nl then
      writeln(yyoutput)
    else
      write(yyoutput, c) *)
  end(*put_char*);

procedure yyopen(fname : string);
begin
  inc(iptr);

  try
    inputStack[iptr] := GFileReader.Create(fname);
  except
    writeln('Could not open ', fname);
    exit;
  end;

  yyfname := inputStack[iptr].fname;

	yylineno := 0;
end;


var
	yystext            : String;
	yysstate, yylstate : Integer;
	yymatches          : Integer;
	yystack            : array [1..max_matches] of Integer;
	yypos              : array [1..max_rules] of Integer;
	yysleng            : Byte;

(* Utilities: *)

procedure echo;
  var i : Integer;
  begin
    for i := 1 to length(yytext) do
      put_char(yytext[i])
  end(*echo*);

procedure yymore;
  begin
    yystext := yytext;
  end(*yymore*);

procedure yyless ( n : Integer );
  var i : Integer;
  begin
    for i := length(yytext) downto n+1 do
      unget_char(yytext[i]);

    setlength(yytext, n);
  end(*yyless*);

procedure reject;
  var i : Integer;
  begin
    yyreject := true;
    for i := length(yytext)+1 to yysleng do
      yytext := yytext+get_char;
    dec(yymatches);
  end(*reject*);

procedure return ( n : Integer );
  begin
    yyretval := n;
    yydone := true;
  end(*return*);

procedure returnc ( c : Char );
  begin
    yyretval := ord(c);
    yydone := true;
  end(*returnc*);

procedure start ( state : Integer );
  begin
    yysstate := state;
  end(*start*);

(* yywrap: *)

function yywrap : Boolean;
  begin
    inputStack[iptr].Free;
    dec(iptr);

    if (iptr > 0) then
      begin
      yylineno := inputStack[iptr].line;
      yywrap := false;
			bufptr := 0;
      yyfname := inputStack[iptr].fname;
      end
    else
      yywrap := true;
  end(*yywrap*);

(* Internal routines: *)

procedure yynew;
  begin
    if yylastchar<>#0 then
      if yylastchar=nl then
        yylstate := 1
      else
        yylstate := 0;
    yystate := yysstate+yylstate;
    yytext  := yystext;
    yystext := '';
    yymatches := 0;
    yydone := false;
  end(*yynew*);

procedure yyscan;
  begin
    yyactchar := get_char;
    yytext := yytext + yyactchar;
  end(*yyscan*);

procedure yymark ( n : Integer );
  begin
    if n>max_rules then fatal('too many rules');
    yypos[n] := length(yytext);
  end(*yymark*);

procedure yymatch ( n : Integer );
  begin
    inc(yymatches);
    if yymatches>max_matches then fatal('match stack overflow');
    yystack[yymatches] := n;
  end(*yymatch*);

function yyfind ( var n : Integer ) : Boolean;
  begin
    yyreject := false;
    while (yymatches>0) and (yypos[yystack[yymatches]]=0) do
      dec(yymatches);
    if yymatches>0 then
      begin
        yysleng := length(yytext);
        n       := yystack[yymatches];
        yyless(yypos[n]);
        yypos[n] := 0;

        if length(yytext) > 0 then
          yylastchar := yytext[length(yytext)]
        else
          yylastchar := #0;
        yyfind := true;
      end
    else
      begin
        yyless(0);
        yylastchar := #0;
        yyfind := false;
      end
  end(*yyfind*);

function yydefault : Boolean;
  begin
    yyreject := false;
    yyactchar := get_char;
    if yyactchar<>#0 then
      begin
        put_char(yyactchar);
        yydefault := true;
      end
    else
      begin
        yylstate := 1;
        yydefault := false;
      end;
    yylastchar := yyactchar;
  end(*yydefault*);

procedure yyclear;
  begin
    bufptr := 0;
    yysstate := 0;
    yylstate := 1;
    yylastchar := #0;
    yytext := '';
    yystext := '';
  end(*yyclear*);

begin
{  yyopen(''); }
  assign(yyoutput, '');
  rewrite(yyoutput);
  yylineno := 0;
  iptr := 0;
  yyclear;
end(*LexLib*).