Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Xabsl2/yabsl/vsyabsl/stdservice.h

Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003          Copyright (c) Microsoft Corporation, All rights reserved.             
00004     This code sample is provided "AS IS" without warranty of any kind, 
00005     it is not recommended for use in a production environment.
00006 ***************************************************************************/
00007 
00008 #ifndef babel_stdservice_h
00009 #define babel_stdservice_h
00010 
00011 //---------------------------------------------------------
00012 //  Basic type definitions
00013 //---------------------------------------------------------
00014 typedef wchar_t  InputChar;      
00015 
00016 const int MaxErrorMessage = 128;
00017 const int MaxStr          = 512;
00018 
00019 //---------------------------------------------------------
00020 //  Documenting defines
00021 //---------------------------------------------------------
00022 #define override
00023 #define final
00024 #define pure            = 0
00025 #define local   static
00026 #define global
00027 
00028 
00029 //---------------------------------------------------------
00030 //  Handle Colorizer state
00031 //---------------------------------------------------------
00032 typedef unsigned State;
00033 typedef unsigned Bits;
00034 typedef unsigned LexState;
00035 
00036 const Bits  StateBits     = 4;            //max 16 lex states
00037 const Bits  CommentBits   = 8;            //max 256 nesting levels
00038 const State MaxCommentNesting = 255;
00039 
00040 class ColorizerState
00041 {
00042 private:
00043   State   m_state;
00044   Bits    m_bitsValid;
00045 
00046 public:
00047   ColorizerState();        
00048   ColorizerState( in State );
00049   void  reset( in State );
00050   
00051   State getState(void);            
00052 
00053   State load( in Bits );
00054   void  save( in State, in Bits );
00055 };
00056 
00057 //---------------------------------------------------------
00058 //  Locations
00059 //---------------------------------------------------------
00060 
00061 struct Location
00062 {
00063 public:
00064     int startRow, endRow;   //line number
00065     int startIdx, endIdx;   //character index ('\t' counts as one character)
00066     const char* text;       //the scanned text
00067     int   textLen;          //length of the text
00068     int   textOfs;          //offset in the *original* text buffer
00069     int   token;            //token at the location
00070 
00071 // "initialize" initializes the location to the start state
00072     Location();
00073     Location( in const Location&, in const Location& );
00074     final void initialize(void);
00075 
00076 // "update" updates the location given some text
00077     final void update( in int token, in const char* text, in int textLen );
00078 };
00079 
00080 //bison/yacc specific defines
00081 #ifndef YYLTYPE
00082  #define YYLTYPE            Location
00083 #endif
00084 
00085 #ifndef YYSTYPE
00086  #define YYSTYPE            Location
00087 #endif
00088 
00089 #define first_line      startRow
00090 #define first_column    startIdx
00091 #define last_line       endRow
00092 #define last_column     endIdx
00093 
00094 //---------------------------------------------------------
00095 //  Token information
00096 //---------------------------------------------------------
00097 typedef int      Token;
00098 const Token      TokenEnd        = (Token)(-1);
00099 const ColorClass ColorClassEnd   = (ColorClass)(-1);
00100 
00101 struct TokenInfo 
00102 {
00103   Token         token;
00104   ColorClass    colorClass;
00105   const char*   description;
00106   CharClass     charClass;
00107   TriggerClass  trigger;
00108 };
00109 
00110 
00111 //---------------------------------------------------------
00112 //  Color information
00113 //---------------------------------------------------------
00114 struct ColorInfo 
00115 {
00116   ColorClass  colorClass;
00117   const char* description;
00118   const char* style;
00119 };
00120 
00121 //---------------------------------------------------------
00122 //  Method format information
00123 //---------------------------------------------------------
00124 struct MethodFormat
00125 {
00126   const char* parStart;
00127   const char* parSep;
00128   const char* parEnd;
00129   const char* typeStart;
00130   const char* typeEnd;
00131   bool        typePrefixed; 
00132 };
00133 
00134 //---------------------------------------------------------
00135 //  Comment format information
00136 //---------------------------------------------------------
00137 struct CommentFormat
00138 {
00139   const char* lineStart;
00140   const char* blockStart;
00141   const char* blockEnd;
00142   bool        useLineComments; 
00143 };
00144 
00145 
00146 //---------------------------------------------------------
00147 //  Colorizer state
00148 //---------------------------------------------------------
00149 struct yy_buffer_state;
00150 
00151 struct LexBuffer
00152 {
00153   LexBuffer*        prevBuffer;
00154 
00155   const InputChar*  inputLim;
00156   const InputChar*  input;
00157   const InputChar*  inputStart;
00158   yy_buffer_state*  yy_buffer;
00159 
00160   IParseSink*       sink;         //used by error messages
00161   ParseReason       reason;
00162   
00163   //these variables are influenced by the lexer
00164   ColorizerState    cstate;
00165   Token             token;
00166   Location          location;
00167   
00168   //sometimes these globals need to be saved/restored 
00169   YYLTYPE           yylloc;
00170   YYSTYPE           yylval;
00171   Service*          service;
00172 
00173   LexBuffer( int size = 16*1024);
00174   ~LexBuffer();
00175 };
00176   
00177 //---------------------------------------------------------
00178 //  Basic service implementation for colorization and syntax checking
00179 //---------------------------------------------------------
00180 class StdService : public IBabelService
00181 {
00182 private:
00183     ULONG             m_refCount;
00184     ITypeInfo*        m_typeInfo;   //IBabelService typeinfo.
00185     
00186     CRITICAL_SECTION  m_lexerLock;
00187     CRITICAL_SECTION  m_parserLock;
00188         
00189     
00190 protected:
00191     LexBuffer*    m_buffer;
00192     LexBuffer     m_lexerBuffer;
00193     LexBuffer     m_parserBuffer;
00194 
00195     final void    enterParser();
00196     final void    leaveParser();
00197     final void    enterLexer();  
00198     final void    leaveLexer();
00199 
00200     final void    enterSink() const; 
00201     final void    leaveSink() const;
00202     
00203     final void    initBuffer( inout LexBuffer& buffer );
00204     final void    switchBuffer( inout LexBuffer&    buffer,
00205                                 in State            state,
00206                                 in int              inputLen  = 0,
00207                                 in const InputChar* input     = NULL,
00208                                 in IParseSink*      sink      = NULL,
00209                                 in ParseReason      reason    = ReasonColorize );
00210     final State   doneBuffer();  
00211     
00212 
00213 friend int yyparse(void);       //now the parser can call "parserNextToken"
00214 
00215     StdService();
00216     virtual ~StdService();
00217    
00218 //scan a new token, called by parser and ColorLine.
00219     virtual Token nextToken(void);    
00220     virtual Token parserNextToken(void);    //ignores 'white' tokens    
00221 
00222 //which tokens are passed to the parser, override to see whitespace and comments
00223     virtual bool  isParserToken( in const TokenInfo& tokenInfo ) const;
00224 
00225 //color info
00226 //  this needs to be overridden only if the language provides
00227 //  custom color classes instead of the default ones.
00228     virtual const ColorInfo* getColorInfo(void) const;
00229 
00230     final   const ColorInfo* lookupColorInfo( in ColorClass ) const;
00231     
00232 //token information
00233 // "getTokenInfo" needs to be overridden for each new language to
00234 // map tokens to colorclasses and to tell if a token should be
00235 // considered white space for the parser.
00236     virtual const TokenInfo* getTokenInfo(void) const;
00237 
00238     final   const TokenInfo* lookupTokenInfo( in Token ) const;
00239     final   const char*      getTokenDescription( in Token ) const;
00240 
00241 
00242 //method format
00243 //  override this method for custom formatting
00244     virtual const MethodFormat* getMethodFormat(void) const;
00245 
00246 //comment format
00247 //  override this method for custom comments
00248     virtual const CommentFormat* getCommentFormat(void) const;
00249 
00250 //override these two functions to implement your own state
00251     virtual void initColorizerState( inout ColorizerState& );
00252     virtual void doneColorizerState( inout ColorizerState& );
00253 
00254      
00255 public:
00256     //hook for the lexer (thats why it is public)
00257     virtual void  readInput( out   char* buffer, 
00258                              out   int*  result, 
00259                              in    int   maxSize );
00260 
00261     //send an error message (only sends within "ParseSource" context)
00262     virtual void  errorMessage( in Severity, 
00263                                 in const char* message,
00264                                 in const Location* = NULL )    const;
00265 
00266     //convenient error functions 
00267     final void fatalFlexError( in const char* message )  const;
00268 
00269     final void lexicalError( in Severity, 
00270                              in const char* message )     const;
00271     final void syntaxError( in const char* construct,
00272                             in const Location* = NULL )  const;
00273 
00274     final void expectError( in const char* construct,
00275                             in const char* expecting,
00276                             in const Location* = NULL )  const;
00277     
00278     //parenthesis
00279     final void matchPair( in const Location& loc1, in const Location& loc2 ) const;
00280     final void matchTriple( in const Location& loc1, in const Location& loc2, in const Location& loc3 ) const;
00281 
00282     //scope functions
00283     final Location range( in const Location& loc1, in const Location& loc2 ) const;
00284     final const char* tokenText( in const Location* = NULL, in const Location* = NULL ) const;
00285     final BSTR tokenBstr( in const Location* tokenStart = NULL
00286                         , in const Location* tokenEnd   = NULL ) const;
00287 
00288     final void addScope( in const Location& start, in const Location& end,
00289                          in ScopeKind kind, in ScopeAccess access, in ScopeStorage storage,
00290                          in const Location& name, 
00291                          in const Location& descStart, in const Location& descEnd,
00292                          in const Location* type = NULL,         
00293                          in long glyph = -1,
00294                          in bool merge = false,
00295                          in bool makeDescription = false
00296                         );
00297     final void addScopeText( in const Location& start, in const Location& end,
00298                              in ScopeKind kind, in ScopeAccess access, in ScopeStorage storage,
00299                              in const char* name    = NULL, 
00300                              in const char* description = NULL,
00301                              in const char* type    = NULL,
00302                              in const char* display = NULL, 
00303                              in long glyph = -1,
00304                              in bool merge = false );
00305     final void addExtern( in const Location& start, in const Location& end,
00306                           in IScope* scope );
00307 
00308     //member selection
00309     final void startName( in const Location& name) const;
00310     final void qualifyName( in const Location& selector, in const Location& name) const;
00311     
00312     final void autoExpression( in const Location& expr ) const;
00313     final void codeSpan( in const Location& start, in const Location& end ) const;
00314 
00315     //method info
00316     final void startParameters( in const Location& ) const;
00317     final void parameter(in const Location& ) const;
00318     final void endParameters(in const Location& ) const;
00319 
00320 
00321     //context
00322     void getProject( out IBabelProject** project );
00323     void getPackage( out IBabelPackage** package );
00324     void getFileName( out char* filePath, in int nameLen );    
00325     
00326     void searchFile( inout char* fileName, in int nameLen );
00327     void loadScope( in const char* fileName, out IScope** scope );
00328 
00329     //lexer interface
00330     final void     setLexState( in LexState );
00331     final LexState getLexState(void)    const;
00332 
00333     // IUnknown methods 
00334     STDMETHODIMP QueryInterface( in REFIID iid, out void** obj);
00335     STDMETHODIMP_(ULONG) AddRef();
00336     STDMETHODIMP_(ULONG) Release();
00337 
00338     //implement IDispatch (for IBabelService only)
00339     STDMETHODIMP GetTypeInfoCount( out UINT* count );
00340     STDMETHODIMP GetTypeInfo     ( in UINT index, in LCID lcid, out ITypeInfo** typeInfo );
00341     STDMETHODIMP GetIDsOfNames   ( in REFIID iid, in OLECHAR** names, in UINT count, in LCID lcid, out DISPID* dispids );
00342     STDMETHODIMP Invoke          ( in DISPID dispid, in REFIID iid, in LCID lcid, in WORD flags, in DISPPARAMS* args, out VARIANT* result, out EXCEPINFO* error, out UINT* errorArg );
00343 
00344     //implement IBabelService
00345     STDMETHODIMP  Init( in LCID lcid, in long reserved );
00346     STDMETHODIMP  Done();
00347 
00348     STDMETHODIMP  ColorCount  ( out ColorClass* count );
00349     STDMETHODIMP  GetColorInfo( in  ColorClass index, 
00350                                 out BSTR* description,
00351                                 out BSTR* style ); 
00352     STDMETHODIMP  ColorLine   ( in BSTR line, 
00353                                 in IColorSink* sink, 
00354                                 inout long* state );
00355     STDMETHODIMP  ParseSource ( in BSTR text,
00356                                 in IParseSink* sink,
00357                                 in ParseReason reason,
00358                                 in long reserved,
00359                                 out IScope** scope );
00360     STDMETHODIMP GetMethodFormat(out BSTR* parStart, out BSTR* parSep, out BSTR* parEnd,
00361                                  out BSTR* typeStart, out BSTR* typeEnd,
00362                                  out VARIANT_BOOL* typePrefixed );
00363     STDMETHODIMP GetCommentFormat( out BSTR* lineStart, 
00364                                    out BSTR* blockStart, out BSTR* blockEnd,
00365                                    out VARIANT_BOOL* useLineComments );
00366     STDMETHODIMP GetImageList( out long* imageListHandle, out long* glyphCount );
00367 };
00368 
00369 
00370 //---------------------------------------------------------
00371 //  Extended service that implements nested comments
00372 //---------------------------------------------------------
00373 class CommentService : public StdService
00374 {
00375 private:
00376     State    m_commentNesting;
00377     LexState m_returnState;
00378 
00379 protected:
00380 //implement our own state
00381     override void initColorizerState( inout ColorizerState& );
00382     override void doneColorizerState( inout ColorizerState& );
00383 
00384 public:
00385     CommentService();
00386 
00387 //commands
00388     void  enterComment( in LexState commentState = 0 );       
00389     void  leaveComment(void);
00390 
00391 //queries
00392     bool  inComment(void)   const;
00393 };
00394 
00395 
00396     
00397 
00398 //---------------------------------------------------------
00399 //  Prototypes for both the lexer and parser
00400 //---------------------------------------------------------
00401 extern int      yylex();
00402 extern void     yyrestart( in FILE* );
00403 extern "C" int yywrap();
00404 
00405 extern char*    yytext;
00406 extern int      yyleng;
00407 
00408 #ifndef YY_NEVER_INTERACTIVE
00409 #define YY_NEVER_INTERACTIVE 1
00410 #endif
00411 
00412 #define YY_FATAL_ERROR(msg) g_service->fatalFlexError( msg ) 
00413 
00414 extern int      yyparse();
00415 extern "C" void yyerror( const char* message );
00416 
00417 extern YYSTYPE  yylval;
00418 extern YYLTYPE  yylloc;
00419 extern int      yychar;
00420 
00421 #ifndef YYLSP_NEEDED
00422 #define YYLSP_NEEDED 1              //we need 'yylloc'
00423 #endif
00424 
00425 //make the lexer read its input from our input buffer
00426 #define YY_INPUT(buf,result,maxSize)  g_service->readInput( buf, &result, maxSize )
00427 
00428 
00429 
00430 //make the parser use our lexer
00431 #ifdef YYBISON           //only if we are inside the parser
00432 #define yylex            g_service->parserNextToken
00433 #endif
00434 
00435 
00436 //multi-threading means we have to save the entire lexer global state, sigh
00437 
00438 struct LexCompleteState
00439 {
00440   yy_buffer_state*    yy_current_buffer;
00441 
00442   char  yy_hold_char; /* yy_hold_char holds the character lost when yytext is formed. */
00443   int   yy_n_chars;   /* number of characters read into yy_ch_buf */
00444   int   yyleng;
00445 
00446   /* Points to current character in buffer. */
00447   char *yy_c_buf_p;
00448   int   yy_init;    /* whether we need to initialize */
00449   int   yy_start; /* start state number */
00450 
00451   /* Flag which is used to allow yywrap()'s to do buffer switches
00452    * instead of setting up a fresh yyin.  A bit of a hack ...
00453    */
00454   int yy_did_buffer_switch_on_eof;
00455   FILE *yyin;
00456   FILE *yyout;
00457 
00458   char    *yytext;
00459   int     yy_last_accepting_state;
00460   char    *yy_last_accepting_cpos;
00461 
00462   /* The intent behind this definition is that it'll catch
00463    * any uses of REJECT which flex missed.
00464    */
00465   int yy_more_flag;
00466   int yy_more_len;
00467 
00468   /* sometimes needed but not yet supported */
00469   int yy_start_stack_ptr;
00470   int yy_start_stack_depth;
00471   int* yy_start_stack;
00472 
00473   int* yy_state_buf;
00474   int* yy_state_ptr;
00475 
00476   char* yy_full_match;
00477   int* yy_full_state;
00478   int yy_full_lp;
00479 
00480   int yy_lp;
00481   int yy_looking_for_trail_begin;
00482 };
00483 
00484 //things that just need to be defined in the lex-spec
00485 extern void     primSetLexState( in LexState );
00486 extern LexState primGetLexState( void );
00487 
00488 extern void     yy_switch_to_buffer( yy_buffer_state* );
00489 extern void     yy_flush_buffer( yy_buffer_state* );
00490 extern void     yy_delete_buffer( yy_buffer_state* );
00491 extern yy_buffer_state* yy_create_buffer( FILE*, int );
00492 
00493 
00494 extern void     primSaveLexCompleteState( out LexCompleteState& );
00495 extern void     primRestoreLexCompleteState( in LexCompleteState& );
00496 
00497 #endif

Generated on Mon Mar 20 22:00:10 2006 for GT2005 by doxygen 1.3.6