Main Page   Class Hierarchy   Compound List   File List   Header Files   Compound Members   File Members  

scanner.h

This is the verbatim text of the scanner.h include file.
/* Sun-$Revision: 23.8 $ */

/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
   See the LICENSE file for license information. */

# pragma interface


class Token: public ResourceObj {
 public:

  enum TokenType {
    LAST_CHAR = 255,
    INTEGER, FLOAT, STRING, COMMENT,
    SELF_TOKEN, RESEND_TOKEN, 
    NAME, PRIMNAME, OPERATOR, PRIMKEYWORD, KEYWORD, CAPKEYWORD, ARG,
    DELEGATE, 
    ARROW, 
    ANNOTATION_START, ANNOTATION_END,
    ACCEPT, ERROR_TOKEN
  };  
  TokenType type;
  
  union {
    int32 integer;
    float floating;
    String* string;
  };
  fint line;
  fint column;
  char* sourceStart;
  
  Token(TokenType t, fint l, fint c, char* ss) {
    type = t; line = l; column = c; sourceStart = ss; }
  // wierd order to avoid overloading ambiguity
  Token(TokenType t, char* ss, int32 i, fint l, fint c) {
    type = t; integer = i; line = l; column = c; sourceStart = ss; }
  Token(TokenType t, float f, fint l, fint c, char* ss) {
    type = t; floating = f; line = l; column = c; sourceStart = ss; }
  Token(TokenType t, String* s, fint l, fint c, char* ss) {
    type = t; string = s; line = l; column = c; sourceStart = ss; }
  void print();
};

struct TokenPushback: ResourceObj {
  Token* token;
  TokenPushback* prev;
  
  TokenPushback(Token* t, TokenPushback* p) { token = t; prev = p; }
};

struct CharPushback: ResourceObj {
  fint c;
  CharPushback* prev;
  
  CharPushback(fint ch, CharPushback* p) { c = ch; prev = p; }
};

class SourceBuffer: public ResourceObj {
  
 protected:
  char *next, *last;
 public:
  int length;
  char *first;

  SourceBuffer(long len) {
    if (len < 0)
      fatal1("bad length %d for SourceBuffer", len);
    first = NEW_RESOURCE_ARRAY( char, len);
    if (!first)
      fatal1("new failed for length %d", len);
    next = first;
    last = first + len;
  }

  SourceBuffer(char *start, long len) {
    if (len < 0)
      fatal1("bad length %d for SourceBuffer", len);
    first= next= start;
    last= first + len;
  }

  SourceBuffer(FILE* source_file);
  // map the contents of the file into virtual memory.

  void nextPut(char c) {
    if (next >= last)
      fatal("source buffer overflow - file has changed while it was read");
    *next++ = c;
  }
  char* where() { return next; }
  char  current_char() { return next < last ? *next : EOF; }
  void  advance() { next++; }
  void reset() { next = first; }
  void pop() {
    if (next == first)
      fatal("bad pop in source buffer");
    --next;
  }
  char* lastWhiteSpaceBefore(char* start);
};


class Scanner: public StackObj {
 protected:
  SourceBuffer* sourceBuf;
  
  fint          line;
  fint          column;
  fint          depth;

  TokenPushback* tokens;
  CharPushback* chars;
  
  bool suppress;
  
  Scanner();
  Scanner(long fsz);
  Scanner(FILE* source_file);

  void          initialize();

  virtual fint  read_next_char() = 0;
  virtual bool  is_buffer_filled() { SubclassResponsibility(); return false; }
  fint          get_char(); 
  
  Token*        read_numeric_escape(fint base, fint howMany, char& ch);
  Token*        read_char(char*& buf, bool& cannot_be_a_delimeter);
  Token*        read_escaped_char(char*& buf, bool& cannot_be_a_delimeter);
  
  Token*        skip_comment();
  
  Token*        read_name(fint c);
  Token*        read_op(fint c);
  Token*        read_number(fint c);
  Token*        read_string();
  Token*        read_general_string(char delimiter, Token::TokenType t);
  Token*        read_dot();
  
  void          initSourcePos();
  
  Token*        TokenizingError(char* msg);

