🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.bugs.4bsd
Article #14

Lex bug

#14
From: Charles Sandel
Date: Thu, 22 Jun 1989 22:57
39 lines
2480 bytes
One of our programmers found a bug in the 'lex' source.
The bug report follows.

    We get various error messages from Andrew's class.  I finally tracked
    down what was the problem: a bug in lex.  class uses lex for its
    lexical input, in particular to recognize the class keywords like
    InitializeObject and FinalizeObject.  InitializeObject was not being
    recognized.  Tracing through the state machine generated by lex and
    then used to parse the input, it turns out that there are *exactly*
    255 states in the state machine.  During construction, the states are
    listed as 0 to 255.  In cmd/lex/sub2.c, line 797, lex checks to see
    if it needs a byte (char) or larger quantity to store the states:

    fprintf(fout,"# define YYTYPE %s\n",stnum+1 > NCH ? "int" : "char");

    where NCH is 256 (number of characters).  Notice that stnum+1 is
    compared rather than stnum (number of states).  This is because the
    zero state is used as an error state, and the states 0..255 are shifted
    up by 1 to 1..256.  stnum is 255 so stnum+1 is 256.  stnum+1 is not
    greater than NCH (which is 256) since they are equal, and a char is
    then used for YYTYPE which holds the state number.  As a result, lex
    creates tables which store state 256 (old state 255+1) in a char.  This
    is, of course, zero, and the lexical token ending in that state is
    not recognized.  I will submit a bug report on this today.
    
    In fact this code is badly written in several respects.  First, the
    comparison should not be against NCH.  The value of NCH varies according
    to whether NLS (with an 8-bit character code) is used or not.  However
    the size of a number that can be stored in a char is dependent upon
    the size of the char, not whether a 7-bit or 8-bit character code is
    used.  Further, we want the smallest storage unit that will hold all
    the state values.  Thus the code should be:


    fprintf(fout,"# define YYTYPE %s\n",
               (stnum+1 <= 0xFF) ? "unsigned char" 
	       :  (stnum+1 <= 0xFFFF) ? "unsigned short" 
	       :   "unsigned long");
Technical Details
Message-ID: <2521@tuvalu.sw.mcc.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!milano!tuvalu!sandel

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!milano!tuvalu!sandel
From: sandel@tuvalu.sw.mcc.com (Charles Sandel)
Newsgroups: comp.bugs.4bsd,comp.bugs.sys5
Subject: Lex bug
Keywords: lex
Message-ID: <2521@tuvalu.sw.mcc.com>
Date: 22 Jun 89 22:57:16 GMT
Organization: MCC, Austin, TX
Lines: 39