source: other-projects/rsyntax-textarea/src/java/org/fife/ui/rsyntaxtextarea/modes/PropertiesFileTokenMaker.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: 7.3 KB
Line 
1/*
2 * 03/21/2005
3 *
4 * PropertiesFileTokenMaker.java - Scanner for properties files.
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 * This class splits up text into tokens representing a Java properties file.<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 <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.
49 * </ul>
50 *
51 * @author Robert Futrell
52 * @version 0.4
53 *
54 */
55%%
56
57%public
58%class PropertiesFileTokenMaker
59%extends AbstractJFlexTokenMaker
60%implements TokenMaker
61%unicode
62%type org.fife.ui.rsyntaxtextarea.Token
63
64
65%{
66
67
68 /**
69 * Constructor. This must be here because JFlex does not generate a
70 * no-parameter constructor.
71 */
72 public PropertiesFileTokenMaker() {
73 super();
74 }
75
76
77 /**
78 * Adds the token specified to the current linked list of tokens.
79 *
80 * @param tokenType The token's type.
81 */
82 private void addToken(int tokenType) {
83 addToken(zzStartRead, zzMarkedPos-1, tokenType);
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 start, int end, int tokenType) {
93 int so = start + offsetShift;
94 addToken(zzBuffer, start,end, tokenType, so);
95 }
96
97
98 /**
99 * Adds the token specified to the current linked list of tokens.
100 *
101 * @param array The character array.
102 * @param start The starting offset in the array.
103 * @param end The ending offset in the array.
104 * @param tokenType The token's type.
105 * @param startOffset The offset in the document at which this token
106 * occurs.
107 */
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;
111 }
112
113
114 /**
115 * Returns the text to place at the beginning and end of a
116 * line to "comment" it in a this programming language.
117 *
118 * @return The start and end strings to add to a line to "comment"
119 * it out.
120 */
121 public String[] getLineCommentStartAndEnd() {
122 return new String[] { "#", null };
123 }
124
125
126 /**
127 * Returns the first token in the linked list of tokens generated
128 * from <code>text</code>. This method must be implemented by
129 * subclasses so they can correctly implement syntax highlighting.
130 *
131 * @param text The text from which to get tokens.
132 * @param initialTokenType The token type we should start with.
133 * @param startOffset The offset into the document at which
134 * <code>text</code> starts.
135 * @return The first <code>Token</code> in a linked list representing
136 * the syntax highlighted text.
137 */
138 public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
139
140 resetTokenList();
141 this.offsetShift = -text.offset + startOffset;
142
143 // Start off in the proper state.
144 int state = Token.NULL;
145 switch (initialTokenType) {
146 case Token.LITERAL_STRING_DOUBLE_QUOTE:
147 state = VALUE;
148 start = text.offset;
149 break;
150 default:
151 state = Token.NULL;
152 }
153
154 s = text;
155 try {
156 yyreset(zzReader);
157 yybegin(state);
158 return yylex();
159 } catch (IOException ioe) {
160 ioe.printStackTrace();
161 return new DefaultToken();
162 }
163
164 }
165
166
167 /**
168 * Refills the input buffer.
169 *
170 * @return <code>true</code> if EOF was reached, otherwise
171 * <code>false</code>.
172 * @exception IOException if any I/O-Error occurs.
173 */
174 private boolean zzRefill() {
175 return zzCurrentPos>=s.offset+s.count;
176 }
177
178
179 /**
180 * Resets the scanner to read from a new input stream.
181 * Does not close the old reader.
182 *
183 * All internal variables are reset, the old input stream
184 * <b>cannot</b> be reused (internal buffer is discarded and lost).
185 * Lexical state is set to <tt>YY_INITIAL</tt>.
186 *
187 * @param reader the new input stream
188 */
189 public final void yyreset(java.io.Reader reader) {
190 // 's' has been updated.
191 zzBuffer = s.array;
192 /*
193 * We replaced the line below with the two below it because zzRefill
194 * no longer "refills" the buffer (since the way we do it, it's always
195 * "full" the first time through, since it points to the segment's
196 * array). So, we assign zzEndRead here.
197 */
198 //zzStartRead = zzEndRead = s.offset;
199 zzStartRead = s.offset;
200 zzEndRead = zzStartRead + s.count - 1;
201 zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset;
202 zzLexicalState = YYINITIAL;
203 zzReader = reader;
204 zzAtBOL = true;
205 zzAtEOF = false;
206 }
207
208
209%}
210
211Equals = ([=\:])
212Name = ([^=\: \t\n#!]*)
213Whitespace = ([ \t]+)
214Comment = ([#!].*)
215SingleQuote = (')
216
217%state VALUE
218
219%%
220
221<YYINITIAL> {
222 {Name} { addToken(Token.RESERVED_WORD); }
223 {Equals} { start = zzMarkedPos; addToken(Token.OPERATOR); yybegin(VALUE); }
224 {Whitespace} { addToken(Token.WHITESPACE); }
225 {Comment} { addToken(Token.COMMENT_EOL); }
226 <<EOF>> { addNullToken(); return firstToken; }
227}
228
229<VALUE> {
230 {SingleQuote}[^']*{SingleQuote}? { addToken(start, zzMarkedPos-1, Token.LITERAL_STRING_DOUBLE_QUOTE); start = zzMarkedPos; }
231 [^'\{\\]+ {}
232 "{"[^\}]*"}"? { int temp=zzStartRead; addToken(start, zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp, zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; }
233 [\\]. {}
234 [\\] { addToken(start, zzEndRead, Token.LITERAL_STRING_DOUBLE_QUOTE); return firstToken; }
235 <<EOF>> { addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addNullToken(); return firstToken; }
236}
Note: See TracBrowser for help on using the repository browser.