home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / CALCPLUS.ZIP / CALCLEX.H < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-02  |  9.0 KB  |  377 lines

  1. /*******************************************************
  2.  
  3.     The CalcPlus Class Library Version 1.0,
  4.     Author: Vladimir Schipunov, Copyright (C) 1996
  5.  
  6.     This library is free software. Permission to use,
  7.     copy, modify and redistribute the CalcPlus library
  8.     for any purpose is hereby granted without fee,
  9.     provided that the above copyright notice appear
  10.     in all copies.
  11.  
  12. *******************************************************/
  13.  
  14. #ifndef __CALCLEX_H
  15. #define __CALCLEX_H
  16.  
  17. //
  18. //  File calclex.h has description of lexical analyzer.
  19. //  Also some container classes are defined here.
  20. //
  21.  
  22. class   ostream;
  23. class   istream;
  24.  
  25. class   Var;
  26. class   CType;
  27. class   CArray;
  28. class   LexList;
  29. class   LexStack;
  30. class   LexDefine;
  31. class   SyntaxError;
  32. class   LStream;
  33.  
  34. class   Expression;
  35. class   XFunction;
  36. class   XEcho;
  37. class   XBlock;
  38. class   XVariable;
  39.  
  40. const   MaxLexLength = 1024,
  41.         MaxIdLength  = 32;
  42.  
  43. typedef int Token;
  44.  
  45. //
  46. //  YLex class contains hand written yylex and some help functions.
  47. //  It performs lexical analysis and simple preprocessing of input stream.
  48. //
  49.  
  50. class YLex
  51. {
  52. protected:
  53.     virtual Token __number();               //  Parsing methods
  54.     virtual Token __name();
  55.     virtual Token __comparison();
  56.     virtual Token __assignment();
  57.     virtual Token __comment();
  58.     virtual Token __string();
  59.     virtual Token __implication();
  60.     virtual Token __increment();
  61.     virtual Token __preprocessor();
  62.     virtual void  __definition();
  63.     virtual void  __whitespace();
  64.     virtual int   __macro( const char* );
  65.  
  66.     virtual void yyerror
  67.     (
  68.         const char*s1 = "syntax error",
  69.         const char*s2 = "",
  70.         const char*s3=""
  71.     );
  72.     virtual yylex();
  73.     virtual char *pyylval(){ return 0; }    //  Pointer to yylval which
  74.                                             //  should be defined along
  75.                                             //  with yyparse function
  76.     char    GetChar();
  77.     void    PutBack( char );
  78.     void    NextLine();
  79.     int     NextStream();
  80.  
  81. public:
  82.     char c, Lex[ MaxLexLength+1 ];
  83.  
  84.     istream *in;            //  current input stream
  85.     LexList *errors;        //  list of errors
  86.     LexList *defines;       //  list of cpp defs for current stream
  87.     int Macros;             //  nonzero if macros may be expanded
  88.     LexStack *input;
  89.  
  90.     int IfDefStack[ 32 ];   //  preprocessor's directives stack
  91.     int IfDefSP;            //  preprocessor's directives stack pointer
  92.     int Skipping;           //  nonzero if inside false ifdef directive
  93.     
  94.     static TokenProc( int isProc ); //  unimportant help function
  95.  
  96.     static LStream *lexstr; //  input stream with information
  97.                             //  about current line, pos etc.
  98.  
  99.     virtual void File       //  Undef parameter is nonzero if yylex
  100.     (                       //  should free all defines when eof reached
  101.         const char* name,
  102.         int Undef = 1
  103.     );    
  104.     virtual void Errors( ostream& ) const;  //  Show all errors
  105.  
  106.     YLex( const char* file = 0 );
  107.     virtual ~YLex();
  108.     virtual yyparse() = 0;  //  To be generated using YACC
  109. };
  110.  
  111. #define YYLVAL(x) memcpy(pyylval(),&x,sizeof(x))
  112.  
  113. #define lxEof      ((Token)(-1))
  114. #define lxBadToken ((Token)0xFF)
  115.  
  116. //
  117. //  Class PrintObj represents objects which
  118. //  can be printed on a stream.
  119. //
  120.  
  121. class PrintObj
  122. {
  123. public:
  124.     virtual void print( ostream& ) const = 0;
  125.     virtual ~PrintObj(){}
  126. };
  127.  
  128. inline ostream& operator <<( ostream& o, const PrintObj& obj )
  129. {
  130.     obj.print( o );
  131.     return o;
  132. }
  133.  
  134. //
  135. //  Item of List.
  136. //
  137.  
  138. class LexObj : public PrintObj
  139. {
  140. public:
  141.     LexObj *NextInList;
  142.     LexObj *PrevInList;
  143.  
  144.     LexObj() : PrevInList( 0 ), NextInList( 0 ){}
  145.     virtual const char* StringValue() const { return 0; }
  146.     virtual isEqual( const LexObj& ) const;
  147.     void print( ostream& ) const;
  148. };
  149.  
  150. //
  151. //  LStream contains pointer to the input stream,
  152. //  information about current position and name of file
  153. //  associated with the stream. This is the base class
  154. //  for LSFile and LSMacro.
  155. //
  156.  
  157. class LStream : public LexObj
  158. {
  159. public:
  160.     istream *in;
  161.     int dirty;
  162.     char *file;
  163.     int line, pos, begline;
  164.  
  165.     LStream() : in( 0 ), dirty( 0 ), file( 0 ){}
  166.     ~LStream();
  167.     virtual operator int() const { return 0; }  //  zero when stream is good
  168.     virtual Open() { return 0; }            //  Stream initialization
  169.     virtual isFile() const { return 0; }    //  File or macro expansion
  170.     virtual UndefAll() const { return 0; }  //  Should free definitions at eof
  171. };
  172.  
  173. class LSFile : public LStream
  174. {
  175. public:
  176.     int Undef;
  177.     LSFile( const char*, int Undef = 1 );
  178.     ~LSFile(){}
  179.     Open();
  180.     operator int() const;
  181.     UndefAll() const { return Undef; }
  182.     isFile() const { return 1; }
  183. };
  184.  
  185. class LSMacro : public LStream
  186. {
  187. public:
  188.     LexDefine* def;
  189.     char* str;
  190.  
  191.     LSMacro( LexDefine*, char* );
  192.     ~LSMacro();
  193. };
  194.  
  195. //
  196. //  LexDefine class performs macro expansion, e.g.
  197. //  definition "#define A(x) a+x" correspoponds to something like
  198. //
  199. //      LexDefine* lex = new LexDefine( "A" );
  200. //      lex->Translate( "a+x" );
  201. //
  202. //  and than
  203. //
  204. //      input->Push( new LSMacro( new istrstream( lex->Generate( in ), size )));
  205. //
  206.  
  207. class LexDefine : public LexObj
  208. {
  209. public:
  210.     char *name;
  211.     char *value;
  212.     int busy;
  213.     int argc;
  214.  
  215.     LexDefine( const char* );
  216.     ~LexDefine(){ delete[] name; delete[] value; }
  217.     const char* StringValue() const { return name; }
  218.     void Translate( const char* value );
  219.     char* Generate( istream& );
  220. };
  221.  
  222. //
  223. //  List of LexObj's
  224. //
  225.  
  226. class LexList : public LexObj
  227. {
  228. public:
  229.     LexObj *FirstInList;
  230.     LexObj *LastInList;
  231.     int NumObj;
  232.  
  233.     LexList() : FirstInList( 0 ), LastInList( 0 ), NumObj( 0 ){}
  234.     ~LexList();
  235.     virtual void Add( LexObj* );
  236.     virtual void Remove( LexObj* );
  237.     virtual LexObj* operator()( const char* ) const;
  238.     void print( ostream& o ) const;
  239.     isEmpty(){ return !FirstInList; }
  240. };
  241.  
  242. //
  243. //  List iterator
  244. //
  245.  
  246. class ListIdx
  247. {
  248. public:
  249.     LexObj *obj;
  250.     ListIdx( LexList& list, int first = 1 )
  251.     { obj = first ? list.FirstInList : list.LastInList; }
  252.     operator ++( int ){ obj = obj ? obj->NextInList : 0; return *this; }
  253.     operator --( int ){ obj = obj ? obj->PrevInList : 0; return *this; }
  254.     operator int(){ return obj!=0; }
  255. };
  256.  
  257. //
  258. //  Reference to the object
  259. //
  260.  
  261. class LexRef : public LexObj
  262. {
  263. public:
  264.     LexObj *o;
  265.     LexRef( LexObj* obj ) : o( obj ){}
  266.     ~LexRef(){}
  267.     LexObj* Obj(){ return o; }
  268. };
  269.  
  270. //
  271. //  Stack container
  272. //
  273.  
  274. class LexStack : public LexList
  275. {
  276. public:
  277.     int ref;    //  objects or references (default)
  278.                 //  should be put in stack
  279.  
  280.     LexStack( int r = 1 ) : ref( r ) {}
  281.     ~LexStack(){}
  282.     void Push( LexObj*o );
  283.     void Pop();
  284.     LexObj* Last() const;
  285. };
  286.  
  287. //
  288. //  Class SyntaxError.
  289. //  To be stored in YLex::errors
  290. //
  291.  
  292. class SyntaxError : public LexObj
  293. {
  294. public:
  295.     char* str;
  296.     char* file;
  297.     int line;
  298.  
  299.     SyntaxError( const char*,const char*s2="",const char*s3="");
  300.     ~SyntaxError(){ delete[] str; delete[] file; }
  301.     const char* StringValue() const { return str; }
  302. };
  303.  
  304. //
  305. //  Class Lexema is used for storing objects which
  306. //  will copy their values to yylval by themselves
  307. //  and return appopriate token to yyparse.
  308. //  Macro LEXEMA implements necessary methods.
  309. //
  310.  
  311. class Lexema : public LexObj
  312. {
  313. public:
  314.     char* lex;
  315.     int token;
  316.  
  317.     Lexema( const char *s, int t = 0 );
  318.     Lexema( const Lexema& );
  319.     ~Lexema(){ delete[] lex; }
  320.     void print( ostream& ) const;
  321.     const char* StringValue() const { return lex; }
  322.  
  323.     virtual void   *yyData()       { return 0; }
  324.     virtual int     yySize() const { return 0; }
  325.     virtual setYyLval( void *yylvalPtr );
  326. };
  327.  
  328. #define LEXEMA(X,T,tok) \
  329. class X : public Lexema                     \
  330. {                                           \
  331. public:                                     \
  332.     T data;                                 \
  333.     X( const char* s, int t = tok ) :       \
  334.         Lexema( s, t ) {}                   \
  335.     X( const char* s, T& v, int t = tok ) : \
  336.         Lexema( s, t ), data( v ) {}        \
  337.     ~X();                                   \
  338.     void *yyData() { return &data;  }       \
  339.     yySize() const { return sizeof(data); } \
  340.     T &GetData() { return data; }           \
  341. };
  342.  
  343. //
  344. //  Useful definition for finding lexical objects
  345. //  in different lists. Argument type here explicitly
  346. //  shows the class of lexema we are trying to find.
  347. //
  348.  
  349. #define LOOKUP(list,type) {     \
  350.     LexObj* o = list( Lex );    \
  351.     if( o ) return ((type*)o)-> \
  352.         setYyLval( pyylval() );}
  353.  
  354. typedef struct { int x; } LexDummy;
  355. LEXEMA( Keyword, LexDummy, 0 )
  356.  
  357. typedef struct
  358. {
  359.     const char* token;
  360.     int lex;
  361. } KeyDef;
  362.  
  363. //
  364. //  Class Keywords performs static initialization
  365. //  of the interpreter's dictionary.
  366. //
  367.  
  368. class Keywords : public LexList
  369. {
  370. public:
  371.     Keywords();
  372.     ~Keywords(){}
  373.     static Keywords Dictionary;
  374. };
  375.  
  376. #endif
  377.