source: other-projects/rsyntax-textarea/src/java/org/fife/ui/rsyntaxtextarea/modes/GroovyTokenMaker.flex@ 25584

Last change on this file since 25584 was 25584, checked in by davidb, 12 years ago

Initial cut an a text edit area for GLI that supports color syntax highlighting

File size: 20.0 KB
Line 
1/*
2 * 09/28/2007
3 *
4 * GroovyTokenMaker.java - Scanner for the Groovy programming language.
5 *
6 * This library is distributed under a modified BSD license. See the included
7 * RSyntaxTextArea.License.txt file for details.
8 */
9package org.fife.ui.rsyntaxtextarea.modes;
10
11import java.io.*;
12import javax.swing.text.Segment;
13
14import org.fife.ui.rsyntaxtextarea.*;
15
16
17/**
18 * Scanner for the Groovy programming language.<p>
19 *
20 * This implementation was created using
21 * <a href="http://www.jflex.de/">JFlex</a> 1.4.1; however, the generated file
22 * was modified for performance. Memory allocation needs to be almost
23 * completely removed to be competitive with the handwritten lexers (subclasses
24 * of <code>AbstractTokenMaker</code>, so this class has been modified so that
25 * Strings are never allocated (via yytext()), and the scanner never has to
26 * worry about refilling its buffer (needlessly copying chars around).
27 * We can achieve this because RText always scans exactly 1 line of tokens at a
28 * time, and hands the scanner this line as an array of characters (a Segment
29 * really). Since tokens contain pointers to char arrays instead of Strings
30 * holding their contents, there is no need for allocating new memory for
31 * Strings.<p>
32 *
33 * The actual algorithm generated for scanning has, of course, not been
34 * modified.<p>
35 *
36 * If you wish to regenerate this file yourself, keep in mind the following:
37 * <ul>
38 * <li>The generated GroovyTokenMaker.java</code> file will contain two
39 * definitions of both <code>zzRefill</code> and <code>yyreset</code>.
40 * You should hand-delete the second of each definition (the ones
41 * generated by the lexer), as these generated methods modify the input
42 * buffer, which we'll never have to do.</li>
43 * <li>You should also change the declaration/definition of zzBuffer to NOT
44 * be initialized. This is a needless memory allocation for us since we
45 * will be pointing the array somewhere else anyway.</li>
46 * <li>You should NOT call <code>yylex()</code> on the generated scanner
47 * directly; rather, you should use <code>getTokenList</code> as you would
48 * with any other <code>TokenMaker</code> instance.</li>
49 * </ul>
50 *
51 * @author Robert Futrell
52 * @version 0.5
53 *
54 */
55%%
56
57%public
58%class GroovyTokenMaker
59%extends AbstractJFlexCTokenMaker
60%unicode
61%type org.fife.ui.rsyntaxtextarea.Token
62
63
64%{
65
66
67 /**
68 * Constructor. This must be here because JFlex does not generate a
69 * no-parameter constructor.
70 */
71 public GroovyTokenMaker() {
72 }
73
74
75 /**
76 * Adds the token specified to the current linked list of tokens.
77 *
78 * @param tokenType The token's type.
79 * @see #addToken(int, int, int)
80 */
81 private void addHyperlinkToken(int start, int end, int tokenType) {
82 int so = start + offsetShift;
83 addToken(zzBuffer, start,end, tokenType, so, true);
84 }
85
86
87 /**
88 * Adds the token specified to the current linked list of tokens.
89 *
90 * @param tokenType The token's type.
91 */
92 private void addToken(int tokenType) {
93 addToken(zzStartRead, zzMarkedPos-1, tokenType);
94 }
95
96
97 /**
98 * Adds the token specified to the current linked list of tokens.
99 *
100 * @param tokenType The token's type.
101 */
102 private void addToken(int start, int end, int tokenType) {
103 int so = start + offsetShift;
104 addToken(zzBuffer, start,end, tokenType, so);
105 }
106
107
108 /**
109 * Adds the token specified to the current linked list of tokens.
110 *
111 * @param array The character array.
112 * @param start The starting offset in the array.
113 * @param end The ending offset in the array.
114 * @param tokenType The token's type.
115 * @param startOffset The offset in the document at which this token
116 * occurs.
117 */
118 public void addToken(char[] array, int start, int end, int tokenType, int startOffset) {
119 super.addToken(array, start,end, tokenType, startOffset);
120 zzStartRead = zzMarkedPos;
121 }
122
123
124 /**
125 * Returns the text to place at the beginning and end of a
126 * line to "comment" it in a this programming language.
127 *
128 * @return The start and end strings to add to a line to "comment"
129 * it out.
130 */
131 public String[] getLineCommentStartAndEnd() {
132 return new String[] { "//", null };
133 }
134
135
136 /**
137 * Returns the first token in the linked list of tokens generated
138 * from <code>text</code>. This method must be implemented by
139 * subclasses so they can correctly implement syntax highlighting.
140 *
141 * @param text The text from which to get tokens.
142 * @param initialTokenType The token type we should start with.
143 * @param startOffset The offset into the document at which
144 * <code>text</code> starts.
145 * @return The first <code>Token</code> in a linked list representing
146 * the syntax highlighted text.
147 */
148 public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
149
150 resetTokenList();
151 this.offsetShift = -text.offset + startOffset;
152
153 // Start off in the proper state.
154 int state = Token.NULL;
155 switch (initialTokenType) {
156 case Token.LITERAL_STRING_DOUBLE_QUOTE:
157 state = MULTILINE_STRING_DOUBLE;
158 start = text.offset;
159 break;
160 case Token.LITERAL_CHAR:
161 state = MULTILINE_STRING_SINGLE;
162 start = text.offset;
163 break;
164 case Token.COMMENT_MULTILINE:
165 state = MLC;
166 start = text.offset;
167 break;
168 case Token.COMMENT_DOCUMENTATION:
169 state = DOCCOMMENT;
170 start = text.offset;
171 break;
172 default:
173 state = Token.NULL;
174 }
175
176 s = text;
177 try {
178 yyreset(zzReader);
179 yybegin(state);
180 return yylex();
181 } catch (IOException ioe) {
182 ioe.printStackTrace();
183 return new DefaultToken();
184 }
185
186 }
187
188
189 /**
190 * Returns whether a regular expression token can follow the specified
191 * token.
192 *
193 * @param t The token to check, which may be <code>null</code>.
194 * @return Whether a regular expression token may follow this one.
195 */
196 private static final boolean regexCanFollow(Token t) {
197 char ch;
198 return t==null ||
199 //t.isOperator() ||
200 (t.textCount==1 && (
201 (ch=t.text[t.textOffset])=='=' ||
202 ch=='(' ||
203 ch==',' ||
204 ch=='?' ||
205 ch==':' ||
206 ch=='['
207 )) ||
208 /* Operators "==", "===", "!=", "!==", etc. */
209 (t.type==Token.OPERATOR &&
210 ((ch=t.text[t.textOffset+t.textCount-1])=='=' || ch=='~'));
211 }
212
213
214 /**
215 * Refills the input buffer.
216 *
217 * @return <code>true</code> if EOF was reached, otherwise
218 * <code>false</code>.
219 */
220 private boolean zzRefill() {
221 return zzCurrentPos>=s.offset+s.count;
222 }
223
224
225 /**
226 * Resets the scanner to read from a new input stream.
227 * Does not close the old reader.
228 *
229 * All internal variables are reset, the old input stream
230 * <b>cannot</b> be reused (internal buffer is discarded and lost).
231 * Lexical state is set to <tt>YY_INITIAL</tt>.
232 *
233 * @param reader the new input stream
234 */
235 public final void yyreset(java.io.Reader reader) {
236 // 's' has been updated.
237 zzBuffer = s.array;
238 /*
239 * We replaced the line below with the two below it because zzRefill
240 * no longer "refills" the buffer (since the way we do it, it's always
241 * "full" the first time through, since it points to the segment's
242 * array). So, we assign zzEndRead here.
243 */
244 //zzStartRead = zzEndRead = s.offset;
245 zzStartRead = s.offset;
246 zzEndRead = zzStartRead + s.count - 1;
247 zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset;
248 zzLexicalState = YYINITIAL;
249 zzReader = reader;
250 zzAtBOL = true;
251 zzAtEOF = false;
252 }
253
254
255%}
256
257Letter = [A-Za-z]
258LetterOrUnderscore = ({Letter}|"_")
259NonzeroDigit = [1-9]
260Digit = ("0"|{NonzeroDigit})
261HexDigit = ({Digit}|[A-Fa-f])
262OctalDigit = ([0-7])
263AnyCharacterButApostropheOrBackSlash = ([^\\'])
264EscapedSourceCharacter = ("u"{HexDigit}{HexDigit}{HexDigit}{HexDigit})
265Escape = ("\\"(([btnfr\"'\\])|([0123]{OctalDigit}?{OctalDigit}?)|({OctalDigit}{OctalDigit}?)|{EscapedSourceCharacter}))
266NonSeparator = ([^\t\f\r\n\ \(\)\{\}\[\]\;\,\.\=\>\<\!\~\?\:\+\-\*\/\&\|\^\%\"\']|"#"|"\\")
267IdentifierStart = ({LetterOrUnderscore}|"$")
268IdentifierPart = ({IdentifierStart}|{Digit}|("\\"{EscapedSourceCharacter}))
269
270LineTerminator = (\n)
271WhiteSpace = ([ \t\f])
272
273CharLiteral = ([\']({AnyCharacterButApostropheOrBackSlash}|{Escape})*[\'])
274UnclosedCharLiteral = ([\'][^\'\n]*)
275ErrorCharLiteral = ({UnclosedCharLiteral}[\'])
276
277MLCBegin = "/*"
278MLCEnd = "*/"
279DocCommentBegin = "/**"
280LineCommentBegin = "//"
281
282IntegerHelper1 = (({NonzeroDigit}{Digit}*)|"0")
283IntegerHelper2 = ("0"(([xX]{HexDigit}+)|({OctalDigit}*)))
284IntegerLiteral = ({IntegerHelper1}[lL]?)
285HexLiteral = ({IntegerHelper2}[lL]?)
286FloatHelper1 = ([fFdD]?)
287FloatHelper2 = ([eE][+-]?{Digit}+{FloatHelper1})
288FloatLiteral1 = ({Digit}+"."({FloatHelper1}|{FloatHelper2}|{Digit}+({FloatHelper1}|{FloatHelper2})))
289FloatLiteral2 = ("."{Digit}+({FloatHelper1}|{FloatHelper2}))
290FloatLiteral3 = ({Digit}+{FloatHelper2})
291FloatLiteral = ({FloatLiteral1}|{FloatLiteral2}|{FloatLiteral3}|({Digit}+[fFdD]))
292ErrorNumberFormat = (({IntegerLiteral}|{HexLiteral}|{FloatLiteral}){NonSeparator}+)
293BooleanLiteral = ("true"|"false")
294Regex = ([~]?"/"([^\*\\/]|\\.)([^/\\]|\\.)*"/")
295
296Separator = ([\(\)\{\}\[\]])
297Separator2 = ([\;,.])
298
299NonAssignmentOperator = ("+"|"-"|"<="|"^"|"++"|"<"|"*"|">="|"%"|"--"|">"|"/"|"!="|"?"|">>"|"!"|"&"|"=="|":"|">>"|"~"|"|"|"&&"|">>>")
300AssignmentOperator = ("="|"-="|"*="|"/="|"|="|"&="|"^="|"+="|"%="|"<<="|">>="|">>>=")
301GroovyOperator = ("=~")
302Operator = ({NonAssignmentOperator}|{AssignmentOperator}|{GroovyOperator})
303
304CurrentBlockTag = ("author"|"deprecated"|"exception"|"param"|"return"|"see"|"serial"|"serialData"|"serialField"|"since"|"throws"|"version")
305ProposedBlockTag = ("category"|"example"|"tutorial"|"index"|"exclude"|"todo"|"internal"|"obsolete"|"threadsafety")
306BlockTag = ({CurrentBlockTag}|{ProposedBlockTag})
307InlineTag = ("code"|"docRoot"|"inheritDoc"|"link"|"linkplain"|"literal"|"value")
308
309Identifier = ({IdentifierStart}{IdentifierPart}*)
310ErrorIdentifier = ({NonSeparator}+)
311
312// Variables in strings
313VariableStart = ([\$])
314BracedVariable = ({VariableStart}\{[^\}]+\})
315UnbracedVariable = ({VariableStart}{Identifier})
316Variable = ({BracedVariable}|{UnbracedVariable})
317
318Annotation = ("@"{Identifier}?)
319
320URLGenDelim = ([:\/\?#\[\]@])
321URLSubDelim = ([\!\$&'\(\)\*\+,;=])
322URLUnreserved = ({LetterOrUnderscore}|{Digit}|[\-\.\~])
323URLCharacter = ({URLGenDelim}|{URLSubDelim}|{URLUnreserved}|[%])
324URLCharacters = ({URLCharacter}*)
325URLEndCharacter = ([\/\$]|{Letter}|{Digit})
326URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?)
327
328%state MLC
329%state DOCCOMMENT
330%state MULTILINE_STRING_DOUBLE
331%state MULTILINE_STRING_SINGLE
332%state STRING_DOUBLE
333
334%%
335
336<YYINITIAL> {
337
338 /* Keywords */
339 "abstract" |
340 "break" |
341 "case" |
342 "catch" |
343 "class" |
344 "continue" |
345 "default" |
346 "do" |
347 "else" |
348 "extends" |
349 "final" |
350 "finally" |
351 "for" |
352 "if" |
353 "it" |
354 "implements" |
355 "import" |
356 "instanceof" |
357 "native" |
358 "new" |
359 "null" |
360 "package" |
361 "private" |
362 "protected" |
363 "public" |
364 "return" |
365 "static" |
366 "strictfp" |
367 "super" |
368 "switch" |
369 "synchronized" |
370 "this" |
371 "throw" |
372 "throws" |
373 "transient" |
374 "try" |
375 "void" |
376 "volatile" |
377 "while" { addToken(Token.RESERVED_WORD); }
378
379 /* Groovy keywords */
380 "as" |
381 "assert" |
382 "def" |
383 "mixin" |
384 "property" |
385 "test" |
386 "using" |
387 "in" { addToken(Token.RESERVED_WORD); }
388
389 /* Data types. */
390 "boolean" |
391 "byte" |
392 "char" |
393 "double" |
394 "float" |
395 "int" |
396 "long" |
397 "short" { addToken(Token.DATA_TYPE); }
398
399 /* Booleans. */
400 {BooleanLiteral} { addToken(Token.LITERAL_BOOLEAN); }
401
402 /* java.lang stuff */
403 "Appendable" |
404 "CharSequence" |
405 "Cloneable" |
406 "Comparable" |
407 "Iterable" |
408 "Readable" |
409 "Runnable" |
410 "Boolean" |
411 "Byte" |
412 "Character" |
413 "Character.Subset" |
414 "Character.UnicodeBlock" |
415 "Class" |
416 "ClassLoader" |
417 "Compiler" |
418 "Double" |
419 "Enum" |
420 "Float" |
421 "InheritableThreadLocal" |
422 "Integer" |
423 "Long" |
424 "Math" |
425 "Number" |
426 "Object" |
427 "Package" |
428 "Process" |
429 "ProcessBuilder" |
430 "Runtime" |
431 "RuntimePermission" |
432 "SecurityManager" |
433 "Short" |
434 "StackTraceElement" |
435 "StrictMath" |
436 "String" |
437 "StringBuffer" |
438 "StringBuilder" |
439 "System" |
440 "Thread" |
441 "ThreadGroup" |
442 "ThreadLocal" |
443 "Throwable" |
444 "Void" |
445 "Thread.State" |
446 "ArithmeticException" |
447 "ArrayIndexOutOfBoundsException" |
448 "ArrayStoreException" |
449 "ClassCastException" |
450 "ClassNotFoundException" |
451 "CloneNotSupportedException" |
452 "EnumConstantNotPresentException" |
453 "Exception" |
454 "IllegalAccessException" |
455 "IllegalArgumentException" |
456 "IllegalMonitorStateException" |
457 "IllegalStateException" |
458 "IllegalThreadStateException" |
459 "IndexOutOfBoundsException" |
460 "InstantiationException" |
461 "InterruptedException" |
462 "NegativeArraySizeException" |
463 "NoSuchFieldException" |
464 "NoSuchMethodException" |
465 "NullPointerException" |
466 "NumberFormatException" |
467 "RuntimeException" |
468 "SecurityException" |
469 "StringIndexOutOfBoundsException" |
470 "TypeNotPresentException" |
471 "UnsupportedOperationException" |
472 "AbstractMethodError" |
473 "AssertionError" |
474 "ClassCircularityError" |
475 "ClassFormatError" |
476 "Error" |
477 "ExceptionInInitializerError" |
478 "IllegalAccessError" |
479 "IncompatibleClassChangeError" |
480 "InstantiationError" |
481 "InternalError" |
482 "LinkageError" |
483 "NoClassDefFoundError" |
484 "NoSuchFieldError" |
485 "NoSuchMethodError" |
486 "OutOfMemoryError" |
487 "StackOverflowError" |
488 "ThreadDeath" |
489 "UnknownError" |
490 "UnsatisfiedLinkError" |
491 "UnsupportedClassVersionError" |
492 "VerifyError" |
493 "VirtualMachineError" { addToken(Token.FUNCTION); }
494
495 /* Commonly used methods added to Object class */
496 "addShutdownHook" |
497 "any" |
498 "asBoolean" |
499 "asType" |
500 "collect" |
501 "dump" |
502 "each" |
503 "eachWithIndex" |
504 "every" |
505 "find" |
506 "findAll" |
507 "findIndexOf" |
508 "findIndexValues" |
509 "findLastIndexOf" |
510 "getAt" |
511 "getMetaClass" |
512 "getMetaPropertyValues" |
513 "getProperties" |
514 "grep" |
515 "hasProperty" |
516 "identity" |
517 "inject" |
518 "inspect" |
519 "invokeMethod" |
520 "is" |
521 "isCase" |
522 "iterator" |
523 "metaClass" |
524 "print" |
525 "printf" |
526 "println" |
527 "putAt" |
528 "respondsTo" |
529 "setMetaClass" |
530 "sleep" |
531 "split" |
532 "sprintf" |
533 "toString" |
534 "use" |
535 "with" { addToken(Token.FUNCTION); }
536
537 {LineTerminator} { addNullToken(); return firstToken; }
538
539 {Identifier} { addToken(Token.IDENTIFIER); }
540
541 {WhiteSpace}+ { addToken(Token.WHITESPACE); }
542
543 /* Multiline string literals. */
544 \"\"\" { start = zzMarkedPos-3; yybegin(MULTILINE_STRING_DOUBLE); }
545 \'\'\' { start = zzMarkedPos-3; yybegin(MULTILINE_STRING_SINGLE); }
546
547
548 /* String/Character literals. */
549 {CharLiteral} { addToken(Token.LITERAL_CHAR); }
550 {UnclosedCharLiteral} { addToken(Token.ERROR_CHAR); addNullToken(); return firstToken; }
551 {ErrorCharLiteral} { addToken(Token.ERROR_CHAR); }
552 \" { start = zzMarkedPos-1; yybegin(STRING_DOUBLE); }
553
554 /* Comment literals. */
555 "/**/" { addToken(Token.COMMENT_MULTILINE); }
556 {MLCBegin} { start = zzMarkedPos-2; yybegin(MLC); }
557 {DocCommentBegin} { start = zzMarkedPos-3; yybegin(DOCCOMMENT); }
558 {LineCommentBegin}.* { addToken(Token.COMMENT_EOL); addNullToken(); return firstToken; }
559
560 /* Regular expressions. */
561 {Regex} {
562 boolean highlightedAsRegex = false;
563 if (zzBuffer[zzStartRead]=='~' || firstToken==null) {
564 addToken(Token.REGEX);
565 highlightedAsRegex = true;
566 }
567 else {
568 // If this is *likely* to be a regex, based on
569 // the previous token, highlight it as such.
570 Token t = firstToken.getLastNonCommentNonWhitespaceToken();
571 if (regexCanFollow(t)) {
572 addToken(Token.REGEX);
573 highlightedAsRegex = true;
574 }
575 }
576 // If it doesn't *appear* to be a regex, highlight it as
577 // individual tokens.
578 if (!highlightedAsRegex) {
579 int temp = zzStartRead + 1;
580 addToken(zzStartRead, zzStartRead, Token.OPERATOR);
581 zzStartRead = zzCurrentPos = zzMarkedPos = temp;
582 }
583 }
584
585 /* Annotations. */
586 {Annotation} { addToken(Token.ANNOTATION); }
587
588 /* Separators. */
589 {Separator} { addToken(Token.SEPARATOR); }
590 {Separator2} { addToken(Token.IDENTIFIER); }
591
592 /* Operators. */
593 {Operator} { addToken(Token.OPERATOR); }
594
595 /* Numbers */
596 {IntegerLiteral} { addToken(Token.LITERAL_NUMBER_DECIMAL_INT); }
597 {HexLiteral} { addToken(Token.LITERAL_NUMBER_HEXADECIMAL); }
598 {FloatLiteral} { addToken(Token.LITERAL_NUMBER_FLOAT); }
599 {ErrorNumberFormat} { addToken(Token.ERROR_NUMBER_FORMAT); }
600
601 {ErrorIdentifier} { addToken(Token.ERROR_IDENTIFIER); }
602
603 /* Ended with a line not in a string or comment. */
604 <<EOF>> { addNullToken(); return firstToken; }
605
606 /* Catch any other (unhandled) characters and flag them as bad. */
607 . { addToken(Token.ERROR_IDENTIFIER); }
608
609}
610
611
612<MLC> {
613
614 [^hwf\n\*]+ {}
615 {URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_MULTILINE); start = zzMarkedPos; }
616 [hwf] {}
617
618 \n { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); return firstToken; }
619 {MLCEnd} { yybegin(YYINITIAL); addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); }
620 \* {}
621 <<EOF>> { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); return firstToken; }
622
623}
624
625
626<DOCCOMMENT> {
627
628 [^hwf\@\{\n\<\*]+ {}
629 {URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_DOCUMENTATION); start = zzMarkedPos; }
630 [hwf] {}
631
632 "@"{BlockTag} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
633 "@" {}
634 "{@"{InlineTag}[^\}]*"}" { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
635 "{" {}
636 \n { addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); return firstToken; }
637 "<"[/]?({Letter}[^\>]*)?">" { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addToken(temp,zzMarkedPos-1, Token.PREPROCESSOR); start = zzMarkedPos; }
638 \< {}
639 {MLCEnd} { yybegin(YYINITIAL); addToken(start,zzStartRead+1, Token.COMMENT_DOCUMENTATION); }
640 \* {}
641 <<EOF>> { yybegin(YYINITIAL); addToken(start,zzEndRead, Token.COMMENT_DOCUMENTATION); return firstToken; }
642
643}
644
645
646<MULTILINE_STRING_DOUBLE> {
647 [^\"\\\$\n]* {}
648 \\.? { /* Skip escaped chars, handles case: '\"""'. */ }
649 \"\"\" { yybegin(YYINITIAL); addToken(start,zzStartRead+2, Token.LITERAL_STRING_DOUBLE_QUOTE); }
650 {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
651 {VariableStart} {}
652 \" {}
653 \n |
654 <<EOF>> { addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); return firstToken; }
655}
656
657
658<MULTILINE_STRING_SINGLE> {
659 [^\'\\\n]* {}
660 \\.? { /* Skip escaped chars, handles case: "\'''". */ }
661 \'\'\' { yybegin(YYINITIAL); addToken(start,zzStartRead+2, Token.LITERAL_CHAR); }
662 \' {}
663 \n |
664 <<EOF>> { addToken(start,zzStartRead-1, Token.LITERAL_CHAR); return firstToken; }
665}
666
667<STRING_DOUBLE> {
668 [^\n\\\$\"]+ {}
669 \n { addToken(start,zzStartRead-1, Token.ERROR_STRING_DOUBLE); addNullToken(); return firstToken; }
670 \\.? { /* Skip escaped chars. */ }
671 {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
672 {VariableStart} {}
673 \" { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_STRING_DOUBLE_QUOTE); }
674 <<EOF>> { addToken(start,zzStartRead-1, Token.ERROR_STRING_DOUBLE); return firstToken; }
675}
676
Note: See TracBrowser for help on using the repository browser.