source: other-projects/rsyntax-textarea/src/java/org/fife/ui/rsyntaxtextarea/modes/BBCodeTokenMaker.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: 8.1 KB
Line 
1/*
2 * 11/18/2009
3 *
4 * BBCodeTokenMaker.java - Generates tokens for BBCode syntax highlighting.
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 BBCode.
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 BBCodeTokenMaker.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.7
53 *
54 */
55%%
56
57%public
58%class BBCodeTokenMaker
59%extends AbstractMarkupTokenMaker
60%unicode
61%type org.fife.ui.rsyntaxtextarea.Token
62
63
64%{
65
66 /**
67 * Token type specific to BBCodeTokenMaker; this signals that the user has
68 * ended a line with an unclosed tag; thus a new line is beginning
69 * still inside of the tag.
70 */
71 public static final int INTERNAL_INTAG = -1;
72
73 /**
74 * Whether closing markup tags are automatically completed for BBCode.
75 */
76 private static boolean completeCloseTags = true;
77
78
79 /**
80 * Constructor. This must be here because JFlex does not generate a
81 * no-parameter constructor.
82 */
83 public BBCodeTokenMaker() {
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 * Sets whether markup close tags should be completed. The default value
126 * for BBCode is <code>true</code>.
127 *
128 * @return Whether closing markup tags are completed.
129 * @see #setCompleteCloseTags(boolean)
130 */
131 public boolean getCompleteCloseTags() {
132 return completeCloseTags;
133 }
134
135
136 /**
137 * Returns <code>null</code> since BBCode has no comments.
138 *
139 * @return <code>null</code> always.
140 */
141 public String[] getLineCommentStartAndEnd() {
142 return null;
143 }
144
145
146 /**
147 * Returns the first token in the linked list of tokens generated
148 * from <code>text</code>. This method must be implemented by
149 * subclasses so they can correctly implement syntax highlighting.
150 *
151 * @param text The text from which to get tokens.
152 * @param initialTokenType The token type we should start with.
153 * @param startOffset The offset into the document at which
154 * <code>text</code> starts.
155 * @return The first <code>Token</code> in a linked list representing
156 * the syntax highlighted text.
157 */
158 public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
159
160 resetTokenList();
161 this.offsetShift = -text.offset + startOffset;
162
163 // Start off in the proper state.
164 int state = Token.NULL;
165 switch (initialTokenType) {
166 case INTERNAL_INTAG:
167 state = INTAG;
168 start = text.offset;
169 break;
170 default:
171 state = Token.NULL;
172 }
173
174 s = text;
175 try {
176 yyreset(zzReader);
177 yybegin(state);
178 return yylex();
179 } catch (IOException ioe) {
180 ioe.printStackTrace();
181 return new DefaultToken();
182 }
183
184 }
185
186
187 /**
188 * Sets whether markup close tags should be completed.
189 *
190 * @param complete Whether closing markup tags are completed.
191 * @see #getCompleteCloseTags()
192 */
193 public static void setCompleteCloseTags(boolean complete) {
194 completeCloseTags = complete;
195 }
196
197
198 /**
199 * Refills the input buffer.
200 *
201 * @return <code>true</code> if EOF was reached, otherwise
202 * <code>false</code>.
203 */
204 private boolean zzRefill() {
205 return zzCurrentPos>=s.offset+s.count;
206 }
207
208
209 /**
210 * Resets the scanner to read from a new input stream.
211 * Does not close the old reader.
212 *
213 * All internal variables are reset, the old input stream
214 * <b>cannot</b> be reused (internal buffer is discarded and lost).
215 * Lexical state is set to <tt>YY_INITIAL</tt>.
216 *
217 * @param reader the new input stream
218 */
219 public final void yyreset(java.io.Reader reader) {
220 // 's' has been updated.
221 zzBuffer = s.array;
222 /*
223 * We replaced the line below with the two below it because zzRefill
224 * no longer "refills" the buffer (since the way we do it, it's always
225 * "full" the first time through, since it points to the segment's
226 * array). So, we assign zzEndRead here.
227 */
228 //zzStartRead = zzEndRead = s.offset;
229 zzStartRead = s.offset;
230 zzEndRead = zzStartRead + s.count - 1;
231 zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset;
232 zzLexicalState = YYINITIAL;
233 zzReader = reader;
234 zzAtBOL = true;
235 zzAtEOF = false;
236 }
237
238
239%}
240
241Whitespace = ([ \t\f]+)
242LineTerminator = ([\n])
243Identifier = ([^ \t\f\n\[]+)
244InTagIdentifier = ([^ \t\f\n\[\]\/\=]+)
245Tag = ("b"|"i"|"u"|"s"|"size"|"color"|"center"|"quote"|"url"|"img"|"ul"|"li"|"ol"|"youtube"|"gvideo")
246
247%state INTAG
248
249%%
250
251<YYINITIAL> {
252 {Identifier} { addToken(Token.IDENTIFIER); }
253 {Whitespace} { addToken(Token.WHITESPACE); }
254 "[" { addToken(Token.MARKUP_TAG_DELIMITER); yybegin(INTAG); }
255 "[/" { addToken(Token.MARKUP_TAG_DELIMITER); yybegin(INTAG); }
256 {LineTerminator} { addNullToken(); return firstToken; }
257 <<EOF>> { addNullToken(); return firstToken; }
258}
259
260<INTAG> {
261 "/" { addToken(Token.MARKUP_TAG_DELIMITER); }
262 {Tag} { addToken(Token.MARKUP_TAG_NAME); }
263 {InTagIdentifier} { addToken(Token.MARKUP_TAG_ATTRIBUTE); }
264 {Whitespace} { addToken(Token.WHITESPACE); }
265 "=" { addToken(Token.OPERATOR); }
266 "/]" { yybegin(YYINITIAL); addToken(Token.MARKUP_TAG_DELIMITER); }
267 "]" { yybegin(YYINITIAL); addToken(Token.MARKUP_TAG_DELIMITER); }
268 . { addToken(Token.IDENTIFIER); /* Unhandled chars, not likely */ }
269 <<EOF>> { addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG); return firstToken; }
270}
Note: See TracBrowser for help on using the repository browser.