 public:
  void          push_char(fint c);

  TokenList*    commentList;
  
  virtual char* fileName()                      = 0;
  virtual void  start_line(char* prompt) { Unused(prompt); }
  virtual void  reset()                         {};

  int get_line_number() { return line; }
  int get_column()      { return column; }

  virtual bool  is_interactive()                {return false;}
  virtual bool  is_string_scanner()             {return false;}
  virtual bool  is_file_scanner()               {return false;}
  
  void          SuppressErrors(bool b);

  bool          is_done();
  Scanner*      close();
  
  Token*        get_token();
  void          push_token(Token* t) { tokens = new TokenPushback(t, tokens); }
  char*         sourceAddr() { return sourceBuf->where(); }
  char*         lastWhiteSpaceBefore(char* start) { 
    return sourceBuf->lastWhiteSpaceBefore(start); }
  virtual void  discardInput() {
    SubclassResponsibility(); } // only applies to the interactive scanner
  virtual void ErrorMessage(char* msg, fint l, fint c);
  void          resetTokenList();

 private:
  unsigned int commentsOK;
 public:
  // as long as comment is in SOME (even outer) method it will be kept
  void start_allowing_comments() {++commentsOK;}
  void stop_allowing_comments()  {--commentsOK;}
};

class InteractiveScanner: public Scanner {
 protected:
  void  ErrorMessage(char* msg, fint l, fint c);
  fint  read_next_char();
  bool  is_buffer_filled() { return false; }
 public:
  InteractiveScanner();
  
  char* fileName()    { return "<stdin>"; }
  void  reset()       { depth = 0; initSourcePos(); }
  
  bool  is_interactive() { return true; }
  void  start_line(char* prompt);

  void  discardInput();
};

class FileScanner: public Scanner {
 protected:
  FILE* file;
  char* _fileName;
  char* _fullName;
  fint  read_next_char() {
    return sourceBuf->current_char();
  }
  FILE* openFileAndReturnFile(char* filename);
  bool  is_buffer_filled() { return true; }
 public:
  int32 fileError;

  FileScanner(char* filename);
  
  ~FileScanner();

  char* fileName()       { return _fileName; }
  char* fullName()       { return _fullName; }

  bool is_file_scanner() { return true;       }
};

class StringScanner : public Scanner {
 protected:
  char* _fileName;
  fint  read_next_char()   { return sourceBuf->current_char(); }
  bool  is_buffer_filled() { return true; }
 public:
  StringScanner(char* s, fint len, char* fn = "<a string>", fint l = 1, fint c = 1);
  char* fileName()         { return _fileName; }
  bool is_string_scanner() { return true;      }
};

extern InteractiveScanner *VMScanner;

extern unsigned char c_type[];

#define ctype (c_type+1)

enum Ctype {
  _O = 0,
  _U = 001,     // Upper case
  _L = 002,     // Lower case
  _N = 004,     // Numeral (digit)
  _S = 010,     // Spacing character
  _P = 020,     // Punctuation
  _A = 040,     // Alpha including underscore
  _X = 0200     // heXadecimal digit
  };

inline bool is_id_alpha(fint c)         // a-zA-Z_
  { return ctype[c] & _A; }
inline bool is_alpha(fint c)            // a-zA-Z
  { return ctype[c] & ( _L | _U ); }
inline bool is_upper(fint c)            // A-Z
  { return ctype[c] & _U; }
inline bool is_lower(fint c)            // a-z
  { return ctype[c] & _L; }
inline bool is_digit(fint c)            // 0-9
  { return ctype[c] & _N; }
inline bool is_space(fint c)            // \t\n\f\r' '
  { return ctype[c] & _S; }
inline bool is_punct(fint c)            // not " ' ( ) . : [ ] _ { }
  { return ctype[c] & _P; } 
inline bool is_alphadigit(fint c)       // a-zA-Z0-9
  { return ctype[c] & (_N | _L | _U); }
inline bool is_id_char(fint c)          // a-zA-Z0-9_
  { return ctype[c] & (_A | _N); }



Generated at Tue Jun 27 12:10:46 2000 for SelfVM by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999