org.fife.ui.rsyntaxtextarea.modes.MxmlTokenMaker.flex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rsyntaxtextarea Show documentation
Show all versions of rsyntaxtextarea Show documentation
RSyntaxTextArea is the syntax highlighting text editor for Swing applications. Features include syntax highlighting for 40+ languages, code folding, code completion, regex find and replace, macros, code templates, undo/redo, line numbering and bracket matching.
/*
* 01/21/2011
*
* MxmlTokenMaker.java - Generates tokens for MXML syntax highlighting.
*
* This library is distributed under a modified BSD license. See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.rsyntaxtextarea.modes;
import java.io.*;
import javax.swing.text.Segment;
import org.fife.ui.rsyntaxtextarea.*;
/**
* Scanner for MXML.
*
* This implementation was created using
* JFlex 1.4.1; however, the generated file
* was modified for performance. Memory allocation needs to be almost
* completely removed to be competitive with the handwritten lexers (subclasses
* of AbstractTokenMaker
, so this class has been modified so that
* Strings are never allocated (via yytext()), and the scanner never has to
* worry about refilling its buffer (needlessly copying chars around).
* We can achieve this because RText always scans exactly 1 line of tokens at a
* time, and hands the scanner this line as an array of characters (a Segment
* really). Since tokens contain pointers to char arrays instead of Strings
* holding their contents, there is no need for allocating new memory for
* Strings.
*
* The actual algorithm generated for scanning has, of course, not been
* modified.
*
* If you wish to regenerate this file yourself, keep in mind the following:
*
* - The generated
MXMLTokenMaker.java
file will contain two
* definitions of both zzRefill
and yyreset
.
* You should hand-delete the second of each definition (the ones
* generated by the lexer), as these generated methods modify the input
* buffer, which we'll never have to do.
* - You should also change the declaration/definition of zzBuffer to NOT
* be initialized. This is a needless memory allocation for us since we
* will be pointing the array somewhere else anyway.
* - You should NOT call
yylex()
on the generated scanner
* directly; rather, you should use getTokenList
as you would
* with any other TokenMaker
instance.
*
*
* @author Robert Futrell
* @version 0.5
*
*/
%%
%public
%class MxmlTokenMaker
%extends AbstractMarkupTokenMaker
%unicode
%type org.fife.ui.rsyntaxtextarea.Token
%{
/**
* Type specific to JSPTokenMaker denoting a line ending with an unclosed
* double-quote attribute.
*/
public static final int INTERNAL_ATTR_DOUBLE = -1;
/**
* Type specific to JSPTokenMaker denoting a line ending with an unclosed
* single-quote attribute.
*/
public static final int INTERNAL_ATTR_SINGLE = -2;
/**
* Token type specific to this class; this signals that the user has
* ended a line with an unclosed XML tag; thus a new line is beginning
* still inside of the tag.
*/
public static final int INTERNAL_INTAG = -3;
/**
* Token type specific to this class; this signals that the user has
* ended a line with an unclosed Script tag; thus a new line is beginning
* still inside of the tag.
*/
public static final int INTERNAL_INTAG_SCRIPT = -4;
/**
* Token type specific to this class; this signals that the user has
* ended a line in the middle of a double-quoted attribute in a Script
* tag.
*/
public static final int INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT = -5;
/**
* Token type specific to this class; this signals that the user has
* ended a line in the middle of a single-quoted attribute in a Script
* tag.
*/
public static final int INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT = -6;
/**
* Token type specific to this class; this signals that the user has
* ended a line in an ActionScript code block (text content inside a
* Script tag).
*/
public static final int INTERNAL_IN_AS = -7;
/**
* Token type specific to this class; this signals that the user has
* ended a line in an MLC in an ActionScript code block (text content
* inside a Script tag).
*/
public static final int INTERNAL_IN_AS_MLC = -8;
/**
* Whether closing markup tags are automatically completed for HTML.
*/
private static boolean completeCloseTags;
/**
* Constructor. This must be here because JFlex does not generate a
* no-parameter constructor.
*/
public MxmlTokenMaker() {
}
static {
completeCloseTags = true;
}
/**
* Adds the token specified to the current linked list of tokens as an
* "end token;" that is, at zzMarkedPos
.
*
* @param tokenType The token's type.
*/
private void addEndToken(int tokenType) {
addToken(zzMarkedPos,zzMarkedPos, tokenType);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param tokenType The token's type.
* @see #addToken(int, int, int)
*/
private void addHyperlinkToken(int start, int end, int tokenType) {
int so = start + offsetShift;
addToken(zzBuffer, start,end, tokenType, so, true);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param tokenType The token's type.
*/
private void addToken(int tokenType) {
addToken(zzStartRead, zzMarkedPos-1, tokenType);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param tokenType The token's type.
*/
private void addToken(int start, int end, int tokenType) {
int so = start + offsetShift;
addToken(zzBuffer, start,end, tokenType, so);
}
/**
* Adds the token specified to the current linked list of tokens.
*
* @param array The character array.
* @param start The starting offset in the array.
* @param end The ending offset in the array.
* @param tokenType The token's type.
* @param startOffset The offset in the document at which this token
* occurs.
* @param hyperlink Whether this token is a hyperlink.
*/
@Override
public void addToken(char[] array, int start, int end, int tokenType,
int startOffset, boolean hyperlink) {
super.addToken(array, start,end, tokenType, startOffset, hyperlink);
zzStartRead = zzMarkedPos;
}
/**
* Returns whether markup close tags should be completed. For XML, the
* default value is true
.
*
* @return Whether closing markup tags are completed.
* @see #setCompleteCloseTags(boolean)
*/
@Override
public boolean getCompleteCloseTags() {
return completeCloseTags;
}
/**
* Static version of {@link #getCompleteCloseTags()}. This hack is
* unfortunately needed for applications to be able to query this value
* without instantiating this class.
*
* @return Whether closing markup tags are completed.
* @see #setCompleteCloseTags(boolean)
*/
public static boolean getCompleteCloseMarkupTags() {
return completeCloseTags;
}
/**
* Always returns false
, as you never want "mark occurrences"
* working in XML files.
*
* @param type The token type.
* @return Whether tokens of this type should have "mark occurrences"
* enabled.
*/
public boolean getMarkOccurrencesOfTokenType(int type) {
return false;
}
/**
* Returns the first token in the linked list of tokens generated
* from text
. This method must be implemented by
* subclasses so they can correctly implement syntax highlighting.
*
* @param text The text from which to get tokens.
* @param initialTokenType The token type we should start with.
* @param startOffset The offset into the document at which
* text
starts.
* @return The first Token
in a linked list representing
* the syntax highlighted text.
*/
public Token getTokenList(Segment text, int initialTokenType, int startOffset) {
resetTokenList();
this.offsetShift = -text.offset + startOffset;
// Start off in the proper state.
int state = Token.NULL;
switch (initialTokenType) {
case Token.MARKUP_COMMENT:
state = COMMENT;
start = text.offset;
break;
case Token.MARKUP_DTD:
state = DTD;
start = text.offset;
break;
case INTERNAL_ATTR_DOUBLE:
state = INATTR_DOUBLE;
start = text.offset;
break;
case INTERNAL_ATTR_SINGLE:
state = INATTR_SINGLE;
start = text.offset;
break;
case Token.MARKUP_PROCESSING_INSTRUCTION:
state = PI;
start = text.offset;
break;
case INTERNAL_INTAG:
state = INTAG;
start = text.offset;
break;
case INTERNAL_INTAG_SCRIPT:
state = INTAG_SCRIPT;
start = text.offset;
break;
case INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT:
state = INATTR_DOUBLE_SCRIPT;
start = text.offset;
break;
case INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT:
state = INATTR_SINGLE_SCRIPT;
start = text.offset;
break;
case INTERNAL_IN_AS:
state = AS;
start = text.offset;
break;
case INTERNAL_IN_AS_MLC:
state = AS_MLC;
start = text.offset;
break;
case Token.MARKUP_CDATA:
state = CDATA;
start = text.offset;
break;
default:
state = Token.NULL;
}
s = text;
try {
yyreset(zzReader);
yybegin(state);
return yylex();
} catch (IOException ioe) {
ioe.printStackTrace();
return new TokenImpl();
}
}
/**
* Sets whether markup close tags should be completed.
*
* @param complete Whether closing markup tags are completed.
* @see #getCompleteCloseTags()
*/
public static void setCompleteCloseTags(boolean complete) {
completeCloseTags = complete;
}
/**
* Refills the input buffer.
*
* @return true
if EOF was reached, otherwise
* false
.
*/
private boolean zzRefill() {
return zzCurrentPos>=s.offset+s.count;
}
/**
* Resets the scanner to read from a new input stream.
* Does not close the old reader.
*
* All internal variables are reset, the old input stream
* cannot be reused (internal buffer is discarded and lost).
* Lexical state is set to YY_INITIAL
.
*
* @param reader the new input stream
*/
public final void yyreset(java.io.Reader reader) {
// 's' has been updated.
zzBuffer = s.array;
/*
* We replaced the line below with the two below it because zzRefill
* no longer "refills" the buffer (since the way we do it, it's always
* "full" the first time through, since it points to the segment's
* array). So, we assign zzEndRead here.
*/
//zzStartRead = zzEndRead = s.offset;
zzStartRead = s.offset;
zzEndRead = zzStartRead + s.count - 1;
zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset;
zzLexicalState = YYINITIAL;
zzReader = reader;
zzAtBOL = true;
zzAtEOF = false;
}
%}
/* XML macros (and some building-block macros used by AS macros). */
Letter = [A-Za-z]
NonzeroDigit = [1-9]
Digit = ("0"|{NonzeroDigit})
LetterOrUnderscore = ({Letter}|"_")
NameStartChar = ({Letter}|[\:])
NameChar = ({NameStartChar}|[\-\.]|{Digit})
TagName = ({NameStartChar}{NameChar}*)
Whitespace = ([ \t\f])
LineTerminator = ([\n])
Identifier = ([^ \t\n<&]+)
EntityReference = ([&][^; \t]*[;]?)
InTagIdentifier = ([^ \t\n\"\'=\/>]+)
CDataBegin = ("")
/* ActionScript macros. */
HexDigit = ({Digit}|[A-Fa-f])
OctalDigit = ([0-7])
AnyCharacterButApostropheOrBackSlash = ([^\\'])
AnyCharacterButDoubleQuoteOrBackSlash = ([^\\\"\n])
EscapedSourceCharacter = ("u"{HexDigit}{HexDigit}{HexDigit}{HexDigit})
Escape = ("\\"(([btnfr\"'\\])|([0123]{OctalDigit}?{OctalDigit}?)|({OctalDigit}{OctalDigit}?)|{EscapedSourceCharacter}))
NonSeparator = ([^\t\f\r\n\ \(\)\{\}\[\]\;\,\.\=\>\<\!\~\?\:\+\-\*\/\&\|\^\%\"\']|"#"|"\\")
IdentifierStart = ({LetterOrUnderscore}|"$")
IdentifierPart = ({IdentifierStart}|{Digit}|("\\"{EscapedSourceCharacter}))
AS_CharLiteral = ([\']({AnyCharacterButApostropheOrBackSlash}|{Escape})*[\'])
AS_UnclosedCharLiteral = ([\']([\\].|[^\\\'])*[^\']?)
AS_ErrorCharLiteral = ({AS_UnclosedCharLiteral}[\'])
AS_StringLiteral = ([\"]({AnyCharacterButDoubleQuoteOrBackSlash}|{Escape})*[\"])
AS_UnclosedStringLiteral = ([\"]([\\].|[^\\\"])*[^\"]?)
AS_ErrorStringLiteral = ({AS_UnclosedStringLiteral}[\"])
AS_MLCBegin = ("/*")
AS_MLCEnd = ("*/")
AS_LineCommentBegin = ("//")
IntegerHelper1 = (({NonzeroDigit}{Digit}*)|"0")
IntegerHelper2 = ("0"(([xX]{HexDigit}+)|({OctalDigit}*)))
AS_IntegerLiteral = ({IntegerHelper1}[lL]?)
AS_HexLiteral = ({IntegerHelper2}[lL]?)
FloatHelper1 = ([fFdD]?)
FloatHelper2 = ([eE][+-]?{Digit}+{FloatHelper1})
FloatLiteral1 = ({Digit}+"."({FloatHelper1}|{FloatHelper2}|{Digit}+({FloatHelper1}|{FloatHelper2})))
FloatLiteral2 = ("."{Digit}+({FloatHelper1}|{FloatHelper2}))
FloatLiteral3 = ({Digit}+{FloatHelper2})
AS_FloatLiteral = ({FloatLiteral1}|{FloatLiteral2}|{FloatLiteral3}|({Digit}+[fFdD]))
AS_ErrorNumberFormat = (({AS_IntegerLiteral}|{AS_HexLiteral}|{AS_FloatLiteral}){NonSeparator}+)
AS_BooleanLiteral = ("true"|"false")
AS_Separator = ([\(\)\{\}\[\]])
AS_Separator2 = ([\;,.])
NonAssignmentOperator = ("+"|"-"|"<="|"^"|"++"|"<"|"*"|">="|"%"|"--"|">"|"/"|"!="|"?"|">>"|"!"|"&"|"=="|":"|">>"|"~"|"|"|"&&"|">>>")
AssignmentOperator = ("="|"-="|"*="|"/="|"|="|"&="|"^="|"+="|"%="|"<<="|">>="|">>>=")
AS_Operator = ({NonAssignmentOperator}|{AssignmentOperator})
AS_Identifier = ({IdentifierStart}{IdentifierPart}*)
AS_ErrorIdentifier = ({NonSeparator}+)
AS_EndScriptTag = ("")
URLGenDelim = ([:\/\?#\[\]@])
URLSubDelim = ([\!\$&'\(\)\*\+,;=])
URLUnreserved = ({LetterOrUnderscore}|{Digit}|[\-\.\~])
URLCharacter = ({URLGenDelim}|{URLSubDelim}|{URLUnreserved}|[%])
URLCharacters = ({URLCharacter}*)
URLEndCharacter = ([\/\$]|{Letter}|{Digit})
URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?)
%state COMMENT
%state PI
%state DTD
%state INTAG
%state INATTR_DOUBLE
%state INATTR_SINGLE
%state INTAG_SCRIPT
%state INATTR_DOUBLE_SCRIPT
%state INATTR_SINGLE_SCRIPT
%state CDATA
%state AS
%state AS_MLC
%state AS_EOL_COMMENT
%%
{
"" { yybegin(YYINITIAL); addToken(start,zzStartRead+2, Token.MARKUP_COMMENT); }
"-" {}
{LineTerminator} |
<> { addToken(start,zzStartRead-1, Token.MARKUP_COMMENT); return firstToken; }
}
{
[^\n\?]+ {}
{LineTerminator} { addToken(start,zzStartRead-1, Token.MARKUP_PROCESSING_INSTRUCTION); return firstToken; }
"?>" { yybegin(YYINITIAL); addToken(start,zzStartRead+1, Token.MARKUP_PROCESSING_INSTRUCTION); }
"?" {}
<> { addToken(start,zzStartRead-1, Token.MARKUP_PROCESSING_INSTRUCTION); return firstToken; }
}
{
[^\n>]+ {}
{LineTerminator} { addToken(start,zzStartRead-1, Token.MARKUP_DTD); return firstToken; }
">" { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.MARKUP_DTD); }
<> { addToken(start,zzStartRead-1, Token.MARKUP_DTD); return firstToken; }
}
{
{InTagIdentifier} { addToken(Token.MARKUP_TAG_ATTRIBUTE); }
{Whitespace}+ { addToken(Token.WHITESPACE); }
"=" { addToken(Token.OPERATOR); }
"/" { addToken(Token.MARKUP_TAG_DELIMITER); /* Not valid but we'll still accept it */ }
"/>" { yybegin(YYINITIAL); addToken(Token.MARKUP_TAG_DELIMITER); }
">" { yybegin(YYINITIAL); addToken(Token.MARKUP_TAG_DELIMITER); }
[\"] { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE); }
[\'] { start = zzMarkedPos-1; yybegin(INATTR_SINGLE); }
<> { addToken(start,zzStartRead-1, INTERNAL_INTAG); return firstToken; }
}
{
[^\"]* {}
[\"] { yybegin(INTAG); addToken(start,zzStartRead, Token.MARKUP_TAG_ATTRIBUTE_VALUE); }
<> { addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE); return firstToken; }
}
{
[^\']* {}
[\'] { yybegin(INTAG); addToken(start,zzStartRead, Token.MARKUP_TAG_ATTRIBUTE_VALUE); }
<> { addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE); return firstToken; }
}
{
{InTagIdentifier} { addToken(Token.MARKUP_TAG_ATTRIBUTE); }
{Whitespace}+ { addToken(Token.WHITESPACE); }
"=" { addToken(Token.OPERATOR); }
"/" { addToken(Token.MARKUP_TAG_DELIMITER); /* Not valid but we'll still accept it */ }
"/>" { yybegin(YYINITIAL); addToken(Token.MARKUP_TAG_DELIMITER); }
">" { yybegin(AS); addToken(Token.MARKUP_TAG_DELIMITER); }
[\"] { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE_SCRIPT); }
[\'] { start = zzMarkedPos-1; yybegin(INATTR_SINGLE_SCRIPT); }
<> { addToken(start,zzStartRead-1, INTERNAL_INTAG_SCRIPT); return firstToken; }
}
{
[^\"]* {}
[\"] { yybegin(INTAG_SCRIPT); addToken(start,zzStartRead, Token.MARKUP_TAG_ATTRIBUTE_VALUE); }
<> { addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT); return firstToken; }
}
{
[^\']* {}
[\'] { yybegin(INTAG_SCRIPT); addToken(start,zzStartRead, Token.MARKUP_TAG_ATTRIBUTE_VALUE); }
<> { addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT); return firstToken; }
}
{
[^\]]+ {}
{CDataEnd} { int temp=zzStartRead; yybegin(YYINITIAL); addToken(start,zzStartRead-1, Token.MARKUP_CDATA); addToken(temp,zzMarkedPos-1, Token.MARKUP_CDATA_DELIMITER); }
"]" {}
<> { addToken(start,zzStartRead-1, Token.MARKUP_CDATA); return firstToken; }
}
{
{AS_EndScriptTag} {
int origStart = zzStartRead;
String text = yytext();
int tagNameEnd = text.length() - 2; // "-1" is '>'
while (Character.isWhitespace(text.charAt(tagNameEnd))) {
tagNameEnd--;
}
int tagNameLen = tagNameEnd - 1;
yybegin(YYINITIAL);
addToken(zzStartRead,zzStartRead+1, Token.MARKUP_TAG_DELIMITER);
addToken(origStart+2,origStart+2+tagNameLen-1, Token.MARKUP_TAG_NAME);
if (tagNameEnd> { addEndToken(INTERNAL_IN_AS); return firstToken; }
/* Catch any other (unhandled) characters and flag them as bad. */
. { addToken(Token.ERROR_IDENTIFIER); }
}
{
[^hwf\n\*]+ {}
{URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_MULTILINE); start = zzMarkedPos; }
[hwf] {}
\n { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addEndToken(INTERNAL_IN_AS_MLC); return firstToken; }
{AS_MLCEnd} { yybegin(AS); addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); }
\* {}
<> { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addEndToken(INTERNAL_IN_AS_MLC); return firstToken; }
}
{
[^hwf\n]+ {}
{URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_EOL); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_EOL); start = zzMarkedPos; }
[hwf] {}
\n |
<> { addToken(start,zzStartRead-1, Token.COMMENT_EOL); addEndToken(INTERNAL_IN_AS); return firstToken; }
}