4
* PropertiesFileTokenMaker.java - Scanner for properties files.
6
* This library is distributed under a modified BSD license. See the included
7
* RSyntaxTextArea.License.txt file for details.
9
package org.fife.ui.rsyntaxtextarea.modes;
12
import javax.swing.text.Segment;
14
import org.fife.ui.rsyntaxtextarea.*;
18
* This class splits up text into tokens representing a Java properties file.<p>
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
33
* The actual algorithm generated for scanning has, of course, not been
36
* If you wish to regenerate this file yourself, keep in mind the following:
38
* <li>The generated <code>PropertiesFileTokenMaker.java</code> file will
39
* contain two definitions of both <code>zzRefill</code> and
40
* <code>yyreset</code>. You should hand-delete the second of each
41
* definition (the ones generated by the lexer), as these generated
42
* methods modify the input buffer, which we'll never have to do.
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.
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.
51
* @author Robert Futrell
58
%class PropertiesFileTokenMaker
59
%extends AbstractJFlexTokenMaker
61
%type org.fife.ui.rsyntaxtextarea.Token
68
* Constructor. This must be here because JFlex does not generate a
69
* no-parameter constructor.
71
public PropertiesFileTokenMaker() {
77
* Adds the token specified to the current linked list of tokens.
79
* @param tokenType The token's type.
81
private void addToken(int tokenType) {
82
addToken(zzStartRead, zzMarkedPos-1, tokenType);
87
* Adds the token specified to the current linked list of tokens.
89
* @param tokenType The token's type.
91
private void addToken(int start, int end, int tokenType) {
92
int so = start + offsetShift;
93
addToken(zzBuffer, start,end, tokenType, so);
98
* Adds the token specified to the current linked list of tokens.
100
* @param array The character array.
101
* @param start The starting offset in the array.
102
* @param end The ending offset in the array.
103
* @param tokenType The token's type.
104
* @param startOffset The offset in the document at which this token
108
public void addToken(char[] array, int start, int end, int tokenType, int startOffset) {
109
super.addToken(array, start,end, tokenType, startOffset);
110
zzStartRead = zzMarkedPos;
115
* Returns the text to place at the beginning and end of a
116
* line to "comment" it in a this programming language.
118
* @return The start and end strings to add to a line to "comment"
122
public String[] getLineCommentStartAndEnd() {
123
return new String[] { "#", null };
128
* Returns the first token in the linked list of tokens generated
129
* from <code>text</code>. This method must be implemented by
130
* subclasses so they can correctly implement syntax highlighting.
132
* @param text The text from which to get tokens.
133
* @param initialTokenType The token type we should start with.
134
* @param startOffset The offset into the document at which
135
* <code>text</code> starts.
136
* @return The first <code>Token</code> in a linked list representing
137
* the syntax highlighted text.
139
public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
142
this.offsetShift = -text.offset + startOffset;
144
// Start off in the proper state.
145
int state = Token.NULL;
146
switch (initialTokenType) {
147
case Token.LITERAL_STRING_DOUBLE_QUOTE:
160
} catch (IOException ioe) {
161
ioe.printStackTrace();
162
return new TokenImpl();
169
* Refills the input buffer.
171
* @return <code>true</code> if EOF was reached, otherwise
172
* <code>false</code>.
173
* @exception IOException if any I/O-Error occurs.
175
private boolean zzRefill() {
176
return zzCurrentPos>=s.offset+s.count;
181
* Resets the scanner to read from a new input stream.
182
* Does not close the old reader.
184
* All internal variables are reset, the old input stream
185
* <b>cannot</b> be reused (internal buffer is discarded and lost).
186
* Lexical state is set to <tt>YY_INITIAL</tt>.
188
* @param reader the new input stream
190
public final void yyreset(java.io.Reader reader) {
191
// 's' has been updated.
194
* We replaced the line below with the two below it because zzRefill
195
* no longer "refills" the buffer (since the way we do it, it's always
196
* "full" the first time through, since it points to the segment's
197
* array). So, we assign zzEndRead here.
199
//zzStartRead = zzEndRead = s.offset;
200
zzStartRead = s.offset;
201
zzEndRead = zzStartRead + s.count - 1;
202
zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset;
203
zzLexicalState = YYINITIAL;
213
Name = ([^=\: \t\n#!]*)
214
Whitespace = ([ \t]+)
223
{Name} { addToken(Token.RESERVED_WORD); }
224
{Equals} { start = zzMarkedPos; addToken(Token.OPERATOR); yybegin(VALUE); }
225
{Whitespace} { addToken(Token.WHITESPACE); }
226
{Comment} { addToken(Token.COMMENT_EOL); }
227
<<EOF>> { addNullToken(); return firstToken; }
231
{SingleQuote}[^']*{SingleQuote}? { addToken(start, zzMarkedPos-1, Token.LITERAL_STRING_DOUBLE_QUOTE); start = zzMarkedPos; }
233
"{"[^\}]*"}"? { int temp=zzStartRead; addToken(start, zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp, zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
235
[\\] { addToken(start, zzEndRead, Token.LITERAL_STRING_DOUBLE_QUOTE); return firstToken; }
236
<<EOF>> { addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addNullToken(); return firstToken; }