xref: /AOO41X/main/basic/source/comp/token.cxx (revision 0c8b819cba58d752925fe3b4b585b9da6c3db38b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 
27 #include <ctype.h>
28 #include "sbcomp.hxx"
29 
30 struct TokenTable { SbiToken t; const char *s; };
31 
32 static short nToken;                    // Anzahl der Tokens
33 
34 static TokenTable* pTokTable;
35 
36 static TokenTable aTokTable_Basic [] = {        // Token-Tabelle:
37 
38     { CAT,      "&" },
39     { MUL,      "*" },
40     { PLUS,     "+" },
41     { MINUS,    "-" },
42     { DIV,      "/" },
43     { EOS,      ":" },
44     { ASSIGN,   ":=" },
45     { LT,       "<" },
46     { LE,       "<=" },
47     { NE,       "<>" },
48     { EQ,       "=" },
49     { GT,       ">" },
50     { GE,       ">=" },
51     { ACCESS,   "Access" },
52     { ALIAS,    "Alias" },
53     { AND,      "And" },
54     { ANY,      "Any" },
55     { APPEND,   "Append" },
56     { AS,       "As" },
57     { BASE,     "Base" },
58     { BINARY,   "Binary" },
59     { TBOOLEAN, "Boolean" },
60     { BYREF,    "ByRef", },
61     { TBYTE,    "Byte", },
62     { BYVAL,    "ByVal", },
63     { CALL,     "Call" },
64     { CASE,     "Case" },
65     { _CDECL_,  "Cdecl" },
66     { CLASSMODULE, "ClassModule" },
67     { CLOSE,    "Close" },
68     { COMPARE,  "Compare" },
69     { COMPATIBLE,"Compatible" },
70     { _CONST_,  "Const" },
71     { TCURRENCY,"Currency" },
72     { TDATE,    "Date" },
73     { DECLARE,  "Declare" },
74     { DEFBOOL,  "DefBool" },
75     { DEFCUR,   "DefCur" },
76     { DEFDATE,  "DefDate" },
77     { DEFDBL,   "DefDbl" },
78     { DEFERR,   "DefErr" },
79     { DEFINT,   "DefInt" },
80     { DEFLNG,   "DefLng" },
81     { DEFOBJ,   "DefObj" },
82     { DEFSNG,   "DefSng" },
83     { DEFSTR,   "DefStr" },
84     { DEFVAR,   "DefVar" },
85     { DIM,      "Dim" },
86     { DO,       "Do" },
87     { TDOUBLE,  "Double" },
88     { EACH,     "Each" },
89     { ELSE,     "Else" },
90     { ELSEIF,   "ElseIf" },
91     { END,      "End" },
92     { ENDENUM,  "End Enum" },
93     { ENDFUNC,  "End Function" },
94     { ENDIF,    "End If" },
95     { ENDPROPERTY, "End Property" },
96     { ENDSELECT,"End Select" },
97     { ENDSUB,   "End Sub" },
98     { ENDTYPE,  "End Type" },
99     { ENDIF,    "EndIf" },
100     { ENUM,     "Enum" },
101     { EQV,      "Eqv" },
102     { ERASE,    "Erase" },
103     { _ERROR_,  "Error" },
104     { EXIT,     "Exit" },
105     { BASIC_EXPLICIT, "Explicit" },
106     { FOR,      "For" },
107     { FUNCTION, "Function" },
108     { GET,      "Get" },
109     { GLOBAL,   "Global" },
110     { GOSUB,    "GoSub" },
111     { GOTO,     "GoTo" },
112     { IF,       "If" },
113     { IMP,      "Imp" },
114     { IMPLEMENTS, "Implements" },
115     { _IN_,     "In" },
116     { INPUT,    "Input" },              // auch INPUT #
117     { TINTEGER, "Integer" },
118     { IS,       "Is" },
119     { LET,      "Let" },
120     { LIB,      "Lib" },
121     { LIKE,     "Like" },
122     { LINE,     "Line" },
123     { LINEINPUT,"Line Input" },
124     { LOCAL,    "Local" },
125     { LOCK,     "Lock" },
126     { TLONG,    "Long" },
127     { LOOP,     "Loop" },
128     { LPRINT,   "LPrint" },
129     { LSET,     "LSet" }, // JSM
130     { MOD,      "Mod" },
131     { NAME,     "Name" },
132     { NEW,      "New" },
133     { NEXT,     "Next" },
134     { NOT,      "Not" },
135     { TOBJECT,  "Object" },
136     { ON,       "On" },
137     { OPEN,     "Open" },
138     { OPTION,   "Option" },
139     { _OPTIONAL_,   "Optional" },
140     { OR,       "Or" },
141     { OUTPUT,   "Output" },
142     { PARAMARRAY,   "ParamArray" },
143     { PRESERVE, "Preserve" },
144     { PRINT,    "Print" },
145     { PRIVATE,  "Private" },
146     { PROPERTY, "Property" },
147     { PUBLIC,   "Public" },
148     { RANDOM,   "Random" },
149     { READ,     "Read" },
150     { REDIM,    "ReDim" },
151     { REM,      "Rem" },
152     { RESUME,   "Resume" },
153     { RETURN,   "Return" },
154     { RSET,     "RSet" }, // JSM
155     { SELECT,   "Select" },
156     { SET,      "Set" },
157 #ifdef SHARED
158 #undef SHARED
159 #define tmpSHARED
160 #endif
161     { SHARED,   "Shared" },
162 #ifdef tmpSHARED
163 #define SHARED
164 #undef tmpSHARED
165 #endif
166     { TSINGLE,  "Single" },
167     { STATIC,   "Static" },
168     { STEP,     "Step" },
169     { STOP,     "Stop" },
170     { TSTRING,  "String" },
171     { SUB,      "Sub" },
172     { STOP,     "System" },
173     { TEXT,     "Text" },
174     { THEN,     "Then" },
175     { TO,       "To", },
176     { TYPE,     "Type" },
177     { TYPEOF,   "TypeOf" },
178     { UNTIL,    "Until" },
179     { TVARIANT, "Variant" },
180     { VBASUPPORT,   "VbaSupport" },
181     { WEND,     "Wend" },
182     { WHILE,    "While" },
183     { WITH,     "With" },
184     { WITHEVENTS,   "WithEvents" },
185     { WRITE,    "Write" },              // auch WRITE #
186     { XOR,      "Xor" },
187     { NIL,      "" }
188 };
189 
190 /*
191 TokenTable aTokTable_Java [] = {        // Token-Tabelle:
192 
193     { JS_LOG_NOT,   "!" },
194     { JS_NE,        "!=" },
195     { JS_MOD,       "%" },
196     { JS_ASS_MOD,   "%=" },
197     { JS_BIT_AND,   "&" },
198     { JS_LOG_AND,   "&&" },
199     { JS_ASS_AND,   "&=" },
200     { JS_LPAREN,    "(" },
201     { JS_RPAREN,    ")" },
202     { JS_MUL,       "*" },
203     { JS_ASS_MUL,   "*=" },
204     { JS_PLUS,      "+" },
205     { JS_INC,       "++" },
206     { JS_ASS_PLUS,  "+=" },
207     { JS_COMMA,     "," },
208     { JS_MINUS,     "-" },
209     { JS_DEC,       "--" },
210     { JS_ASS_MINUS, "-=" },
211     { JS_DIV,       "/" },
212     { JS_ASS_DIV,   "/=" },
213     { JS_COND_SEL,  ":" },
214     { JS_LT,        "<" },
215     { JS_LSHIFT,    "<<" },
216     { JS_ASS_LSHIFT,"<<=" },
217     { JS_LE,        "<=" },
218     { JS_NE,        "<>" },
219     { JS_ASSIGNMENT,"=" },
220     { JS_EQ,        "==" },
221     { JS_GT,        ">" },
222     { JS_RSHIFT,    ">>" },
223     { JS_ASS_RSHIFT,">>=" },
224     { JS_RSHIFT_Z,  ">>>" },
225     { JS_ASS_RSHIFT_Z,">>>=" },
226     { JS_GE,        ">=" },
227     { JS_COND_QUEST,"?" },
228     { ACCESS,   "Access" },
229     { ALIAS,    "Alias" },
230     { AND,      "And" },
231     { ANY,      "Any" },
232     { APPEND,   "Append" },
233     { AS,       "As" },
234     { BASE,     "Base" },
235     { BINARY,   "Binary" },
236     { TBOOLEAN, "Boolean" },
237     { BYVAL,    "ByVal", },
238     { CALL,     "Call" },
239     { CASE,     "Case" },
240     { _CDECL_,  "Cdecl" },
241     { CLOSE,    "Close" },
242     { COMPARE,  "Compare" },
243     { _CONST_,  "Const" },
244     { TCURRENCY,"Currency" },
245     { TDATE,    "Date" },
246     { DECLARE,  "Declare" },
247     { DEFBOOL,  "DefBool" },
248     { DEFCUR,   "DefCur" },
249     { DEFDATE,  "DefDate" },
250     { DEFDBL,   "DefDbl" },
251     { DEFERR,   "DefErr" },
252     { DEFINT,   "DefInt" },
253     { DEFLNG,   "DefLng" },
254     { DEFOBJ,   "DefObj" },
255     { DEFSNG,   "DefSng" },
256     { DEFSTR,   "DefStr" },
257     { DEFVAR,   "DefVar" },
258     { DIM,      "Dim" },
259     { DO,       "Do" },
260     { TDOUBLE,  "Double" },
261     { EACH,     "Each" },
262     { ELSE,     "Else" },
263     { ELSEIF,   "ElseIf" },
264     { END,      "End" },
265     { ENDFUNC,  "End Function" },
266     { ENDIF,    "End If" },
267     { ENDSELECT,"End Select" },
268     { ENDSUB,   "End Sub" },
269     { ENDTYPE,  "End Type" },
270     { ENDIF,    "EndIf" },
271     { EQV,      "Eqv" },
272     { ERASE,    "Erase" },
273     { _ERROR_,  "Error" },
274     { EXIT,     "Exit" },
275     { BASIC_EXPLICIT, "Explicit" },
276     { FOR,      "For" },
277     { FUNCTION, "Function" },
278     { GLOBAL,   "Global" },
279     { GOSUB,    "GoSub" },
280     { GOTO,     "GoTo" },
281     { IF,       "If" },
282     { IMP,      "Imp" },
283     { _IN_,     "In" },
284     { INPUT,    "Input" },              // auch INPUT #
285     { TINTEGER, "Integer" },
286     { IS,       "Is" },
287     { LET,      "Let" },
288     { LIB,      "Lib" },
289     { LINE,     "Line" },
290     { LINEINPUT,"Line Input" },
291     { LOCAL,    "Local" },
292     { LOCK,     "Lock" },
293     { TLONG,    "Long" },
294     { LOOP,     "Loop" },
295     { LPRINT,   "LPrint" },
296     { LSET,     "LSet" }, // JSM
297     { MOD,      "Mod" },
298     { NAME,     "Name" },
299     { NEW,      "New" },
300     { NEXT,     "Next" },
301     { NOT,      "Not" },
302     { TOBJECT,  "Object" },
303     { ON,       "On" },
304     { OPEN,     "Open" },
305     { OPTION,   "Option" },
306     { _OPTIONAL_,   "Optional" },
307     { OR,       "Or" },
308     { OUTPUT,   "Output" },
309     { PRESERVE, "Preserve" },
310     { PRINT,    "Print" },
311     { PRIVATE,  "Private" },
312     { PUBLIC,   "Public" },
313     { RANDOM,   "Random" },
314     { READ,     "Read" },
315     { REDIM,    "ReDim" },
316     { REM,      "Rem" },
317     { RESUME,   "Resume" },
318     { RETURN,   "Return" },
319     { RSET,     "RSet" }, // JSM
320     { SELECT,   "Select" },
321     { SET,      "Set" },
322     { SHARED,   "Shared" },
323     { TSINGLE,  "Single" },
324     { STATIC,   "Static" },
325     { STEP,     "Step" },
326     { STOP,     "Stop" },
327     { TSTRING,  "String" },
328     { SUB,      "Sub" },
329     { STOP,     "System" },
330     { TEXT,     "Text" },
331     { THEN,     "Then" },
332     { TO,       "To", },
333     { TYPE,     "Type" },
334     { UNTIL,    "Until" },
335     { TVARIANT, "Variant" },
336     { WEND,     "Wend" },
337     { WHILE,    "While" },
338     { WITH,     "With" },
339     { WRITE,    "Write" },              // auch WRITE #
340     { XOR,      "Xor" },
341     { JS_LINDEX,    "[" },
342     { JS_RINDEX,    "]" },
343     { JS_BIT_XOR,   "^" },
344     { JS_ASS_XOR,   "^=" },
345     { JS_BIT_OR,    "|" },
346     { JS_ASS_OR,    "|=" },
347     { JS_LOG_OR,    "||" },
348     { JS_BIT_NOT,   "~" },
349     { NIL }
350 };
351 */
352 
353 // #i109076
TokenLabelInfo(void)354 TokenLabelInfo::TokenLabelInfo( void )
355 {
356     m_pTokenCanBeLabelTab = new bool[VBASUPPORT+1];
357     for( int i = 0 ; i <= VBASUPPORT ; ++i )
358         m_pTokenCanBeLabelTab[i] = false;
359 
360     // Token accepted as label by VBA
361     SbiToken eLabelToken[] = { ACCESS, ALIAS, APPEND, BASE, BINARY, CLASSMODULE,
362         COMPARE, COMPATIBLE, DEFERR, _ERROR_, BASIC_EXPLICIT, LIB, LINE, LPRINT, NAME,
363         TOBJECT, OUTPUT, PROPERTY, RANDOM, READ, STEP, STOP, TEXT, VBASUPPORT, NIL };
364     SbiToken* pTok = eLabelToken;
365     SbiToken eTok;
366     for( pTok = eLabelToken ; (eTok = *pTok) != NIL ; ++pTok )
367         m_pTokenCanBeLabelTab[eTok] = true;
368 }
369 
~TokenLabelInfo()370 TokenLabelInfo::~TokenLabelInfo()
371 {
372     delete[] m_pTokenCanBeLabelTab;
373 }
374 
375 
376 // Der Konstruktor ermittelt die Laenge der Token-Tabelle.
377 
SbiTokenizer(const::rtl::OUString & rSrc,StarBASIC * pb)378 SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb )
379            : SbiScanner( rSrc, pb )
380 {
381     pTokTable = aTokTable_Basic;
382     //if( StarBASIC::GetGlobalLanguageMode() == SB_LANG_JAVASCRIPT )
383     //  pTokTable = aTokTable_Java;
384     TokenTable *tp;
385     bEof = bAs = sal_False;
386     eCurTok = NIL;
387     ePush = NIL;
388     bEos = bKeywords = bErrorIsSymbol = sal_True;
389     if( !nToken )
390         for( nToken = 0, tp = pTokTable; tp->t; nToken++, tp++ ) {}
391 }
392 
~SbiTokenizer()393 SbiTokenizer::~SbiTokenizer()
394 {
395 }
396 
397 // Wiederablage (Pushback) eines Tokens. (Bis zu 2 Tokens)
398 
Push(SbiToken t)399 void SbiTokenizer::Push( SbiToken t )
400 {
401     if( ePush != NIL )
402         Error( SbERR_INTERNAL_ERROR, "PUSH" );
403     else ePush = t;
404 }
405 
Error(SbError code,const char * pMsg)406 void SbiTokenizer::Error( SbError code, const char* pMsg )
407 {
408     aError = String::CreateFromAscii( pMsg );
409     Error( code );
410 }
411 
Error(SbError code,String aMsg)412 void SbiTokenizer::Error( SbError code, String aMsg )
413 {
414     aError = aMsg;
415     Error( code );
416 }
417 
Error(SbError code,SbiToken tok)418 void SbiTokenizer::Error( SbError code, SbiToken tok )
419 {
420     aError = Symbol( tok );
421     Error( code );
422 }
423 
424 // Einlesen des naechsten Tokens, ohne dass das Token geschluckt wird
425 
Peek()426 SbiToken SbiTokenizer::Peek()
427 {
428     if( ePush == NIL )
429     {
430         sal_uInt16 nOldLine = nLine;
431         sal_uInt16 nOldCol1 = nCol1;
432         sal_uInt16 nOldCol2 = nCol2;
433         ePush = Next();
434         nPLine = nLine; nLine = nOldLine;
435         nPCol1 = nCol1; nCol1 = nOldCol1;
436         nPCol2 = nCol2; nCol2 = nOldCol2;
437     }
438     return eCurTok = ePush;
439 }
440 
441 // Dies ist fuer die Decompilation.
442 // Zahlen und Symbole liefern einen Leerstring zurueck.
443 
Symbol(SbiToken t)444 const String& SbiTokenizer::Symbol( SbiToken t )
445 {
446     // Zeichen-Token?
447     if( t < FIRSTKWD )
448     {
449         aSym = (char) t;
450         return aSym;
451     }
452     switch( t )
453     {
454         case NEG   : aSym = '-'; return aSym;
455         case EOS   : aSym = String::CreateFromAscii( ":/CRLF" ); return aSym;
456         case EOLN  : aSym = String::CreateFromAscii( "CRLF" ); return aSym;
457         default: break;
458     }
459     TokenTable* tp = pTokTable;
460     for( short i = 0; i < nToken; i++, tp++ )
461     {
462         if( tp->t == t )
463         {
464             aSym = String::CreateFromAscii( tp->s );
465             return aSym;
466         }
467     }
468     const sal_Unicode *p = aSym.GetBuffer();
469     if (*p <= ' ') aSym = String::CreateFromAscii( "???" );
470     return aSym;
471 }
472 
473 // Einlesen des naechsten Tokens und Ablage desselben
474 // Tokens, die nicht in der Token-Tabelle vorkommen, werden
475 // direkt als Zeichen zurueckgeliefert.
476 // Einige Worte werden gesondert behandelt.
477 
Next()478 SbiToken SbiTokenizer::Next()
479 {
480     if (bEof) return EOLN;
481     // Schon eines eingelesen?
482     if( ePush != NIL )
483     {
484         eCurTok = ePush;
485         ePush = NIL;
486         nLine = nPLine;
487         nCol1 = nPCol1;
488         nCol2 = nPCol2;
489         bEos = IsEoln( eCurTok );
490         return eCurTok;
491     }
492     TokenTable *tp;
493 
494     // Sonst einlesen:
495     if( !NextSym() )
496     {
497         bEof = bEos = sal_True;
498         return eCurTok = EOLN;
499     }
500     // Zeilenende?
501     if( aSym.GetBuffer()[0] == '\n' )
502     {
503         bEos = sal_True; return eCurTok = EOLN;
504     }
505     bEos = sal_False;
506 
507     // Zahl?
508     if( bNumber )
509         return eCurTok = NUMBER;
510 
511     // String?
512     else if( ( eScanType == SbxDATE || eScanType == SbxSTRING ) && !bSymbol )
513         return eCurTok = FIXSTRING;
514     // Sonderfaelle von Zeichen, die zwischen "Z" und "a" liegen. ICompare()
515     // wertet die Position dieser Zeichen unterschiedlich aus.
516     else if( aSym.GetBuffer()[0] == '^' )
517         return eCurTok = EXPON;
518     else if( aSym.GetBuffer()[0] == '\\' )
519         return eCurTok = IDIV;
520     else
521     {
522         // Mit Typkennung oder ein Symbol und keine Keyword-Erkennung?
523         // Dann kein Token-Test
524         if( eScanType != SbxVARIANT
525          || ( !bKeywords && bSymbol ) )
526             return eCurTok = SYMBOL;
527         // Gueltiges Token?
528         short lb = 0;
529         short ub = nToken-1;
530         short delta;
531         do
532         {
533             delta = (ub - lb) >> 1;
534             tp = &pTokTable[ lb + delta ];
535             StringCompare res = aSym.CompareIgnoreCaseToAscii( tp->s );
536             // Gefunden?
537             if( res == COMPARE_EQUAL )
538                 goto special;
539             // Groesser? Dann untere Haelfte
540             if( res == COMPARE_LESS )
541             {
542                 if ((ub - lb) == 2) ub = lb;
543                 else ub = ub - delta;
544             }
545             // Kleiner? Dann obere Haelfte
546             else
547             {
548                 if ((ub -lb) == 2) lb = ub;
549                 else lb = lb + delta;
550             }
551         } while( delta );
552         // Symbol? Wenn nicht >= Token
553         sal_Unicode ch = aSym.GetBuffer()[0];
554         if( !BasicSimpleCharClass::isAlpha( ch, bCompatible ) && !bSymbol )
555             return eCurTok = (SbiToken) (ch & 0x00FF);
556         return eCurTok = SYMBOL;
557     }
558 special:
559     // #i92642
560     bool bStartOfLine = (eCurTok == NIL || eCurTok == REM || eCurTok == EOLN ||
561             eCurTok == THEN || eCurTok == ELSE); // single line If
562     if( !bStartOfLine && (tp->t == NAME || tp->t == LINE) )
563         return eCurTok = SYMBOL;
564     else if( tp->t == TEXT )
565         return eCurTok = SYMBOL;
566 
567     // #i92642: Special LINE token handling -> SbiParser::Line()
568 
569     // END IF, CASE, SUB, DEF, FUNCTION, TYPE, CLASS, WITH
570     if( tp->t == END )
571     {
572         // AB, 15.3.96, Spezialbehandlung fuer END, beim Peek() geht die
573         // aktuelle Zeile verloren, daher alles merken und danach restaurieren
574         sal_uInt16 nOldLine = nLine;
575         sal_uInt16 nOldCol  = nCol;
576         sal_uInt16 nOldCol1 = nCol1;
577         sal_uInt16 nOldCol2 = nCol2;
578         String aOldSym = aSym;
579         SaveLine();             // pLine im Scanner sichern
580 
581         eCurTok = Peek();
582         switch( eCurTok )
583         {
584             case IF:       Next(); eCurTok = ENDIF; break;
585             case SELECT:   Next(); eCurTok = ENDSELECT; break;
586             case SUB:      Next(); eCurTok = ENDSUB; break;
587             case FUNCTION: Next(); eCurTok = ENDFUNC; break;
588             case PROPERTY: Next(); eCurTok = ENDPROPERTY; break;
589             case TYPE:     Next(); eCurTok = ENDTYPE; break;
590             case ENUM:     Next(); eCurTok = ENDENUM; break;
591             case WITH:     Next(); eCurTok = ENDWITH; break;
592             default :      eCurTok = END;
593         }
594         nCol1 = nOldCol1;
595         if( eCurTok == END )
596         {
597             // Alles zuruecksetzen, damit Token nach END ganz neu gelesen wird
598             ePush = NIL;
599             nLine = nOldLine;
600             nCol  = nOldCol;
601             nCol2 = nOldCol2;
602             aSym = aOldSym;
603             RestoreLine();      // pLine im Scanner restaurieren
604         }
605         return eCurTok;
606     }
607     // Sind Datentypen Keywords?
608     // Nur nach AS, sonst sind es Symbole!
609     // Es gibt ja ERROR(), DATA(), STRING() etc.
610     eCurTok = tp->t;
611     // AS: Datentypen sind Keywords
612     if( tp->t == AS )
613         bAs = sal_True;
614     else
615     {
616         if( bAs )
617             bAs = sal_False;
618         else if( eCurTok >= DATATYPE1 && eCurTok <= DATATYPE2 && (bErrorIsSymbol || eCurTok != _ERROR_) )
619             eCurTok = SYMBOL;
620     }
621 
622     // CLASSMODULE, PROPERTY, GET, ENUM token only visible in compatible mode
623     SbiToken eTok = tp->t;
624     if( bCompatible )
625     {
626         // #129904 Suppress system
627         if( eTok == STOP && aSym.CompareIgnoreCaseToAscii( "system" ) == COMPARE_EQUAL )
628             eCurTok = SYMBOL;
629 
630         if( eTok == GET && bStartOfLine )
631             eCurTok = SYMBOL;
632     }
633     else
634     {
635         if( eTok == CLASSMODULE ||
636             eTok == IMPLEMENTS ||
637             eTok == PARAMARRAY ||
638             eTok == ENUM ||
639             eTok == PROPERTY ||
640             eTok == GET ||
641             eTok == TYPEOF )
642         {
643             eCurTok = SYMBOL;
644         }
645     }
646 
647     bEos = IsEoln( eCurTok );
648     return eCurTok;
649 }
650 
651 #ifdef _MSC_VER
652 #pragma optimize("",off)
653 #endif
654 
655 // Kann das aktuell eingelesene Token ein Label sein?
656 
MayBeLabel(sal_Bool bNeedsColon)657 sal_Bool SbiTokenizer::MayBeLabel( sal_Bool bNeedsColon )
658 {
659     if( eCurTok == SYMBOL || m_aTokenLabelInfo.canTokenBeLabel( eCurTok ) )
660         return bNeedsColon ? DoesColonFollow() : sal_True;
661     else
662         return sal_Bool( eCurTok == NUMBER
663                   && eScanType == SbxINTEGER
664                   && nVal >= 0 );
665 }
666 
667 #ifdef _MSC_VER
668 #pragma optimize("",off)
669 #endif
670 
671 
Hilite(SbTextPortions & rList)672 void SbiTokenizer::Hilite( SbTextPortions& rList )
673 {
674     bErrors = sal_False;
675     bUsedForHilite = sal_True;
676     SbiToken eLastTok = NIL;
677     for( ;; )
678     {
679         Next();
680         if( IsEof() )
681             break;
682         SbTextPortion aRes;
683         aRes.nLine = nLine;
684         aRes.nStart = nCol1;
685         aRes.nEnd = nCol2;
686         switch( eCurTok )
687         {
688             case REM:
689                 aRes.eType = SB_COMMENT; break;
690             case SYMBOL:
691                 aRes.eType = SB_SYMBOL; break;
692             case FIXSTRING:
693                 aRes.eType = SB_STRING; break;
694             case NUMBER:
695                 aRes.eType = SB_NUMBER; break;
696             default:
697                 if( ( eCurTok >= FIRSTKWD && eCurTok <= LASTKWD )
698                  || (eCurTok >= _CDECL_ ) )
699                     aRes.eType = SB_KEYWORD;
700                 else
701                     aRes.eType = SB_PUNCTUATION;
702         }
703         // Die Folge xxx.Keyword sollte nicht als Kwd geflagt werden
704         if( aRes.eType == SB_KEYWORD
705          && ( eLastTok == DOT|| eLastTok == EXCLAM ) )
706             aRes.eType = SB_SYMBOL;
707         if( eCurTok != EOLN && aRes.nStart <= aRes.nEnd )
708             rList.Insert( aRes, rList.Count() );
709         if( aRes.eType == SB_COMMENT )
710             break;
711         eLastTok = eCurTok;
712     }
713     bUsedForHilite = sal_False;
714 }
715 
716