/*ident "@(#)fs:fsippsrc/Lexer.h 3.1" */ /****************************************************************************** * * C++ Standard Components, Release 3.0. * * Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc. * Copyright (c) 1988, 1989, 1990 AT&T. All Rights Reserved. * * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System * Laboratories, Inc. The copyright notice above does not evidence * any actual or intended publication of such source code. * ******************************************************************************/ #ifndef FSLEXER_H #define FSLEXER_H #include "Token.h" #include #include #include #include typedef void (*ContractAction)(Token *); class Lexer { protected: // Returns the absolute index of relative window position i. int absI(int i) const { return i+curToki; } // Returns the relative index of absolute window position i. int relI(int i) const { return i-curToki; } // Make i a valid absolute position, or raise exception. int resize(int i); public: static Objection DestroyingFrozenLexer, ContractingFrozenLexer; static Objection UnattachedLexer, DiscardedToken, BadHandshake; enum { infinity = -1 }; Lexer(); ~Lexer(); // Attach lexer to input character stream void attach(istream &f); void attach(istream &f, const String &fname); // Returns true if there are no tokens in the current window. // (True before the lexer is attached to a file.) int emptyWindow() const { return curToki == -1; } // Access the name of the input file. void setFilename(const String &s) { thefilename = s; } String filename() const { return thefilename; } // Access the trail size. void setTrailsize(int l) { thetrailsize = l; addBofs(l); } int trailsize() const { return thetrailsize; } // Move the current token pointer i tokens to the right (left if i is // negative), extending and contracting the window as necessary. void move(int i=1); // Same as move, but i is relative to beginning of window. void moveAbs(int i) { move(relI(i)); } // Ditto, but i is relative to beginning of file. void moveInFile(int i) { moveAbs(i-left_posinfile); } // Add i tokens to the right of the window (but don't move the current token). void extend(int i=1); // Insert a token into the window after the token at absolute location i. // If i==-1, insert before the first token. void insertAfterAbs(const Token *t, int i); void insertBeforeAbs(const Token *t, int i) { insertAfterAbs(t, i-1); } // Remove i tokens from the left of the window, or as many as possible up to the current token. // Return the number actually removed. int contract(int i=1) { return docontract(i, contractAction, 1); } // Remove enough tokens from the left of the window so that there are no more than i to the left of the current token. int contractTo(int i) { return docontract(curToki - i, contractAction, 1); } // Same as above two, but don't do contractAction. int discard(int i=1) { return docontract(i, 0, 1); } int discardTo(int i) { return docontract(curToki - i, 0, 1); } // Disable automatic contracting. void freeze() { frozen = 1; } // Disable all contracting, both explicit and automatic. void freezeTotally() { frozen = 2; } // Enable all contracting. void melt() { frozen = 0; } // 0 is quiet, 1 is "show each token as it becomes current," // >1 is "show each token as it enters window." void verbose(int i) { verboselevel = i; } // Set the contract action. Return the old value. ContractAction setContractAction(ContractAction ca) { ContractAction cur = contractAction; contractAction = ca; return cur; } // Return the current size of the window. int windowSize() const { return theWindow.length(); } // Return the offset of the current token from the beginning // of the window/begining of the file. int curpos() const { return curToki; } int posinfile() const { return (left_posinfile + curToki); } // Functions for retreiving information from the window. // // The first two functions return a pointer to the *base part* of the i'th token. // These functions are provided as a courtesy to the client, so she can avoid // handshaking wherever possible. // // i is offset relative to the beginning of the window/current token. Token *windowAbs(int i); Token *window(int i) { return windowAbs(absI(i)); } // There are also a bunch of functions to get tokens of particular // types from the window. // Since the token types are specific to the particular language // being lexed, these functions must be defined in the derived class. // They shouldn't move the current token. // Line number access. void setLineno(int l) { lalineno = l; } int lineno() const { return lalineno; } void printWindow(int verbose=0) /* const */; protected /* functions */: // Add i BOF tokens to left of the current window. void addBofs(int i); // Returns the number of tokens actually removed. int docontract(int i, ContractAction ca, int is_explicit); int implicitContract(int i) { return docontract(i, contractAction, 0); } // The function which actually does a contraction. void dropLeftmostToken(ContractAction ca); // The user-supplied gettok. It should return a pointer to the next // Token in the input stream. virtual Token *gettok() = 0; // Make sure the i'th token has type type. int handshake(int type, int i); // Get the next character from the input stream, put it in la, and // also return it. char in(); // Return what the next call to in() will return. char peek(); protected /* data */: // offset of the leftmost token in window wrt entire file. int left_posinfile; // true if the leftmost token in current window is first token in file, // or if no tokens yet in window. int atBof; // See above. int verboselevel; // 1 if automatic contracting is disabled, 2 if all contracting is disabled, 0 otherwise. int frozen; // User-specified action to perform on token when contracting it out // of window due to exceeding trail size, or explicit request from // client. ContractAction contractAction; // Maximum allowed number of tokens in window to the left of the current token. int thetrailsize; // Input character *following* the current token. char la; // The input file. istream *inf; // Name of input stream, and line number of la. String thefilename; int lalineno; // The token window. curTok points to the current token, and curToki // is its index in the window. // For this data structure, we want "a Block that you can shrink or // expand on either side." // For now, let's give up the O(1) time for operator[], and just // implement it with lists. If we decide to stick with lists, we can // change the use of operator[] in the move function to instead use // the list's "current position". // List_of_p theWindow; // Pointer to current token. Token *curTok; // Offset of current token wrt leftmost token in window // (-1 if window is empty). int curToki; }; #define TOK lexer->window(0)->type #define NEXTTOK lexer->window(1)->type #define NEXTNEXTTOK lexer->window(2)->type #define PREVTOK lexer->window(-1)->type #define PREVPREVTOK lexer->window(-2)->type #define LEXEME lexer->window(0)->lexeme #define LINENO lexer->window(0)->lineno #define LEXWS lexer->window(0)->ws #define ADV lexer->move(1) #define BACKUP lexer->move(-1) /* Macro used by the derived classes to easily define a get function. */ #define DEFINE_GET(a_typename, typecode) \ void get(a_typename &x, int i=0) \ { if (resize(absI(i)) && handshake(typecode, i)) \ x = *(a_typename*)window(i); \ } #endif