Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

lclscanline.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** scanline.c
00026 **
00027 **  MODULE DESCRIPTION:
00028 **
00029 **      This module scans one line of Larch C Interface Language (LCL) input at
00030 **      a time.
00031 **
00032 **      The input is source text, line at a time.   The output is a sequence
00033 **      of tokens, reported by call-out LSLScanFreshToken.
00034 **
00035 **      This organization allows implementation of line-at-a-time incremental
00036 **      scanning.  The incremental mechanism is in the driving module scan.c.
00037 **
00038 **      The main loop of the scanner keys on the leading character.
00039 **      Within the loop are actions which collect the rest of the
00040 **      token starting with the character.  Various careful hacks
00041 **      show up to disambiguate tokens that break the general pattern
00042 **      (Examples, \/ and /\).  White space is passed and the loop
00043 **      goes once again without calling LSLScanFreshToken ().
00044 **      The line ends with a null.
00045 **
00046 **  AUTHORS:
00047 **
00048 **    JPW, GAF, Yang Meng Tan
00049 */
00050 
00051 
00052 # include "lclintMacros.nf"
00053 # include "llbasic.h"
00054 # include "gram.h"
00055 # include "lclscan.h"
00056 # include "scanline.h"
00057 # include "lclscanline.h"
00058 # include "lcltokentable.h"
00059 # include "lclsyntable.h"
00060 
00061 /*@constant int CHARSIZE;@*/
00062 # define CHARSIZE    256                /* on an 8-bit machine  */
00063 
00064 /*@notfunction@*/
00065 # define LCLMOVECHAR() \
00066    do { *bufPtr++ = currentChar; currentChar = *currentLine++; \
00067         colNumber++; } while (FALSE)
00068 
00069 /*@notfunction@*/
00070 # define LOOKAHEADCHAR()      (*currentLine)
00071 
00072 /*@notfunction@*/
00073 # define LOOKAHEADTWICECHAR() (*(currentLine + 1))
00074 
00075 /*@constant static int MAXCHAR;@*/
00076 # define MAXCHAR     512        /* storage for a lexeme     */
00077 
00078 /*
00079 ** Printname for the TokenCode NOTTOKEN   (also 1st one reserved)
00080 ** Printname for the TokenCode BADTOKEN   (also last one reserved)
00081 */
00082 
00083 /*@constant static observer char *FIRSTRESERVEDNAME;@*/
00084 # define FIRSTRESERVEDNAME "?"
00085 
00086 /*
00087 ** The scanner establishes lexical boundaries by first switching            
00088 ** on the leading character of the pending lexeme.                          
00089 */
00090 
00091 typedef enum
00092 {
00093   STARTCNUM,                    /* First character of a C number. */
00094   STARTCNUMDOT,                 /* "." only starts a C number if digit follows*/
00095   STARTCSTR,                    /* First character of a C string. */
00096   STARTCCHAR,                   /* First character of a C character. */
00097   STARTWIDE,                    /* slash L starts both string and character. */
00098   STARTSLASH,                   /* "/" starts caret, comment comment, operator */
00099   STARTOTHER                    /* Everything else. */
00100 } StartCharType;
00101 
00102 static void ScanCComment (void);
00103 static void ScanEscape (void);
00104 static void ScanCString (void);
00105 static void ScanCChar (void);
00106 static void ScanCNumber (void);
00107 static void LocalUserError (/*@temp@*/ char *);
00108 
00109 /*
00110 ** Array to store character class defintions and record end-of-comment      
00111 ** characters.                                                              
00112 */
00113 
00114 static charClassData LCLcharClass[LASTCHAR + 1];
00115 
00116 /*
00117 ** Data shared between routines LCLScanLine, ScanCString, ScanCChar,        
00118 ** ScanCNumber.  LCLScanLine was getting too big for one routine and        
00119 ** passing this data was rather cumbersome.  Making this data global seemed 
00120 ** to be the simpliest solution.                                            
00121 */
00122 
00123 /* evs - sounds bogus to me! */
00124 
00125 static unsigned int colNumber;  
00126 static unsigned int startCol;   
00127 static char *currentLine;      
00128 static char currentChar;        
00129 static ltokenCode tokenCode;    
00130 static lsymbol tokenSym;        
00131 static char *bufPtr;            
00132 
00133 static bool inComment;  
00134 static /*@only@*/ ltoken commentTok;    
00135 static ltokenCode prevTokenCode; /* to disambiguate '        */
00136 
00137 static StartCharType startClass[CHARSIZE] =
00138 {
00139   STARTOTHER,                   /*      ^@                          00x */
00140   STARTOTHER,                   /*      ^a                          01x */
00141   STARTOTHER,                   /*      ^b                          02x */
00142   STARTOTHER,                   /*      ^c                          03x */
00143   STARTOTHER,                   /*      ^d                          04x */
00144   STARTOTHER,                   /*      ^e                          05x */
00145   STARTOTHER,                   /*      ^f                          06x */
00146   STARTOTHER,                   /*      ^g  BELL                    07x */
00147 
00148   STARTOTHER,                   /*      ^h  BACKSPACE               08x */
00149   STARTOTHER,                   /*      ^i  TAB                     09x */
00150   STARTOTHER,                   /*      ^j  NEWLINE                 0Ax */
00151   STARTOTHER,                   /*      ^k                          0Bx */
00152   STARTOTHER,                   /*      ^l  FORMFEED                0Cx */
00153   STARTOTHER,                   /*      ^m  RETURN                  0Dx */
00154   STARTOTHER,                   /*      ^n                          0Ex */
00155   STARTOTHER,                   /*      ^o                          0Fx */
00156 
00157   STARTOTHER,                   /*      ^p                          10x */
00158   STARTOTHER,                   /*      ^q                          11x */
00159   STARTOTHER,                   /*      ^r                          12x */
00160   STARTOTHER,                   /*      ^s                          13x */
00161   STARTOTHER,                   /*      ^t                          14x */
00162   STARTOTHER,                   /*      ^u                          15x */
00163   STARTOTHER,                   /*      ^v                          16x */
00164   STARTOTHER,                   /*      ^w                          17x */
00165 
00166   STARTOTHER,                   /*      ^x                          18x */
00167   STARTOTHER,                   /*      ^y                          19x */
00168   STARTOTHER,                   /*      ^z                          1Ax */
00169   STARTOTHER,                   /*      ^[ ESC                      1Bx */
00170   STARTOTHER,                   /*      ^slash                      1Cx */
00171   STARTOTHER,                   /*      ^]                          1Dx */
00172   STARTOTHER,                   /*      ^^                          1Ex */
00173   STARTOTHER,                   /*      ^_                          1Fx */
00174 
00175   STARTOTHER,                   /*      BLANK                       20x */
00176   STARTOTHER,                   /*      !                           21x */
00177   STARTCSTR,                    /*      "                           22x */
00178   STARTOTHER,                   /*      #                           23x */
00179   STARTOTHER,                   /*      $ (may be changed in reset) 24x */
00180   STARTOTHER,                   /*      %                           25x */
00181   STARTOTHER,                   /*      &                           26x */
00182   STARTCCHAR,                   /*      '                           27x */
00183 
00184   STARTOTHER,                   /*      (                           28x */
00185   STARTOTHER,                   /*      )                           29x */
00186   STARTOTHER,                   /*      *                           2Ax */
00187   STARTOTHER,                   /*      +                           2Bx */
00188   STARTOTHER,                   /*      ,                           2Cx */
00189   STARTOTHER,                   /*      -                           2Dx */
00190   STARTCNUMDOT,                 /*      .                           2Ex */
00191   STARTSLASH,                   /*      /                           2Fx */
00192 
00193   STARTCNUM,                    /*      0                           30x */
00194   STARTCNUM,                    /*      1                           31x */
00195   STARTCNUM,                    /*      2                           32x */
00196   STARTCNUM,                    /*      3                           33x */
00197   STARTCNUM,                    /*      4                           34x */
00198   STARTCNUM,                    /*      5                           35x */
00199   STARTCNUM,                    /*      6                           36x */
00200   STARTCNUM,                    /*      7                           37x */
00201 
00202   STARTCNUM,                    /*      8                           38x */
00203   STARTCNUM,                    /*      9                           39x */
00204   STARTOTHER,                   /*      :                           3Ax */
00205   STARTOTHER,                   /*      ;                           3Bx */
00206   STARTOTHER,                   /*      <                           3Cx */
00207   STARTOTHER,                   /*      =                           3Dx */
00208   STARTOTHER,                   /*      >                           3Ex */
00209   STARTOTHER,                   /*      ?                           3Fx */
00210 
00211   STARTOTHER,                   /*      @                           40x */
00212   STARTOTHER,                   /*      A                           41x */
00213   STARTOTHER,                   /*      B                           42x */
00214   STARTOTHER,                   /*      C                           43x */
00215   STARTOTHER,                   /*      D                           44x */
00216   STARTOTHER,                   /*      E                           45x */
00217   STARTOTHER,                   /*      F                           46x */
00218   STARTOTHER,                   /*      G                           47x */
00219 
00220   STARTOTHER,                   /*      H                           48x */
00221   STARTOTHER,                   /*      I                           49x */
00222   STARTOTHER,                   /*      J                           4Ax */
00223   STARTOTHER,                   /*      K                           4Bx */
00224   STARTOTHER,                   /*      L                           4Cx */
00225   STARTOTHER,                   /*      M                           4Dx */
00226   STARTOTHER,                   /*      N                           4Ex */
00227   STARTOTHER,                   /*      O                           4Fx */
00228 
00229   STARTOTHER,                   /*      P                           50x */
00230   STARTOTHER,                   /*      Q                           51x */
00231   STARTOTHER,                   /*      R                           52x */
00232   STARTOTHER,                   /*      S                           53x */
00233   STARTOTHER,                   /*      T                           54x */
00234   STARTOTHER,                   /*      U                           55x */
00235   STARTOTHER,                   /*      V                           56x */
00236   STARTOTHER,                   /*      W                           57x */
00237 
00238   STARTOTHER,                   /*      X                           58x */
00239   STARTOTHER,                   /*      Y                           59x */
00240   STARTOTHER,                   /*      Z                           5Ax */
00241   STARTOTHER,                   /*      [                           5Bx */
00242   STARTWIDE,                    /*      slash                       5Cx */
00243   STARTOTHER,                   /*      ]                           5Dx */
00244   STARTOTHER,                   /*      ^                           5Ex */
00245   STARTOTHER,                   /*      _                           5Fx */
00246 
00247   STARTOTHER,                   /*      `                           60x */
00248   STARTOTHER,                   /*      a                           61x */
00249   STARTOTHER,                   /*      b                           62x */
00250   STARTOTHER,                   /*      c                           63x */
00251   STARTOTHER,                   /*      d                           64x */
00252   STARTOTHER,                   /*      e                           65x */
00253   STARTOTHER,                   /*      f                           66x */
00254   STARTOTHER,                   /*      g                           67x */
00255 
00256   STARTOTHER,                   /*      h                           68x */
00257   STARTOTHER,                   /*      i                           69x */
00258   STARTOTHER,                   /*      j                           6Ax */
00259   STARTOTHER,                   /*      k                           6Bx */
00260   STARTOTHER,                   /*      l                           6Cx */
00261   STARTOTHER,                   /*      m                           6Dx */
00262   STARTOTHER,                   /*      n                           6Ex */
00263   STARTOTHER,                   /*      o                           6Fx */
00264 
00265   STARTOTHER,                   /*      p                           70x */
00266   STARTOTHER,                   /*      q                           71x */
00267   STARTOTHER,                   /*      r                           72x */
00268   STARTOTHER,                   /*      s                           73x */
00269   STARTOTHER,                   /*      t                           74x */
00270   STARTOTHER,                   /*      u                           75x */
00271   STARTOTHER,                   /*      v                           76x */
00272   STARTOTHER,                   /*      w                           77x */
00273 
00274   STARTOTHER,                   /*      x                           78x */
00275   STARTOTHER,                   /*      y                           79x */
00276   STARTOTHER,                   /*      z                           7Ax */
00277   STARTOTHER,                   /*      {                           7Dx */
00278   STARTOTHER,                   /*      |                           7Cx */
00279   STARTOTHER,                   /*      }                           7Dx */
00280   STARTOTHER,                   /*      ~                           7Ex */
00281   STARTOTHER,
00282   STARTOTHER                    /*      RUBOUT                      7Fx */
00283 };
00284 
00285 /*
00286 ** Given a character code, its status as part of an decimal escape sequence
00287 ** can be derived from this table.  Digits 0-9 allowed.
00288 */
00289 
00290 static bool isDigit[CHARSIZE] =
00291 {
00292   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00293   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00294   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00295   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00296   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00297   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00298   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00299   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00300   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
00301 };
00302 
00303 /*
00304  * Given a character code, its status as part of an octal escape sequence
00305  * can be derived from this table.  Digits 0-7 allowed.
00306  */
00307 
00308 static bool isOigit[CHARSIZE] =
00309 {
00310   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00311   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00312   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00313   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00314   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00315   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00316   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
00317   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
00318 };
00319 
00320 /*
00321  * Given a character code, its status as part of a hex escape sequence
00322  * can be derived from this table.  Digits, a-f, A-F allowed.
00323  */
00324 
00325 static bool isXigit[CHARSIZE] =
00326 {
00327   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00328   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00329   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00330 
00331   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00332   FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00333   TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00334 
00335   FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
00336   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00337   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00338 
00339   FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
00340   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00341   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
00342 };
00343 
00344 
00345 /*
00346  * Given a character code, its status as part of a C string
00347  * can be derived from this table.  Everything but quotes and newline
00348  * are allowed.
00349  */
00350 
00351 static bool isStrChar[CHARSIZE] =
00352 {
00353   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00354   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00355   TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00356   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00357   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00358   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE,
00359   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00360   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
00361 };
00362 
00363 /*
00364  * Given a character code, its status as part of a C Character
00365  * can be derived from this table.  Everything but quotes and newline
00366  * are allowed.
00367  */
00368 
00369 static bool isCharChar[CHARSIZE] =
00370 {
00371   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE,
00372   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00373   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, 
00374   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00375   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00376   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE,
00377   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
00378   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
00379 };
00380 
00381 /*
00382 ** Given a character code, its status as part of a string or character
00383 ** simple escape sequence ('slash'', 'slash"', 'slash?', 'slashslash', 
00384 ** 'slasha', 'slashb', 'slashf', 'slashn', 'slasht', and 'slashv')
00385 ** can be derived from this table.  ''', '"', '?', 'slash', 'a',
00386 ** 'b', 'f', 'n', 't', and 'v' are allowed.
00387 */
00388 
00389 static bool isSimpleEscape[CHARSIZE] =
00390 {
00391   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00392   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00393   FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00394   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
00395   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
00396   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE,
00397   FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE,
00398   FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
00399 };
00400 
00401 static bool reportEOL;          
00402 static bool reportComments;     
00403 static lsymbol firstReserved;  
00404 
00405 static char tokenBuffer[MAXCHAR];
00406 
00407 static const charClassData charClassDef[] =
00408 {
00409   /* Control characters */
00410 
00411   { SINGLECHAR, FALSE },                /*       0 NULL                     */
00412   { SINGLECHAR, FALSE },                /*       1 CTRL-A                   */
00413   { SINGLECHAR, FALSE },                /*       2 CTRL-B                   */
00414   { SINGLECHAR, FALSE },                /*       3 CTRL-C                   */
00415   { SINGLECHAR, FALSE },                /*       4 CTRL-D                   */
00416   { SINGLECHAR, FALSE },                /*       5 CTRL-E                   */
00417   { SINGLECHAR, FALSE },                /*       6 CTRL-F                   */
00418   { SINGLECHAR, FALSE },                /*       7 CTRL-G                   */
00419   { SINGLECHAR, FALSE },                /*       8 CTRL-H                   */
00420 
00421   /* defined formatting characters */
00422   { WHITECHAR, FALSE },                 /*       9 CTRL-I   TAB             */
00423   { CHC_NULL, TRUE },           /*      10 CTRL-J   EOL             */
00424 
00425   /* more control characters */
00426   { SINGLECHAR, FALSE },                /*      11 CTRL-K                   */
00427   { WHITECHAR, FALSE },                 /*      12 CTRL-L                   */
00428   { SINGLECHAR, FALSE },                /*      13 CTRL-M                   */
00429   { SINGLECHAR, FALSE },                /*      14 CTRL-N                   */
00430   { SINGLECHAR, FALSE },                /*      15 CTRL-O                   */
00431   { SINGLECHAR, FALSE },                /*      16 CTRL-P                   */
00432   { SINGLECHAR, FALSE },                /*      17 CTRL-Q                   */
00433   { SINGLECHAR, FALSE },                /*      18 CTRL-R                   */
00434   { SINGLECHAR, FALSE },                /*      19 CTRL-S                   */
00435   { SINGLECHAR, FALSE },                /*      20 CTRL-T                   */
00436   { SINGLECHAR, FALSE },                /*      21 CTRL-U                   */
00437   { SINGLECHAR, FALSE },                /*      22 CTRL-V                   */
00438   { SINGLECHAR, FALSE },                /*      23 CTRL-W                   */
00439   { SINGLECHAR, FALSE },                /*      24 CTRL-X                   */
00440   { SINGLECHAR, FALSE },                /*      25 CTRL-Y                   */
00441   { SINGLECHAR, FALSE },                /*      26 CTRL-Z                   */
00442   { SINGLECHAR, FALSE },                /*      27 CTRL-[   ESC             */
00443   { SINGLECHAR, FALSE },                /*      28 CTRL-slash   FS          */
00444   { SINGLECHAR, FALSE },                /*      29 CTRL-]   GS              */
00445   { SINGLECHAR, FALSE },                /*      30 CTRL-^   RS              */
00446   { SINGLECHAR, FALSE },                /*      31 CTRL-_   US              */
00447 
00448   /* Special printing characters */
00449   { WHITECHAR, FALSE },                 /*      32 space                    */
00450   { SINGLECHAR, FALSE },                /*      33 !                        */
00451   { SINGLECHAR, FALSE },                /*      34 "                        */
00452   { SINGLECHAR, FALSE },                /*      35 #                        */
00453   { SINGLECHAR, FALSE },                /*      36 $                        */
00454   { SINGLECHAR, FALSE },                /*      37 %                        */
00455   { SINGLECHAR, FALSE },                /*      38 &                        */
00456   { SINGLECHAR, FALSE },                /*      39 '                        */
00457 
00458   /* Reserved characters */
00459   { PERMCHAR, FALSE },                  /*      40 (                        */
00460   { PERMCHAR, FALSE },                  /*      41 )                        */
00461   { PERMCHAR, FALSE },                  /*      42 *                        */
00462   { OPCHAR, FALSE },                    /*      43 +                        */
00463   { PERMCHAR, FALSE },                  /*      44 ,                        */
00464   { OPCHAR, FALSE },                    /*      45 -                        */
00465   { OPCHAR, FALSE },                    /*      46 .                        */
00466   { OPCHAR, FALSE },                    /*      47 /                        */
00467 
00468 /* Numbers                                                          */
00469   { IDCHAR, FALSE },            /*      48 0                        */
00470   { IDCHAR, FALSE },            /*      49 1                        */
00471   { IDCHAR, FALSE },            /*      50 2                        */
00472   { IDCHAR, FALSE },            /*      51 3                        */
00473   { IDCHAR, FALSE },            /*      52 4                        */
00474   { IDCHAR, FALSE },            /*      53 5                        */
00475   { IDCHAR, FALSE },            /*      54 6                        */
00476   { IDCHAR, FALSE },            /*      55 7                        */
00477   { IDCHAR, FALSE },            /*      56 8                        */
00478   { IDCHAR, FALSE },            /*      57 9                        */
00479 
00480   /* More reserved and special printing characters                  */
00481   { PERMCHAR, FALSE },          /*      58 :                        */
00482   { PERMCHAR, FALSE },          /*      59;                         */
00483   { OPCHAR, FALSE },            /*      60 <                        */
00484   { OPCHAR, FALSE },            /*      61 =                        */
00485   { OPCHAR, FALSE },            /*      62 >                        */
00486   { SINGLECHAR, FALSE },        /*      63 ?                        */
00487   { SINGLECHAR, FALSE },        /*      64 @                        */
00488 
00489   /* Uppercase Alphabetics                                          */
00490   { IDCHAR, FALSE },            /*      65 A                        */
00491   { IDCHAR, FALSE },            /*      66 B                        */
00492   { IDCHAR, FALSE },            /*      67 C                        */
00493   { IDCHAR, FALSE },            /*      68 D                        */
00494   { IDCHAR, FALSE },            /*      69 E                        */
00495   { IDCHAR, FALSE },            /*      70 F                        */
00496   { IDCHAR, FALSE },            /*      71 G                        */
00497   { IDCHAR, FALSE },            /*      72 H                        */
00498   { IDCHAR, FALSE },            /*      73 I                        */
00499   { IDCHAR, FALSE },            /*      74 J                        */
00500   { IDCHAR, FALSE },            /*      75 K                        */
00501   { IDCHAR, FALSE },            /*      76 L                        */
00502   { IDCHAR, FALSE },            /*      77 M                        */
00503   { IDCHAR, FALSE },            /*      78 N                        */
00504   { IDCHAR, FALSE },            /*      79 O                        */
00505   { IDCHAR, FALSE },            /*      80 P                        */
00506   { IDCHAR, FALSE },            /*      81 Q                        */
00507   { IDCHAR, FALSE },            /*      82 R                        */
00508   { IDCHAR, FALSE },            /*      83 S                        */
00509   { IDCHAR, FALSE },            /*      84 T                        */
00510   { IDCHAR, FALSE },            /*      85 U                        */
00511   { IDCHAR, FALSE },            /*      86 V                        */
00512   { IDCHAR, FALSE },            /*      87 W                        */
00513   { IDCHAR, FALSE },            /*      88 X                        */
00514   { IDCHAR, FALSE },            /*      89 Y                        */
00515   { IDCHAR, FALSE },            /*      90 Z                        */
00516 
00517   /* Still more reserved and special printing characters            */
00518   { PERMCHAR, FALSE },          /*      91 [                        */
00519   { CHC_EXTENSION, FALSE },     /*      92 slash                    */
00520   { PERMCHAR, FALSE },          /*      93 ]                        */
00521   { SINGLECHAR, FALSE },        /*      94 ^                        */
00522   { IDCHAR, FALSE },            /*      95 _                        */
00523   { SINGLECHAR, FALSE },        /*      96 `                        */
00524 
00525   /* Lowercase alphabetics                                          */
00526   { IDCHAR, FALSE },            /*      97 a                        */
00527   { IDCHAR, FALSE },            /*      98 b                        */
00528   { IDCHAR, FALSE },            /*      99 c                        */
00529   { IDCHAR, FALSE },            /*      100 d                       */
00530   { IDCHAR, FALSE },            /*      101 e                       */
00531   { IDCHAR, FALSE },            /*      102 f                       */
00532   { IDCHAR, FALSE },            /*      103 g                       */
00533   { IDCHAR, FALSE },            /*      104 h                       */
00534   { IDCHAR, FALSE },            /*      105 i                       */
00535   { IDCHAR, FALSE },            /*      106 j                       */
00536   { IDCHAR, FALSE },            /*      107 k                       */
00537   { IDCHAR, FALSE },            /*      108 l                       */
00538   { IDCHAR, FALSE },            /*      109 m                       */
00539   { IDCHAR, FALSE },            /*      110 n                       */
00540   { IDCHAR, FALSE },            /*      111 o                       */
00541   { IDCHAR, FALSE },            /*      112 p                       */
00542   { IDCHAR, FALSE },            /*      113 q                       */
00543   { IDCHAR, FALSE },            /*      114 r                       */
00544   { IDCHAR, FALSE },            /*      115 s                       */
00545   { IDCHAR, FALSE },            /*      116 t                       */
00546   { IDCHAR, FALSE },            /*      117 u                       */
00547   { IDCHAR, FALSE },            /*      118 v                       */
00548   { IDCHAR, FALSE },            /*      119 w                       */
00549   { IDCHAR, FALSE },            /*      120 x                       */
00550   { IDCHAR, FALSE },            /*      121 y                       */
00551   { IDCHAR, FALSE },            /*      122 z                       */
00552 
00553   { SINGLECHAR, FALSE },        /*      123 {                       */
00554   { SINGLECHAR, FALSE },        /*      124 |                       */
00555   { SINGLECHAR, FALSE },        /*      125 }                       */
00556   { SINGLECHAR, FALSE },        /*      126 ~                       */
00557   { SINGLECHAR, FALSE },        /*      127 DEL                     */
00558 
00559   /* MCS - unused in English                                        */
00560   { SINGLECHAR, FALSE },        /*      128                         */
00561   { SINGLECHAR, FALSE },        /*      129                         */
00562   { SINGLECHAR, FALSE },        /*      130                         */
00563   { SINGLECHAR, FALSE },        /*      131                         */
00564   { SINGLECHAR, FALSE },        /*      132                         */
00565   { SINGLECHAR, FALSE },        /*      133                         */
00566   { SINGLECHAR, FALSE },        /*      134                         */
00567   { SINGLECHAR, FALSE },        /*      135                         */
00568   { SINGLECHAR, FALSE },        /*      136                         */
00569   { SINGLECHAR, FALSE },        /*      137                         */
00570   { SINGLECHAR, FALSE },        /*      138                         */
00571   { SINGLECHAR, FALSE },        /*      139                         */
00572   { SINGLECHAR, FALSE },        /*      140                         */
00573   { SINGLECHAR, FALSE },        /*      141                         */
00574   { SINGLECHAR, FALSE },        /*      142                         */
00575   { SINGLECHAR, FALSE },        /*      143                         */
00576   { SINGLECHAR, FALSE },        /*      144                         */
00577   { SINGLECHAR, FALSE },        /*      145                         */
00578   { SINGLECHAR, FALSE },        /*      146                         */
00579   { SINGLECHAR, FALSE },        /*      147                         */
00580   { SINGLECHAR, FALSE },        /*      148                         */
00581   { SINGLECHAR, FALSE },        /*      149                         */
00582   { SINGLECHAR, FALSE },        /*      150                         */
00583   { SINGLECHAR, FALSE },        /*      151                         */
00584   { SINGLECHAR, FALSE },        /*      152                         */
00585   { SINGLECHAR, FALSE },        /*      153                         */
00586   { SINGLECHAR, FALSE },        /*      154                         */
00587   { SINGLECHAR, FALSE },        /*      155                         */
00588   { SINGLECHAR, FALSE },        /*      156                         */
00589   { SINGLECHAR, FALSE },        /*      157                         */
00590   { SINGLECHAR, FALSE },        /*      158                         */
00591   { SINGLECHAR, FALSE },        /*      159                         */
00592   { SINGLECHAR, FALSE },        /*      160                         */
00593   { SINGLECHAR, FALSE },        /*      161                         */
00594   { SINGLECHAR, FALSE },        /*      162                         */
00595   { SINGLECHAR, FALSE },        /*      163                         */
00596   { SINGLECHAR, FALSE },        /*      164                         */
00597   { SINGLECHAR, FALSE },        /*      165                         */
00598   { SINGLECHAR, FALSE },        /*      166                         */
00599   { SINGLECHAR, FALSE },        /*      167                         */
00600   { SINGLECHAR, FALSE },        /*      168                         */
00601   { SINGLECHAR, FALSE },        /*      169                         */
00602   { SINGLECHAR, FALSE },        /*      170                         */
00603   { SINGLECHAR, FALSE },        /*      171                         */
00604   { SINGLECHAR, FALSE },        /*      172                         */
00605   { SINGLECHAR, FALSE },        /*      173                         */
00606   { SINGLECHAR, FALSE },        /*      174                         */
00607   { SINGLECHAR, FALSE },        /*      175                         */
00608   { SINGLECHAR, FALSE },        /*      176                         */
00609   { SINGLECHAR, FALSE },        /*      177                         */
00610   { SINGLECHAR, FALSE },        /*      178                         */
00611   { SINGLECHAR, FALSE },        /*      179                         */
00612   { SINGLECHAR, FALSE },        /*      180                         */
00613   { SINGLECHAR, FALSE },        /*      181                         */
00614   { SINGLECHAR, FALSE },        /*      182                         */
00615   { SINGLECHAR, FALSE },        /*      183                         */
00616   { SINGLECHAR, FALSE },        /*      184                         */
00617   { SINGLECHAR, FALSE },        /*      185                         */
00618   { SINGLECHAR, FALSE },        /*      186                         */
00619   { SINGLECHAR, FALSE },        /*      187                         */
00620   { SINGLECHAR, FALSE },        /*      188                         */
00621   { SINGLECHAR, FALSE },        /*      189                         */
00622   { SINGLECHAR, FALSE },        /*      190                         */
00623   { SINGLECHAR, FALSE },        /*      191                         */
00624   { SINGLECHAR, FALSE },        /*      192                         */
00625   { SINGLECHAR, FALSE },        /*      193                         */
00626   { SINGLECHAR, FALSE },        /*      194                         */
00627   { SINGLECHAR, FALSE },        /*      195                         */
00628   { SINGLECHAR, FALSE },        /*      196                         */
00629   { SINGLECHAR, FALSE },        /*      197                         */
00630   { SINGLECHAR, FALSE },        /*      198                         */
00631   { SINGLECHAR, FALSE },        /*      199                         */
00632   { SINGLECHAR, FALSE },        /*      200                         */
00633   { SINGLECHAR, FALSE },        /*      201                         */
00634   { SINGLECHAR, FALSE },        /*      202                         */
00635   { SINGLECHAR, FALSE },        /*      203                         */
00636   { SINGLECHAR, FALSE },        /*      204                         */
00637   { SINGLECHAR, FALSE },        /*      205                         */
00638   { SINGLECHAR, FALSE },        /*      206                         */
00639   { SINGLECHAR, FALSE },        /*      207                         */
00640   { SINGLECHAR, FALSE },        /*      208                         */
00641   { SINGLECHAR, FALSE },        /*      209                         */
00642   { SINGLECHAR, FALSE },        /*      210                         */
00643   { SINGLECHAR, FALSE },        /*      211                         */
00644   { SINGLECHAR, FALSE },        /*      212                         */
00645   { SINGLECHAR, FALSE },        /*      213                         */
00646   { SINGLECHAR, FALSE },        /*      214                         */
00647   { SINGLECHAR, FALSE },        /*      215                         */
00648   { SINGLECHAR, FALSE },        /*      216                         */
00649   { SINGLECHAR, FALSE },        /*      217                         */
00650   { SINGLECHAR, FALSE },        /*      218                         */
00651   { SINGLECHAR, FALSE },        /*      219                         */
00652   { SINGLECHAR, FALSE },        /*      220                         */
00653   { SINGLECHAR, FALSE },        /*      221                         */
00654   { SINGLECHAR, FALSE },        /*      222                         */
00655   { SINGLECHAR, FALSE },        /*      223                         */
00656   { SINGLECHAR, FALSE },        /*      224                         */
00657   { SINGLECHAR, FALSE },        /*      225                         */
00658   { SINGLECHAR, FALSE },        /*      226                         */
00659   { SINGLECHAR, FALSE },        /*      227                         */
00660   { SINGLECHAR, FALSE },        /*      228                         */
00661   { SINGLECHAR, FALSE },        /*      229                         */
00662   { SINGLECHAR, FALSE },        /*      230                         */
00663   { SINGLECHAR, FALSE },        /*      231                         */
00664   { SINGLECHAR, FALSE },        /*      232                         */
00665   { SINGLECHAR, FALSE },        /*      233                         */
00666   { SINGLECHAR, FALSE },        /*      234                         */
00667   { SINGLECHAR, FALSE },        /*      235                         */
00668   { SINGLECHAR, FALSE },        /*      236                         */
00669   { SINGLECHAR, FALSE },        /*      237                         */
00670   { SINGLECHAR, FALSE },        /*      238                         */
00671   { SINGLECHAR, FALSE },        /*      239                         */
00672   { SINGLECHAR, FALSE },        /*      240                         */
00673   { SINGLECHAR, FALSE },        /*      241                         */
00674   { SINGLECHAR, FALSE },        /*      242                         */
00675   { SINGLECHAR, FALSE },        /*      243                         */
00676   { SINGLECHAR, FALSE },        /*      244                         */
00677   { SINGLECHAR, FALSE },        /*      245                         */
00678   { SINGLECHAR, FALSE },        /*      246                         */
00679   { SINGLECHAR, FALSE },        /*      247                         */
00680   { SINGLECHAR, FALSE },        /*      248                         */
00681   { SINGLECHAR, FALSE },        /*      249                         */
00682   { SINGLECHAR, FALSE },        /*      250                         */
00683   { SINGLECHAR, FALSE },        /*      251                         */
00684   { SINGLECHAR, FALSE },        /*      252                         */
00685   { SINGLECHAR, FALSE },        /*      253                         */
00686   { SINGLECHAR, FALSE },        /*      254                         */
00687   { SINGLECHAR, FALSE }         /*      255                         */
00688 };
00689 
00690 void
00691 ScanCComment (void)
00692 {
00693   inComment = TRUE;
00694   for (;;)
00695     {
00696       switch (currentChar)
00697         {
00698         case '*':
00699           LCLMOVECHAR ();
00700           if (currentChar == '/')
00701             {
00702               LCLMOVECHAR ();
00703               inComment = FALSE;
00704               return;
00705             }
00706           /*@switchbreak@*/ break;
00707         case '\n':
00708           return;
00709         default:
00710           LCLMOVECHAR ();
00711         }
00712     }
00713 }
00714 
00715 void
00716 ScanEscape (void)
00717 {
00718   if (isSimpleEscape[(int)currentChar])
00719     {
00720       LCLMOVECHAR ();           /* discard simple escape character. */
00721     }
00722   else if (currentChar == 'x')
00723     {
00724       LCLMOVECHAR ();           /* discard 'x'. */
00725       if (!isXigit[(int)currentChar])
00726         {
00727           LocalUserError ("at least one hex digit must follow '\\x'");
00728         }
00729       while (isXigit[(int)currentChar])
00730         {
00731           LCLMOVECHAR ();               /* discard hex digits. */
00732         }
00733     }
00734   else if (isOigit[(int)currentChar])
00735     {
00736       LCLMOVECHAR ();           /* discard first hex digit. */
00737       if (isOigit[(int)currentChar])
00738         {
00739           LCLMOVECHAR ();               /* discard second hex digit. */
00740         }
00741       if (isOigit[(int)currentChar])
00742         {
00743           LCLMOVECHAR ();               /* discard third hex digit. */
00744         }
00745     }
00746   else
00747     {
00748       LocalUserError ("invalid escape sequence in a C string or character");
00749     }
00750 }
00751 
00752 void
00753 ScanCString (void)
00754 {
00755   if (currentChar == '\\' && LOOKAHEADCHAR () == 'L')
00756     {
00757       LCLMOVECHAR ();           /* discard slash */
00758       LCLMOVECHAR ();           /* discard 'L'. */
00759     }
00760 
00761   if (currentChar == '\"')
00762     {
00763       LCLMOVECHAR ();           /* discard opening quote. */
00764 
00765       while (currentChar != '\"')
00766         {
00767           if (isStrChar[(int)currentChar])
00768             {
00769               LCLMOVECHAR ();   /* discard string character. */
00770             }
00771           else if (currentChar == '\\')
00772             {
00773               LCLMOVECHAR ();   /* discard slash */
00774               ScanEscape ();
00775             }
00776           else if (currentChar == '\n')
00777             {
00778               LocalUserError ("unterminated C string");
00779             }
00780           else
00781             {
00782               LocalUserError ("invalid character in C string");
00783             }
00784         }
00785       LCLMOVECHAR ();           /* discard closing quote */
00786 
00787     }
00788   else
00789     {
00790       LocalUserError ("C string must start with '\"'");
00791     }
00792 
00793 
00794   *bufPtr = '\0';               /* null terminate in buffer */
00795   tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
00796   tokenCode = LLT_LCSTRING;
00797 }
00798 
00799 void
00800 ScanCChar (void)
00801 {
00802   if (currentChar == '\\' && LOOKAHEADCHAR () == 'L')
00803     {
00804       LCLMOVECHAR ();           /* discard slash */
00805       LCLMOVECHAR ();           /* discard 'L'. */
00806     }
00807 
00808   if (currentChar == '\'')
00809     {
00810       LCLMOVECHAR ();           /* discard opening quote */
00811 
00812       while (currentChar != '\'')
00813         {
00814           if (isCharChar[(int)currentChar])
00815             {
00816               LCLMOVECHAR ();   /* discard string character. */
00817             }
00818           else if (currentChar == '\\')
00819             {
00820               LCLMOVECHAR ();   /* discard slash */
00821               ScanEscape ();
00822             }
00823           else if (currentChar == '\n')
00824             {
00825               LocalUserError ("unterminated C character constant");
00826             }
00827           else
00828             {
00829               LocalUserError ("invalid character in C character");
00830             }
00831         }
00832       LCLMOVECHAR ();           /* discard closing quote */
00833 
00834     }
00835   else
00836     {
00837       LocalUserError ("invalid C character");
00838     }
00839 
00840 
00841   *bufPtr = '\0';               /* null terminate in buffer */
00842   tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
00843   tokenCode = LLT_CCHAR;
00844 }
00845 
00846 void
00847 ScanCNumber (void)
00848 {
00849   tokenCode = LLT_CINTEGER;
00850   
00851   switch (currentChar)
00852     {
00853     case '.':
00854       LCLMOVECHAR ();           
00855       tokenCode = LLT_CFLOAT;
00856       if (!isDigit[(int)currentChar])
00857         {
00858           LocalUserError ("at least one digit must follow '.'");
00859         }
00860       while (isDigit[(int)currentChar])
00861         {
00862           LCLMOVECHAR ();
00863         }
00864       if (currentChar == 'e' || currentChar == 'E')
00865         {
00866           LCLMOVECHAR ();               /* discard 'e' or 'E'. */
00867           if (currentChar == '+' || currentChar == '-')
00868             {
00869               LCLMOVECHAR ();
00870             }
00871           if (!isDigit[(int)currentChar])
00872             {
00873               LocalUserError ("digit must follow exponent");
00874             }
00875           while (isDigit[(int)currentChar])
00876             {
00877               LCLMOVECHAR ();
00878             }
00879         }
00880       if (currentChar == 'f' || currentChar == 'l' ||
00881           currentChar == 'F' || currentChar == 'L')
00882         {
00883           LCLMOVECHAR ();
00884         }
00885       break;
00886       
00887     case '0':
00888       LCLMOVECHAR ();           /* discard '0'. */
00889       switch (currentChar)
00890         {
00891         case 'x':
00892         case 'X':
00893           LCLMOVECHAR ();
00894           if (!isXigit[(int)currentChar])
00895             {
00896               LocalUserError ("hex digit must follow 'x' or 'X'");
00897             }
00898           while (isXigit[(int)currentChar])
00899             {
00900               LCLMOVECHAR ();
00901             }
00902           /*@switchbreak@*/ break;
00903 
00904         default:
00905           /*
00906           ** Could either be an octal number or a floating point  
00907           ** number.  Scan decimal digits so don't run into         
00908           ** problems if turns out problems if it is an fp          
00909           ** number.  Let converter/parser catch bad octal          
00910           ** numbers.   e.g. 018 not caught by scanner.     
00911           */
00912           
00913           while (isDigit[(int)currentChar])
00914             {
00915               LCLMOVECHAR ();
00916             }
00917           switch (currentChar)
00918             {
00919             case '.':
00920               LCLMOVECHAR ();   /* discard '.'. */
00921               tokenCode = LLT_CFLOAT;
00922               while (isDigit[(int)currentChar])
00923                 {
00924                   LCLMOVECHAR ();
00925                 }
00926               if (currentChar == 'e' || currentChar == 'E')
00927                 {
00928                   LCLMOVECHAR ();       /* discard 'e' or 'E'. */
00929                   if (currentChar == '+' || currentChar == '-')
00930                     {
00931                       LCLMOVECHAR ();
00932                     }
00933                   if (!isDigit[(int)currentChar])
00934                     {
00935                       LocalUserError ("digit must follow exponent");
00936                     }
00937                   while (isDigit[(int)currentChar])
00938                     {
00939                       LCLMOVECHAR ();
00940                     }
00941                 }
00942               if (currentChar == 'f' ||
00943                   currentChar == 'l' ||
00944                   currentChar == 'F' ||
00945                   currentChar == 'L')
00946                 {
00947                   LCLMOVECHAR ();
00948                 }
00949               /*@switchbreak@*/ break;
00950 
00951             case 'e':
00952             case 'E':
00953               LCLMOVECHAR ();   
00954               tokenCode = LLT_CFLOAT;
00955               if (currentChar == '+' || currentChar == '-')
00956                 {
00957                   LCLMOVECHAR ();
00958                 }
00959               if (!isDigit[(int)currentChar])
00960                 {
00961                   LocalUserError ("digit must follow exponent");
00962                 }
00963               while (isDigit[(int)currentChar])
00964                 {
00965                   LCLMOVECHAR ();
00966                 }
00967               if (currentChar == 'f' ||
00968                   currentChar == 'l' ||
00969                   currentChar == 'F' ||
00970                   currentChar == 'L')
00971                 {
00972                   LCLMOVECHAR ();
00973                 }
00974               /*@switchbreak@*/ break;
00975 
00976             default:
00977               /* Scan integer suffix. */
00978               switch (currentChar)
00979                 {
00980                 case 'u':
00981                 case 'U':
00982                   LCLMOVECHAR ();       
00983                   if (currentChar == 'l' || currentChar == 'L')
00984                     {
00985                       LCLMOVECHAR ();
00986                     }
00987                   /*@switchbreak@*/ break;
00988                 case 'l':
00989                 case 'L':
00990                   LCLMOVECHAR ();       
00991                   if (currentChar == 'u' || currentChar == 'U')
00992                     {
00993                       LCLMOVECHAR ();
00994                     }
00995                   
00996                   /*@switchbreak@*/ break;
00997                 }       
00998               /*@switchbreak@*/ break;
00999             }           
01000         }                      
01001       
01002       /* Scan integer suffix. */
01003       switch (currentChar)
01004         {
01005         case 'u':
01006         case 'U':
01007           LCLMOVECHAR ();               
01008           if (currentChar == 'l' || currentChar == 'L')
01009             {
01010               LCLMOVECHAR ();   
01011             }
01012           /*@switchbreak@*/ break;
01013         case 'l':
01014         case 'L':
01015           LCLMOVECHAR ();               
01016           if (currentChar == 'u' || currentChar == 'U')
01017             {
01018               LCLMOVECHAR ();   
01019             }
01020           /*@switchbreak@*/ break;
01021         }               
01022       break;
01023       
01024     default:
01025       if (isDigit[(int)currentChar])
01026         {
01027           while (isDigit[(int)currentChar])
01028             {
01029               LCLMOVECHAR ();
01030             }
01031           switch (currentChar)
01032             {
01033             case '.':
01034               LCLMOVECHAR ();   /* discard '.'. */
01035               tokenCode = LLT_CFLOAT;
01036               while (isDigit[(int)currentChar])
01037                 {
01038                   LCLMOVECHAR ();
01039                 }
01040               if (currentChar == 'e' || currentChar == 'E')
01041                 {
01042                   LCLMOVECHAR ();
01043                   if (currentChar == '+' || currentChar == '-')
01044                     {
01045                       LCLMOVECHAR ();
01046                     }
01047                   if (!isDigit[(int)currentChar])
01048                     {
01049                       LocalUserError ("digit must follow exponent");
01050                     }
01051                   while (isDigit[(int)currentChar])
01052                     {
01053                       LCLMOVECHAR ();
01054                     }
01055                 }
01056               if (currentChar == 'f' ||
01057                   currentChar == 'l' ||
01058                   currentChar == 'F' ||
01059                   currentChar == 'L')
01060                 {
01061                   LCLMOVECHAR ();
01062                 }
01063               /*@switchbreak@*/ break;
01064 
01065             case 'e':
01066             case 'E':
01067               LCLMOVECHAR ();   
01068               tokenCode = LLT_CFLOAT;
01069               if (currentChar == '+' || currentChar == '-')
01070                 {
01071                   LCLMOVECHAR ();
01072                 }
01073               if (!isDigit[(int)currentChar])
01074                 {
01075                   LocalUserError ("digit must follow exponent");
01076                 }
01077               while (isDigit[(int)currentChar])
01078                 {
01079                   LCLMOVECHAR ();
01080                 }
01081               if (currentChar == 'f' ||
01082                   currentChar == 'l' ||
01083                   currentChar == 'F' ||
01084                   currentChar == 'L')
01085                 {
01086                   LCLMOVECHAR ();
01087                 }
01088 
01089               /*@switchbreak@*/ break;
01090             default:
01091               switch (currentChar)
01092                 {
01093                 case 'u':
01094                 case 'U':
01095                   LCLMOVECHAR (); 
01096                   if (currentChar == 'l' || currentChar == 'L')
01097                     {
01098                       LCLMOVECHAR ();
01099                     }
01100                   /*@switchbreak@*/ break;
01101                 case 'l':
01102                 case 'L':
01103                   LCLMOVECHAR ();       
01104                   if (currentChar == 'u' || currentChar == 'U')
01105                     {
01106                       LCLMOVECHAR ();
01107                     }
01108                   /*@switchbreak@*/ break;
01109                 }               
01110               /*@switchbreak@*/ break;
01111             }                   
01112         }
01113       else
01114         {
01115           LocalUserError ("invalid C number");
01116         }
01117       break;
01118 
01119 
01120     }   
01121 
01122   *bufPtr = '\0';
01123   tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01124 }
01125 
01126 static void ScanOther (void)
01127 {
01128   switch (LCLScanCharClass (currentChar))
01129     {                         
01130     case CHC_NULL:      
01131       tokenSym = lsymbol_fromChars ("E O L");
01132       tokenCode = LLT_EOL;
01133       break;
01134       
01135       /* identifiers */
01136       
01137     case IDCHAR:
01138       
01139       while (LCLScanCharClass (currentChar) == IDCHAR)
01140         {                       /* identifier: find end     */
01141           LCLMOVECHAR ();
01142         }
01143       
01144       *bufPtr = '\0';           /* null terminate in buffer */
01145       tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01146       tokenCode = simpleId;
01147             break;
01148       
01149       /* one-character tokens */
01150       
01151     case SINGLECHAR:
01152     case PERMCHAR:              
01153       LCLMOVECHAR ();
01154       *bufPtr = '\0';           
01155       tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01156       tokenCode = simpleOp;
01157       break;
01158 
01159      /* operator symbols */
01160 
01161     case OPCHAR:
01162 
01163       if (currentChar == '.' &&  LOOKAHEADCHAR () == '.'  &&
01164           LOOKAHEADTWICECHAR () == '.')
01165         {
01166           LCLMOVECHAR ();
01167           LCLMOVECHAR ();
01168           LCLMOVECHAR ();
01169           *bufPtr = '\0';
01170           tokenSym = lsymbol_fromChars ("...");
01171           tokenCode = LLT_TELIPSIS;
01172         }
01173       else
01174         {
01175           if (currentChar == '/' && LOOKAHEADCHAR () == '\\')
01176             {                   
01177               LCLMOVECHAR ();
01178               LCLMOVECHAR ();
01179             }
01180           else
01181             {                   
01182               while (LCLScanCharClass (currentChar) == OPCHAR)
01183                 {       
01184                   LCLMOVECHAR ();
01185                 }
01186             }
01187           
01188           *bufPtr = '\0';
01189           tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01190           tokenCode = simpleOp;
01191         }
01192       break;
01193       
01194       /* white space */
01195     case WHITECHAR:
01196       /*@-loopswitchbreak@*/
01197       /*@-switchswitchbreak@*/
01198       switch (currentChar)
01199         {
01200         case '\t':
01201           LCLMOVECHAR (); /* tabs only count as one character */
01202           break;
01203 
01204         case '\v':
01205         case '\f':
01206           LCLMOVECHAR ();
01207           colNumber--;          /* does not change column   */
01208           break;
01209 
01210         default:
01211           LCLMOVECHAR ();
01212           break;
01213         }
01214       /*@=switchswitchbreak@*/
01215 
01216       *bufPtr = '\0';   
01217       tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01218       tokenCode = LLT_WHITESPACE;
01219       break;
01220 
01221      /* symbols */
01222 
01223     case CHC_EXTENSION: 
01224       LCLMOVECHAR ();
01225 
01226       /*@-switchswitchbreak@*/
01227       switch (currentChar)
01228         {               
01229          /* open and close */
01230         case '(':               
01231           LCLMOVECHAR ();
01232           while (LCLScanCharClass (currentChar) == IDCHAR)
01233             {                   
01234               LCLMOVECHAR ();
01235             }
01236           *bufPtr = '\0';       
01237           tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01238           tokenCode = openSym;
01239           break;
01240 
01241         case ')':               
01242           LCLMOVECHAR ();
01243           while (LCLScanCharClass (currentChar) == IDCHAR)
01244             {                   
01245               LCLMOVECHAR ();
01246             }
01247           *bufPtr = '\0';       
01248           tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01249           tokenCode = closeSym;
01250           break;
01251 
01252          /* separator */
01253         case ',':       
01254           LCLMOVECHAR ();
01255           while (LCLScanCharClass (currentChar) == IDCHAR)
01256             {           
01257               LCLMOVECHAR ();
01258             }
01259           *bufPtr = '\0';
01260           tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01261           tokenCode = sepSym;
01262           break;
01263 
01264          /* simpleid */
01265         case ':':       
01266           LCLMOVECHAR ();
01267           while (LCLScanCharClass (currentChar) == IDCHAR)
01268             {           
01269               LCLMOVECHAR ();
01270             }
01271           *bufPtr = '\0';
01272           tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01273           tokenCode = simpleId;
01274           break;
01275 
01276         default:                
01277           if (LCLScanCharClass (currentChar) == IDCHAR)
01278             {
01279               do
01280                 {
01281                   LCLMOVECHAR ();
01282                 }
01283               while (LCLScanCharClass (currentChar) == IDCHAR);
01284               *bufPtr = '\0';   
01285               tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01286               tokenCode = simpleOp;
01287             }
01288           else
01289             {
01290               /*
01291               ** Meets none of the above.  Take the extension       
01292               ** character and the character following and treat           
01293               ** together as a SINGLECHAR.  SINGLECHARs tranlate into 
01294               ** SIMPLEOPs.                                         
01295               */
01296 
01297               LCLMOVECHAR ();
01298               *bufPtr = '\0';   
01299               tokenSym = lsymbol_fromChars (&tokenBuffer[0]);
01300               tokenCode = simpleOp;
01301             }
01302           break;
01303           /*@=switchswitchbreak@*/
01304         }
01305       break;                    
01306 
01307     default:
01308       LocalUserError ("unexpected character in input");
01309       return;
01310     }
01311   /*@=loopswitchbreak@*/
01312 }
01313 
01314 static bool
01315 nextCanBeCharLiteral (ltokenCode c)
01316 {
01317   switch (c)
01318     {
01319       /* A ' following these tokens starts a C character literal. */
01320     case logicalOp:             
01321     case equationSym:           
01322     case eqSepSym:              
01323     case openSym:               
01324     case sepSym:                
01325     case simpleOp:              
01326     case LLT_COMMA:                     
01327     case LLT_EQUALS:            
01328     case LLT_LBRACE:            
01329     case LLT_LBRACKET:          
01330     case LLT_LPAR:                      
01331     case eqOp:                  
01332     case LLT_BE:                        
01333     case LLT_ELSE:                      
01334     case LLT_ENSURES:           
01335     case LLT_IF:                        
01336     case LLT_CONSTRAINT:                
01337     case LLT_REQUIRES:          
01338     case LLT_CHECKS:                
01339     case LLT_BODY:                      
01340     case LLT_THEN:                      
01341       return (TRUE);
01342 
01343      /* A ' following these tokens means post */
01344     case selectSym:             
01345     case closeSym:              
01346     case simpleId:              
01347     case preSym:                
01348     case anySym:                
01349     case postSym:               
01350     case LLT_QUOTE:                     
01351     case LLT_RBRACE:            
01352     case LLT_RBRACKET:          
01353     case LLT_RPAR:                      
01354     case LLT_RESULT:            
01355       return (FALSE);
01356 
01357      /* Neither a C character literal nor post should follow these tokens */
01358     case quantifierSym:         
01359     case mapSym:                
01360     case markerSym:             
01361     case LLT_COLON:                     
01362     case LLT_SEMI:                      
01363     case LLT_VERTICALBAR:               
01364     case LLT_MULOP:             
01365     case LLT_CCHAR:                     
01366     case LLT_CFLOAT:            
01367     case LLT_CINTEGER:          
01368     case LLT_LCSTRING:          
01369     case LLT_ALL:                       
01370     case LLT_ANYTHING:          
01371     case LLT_CONSTANT:          
01372     case LLT_FOR:                       
01373     case LLT_IMMUTABLE:         
01374     case LLT_OBJ:                       
01375     case LLT_OUT:                       
01376     case LLT_IMPORTS:           
01377     case LLT_ISSUB:             
01378     case LLT_LET:                       
01379     case LLT_MODIFIES:
01380     case LLT_CLAIMS:
01381     case LLT_MUTABLE:           
01382     case LLT_FRESH:
01383     case LLT_NOTHING:           
01384     case LLT_PRIVATE:           
01385     case LLT_SPEC:                      
01386     case LLT_SIZEOF:            
01387     case LLT_TAGGEDUNION:               
01388     case LLT_TYPE:                      
01389     case LLT_UNCHANGED:         
01390     case LLT_USES:                      
01391     case LLT_CHAR:                      
01392     case LLT_CONST:                     
01393     case LLT_DOUBLE:            
01394     case LLT_ENUM:                      
01395     case LLT_FLOAT:                     
01396     case LLT_INT:                       
01397     case LLT_TYPEDEF_NAME:              
01398     case LLT_LONG:                      
01399     case LLT_SHORT:                     
01400     case LLT_STRUCT:            
01401     case LLT_SIGNED:            
01402     case LLT_UNKNOWN:           
01403     case LLT_UNION:                     
01404     case LLT_UNSIGNED:          
01405     case LLT_VOID:                      
01406     case LLT_VOLATILE:          
01407       return (FALSE);
01408 
01409      /* These tokens should have been ignored */
01410     case NOTTOKEN:
01411     case commentSym:            
01412     case LLT_WHITESPACE:
01413     case LLT_EOL:
01414     case LEOFTOKEN:
01415       llcontbuglit ("scanline: nextCanBeChar");
01416       return FALSE;
01417     BADDEFAULT;
01418     }
01419 
01420   BADEXIT;
01421 }
01422 
01423 void
01424 LCLScanLine (char *line)
01425 {
01426   ltoken newToken;
01427   lsymbol CCommentSym = lsymbol_fromChars ("/*");
01428   size_t linelength = strlen (line);
01429   static bool inSpecComment = FALSE;
01430 
01431     line[(int)linelength] = '\n';
01432 
01433   currentLine = line;
01434   currentChar = *currentLine++; 
01435   context_processedSpecLine ();
01436 
01437   incLine ();
01438   colNumber = 1;                
01439 
01440   if (inComment)
01441     {
01442       ScanCComment ();
01443 
01444       if (reportComments)
01445         {
01446           *bufPtr = '\0';
01447           newToken = ltoken_createRaw (simpleId, lsymbol_fromChars (&tokenBuffer[0]));
01448           LCLScanFreshToken (newToken);
01449         }
01450     }
01451 
01452   if (inSpecComment)
01453     {
01454       if (currentChar == '*' &&
01455           LOOKAHEADCHAR () == '/')
01456         {
01457           LCLMOVECHAR ();
01458           LCLMOVECHAR ();
01459           inSpecComment = FALSE;
01460         }
01461     }
01462 
01463   /*@+loopexec@*/ 
01464   for (;;)
01465     {
01466       if (inSpecComment && currentChar == '*' && LOOKAHEADCHAR () == '/')
01467         {
01468           LCLMOVECHAR ();
01469           LCLMOVECHAR ();
01470           inSpecComment = FALSE;
01471         }
01472 
01473       bufPtr = &tokenBuffer[0]; 
01474       startCol = colNumber;     
01475 
01476       
01477       /*@-loopswitchbreak@*/
01478       switch (startClass[(int)currentChar])
01479         {
01480         case STARTCNUM:
01481           ScanCNumber ();
01482           break;
01483 
01484         case STARTCNUMDOT:
01485           if (isDigit[(int) LOOKAHEADCHAR ()])
01486             {
01487               ScanCNumber ();
01488             }
01489           else
01490             {
01491               ScanOther ();
01492             }
01493           break;
01494 
01495         case STARTCSTR:
01496           ScanCString ();
01497           break;
01498 
01499         case STARTCCHAR:
01500                   if (nextCanBeCharLiteral (prevTokenCode))
01501             {
01502               ScanCChar ();
01503             }
01504           else
01505             {
01506                       ScanOther ();
01507             }
01508           break;
01509 
01510         case STARTWIDE:
01511           if (LOOKAHEADCHAR () == 'L' && LOOKAHEADTWICECHAR () == '\"')
01512             {
01513               ScanCString ();
01514             }
01515           else if (LOOKAHEADCHAR () == 'L' && LOOKAHEADTWICECHAR () == '\'')
01516             {
01517               ScanCChar ();
01518             }
01519           else
01520             {
01521               ScanOther ();
01522             }
01523           break;
01524 
01525         case STARTSLASH:
01526           if (LOOKAHEADCHAR () == '*')
01527             {
01528               LCLMOVECHAR ();
01529               LCLMOVECHAR ();
01530 
01531               if (currentChar == '@')
01532                 {
01533                   char *s = mstring_createEmpty ();
01534 
01535                   LCLMOVECHAR ();
01536 
01537                   while (currentChar != '\0' && currentChar != ' ' 
01538                          && currentChar != '*' && currentChar != '\t' &&
01539                          currentChar != '\n')
01540                     {
01541                       s = mstring_append (s, currentChar);
01542                       LCLMOVECHAR ();
01543                     }
01544 
01545                   if (mstring_equal (s, "alt"))
01546                     {
01547                       tokenCode = LLT_VERTICALBAR;
01548                       tokenSym = lsymbol_fromChars ("|");
01549                       inSpecComment = TRUE;
01550                     }
01551                   else
01552                     {
01553                       ScanCComment ();
01554                       tokenCode = commentSym;
01555                       tokenSym = CCommentSym;
01556                     }
01557 
01558                   sfree (s);
01559                   break;
01560                 }
01561               else
01562                 {
01563                   ScanCComment ();
01564                   tokenCode = commentSym;
01565                   tokenSym = CCommentSym;
01566                   break;
01567                 }
01568             }
01569           else
01570             {
01571               ScanOther ();
01572             } break;
01573 
01574         case STARTOTHER:
01575           ScanOther ();
01576           break;
01577 
01578         default:
01579           llcontbuglit ("LCLScanLine: bad case");
01580           break;
01581 
01582         }
01583       /*@=loopswitchbreak@*/
01584       
01585      /*
01586      ** Above code only "guessed" at token type.  Insert it into the 
01587      ** TokenTable.  If the token already exists, it is returned as         
01588      ** previously defined.  If it does not exist, it is inserted as the 
01589      ** token code computed above.                                          
01590      */
01591       
01592       newToken = LCLInsertToken (tokenCode, tokenSym, lsymbol_undefined, FALSE);
01593       
01594                   
01595       if (LCLIsSyn (ltoken_getText (newToken)))
01596         {
01597           /*
01598           ** Token is a synonym.  Get the actual token and set the raw    
01599           ** text to the synonym name.                              
01600           */
01601 
01602           newToken = ltoken_copy (LCLGetTokenForSyn (ltoken_getText (newToken)));
01603 
01604           ltoken_setRawText (newToken, tokenSym);
01605         }
01606       else
01607         {
01608           newToken = ltoken_copy (newToken);
01609         }
01610 
01611       ltoken_setCol (newToken, startCol);
01612       ltoken_setLine (newToken, tsource_thisLineNumber (LCLScanSource ()));
01613       ltoken_setFileName (newToken, tsource_fileName (LCLScanSource ()));
01614 
01615       if (ltoken_getCode (newToken) == commentSym)
01616         {
01617           if (tokenSym == CCommentSym)
01618             { /* C-style comment   */
01619               ltoken_free (commentTok);
01620               commentTok = ltoken_copy (newToken);
01621 
01622               if (!inComment && reportComments)
01623                 {
01624                   *bufPtr = '\0';
01625                   ltoken_setRawText (newToken, 
01626                                      lsymbol_fromChars (&tokenBuffer[0]));
01627                   LCLScanFreshToken (newToken);
01628                 }
01629               else
01630                 {
01631                   ltoken_free (newToken); 
01632                 }
01633             }
01634           else
01635             { /* LSL-style comment */
01636               bufPtr = &tokenBuffer[0];
01637               while (!LCLIsEndComment (currentChar))
01638                 {
01639                   LCLMOVECHAR ();
01640                 }
01641               if (LCLScanCharClass (currentChar) != CHC_NULL)
01642                 {
01643                   /* Not EOL character.  Toss it out. */
01644                   LCLMOVECHAR ();
01645                 }
01646 
01647               if (reportComments)
01648                 {
01649                   *bufPtr = '\0';
01650                   ltoken_setRawText (newToken, 
01651                                      lsymbol_fromChars (&tokenBuffer[0]));
01652                   LCLScanFreshToken (newToken);
01653                 }
01654               else
01655                 {
01656                   ltoken_free (newToken);
01657                 }
01658             }
01659         }
01660       else if (ltoken_getCode (newToken) == LLT_EOL)
01661         {
01662           if (reportEOL)
01663             {
01664               LCLScanFreshToken (newToken);
01665             }
01666           else
01667             {
01668               ltoken_free (newToken); 
01669             }
01670 
01671           line[(int) linelength] = '\0';
01672           return;
01673         }
01674       else if (ltoken_getCode (newToken) != LLT_WHITESPACE)
01675         {
01676           prevTokenCode = ltoken_getCode (newToken);
01677           LCLScanFreshToken (newToken);
01678         }
01679       else
01680         {
01681           ltoken_free (newToken);
01682         }
01683     } /*@=loopexec@*/
01684 }
01685 
01686 /*@exposed@*/ ltoken
01687 LCLScanEofToken (void)
01688 {
01689   ltoken t = LCLInsertToken (LEOFTOKEN, lsymbol_fromChars ("E O F"), 0, TRUE);
01690 
01691   if (inComment)
01692     {
01693       lclerror (commentTok, cstring_makeLiteral ("Unterminated comment"));
01694     }
01695 
01696   ltoken_setCol (t, colNumber);
01697   ltoken_setLine (t, tsource_thisLineNumber (LCLScanSource ()));
01698   ltoken_setFileName (t, tsource_fileName (LCLScanSource ()));
01699 
01700   return t;
01701 }
01702 
01703 void
01704 LCLReportEolTokens (bool setting)
01705 {
01706   reportEOL = setting;
01707 }
01708 
01709 static void
01710 LocalUserError (char *msg)
01711 {
01712   tsource *s = LCLScanSource ();
01713   llfatalerror (message ("%s:%u,%u: %s", 
01714                          cstring_fromChars (tsource_fileName (s)), 
01715                          tsource_thisLineNumber (s),
01716                          colNumber,
01717                          cstring_fromChars (msg)));
01718 }
01719 
01720 void
01721 LCLScanLineInit (void)
01722 {
01723   int i;
01724 
01725   setCodePoint ();
01726   reportEOL = FALSE;
01727   reportComments = FALSE;
01728 
01729   for (i = 0; i <= LASTCHAR; i++)
01730     {
01731       LCLcharClass[i] = charClassDef[i];
01732     }
01733 
01734   setCodePoint ();
01735 
01736   /*
01737   ** Make sure first postion is never used because use the 0th index to   
01738   ** mean empty. 
01739   */
01740 
01741   firstReserved = lsymbol_fromChars (FIRSTRESERVEDNAME);
01742   setCodePoint ();
01743 
01744   /* Predefined LSL Tokens */
01745   
01746   ltoken_forall = LCLReserveToken (quantifierSym, "\\forall");
01747   setCodePoint ();
01748   ltoken_exists = LCLReserveToken (quantifierSym, "\\exists");
01749   ltoken_implies = LCLReserveToken (logicalOp, "\\implies");
01750   ltoken_eqsep = LCLReserveToken (eqSepSym, "\\eqsep");
01751   ltoken_select = LCLReserveToken (selectSym, "\\select");
01752   ltoken_open = LCLReserveToken (openSym, "\\open");
01753   ltoken_sep = LCLReserveToken (sepSym, "\\,");
01754   ltoken_close = LCLReserveToken (closeSym, "\\close");
01755   ltoken_id = LCLReserveToken (simpleId, "\\:");
01756   ltoken_arrow = LCLReserveToken (mapSym, "\\arrow");
01757   ltoken_marker = LCLReserveToken (markerSym, "\\marker");
01758   ltoken_pre = LCLReserveToken (preSym, "\\pre");
01759   ltoken_post = LCLReserveToken (postSym, "\\post");
01760   ltoken_comment = LCLReserveToken (commentSym, "\\comment");
01761   ltoken_any = LCLReserveToken (anySym, "\\any");
01762 
01763   ltoken_result = LCLReserveToken (LLT_RESULT, "result");
01764   ltoken_typename = LCLReserveToken (LLT_TYPEDEF_NAME, "TYPEDEF_NAME");
01765   ltoken_setIdType (ltoken_typename, SID_TYPE);
01766 
01767   /*
01768   ** Not context_getBoolName () --- "bool" is built in to LCL.
01769   ** This is bogus, but necessary for a lot of old lcl files.
01770   */
01771 
01772   ltoken_bool = LCLReserveToken (LLT_TYPEDEF_NAME, "bool");
01773 
01774   ltoken_lbracked = LCLReserveToken (LLT_LBRACKET, "[");
01775   ltoken_rbracket = LCLReserveToken (LLT_RBRACKET, "]");
01776 
01777   (void) LCLReserveToken (LLT_COLON, ":");
01778   (void) LCLReserveToken (LLT_COMMA, ",");
01779 
01780   (void) LCLReserveToken (LLT_EQUALS, "=");
01781   (void) LCLReserveToken (LLT_LBRACE, "{");
01782   (void) LCLReserveToken (LLT_LPAR, "(");
01783   (void) LCLReserveToken (LLT_RBRACE, "}");
01784   (void) LCLReserveToken (LLT_RPAR, ")");
01785   (void) LCLReserveToken (LLT_SEMI, ";");
01786   (void) LCLReserveToken (LLT_VERTICALBAR, "|");
01787 
01788   (void) LCLReserveToken (LLT_MULOP, "*");
01789 
01790   (void) LCLReserveToken (LLT_WHITESPACE, " ");
01791   (void) LCLReserveToken (LLT_WHITESPACE, "\t");
01792   (void) LCLReserveToken (LLT_WHITESPACE, "\f");
01793   (void) LCLReserveToken (LLT_WHITESPACE, "\n");
01794 
01795   (void) LCLReserveToken (LEOFTOKEN, "E O F");
01796   (void) LCLReserveToken (LLT_EOL, "E O L");
01797 
01798   /* LSL Keywords */
01799   ltoken_and = LCLReserveToken (logicalOp, "\\and");
01800   ltoken_or = LCLReserveToken (logicalOp, "\\or");
01801 
01802   ltoken_equals = LCLReserveToken (equationSym, "\\equals");
01803 
01804   ltoken_eq = LCLReserveToken (eqOp, "\\eq");
01805   ltoken_neq = LCLReserveToken (eqOp, "\\neq");
01806 
01807   ltoken_not = LCLReserveToken (simpleOp, "\\not");
01808   ltoken_true = LCLReserveToken (simpleId, "true");
01809   ltoken_false = LCLReserveToken (simpleId, "false");
01810 
01811   /* LCL Keywords */
01812   (void) LCLReserveToken (LLT_ALL, "all");
01813   (void) LCLReserveToken (LLT_ANYTHING, "anything");
01814   (void) LCLReserveToken (LLT_BE, "be");
01815   (void) LCLReserveToken (LLT_CONSTANT, "constant");
01816   (void) LCLReserveToken (LLT_CHECKS, "checks");
01817   (void) LCLReserveToken (LLT_ELSE, "else");
01818   (void) LCLReserveToken (LLT_ENSURES, "ensures");
01819   (void) LCLReserveToken (LLT_FOR, "for");
01820   (void) LCLReserveToken (LLT_IF, "if");
01821   (void) LCLReserveToken (LLT_IMMUTABLE, "immutable");
01822   (void) LCLReserveToken (LLT_OBJ, "obj");
01823   (void) LCLReserveToken (LLT_OUT, "out");
01824   (void) LCLReserveToken (LLT_ITER, "iter"); 
01825   (void) LCLReserveToken (LLT_YIELD, "yield"); 
01826   (void) LCLReserveToken (LLT_PARTIAL, "partial");
01827   (void) LCLReserveToken (LLT_ONLY, "only");
01828   (void) LCLReserveToken (LLT_UNDEF, "undef");
01829   (void) LCLReserveToken (LLT_KILLED, "killed");
01830   (void) LCLReserveToken (LLT_OWNED, "owned");
01831   (void) LCLReserveToken (LLT_DEPENDENT, "dependent");
01832   (void) LCLReserveToken (LLT_PARTIAL, "partial");
01833   (void) LCLReserveToken (LLT_RELDEF, "reldef");
01834   (void) LCLReserveToken (LLT_KEEP, "keep");
01835   (void) LCLReserveToken (LLT_KEPT, "kept");
01836   (void) LCLReserveToken (LLT_TEMP, "temp");
01837   (void) LCLReserveToken (LLT_SHARED, "shared");
01838   (void) LCLReserveToken (LLT_RELNULL, "relnull");
01839   (void) LCLReserveToken (LLT_RELDEF, "reldef");
01840   (void) LCLReserveToken (LLT_CHECKED, "checked");
01841   (void) LCLReserveToken (LLT_UNCHECKED, "unchecked");
01842   (void) LCLReserveToken (LLT_CHECKEDSTRICT, "checkedstrict");
01843   (void) LCLReserveToken (LLT_CHECKMOD, "checkmod");
01844   (void) LCLReserveToken (LLT_TRUENULL, "truenull");
01845   (void) LCLReserveToken (LLT_FALSENULL, "falsenull");
01846   (void) LCLReserveToken (LLT_LNULL, "null");
01847   (void) LCLReserveToken (LLT_LNOTNULL, "notnull");
01848   (void) LCLReserveToken (LLT_RETURNED, "returned");
01849   (void) LCLReserveToken (LLT_OBSERVER, "observer");
01850   (void) LCLReserveToken (LLT_EXPOSED, "exposed");
01851   (void) LCLReserveToken (LLT_REFCOUNTED, "refcounted");
01852   (void) LCLReserveToken (LLT_REFS, "refs");
01853   (void) LCLReserveToken (LLT_NEWREF, "newref");
01854   (void) LCLReserveToken (LLT_TEMPREF, "tempref");
01855   (void) LCLReserveToken (LLT_KILLREF, "killref");
01856   (void) LCLReserveToken (LLT_EXITS, "exits");
01857   (void) LCLReserveToken (LLT_MAYEXIT, "mayexit");
01858   (void) LCLReserveToken (LLT_TRUEEXIT, "trueexit");
01859   (void) LCLReserveToken (LLT_FALSEEXIT, "falseexit");
01860   (void) LCLReserveToken (LLT_NEVEREXIT, "neverexit");
01861   (void) LCLReserveToken (LLT_SEF, "sef");
01862   (void) LCLReserveToken (LLT_UNUSED, "unused");
01863   (void) LCLReserveToken (LLT_UNIQUE, "unique");
01864   (void) LCLReserveToken (LLT_IMPORTS, "imports");
01865   (void) LCLReserveToken (LLT_CONSTRAINT, "constraint");
01866   (void) LCLReserveToken (LLT_LET, "let");
01867   (void) LCLReserveToken (LLT_MODIFIES, "modifies");
01868   (void) LCLReserveToken (LLT_CLAIMS, "claims");
01869   (void) LCLReserveToken (LLT_BODY, "body");
01870   (void) LCLReserveToken (LLT_MUTABLE, "mutable");
01871   (void) LCLReserveToken (LLT_FRESH, "fresh");
01872   (void) LCLReserveToken (LLT_NOTHING, "nothing");
01873   (void) LCLReserveToken (LLT_INTERNAL, "internalState");
01874   (void) LCLReserveToken (LLT_FILESYS, "fileSystem");
01875   (void) LCLReserveToken (LLT_PRIVATE, "private");
01876   (void) LCLReserveToken (LLT_SPEC, "spec");
01877   (void) LCLReserveToken (LLT_REQUIRES, "requires");
01878   (void) LCLReserveToken (LLT_SIZEOF, "sizeof");
01879   (void) LCLReserveToken (LLT_TAGGEDUNION, "taggedunion");
01880   (void) LCLReserveToken (LLT_THEN, "then");
01881   (void) LCLReserveToken (LLT_TYPE, "type");
01882   (void) LCLReserveToken (LLT_TYPEDEF, "typedef");
01883   (void) LCLReserveToken (LLT_UNCHANGED, "unchanged");
01884   (void) LCLReserveToken (LLT_USES, "uses");
01885   (void) LCLReserveToken (LLT_PRINTFLIKE, "printflike");
01886   (void) LCLReserveToken (LLT_SCANFLIKE, "scanflike");
01887   (void) LCLReserveToken (LLT_MESSAGELIKE, "messagelike");
01888 
01889   /* LCL C Keywords */
01890   (void) LCLReserveToken (LLT_CHAR, "char");
01891   (void) LCLReserveToken (LLT_CONST, "const");
01892   (void) LCLReserveToken (LLT_DOUBLE, "double");
01893   (void) LCLReserveToken (LLT_ENUM, "enum");
01894 
01895   /* comment out so we can add in lclinit.lci: synonym double float */
01896   /* LCLReserveToken (LLT_FLOAT,                    "float"); */
01897   /* But we need to make the scanner parse "float" not as a simpleId, but
01898      as a TYPEDEF_NAME.  This is done later in abstract_init  */
01899   
01900   (void) LCLReserveToken (LLT_INT, "int");
01901   (void) LCLReserveToken (LLT_LONG, "long");
01902   (void) LCLReserveToken (LLT_SHORT, "short");
01903   (void) LCLReserveToken (LLT_STRUCT, "struct");
01904   (void) LCLReserveToken (LLT_SIGNED, "signed");
01905   (void) LCLReserveToken (LLT_UNION, "union");
01906   (void) LCLReserveToken (LLT_UNKNOWN, "__unknown");
01907   (void) LCLReserveToken (LLT_UNSIGNED, "unsigned");
01908   (void) LCLReserveToken (LLT_VOID, "void");
01909   (void) LCLReserveToken (LLT_VOLATILE, "volatile");
01910   setCodePoint ();
01911 }
01912 
01913 void
01914 LCLScanLineReset (void)
01915 {
01916   inComment = FALSE;
01917   prevTokenCode = LLT_LPAR;             /* Presume first ' starts literal */
01918 }
01919 
01920 void
01921 LCLScanLineCleanup (void)
01922 {
01923 }
01924 
01925 bool LCLIsEndComment (char c)
01926 {
01927   return LCLcharClass[(int)(c)].endCommentChar;
01928 }
01929 
01930 charCode LCLScanCharClass (char c)
01931 {
01932   return LCLcharClass[(int)(c)].code;
01933 }
01934 
01935 void LCLSetCharClass (char c, charCode cod) 
01936 {
01937   LCLcharClass[(int)(c)].code = (cod);
01938 }
01939 
01940 void LCLSetEndCommentChar (char c, bool flag) 
01941 {
01942   LCLcharClass[(int)(c)].endCommentChar = flag;
01943 }
01944 

Generated at Fri Nov 3 18:57:42 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000