home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************
-
- The CalcPlus Class Library Version 1.0,
- Author: Vladimir Schipunov, Copyright (C) 1996
-
- This library is free software. Permission to use,
- copy, modify and redistribute the CalcPlus library
- for any purpose is hereby granted without fee,
- provided that the above copyright notice appear
- in all copies.
-
- *******************************************************/
-
- #ifndef __CALCLEX_H
- #define __CALCLEX_H
-
- //
- // File calclex.h has description of lexical analyzer.
- // Also some container classes are defined here.
- //
-
- class ostream;
- class istream;
-
- class Var;
- class CType;
- class CArray;
- class LexList;
- class LexStack;
- class LexDefine;
- class SyntaxError;
- class LStream;
-
- class Expression;
- class XFunction;
- class XEcho;
- class XBlock;
- class XVariable;
-
- const MaxLexLength = 1024,
- MaxIdLength = 32;
-
- typedef int Token;
-
- //
- // YLex class contains hand written yylex and some help functions.
- // It performs lexical analysis and simple preprocessing of input stream.
- //
-
- class YLex
- {
- protected:
- virtual Token __number(); // Parsing methods
- virtual Token __name();
- virtual Token __comparison();
- virtual Token __assignment();
- virtual Token __comment();
- virtual Token __string();
- virtual Token __implication();
- virtual Token __increment();
- virtual Token __preprocessor();
- virtual void __definition();
- virtual void __whitespace();
- virtual int __macro( const char* );
-
- virtual void yyerror
- (
- const char*s1 = "syntax error",
- const char*s2 = "",
- const char*s3=""
- );
- virtual yylex();
- virtual char *pyylval(){ return 0; } // Pointer to yylval which
- // should be defined along
- // with yyparse function
- char GetChar();
- void PutBack( char );
- void NextLine();
- int NextStream();
-
- public:
- char c, Lex[ MaxLexLength+1 ];
-
- istream *in; // current input stream
- LexList *errors; // list of errors
- LexList *defines; // list of cpp defs for current stream
- int Macros; // nonzero if macros may be expanded
- LexStack *input;
-
- int IfDefStack[ 32 ]; // preprocessor's directives stack
- int IfDefSP; // preprocessor's directives stack pointer
- int Skipping; // nonzero if inside false ifdef directive
-
- static TokenProc( int isProc ); // unimportant help function
-
- static LStream *lexstr; // input stream with information
- // about current line, pos etc.
-
- virtual void File // Undef parameter is nonzero if yylex
- ( // should free all defines when eof reached
- const char* name,
- int Undef = 1
- );
- virtual void Errors( ostream& ) const; // Show all errors
-
- YLex( const char* file = 0 );
- virtual ~YLex();
- virtual yyparse() = 0; // To be generated using YACC
- };
-
- #define YYLVAL(x) memcpy(pyylval(),&x,sizeof(x))
-
- #define lxEof ((Token)(-1))
- #define lxBadToken ((Token)0xFF)
-
- //
- // Class PrintObj represents objects which
- // can be printed on a stream.
- //
-
- class PrintObj
- {
- public:
- virtual void print( ostream& ) const = 0;
- virtual ~PrintObj(){}
- };
-
- inline ostream& operator <<( ostream& o, const PrintObj& obj )
- {
- obj.print( o );
- return o;
- }
-
- //
- // Item of List.
- //
-
- class LexObj : public PrintObj
- {
- public:
- LexObj *NextInList;
- LexObj *PrevInList;
-
- LexObj() : PrevInList( 0 ), NextInList( 0 ){}
- virtual const char* StringValue() const { return 0; }
- virtual isEqual( const LexObj& ) const;
- void print( ostream& ) const;
- };
-
- //
- // LStream contains pointer to the input stream,
- // information about current position and name of file
- // associated with the stream. This is the base class
- // for LSFile and LSMacro.
- //
-
- class LStream : public LexObj
- {
- public:
- istream *in;
- int dirty;
- char *file;
- int line, pos, begline;
-
- LStream() : in( 0 ), dirty( 0 ), file( 0 ){}
- ~LStream();
- virtual operator int() const { return 0; } // zero when stream is good
- virtual Open() { return 0; } // Stream initialization
- virtual isFile() const { return 0; } // File or macro expansion
- virtual UndefAll() const { return 0; } // Should free definitions at eof
- };
-
- class LSFile : public LStream
- {
- public:
- int Undef;
- LSFile( const char*, int Undef = 1 );
- ~LSFile(){}
- Open();
- operator int() const;
- UndefAll() const { return Undef; }
- isFile() const { return 1; }
- };
-
- class LSMacro : public LStream
- {
- public:
- LexDefine* def;
- char* str;
-
- LSMacro( LexDefine*, char* );
- ~LSMacro();
- };
-
- //
- // LexDefine class performs macro expansion, e.g.
- // definition "#define A(x) a+x" correspoponds to something like
- //
- // LexDefine* lex = new LexDefine( "A" );
- // lex->Translate( "a+x" );
- //
- // and than
- //
- // input->Push( new LSMacro( new istrstream( lex->Generate( in ), size )));
- //
-
- class LexDefine : public LexObj
- {
- public:
- char *name;
- char *value;
- int busy;
- int argc;
-
- LexDefine( const char* );
- ~LexDefine(){ delete[] name; delete[] value; }
- const char* StringValue() const { return name; }
- void Translate( const char* value );
- char* Generate( istream& );
- };
-
- //
- // List of LexObj's
- //
-
- class LexList : public LexObj
- {
- public:
- LexObj *FirstInList;
- LexObj *LastInList;
- int NumObj;
-
- LexList() : FirstInList( 0 ), LastInList( 0 ), NumObj( 0 ){}
- ~LexList();
- virtual void Add( LexObj* );
- virtual void Remove( LexObj* );
- virtual LexObj* operator()( const char* ) const;
- void print( ostream& o ) const;
- isEmpty(){ return !FirstInList; }
- };
-
- //
- // List iterator
- //
-
- class ListIdx
- {
- public:
- LexObj *obj;
- ListIdx( LexList& list, int first = 1 )
- { obj = first ? list.FirstInList : list.LastInList; }
- operator ++( int ){ obj = obj ? obj->NextInList : 0; return *this; }
- operator --( int ){ obj = obj ? obj->PrevInList : 0; return *this; }
- operator int(){ return obj!=0; }
- };
-
- //
- // Reference to the object
- //
-
- class LexRef : public LexObj
- {
- public:
- LexObj *o;
- LexRef( LexObj* obj ) : o( obj ){}
- ~LexRef(){}
- LexObj* Obj(){ return o; }
- };
-
- //
- // Stack container
- //
-
- class LexStack : public LexList
- {
- public:
- int ref; // objects or references (default)
- // should be put in stack
-
- LexStack( int r = 1 ) : ref( r ) {}
- ~LexStack(){}
- void Push( LexObj*o );
- void Pop();
- LexObj* Last() const;
- };
-
- //
- // Class SyntaxError.
- // To be stored in YLex::errors
- //
-
- class SyntaxError : public LexObj
- {
- public:
- char* str;
- char* file;
- int line;
-
- SyntaxError( const char*,const char*s2="",const char*s3="");
- ~SyntaxError(){ delete[] str; delete[] file; }
- const char* StringValue() const { return str; }
- };
-
- //
- // Class Lexema is used for storing objects which
- // will copy their values to yylval by themselves
- // and return appopriate token to yyparse.
- // Macro LEXEMA implements necessary methods.
- //
-
- class Lexema : public LexObj
- {
- public:
- char* lex;
- int token;
-
- Lexema( const char *s, int t = 0 );
- Lexema( const Lexema& );
- ~Lexema(){ delete[] lex; }
- void print( ostream& ) const;
- const char* StringValue() const { return lex; }
-
- virtual void *yyData() { return 0; }
- virtual int yySize() const { return 0; }
- virtual setYyLval( void *yylvalPtr );
- };
-
- #define LEXEMA(X,T,tok) \
- class X : public Lexema \
- { \
- public: \
- T data; \
- X( const char* s, int t = tok ) : \
- Lexema( s, t ) {} \
- X( const char* s, T& v, int t = tok ) : \
- Lexema( s, t ), data( v ) {} \
- ~X(); \
- void *yyData() { return &data; } \
- yySize() const { return sizeof(data); } \
- T &GetData() { return data; } \
- };
-
- //
- // Useful definition for finding lexical objects
- // in different lists. Argument type here explicitly
- // shows the class of lexema we are trying to find.
- //
-
- #define LOOKUP(list,type) { \
- LexObj* o = list( Lex ); \
- if( o ) return ((type*)o)-> \
- setYyLval( pyylval() );}
-
- typedef struct { int x; } LexDummy;
- LEXEMA( Keyword, LexDummy, 0 )
-
- typedef struct
- {
- const char* token;
- int lex;
- } KeyDef;
-
- //
- // Class Keywords performs static initialization
- // of the interpreter's dictionary.
- //
-
- class Keywords : public LexList
- {
- public:
- Keywords();
- ~Keywords(){}
- static Keywords Dictionary;
- };
-
- #endif
-