www.pudn.com > LexYaccProgs.zip > KWTBL.PAS


 
(* KWTBL - prepare keyword tables for use in lexical analyzers 
 
   USAGE: kwtbl [output-file] 
 
   DESCRIPTION 
 
   KWTBL is a tiny utility that helps you prepare keyword tables for use 
   in lexical analyzers, such as yylex routines prepared with the TP Lex 
   program. 
 
   In languages with a large number of keywords it is often more efficient 
   to analyze the reserved words using a general pattern, and then use a 
   table lookup procedure to determine the actual code for the keyword. 
   Also, large keyword tables in a Lex grammar can easily cause TP Lex to 
   overflow; in such cases the KWTBL utility is useful. 
 
   KWTBL reads in a list of (keyword, code) pairs, sorts keywords alpha- 
   betically, and writes out two typed array constants, one containing 
   the keyword strings and the other containing the corresponding codes. 
   These tables may be accessed through a binary table lookup procedure 
   which is appended to the end of the output file. The code for the 
   table lookup procedure is assumed to be in the file 'KWTBL.COD' which 
   must be present either in the current directory or in the directory 
   from which KWTBL was executed; without this file, KWTBL does not 
   generate the table lookup procedure. 
 
   Consider a typical programming language with identifiers and certain 
   reserved words which look like identifiers. The corresponding rules 
   of your TP Lex program might look like: 
 
   if		return( _IF_ ); 
   while	return( _WHILE_ ); 
   ... 
   [A-Za-z]+	return( ID ); 
 
   Alternatively, you can use KWTBL to produce a keyword table lookup 
   procedure. The input to KWTBL will be something like: 
 
   if		_IF_ 
   while	_WHILE_ 
   ... 
 
   Each keyword entry is on a separate line, and keyword and corresponding 
   code are separated by whitespace (blanks and/or tabs). Empty lines are 
   ignored. You do not have to sort the keyword entries; KWTBL will do that 
   for you. The code for a keyword can actually be any character sequence 
   which denotes a legal constant integer expression. 
 
   From the keyword table, KWTBL produces two typed array constants: 
 
   const 
 
   nkws = ...;   { number of different keywords } 
   kwsize = ...; { maximum size of keywords } 
 
   kwtbl : array [ 1..nkws ] of String[ kwsize ] = ( 
     ..., 'if', ..., 'while', ... 
   ); 
 
   kwcod : array [ 1..nkws ] of Integer = ( 
     ..., _IF_, ..., _WHILE_, ... 
   ); 
 
   These tables may be accessed through the table lookup procedure (named 
   kwlookup in the standard version of the KWTBL.COD file). The corresponding 
   Lex code will now be: 
 
   [A-Za-z]+	if kwlookup( yytext, code ) then 
   		  return( code ) 
                else 
                  return( ID ); 
*) 
 
uses Dos; 
 
(* Quicksort: *) 
 
type 
 
OrderPredicate = function (i, j : Integer) : Boolean; 
SwapProc = procedure (i, j : Integer); 
 
procedure quicksort(lo, hi: Integer; 
                    less : OrderPredicate; 
                    swap : SwapProc); 
  (* derived from the quicksort routine in QSORT.PAS in the Turbo Pascal 
     distribution *) 
  procedure sort(l, r: Integer); 
    var i, j, k : Integer; 
    begin 
      i := l; j := r; k := (l+r) DIV 2; 
      repeat 
        while less(i, k) do inc(i); 
        while less(k, j) do dec(j); 
        if i<=j then 
          begin 
            swap(i, j); 
            if k=i then k := j (* pivot element swapped! *) 
            else if k=j then k := i; 
            inc(i); dec(j); 
          end; 
      until i>j; 
      if l' ') and (line[i]<>tab) do 
      begin 
        if length(kw)'' then 
        begin 
          inc( nkws ); 
          if nkws>maxkws then fatal( 'too many keywords' ); 
          split( line, kwtbl[ nkws ], kwcod[ nkws ] ); 
          if ( kwtbl[ nkws ]='' ) or ( kwcod[ nkws ] = '' ) then 
            begin 
              error( 'error in line '+intStr( lineno ) ); 
              dec( nkws ); 
            end 
	  else if length(kwtbl[nkws])>kwsize then 
	    kwsize := length(kwtbl[nkws]); 
        end; 
    end; 
  (* sort the keyword table: *) 
  quicksort( 1, nkws, less, swap ); 
  (* produce output code: *) 
  if nkws=0 then fatal( 'nothing to do' ); 
  writeln; 
  writeln( 'const' ); 
  writeln; 
  writeln('nkws = ', nkws, ';' ); 
  writeln('kwsize = ', kwsize, ';' ); 
  writeln; 
  writeln('kwtbl : array [ 1..nkws ] of String[ kwsize ] = (' ); 
  write( '  ' ); actcol := 3; 
  for i := 1 to nkws do 
    begin 
      if actcol+length(kwtbl[i])>79 then 
        begin 
          writeln; write( '  ' ); actcol := 3; 
        end; 
      write( '''', kwtbl[i], '''' ); inc( actcol, length( kwtbl[i] )+2 ); 
      if i79 then 
        begin 
          writeln; write( '  ' ); actcol := 3; 
        end; 
      write( kwcod[i] ); inc( actcol, length( kwcod[i] ) ); 
      if i0 then 
    begin 
      assign( codfile, path( paramStr(0) )+'KWTBL.COD' ); reset( codfile ); 
      if ioresult<>0 then halt; 
    end; 
  while not eof( codfile ) do 
    begin 
      readln( codfile, line ); 
      writeln( line ); 
    end; 
  close( codfile ); 
end.