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