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