- Joined
- Jul 10, 2007
- Messages
- 6,306
All right, so far I've finished the Lexer ^_^.
Could use feedback o-o.
Written with Antlr 4
So some of the features
-compatible with vJASS
-string interpolation
-code interpolation
-full code preprocessing interpretation
-binary number support
-any size ascii number support
-for, while, do while, for/in, loop, break, continue
-proper order of initialization
-generic blocks
-declare locals anywhere
-properly working prefix/posfix operators
-modulo
-assign append operators (+=, -=, *=, /=, %=)
-lambda (constant)
-internal, protected modifiers
-private scopes
-auto run code not inside of a function (put it in blocks to localize)
-vJASS interpreter for compile time code, some of it translated to Lua for manipulating map
-new lines no longer required, meaning that they can be used freely as white space!
-native declaration
-type declaration
-struct (extend type, array, or other struct)
-all the other normal vJASS stuff
-use of either # or //! for preprocessor directives
-nested functions
-nested structs
-enums
-textmacros may call other textmacros
-nested textmacros
-globals do not have to be in a global block
-full boolean expression support for static ifs
-modules may take arguments
-module_once vs module (you should be able to guess at what each one does)
-onInit no longer required, use blocks
-no zinc support (sry, hardly anyone uses it, but someone is more than free to write up a lexer/grammar for it)
-static extension (no polymorphism support) vs regular extension (polymorphic support)
-full operator overloading (add missing stuff, allow more stuff)
-function overloading (hi(1) vs hi(1,2))
-default arguments (function hi takes integer m, integer o = 6 returns nothing)
-allow full use of underscores
-public won't add _ for scopes/libraries, that has always been weird...
-structs won't generate code that isn't being utilized
-override allocation, deallocation, create, destroy, polymorphic behavior, extension behavior
-new link type (like delegates, but use "this" instead of what is stored in the delegate)
-import from relative directories
-github support (define github repositories to look up, any missing required libraries will be searched on github, libraries marked for autoupdating will check github for updates)
-function sorting
-variable sorting
-no more need for keyword to see a struct below you
-static ifs may use anything from globals to struct methods to interpolations
-static if is the same as #if is the same as //! if
-textmacro interpolation will only be $ or ${ }, not $$, sry
-textmacros no longer need to take strings, they can take any type
-text inside of a string will not automatically be replaced by a textmacro, you need to interpolate it twice, the textmacro is a #function and its params are locals
-auto clean return of local handles
-hook (takes args), hook_after (takes args + return), hook_override(takes args, returns, can have many) with smarter hooks that only use triggers when absolutely necessary
-triggers will be built as balanced trees when constant (hooks, polymorphism, etc)
-typedef
-multi array overload
-input multiple files (as many .j files as you want, including war3map.j, common.j, Blizzard.j, common.ai, random.j, w/e)
-debug is a variable
-templates (list<int>)
likely going to translate the vJASS preprocess stuff into Groovy + allow users to write preprocessor code in Groovy if they want, this way they can use Java code and a whole slew of things =)
some interesting things you can do with interpolation
#name = "hi"
string $name = "$$name" //string hi = "hi", lol...
"hello there $name[GetPlayerId(GetLocalPlayer())]! Your income is ${team.income + income[GetPlayerId(GetLocalPlayer())]}." //yes, this actually works, lol... look at giant pic for proof, it works
and ofc.. this is the most whacked thing ever
"${"$name"}" //lol...
Input
Output
Grammar (hardly started)
Lexer
Could use feedback o-o.
Written with Antlr 4
So some of the features
-compatible with vJASS
-string interpolation
-code interpolation
-full code preprocessing interpretation
-binary number support
-any size ascii number support
-for, while, do while, for/in, loop, break, continue
-proper order of initialization
-generic blocks
-declare locals anywhere
-properly working prefix/posfix operators
-modulo
-assign append operators (+=, -=, *=, /=, %=)
-lambda (constant)
-internal, protected modifiers
-private scopes
-auto run code not inside of a function (put it in blocks to localize)
-vJASS interpreter for compile time code, some of it translated to Lua for manipulating map
-new lines no longer required, meaning that they can be used freely as white space!
-native declaration
-type declaration
-struct (extend type, array, or other struct)
-all the other normal vJASS stuff
-use of either # or //! for preprocessor directives
-nested functions
-nested structs
-enums
-textmacros may call other textmacros
-nested textmacros
-globals do not have to be in a global block
-full boolean expression support for static ifs
-modules may take arguments
-module_once vs module (you should be able to guess at what each one does)
-onInit no longer required, use blocks
-no zinc support (sry, hardly anyone uses it, but someone is more than free to write up a lexer/grammar for it)
-static extension (no polymorphism support) vs regular extension (polymorphic support)
-full operator overloading (add missing stuff, allow more stuff)
-function overloading (hi(1) vs hi(1,2))
-default arguments (function hi takes integer m, integer o = 6 returns nothing)
-allow full use of underscores
-public won't add _ for scopes/libraries, that has always been weird...
-structs won't generate code that isn't being utilized
-override allocation, deallocation, create, destroy, polymorphic behavior, extension behavior
-new link type (like delegates, but use "this" instead of what is stored in the delegate)
-import from relative directories
-github support (define github repositories to look up, any missing required libraries will be searched on github, libraries marked for autoupdating will check github for updates)
-function sorting
-variable sorting
-no more need for keyword to see a struct below you
-static ifs may use anything from globals to struct methods to interpolations
-static if is the same as #if is the same as //! if
-textmacro interpolation will only be $ or ${ }, not $$, sry
-textmacros no longer need to take strings, they can take any type
-text inside of a string will not automatically be replaced by a textmacro, you need to interpolate it twice, the textmacro is a #function and its params are locals
-auto clean return of local handles
-hook (takes args), hook_after (takes args + return), hook_override(takes args, returns, can have many) with smarter hooks that only use triggers when absolutely necessary
-triggers will be built as balanced trees when constant (hooks, polymorphism, etc)
-typedef
-multi array overload
-input multiple files (as many .j files as you want, including war3map.j, common.j, Blizzard.j, common.ai, random.j, w/e)
-debug is a variable
-templates (list<int>)
likely going to translate the vJASS preprocess stuff into Groovy + allow users to write preprocessor code in Groovy if they want, this way they can use Java code and a whole slew of things =)
some interesting things you can do with interpolation
#name = "hi"
string $name = "$$name" //string hi = "hi", lol...
"hello there $name[GetPlayerId(GetLocalPlayer())]! Your income is ${team.income + income[GetPlayerId(GetLocalPlayer())]}." //yes, this actually works, lol... look at giant pic for proof, it works
and ofc.. this is the most whacked thing ever
"${"$name"}" //lol...
Input
Code:
-0b1011
'\\\\\\\\'
"hello there ${ "$name!" }! /*testing" //test complete
"hello there $player[id]! /*testing"
"$$name!"
"$name"
/* this is at test /*another test o-o /*nesting!!*/ */ */
//"what are you up to? //testing" //test complete
//var = 15.5 + 0b110 + 0xff + 'a' + (('ffff')) + 14 + true + null
//hi there
//ho
/*wtf
/*woah*/
/* /* */ */
*/
Output
Grammar (hardly started)
Code:
parser grammar vJASSParser;
options { tokenVocab = vJASSLexer; }
/*
* globals
* variable declaration
* type declaration
* native declaration
* function declaration
* local declarations
* statements
* statement
* if
* loop
* return
* set
* call
* interface
* struct
* library
* scope
* struct
* interface
* globals
* type
* native
* function
* scope
* struct
* interface
* globals
* type
* native
* function
*/
start: literal*;
variableType
: BOOLEAN_TYPE
| INTEGER_TYPE
| REAL_TYPE
| STRING_TYPE
| CODE_TYPE
| HANDLE_TYPE
| LAMBDA_TYPE
| IDENTIFIER
;
literal
: (
BOOLEAN
| INTEGER
| REAL
| NULL
| IDENTIFIER
)
| stringLiteral
;
//globalBlock: GLOBALS variableDeclaration* ENDGLOBALS;
//variableDeclaration: variableType ARRAY? IDENTIFIER (ASSIGN expression)?;
expression: INTERPOLATE expression | INTERPOLATE LBRACE expression RBRACE | literal | expression LPAREN expression RPAREN | LPAREN expression RPAREN | expression LBRACK expression RBRACK;
stringLiteral: STRING_START (STRING_CHUNK | INTERPOLATE expression | INTERPOLATE LBRACE expression RBRACE)* STRING_END;
/*
expression
: '(' expression ')'
| 'this'
| 'super'
| 'exists'
| 'thistype'
| literal
| Identifier
| expression '.' expression
| expression '[' expression ']'
| expression '(' expressionList? ')'
| expression ('++' | '--')
| ('+'|'-'|'++'|'--') expression
| ('not') expression
| expression ('*'|'/'|'%') expression
| expression ('+'|'-') expression
| expression ('<=' | '>=' | '>' | '<') expression
| expression 'instanceof' type
| expression ('==' | '!=') expression
| expression 'and' expression
| expression 'or' expression
| expression '?' expression ':' expression
| 'set' expression
( '='<assoc=right>
| '+='<assoc=right>
| '-='<assoc=right>
| '*='<assoc=right>
| '/='<assoc=right>
| '%='<assoc=right>
)
expression
;
literal
: Integer
| Real
| stringLiteral
| Ascii
| Boolean
| 'null'
;
*/
//expressionList: expression (',' expression)*;
//functionCallExpression: 'call' functionExpression;
//functionExpression: Identifier '(' expressionList? ')';
//stringLiteral: StringStart (StringText | stringInterpolation)* StringEnd;
//stringInterpolation: StringInterpolationStart interpolationVariable=Identifier StringInterpolationEnd;
//<T> template
//# -> print result
//#{} -> print result
//ternary
//=
//+=, -=
//*=, /=, %=
//<<=, >>>=, >>=
//&=, ^=, |=
//,
Lexer
Code:
lexer grammar vJASSLexer;
tokens {
/* filters */
COMMENT, WHITESPACE
,
/* atoms */
STRING_START, STRING_CHUNK, STRING_END
,
IDENTIFIER
,
GROOVY
,
/* primitives */
BOOLEAN_TYPE, INTEGER_TYPE, REAL_TYPE, STRING_TYPE, CODE_TYPE, HANDLE_TYPE, LAMBDA_TYPE, NOTHING_TYPE,
BOOLEAN, INTEGER, REAL, NULL
,
/* keywords */
ARRAY
,
BLOCK, BREAK
,
CONSTANT, CONTINUE
,
DEBUG, DEBUG_MODE, DEFAULT, DELEGATE, DO
,
ELSE, ELSEIF, ENDBLOCK, ENDDO, ENDENUM, ENDFOR, ENDFUNCTION, ENDGLOBALS,
ENDIF, ENDLIBRARY, ENDLOOP, ENDMETHOD, ENDMODULE, ENDNOVJASS, ENDSCOPE, ENDSTRUCT,
ENDTEXTMACRO, ENDWHILE, ENUM, EXISTS, EXTENDS
,
FINAL, FOR, FUNCTION
,
GLOBALS
,
IF, IMPLEMENT, IMPLEMENTS, IMPORT, IN, INITIALIZER, INSTANCEOF, INTERFACE,
INTERNAL
,
LOCAL, LOOP, LIBRARY
,
METHOD, MODULE
,
NATIVE, NEEDS, NOVJASS
,
OPERATOR
,
PRIVATE, PROTECTED, PUBLIC
,
READONLY, REQUIRES, RETURN, RETURNS, RUNTEXTMACRO
,
SCOPE, SET, STATIC, STRUCT, SUPER
,
TAKES, TEXTMACRO, THIS, THISTYPE
,
USES
,
TYPE
,
WHILE
,
/* separators */
LPAREN, RPAREN
,
LBRACE, RBRACE
,
LBRACK, RBRACK
,
COMMA, DOT
,
/* operators */
ASSIGN, ADD_ASSIGN, SUB_ASSIGN, MUL_ASSIGN, DIV_ASSIGN, MOD_ASSIGN,
AND_ASSIGN, XOR_ASSIGN, OR_ASSIGN, LEFT_SHIFT_ASSIGN, RIGHT_SHIFT_ASSIGN,
LOGICAL_RIGHT_SHIFT_ASSIGN
,
GT, LT, LTE, GTE
,
EQ, NEQ
,
NOT, AND, OR, AND_BITWISE, OR_BITWISE, XOR_BITWISE
,
QUESTION, COLON
,
INC, DEC
,
ADD, SUB, MUL, DIV, MOD
,
INTERPOLATE
,
/* misc */
AT
,
/* generic error */
ERROR
}
@members {
public static final int CHANNEL_WHITESPACE = 1;
public static final int CHANNEL_COMMENTS = 2;
public java.util.Stack<Integer> modeStack = new java.util.Stack<Integer>();
public boolean hasModeTerminal() { return !modeStack.empty(); }
public void pushModeTerminal(int symbol) { modeStack.push(symbol); }
public void popModeTerminal() { if (modeStack.empty()) return; modeStack.pop(); }
public boolean checkModeTerminal(int symbol) { if (modeStack.empty()) return false; return modeStack.peek() == symbol; }
public void parseBinary() {
_text = getText();
if (_text.charAt(0) == '-' || _text.charAt(0) == '+')
_text = _text.substring(0, 1) + _text.substring(3, _text.length());
else
_text = _text.substring(2, _text.length());
_text = Integer.toString(Integer.parseInt(_text, 2));
_type = INTEGER;
}
public void parseOctal() {
_text = getText();
if (_text.charAt(0) == '-' || _text.charAt(0) == '+')
_text = _text.substring(0, 1) + _text.substring(2, _text.length());
else
_text = _text.substring(1, _text.length());
_text = Integer.toString(Integer.parseInt(_text, 8));
_type = INTEGER;
}
public void parseDecimal() {
_text = getText();
_text = Integer.toString(Integer.parseInt(_text, 10));
_type = INTEGER;
}
public void parseHex() {
_text = getText();
if (_text.charAt(0) == '-' || _text.charAt(0) == '+')
_text = _text.substring(0, 1) + _text.substring(3, _text.length());
else
_text = _text.substring(2, _text.length());
_text = Integer.toString(Integer.parseInt(_text, 16));
_type = INTEGER;
}
public void parseAscii() {
_text = getText();
int m = 0;
int start = 1;
int end = _text.length() - 1;
while (start < end) {
if (_text.charAt(start) == '\\')
++start;
m = m*256 + _text.charAt(start++);
}
_text = Integer.toString(m);
_type = INTEGER;
}
public void filterGroovy() {
_text = getText();
_text = _text.substring(6, _text.length() - 9);
_type = GROOVY;
}
}
/*
* Filters
*/
LINE_COMMENT_FILTER
: '//' ('!' | ~[!\n] ~[\n]* '\n'? | '\n'?)
-> type(COMMENT), channel(CHANNEL_COMMENTS);
DELIMITED_COMMENT_FILTER
: '/*'
-> pushMode(inDelimitedComment), more;
WHITESPACE_FILTER
: [ \t\r\n\u000C]+
-> type(WHITESPACE), channel(CHANNEL_WHITESPACE);
/*
* Primitives
*/
BOOLEAN_PRIMITIVE
: 'boolean'
-> type(BOOLEAN_TYPE);
INTEGER_PRIMITIVE
: 'integer'
-> type(INTEGER_TYPE);
REAL_PRIMITIVE
: 'real'
-> type(REAL_TYPE);
STRING_PRIMITIVE
: 'string'
-> type(STRING_TYPE);
CODE_PRIMITIVE
: 'code'
-> type(CODE_TYPE);
HANDLE_PRIMITIVE
: 'handle'
-> type(HANDLE_TYPE);
LAMBDA_PRIMITIVE
: 'lambda'
-> type(LAMBDA_TYPE);
NOTHING_PRIMITIVE
: 'nothing'
-> type(NOTHING_TYPE);
/*
* Keywords
*/
ARRAY_KEYWORD
: 'array'
-> type(ARRAY);
BLOCK_KEYWORD
: 'block'
-> type(BLOCK);
BREAK_KEYWORD
: 'break'
-> type(BREAK);
CONSTANT_KEYWORD
: 'constant'
-> type(CONSTANT);
CONTINUE_KEYWORD
: 'continue'
-> type(CONTINUE);
DEBUG_KEYWORD
: 'debug'
-> type(DEBUG);
DEBUG_MODE_KEYWORD
: 'DEBUG_MODE'
-> type(DEBUG_MODE);
DEFAULT_KEYWORD
: 'default'
-> type(DEFAULT);
DELEGATE_KEYWORD
: 'delegate'
-> type(DELEGATE);
DO_KEYWORD
: 'do'
-> type(DO);
ELSE_KEYWORD
: 'else'
-> type(ELSE);
ELSEIF_KEYWORD
: 'elseif'
-> type(ELSEIF);
ENDBLOCK_KEYWORD
: 'endblock'
-> type(ENDBLOCK);
ENDDO_KEYWORD
: 'enddo'
-> type(ENDDO);
ENDENUM_KEYWORD
: 'endenum'
-> type(ENDENUM);
ENDFOR_KEYWORD
: 'endfor'
-> type(ENDFOR);
ENDFUNCTION_KEYWORD
: 'endfunction'
-> type(ENDFUNCTION);
ENDGLOBALS_KEYWORD
: 'endglobals'
-> type(ENDGLOBALS);
ENDIF_KEYWORD
: 'endif'
-> type(ENDIF);
ENDLIBRARY_KEYWORD
: 'endlibrary'
-> type(ENDLIBRARY);
ENDLOOP_KEYWORD
: 'endloop'
-> type(ENDLOOP);
ENDMETHOD_KEYWORD
: 'endmethod'
-> type(ENDMETHOD);
ENDMODULE_KEYWORD
: 'endmodule'
-> type(ENDMODULE);
ENDNOVJASS_KEYWORD
: 'endnovjass'
-> type(ENDNOVJASS);
ENDSCOPE_KEYWORD
: 'endscope'
-> type(ENDSCOPE);
ENDSTRUCT_KEYWORD
: 'endstruct'
-> type(ENDSTRUCT);
ENDTEXTMACRO_KEYWORD
: 'endtextmacro'
-> type(ENDTEXTMACRO);
ENDWHILE_KEYWORD
: 'endwhile'
-> type(ENDWHILE);
ENUM_KEYWORD
: 'enum'
-> type(ENUM);
EXISTS_KEYWORD
: 'exists'
-> type(EXISTS);
EXTENDS_KEYWORD
: 'extends'
-> type(EXTENDS);
FINAL_KEYWORD
: 'final'
-> type(FINAL);
FOR_KEYWORD
: 'for'
-> type(FOR);
FUNCTION_KEYWORD
: 'function'
-> type(FUNCTION);
GLOBALS_KEYWORD
: 'globals'
-> type(GLOBALS);
IF_KEYWORD
: 'if'
-> type(IF);
IMPLEMENT_KEYWORD
: 'implement'
-> type(IMPLEMENT);
IMPLEMENTS_KEYWORD
: 'implements'
-> type(IMPLEMENTS);
IMPORT_KEYWORD
: 'import'
-> type(IMPORT);
IN_KEYWORD
: 'in'
-> type(IN);
INITIALIZER_KEYWORD
: 'initializer'
-> type(INITIALIZER);
INSTANCEOF_KEYWORD
: 'instanceof'
-> type(INSTANCEOF);
INTERFACE_KEYWORD
: 'interface'
-> type(INTERFACE);
INTERNAL_KEYWORD
: 'internal'
-> type(INTERNAL);
LOCAL_KEYWORD
: 'local'
-> type(LOCAL);
LOOP_KEYWORD
: 'loop'
-> type(LOOP);
LIBRARY_KEYWORD
: 'library'
-> type(LIBRARY);
METHOD_KEYWORD
: 'method'
-> type(METHOD);
MODULE_KEYWORD
: 'module'
-> type(MODULE);
NATIVE_KEYWORD
: 'native'
-> type(NATIVE);
NEEDS_KEYWORD
: 'needs'
-> type(NEEDS);
NOVJASS_KEYWORD
: 'novjass'
-> type(NOVJASS);
OPERATOR_KEYWORD
: 'operator'
-> type(OPERATOR);
PRIVATE_KEYWORD
: 'private'
-> type(PRIVATE);
PROTECTED_KEYWORD
: 'protected'
-> type(PROTECTED);
PUBLIC_KEYWORD
: 'public'
-> type(PUBLIC);
READONLY_KEYWORD
: 'readonly'
-> type(READONLY);
REQUIRES_KEYWORD
: 'requires'
-> type(REQUIRES);
RETURN_KEYWORD
: 'return'
-> type(RETURN);
RETURNS_KEYWORD
: 'returns'
-> type(RETURNS);
RUNTEXTMACRO_KEYWORD
: 'runtextmacro'
-> type(RUNTEXTMACRO);
SCOPE_KEYWORD
: 'scope'
-> type(SCOPE);
SET_KEYWORD
: 'set'
-> type(SET);
STATIC_KEYWORD
: 'static'
-> type(STATIC);
STRUCT_KEYWORD
: 'struct'
-> type(STRUCT);
SUPER_KEYWORD
: 'super'
-> type(SUPER);
TAKES_KEYWORD
: 'takes'
-> type(TAKES);
TEXTMACRO_KEYWORD
: 'textmacro'
-> type(TEXTMACRO);
THIS_KEYWORD
: 'this'
-> type(THIS);
THISTYPE_KEYWORD
: 'thistype'
-> type(THISTYPE);
USES_KEYWORD
: 'uses'
-> type(USES);
TYPE_KEYWORD
: 'type'
-> type(TYPE);
WHILE_KEYWORD
: 'while'
-> type(WHILE);
/*
* Separators
*/
LPAREN_SEP
: '('
{_type = LPAREN; if (hasModeTerminal()) {pushModeTerminal(LPAREN);}};
RPAREN_SEP
: ')'
{_type = RPAREN; if (checkModeTerminal(LPAREN)) {popModeTerminal(); if (!hasModeTerminal()) { popMode(); }}};
LBRACE_SEP
: '{'
{_type = LBRACE; if (hasModeTerminal()) {pushModeTerminal(LBRACE);}};
RBRACE_SEP
: '}'
{_type = RBRACE; if (checkModeTerminal(LBRACE)) {popModeTerminal(); if (!hasModeTerminal()) { popMode(); }}};
LBRACK_SEP
: '['
{_type = LBRACK; if (hasModeTerminal()) {pushModeTerminal(LBRACK);}};
RBRACK_SEP
: ']'
{_type = RBRACK; if (checkModeTerminal(LBRACK)) {popModeTerminal(); if (!hasModeTerminal()) { popMode(); }}};
COMMA_SEP
: ','
-> type(COMMA);
DOT_SEP
: '.'
-> type(DOT);
/*
* Operators
*/
ASSIGN_OP
: '='
-> type(ASSIGN);
ADD_ASSIGN_OP
: '+='
-> type(ADD_ASSIGN);
SUB_ASSIGN_OP
: '-='
-> type(SUB_ASSIGN);
MUL_ASSIGN_OP
: '*='
-> type(MUL_ASSIGN);
DIV_ASSIGN_OP
: '/='
-> type(DIV_ASSIGN);
MOD_ASSIGN_OP
: '%='
-> type(MOD_ASSIGN);
AND_ASSIGN_OP
: '&='
-> type(AND_ASSIGN);
XOR_ASSIGN_OP
: '^='
-> type(XOR_ASSIGN);
OR_ASSIGN_OP
: '|='
-> type(OR_ASSIGN);
LEFT_SHIFT_ASSIGN_OP
: '<<='
-> type(LEFT_SHIFT_ASSIGN);
RIGHT_SHIFT_ASSIGN_OP
: '>>='
-> type(RIGHT_SHIFT_ASSIGN);
LOGICAL_RIGHT_SHIFT_ASSIGN_OP
: '>>>='
-> type(LOGICAL_RIGHT_SHIFT_ASSIGN);
GT_OP
: '>'
{_type = GT;};
LT_OP
: '<'
{_type = LT;};
NOT_OP
: 'not'
-> type(NOT);
QUESTION_OP
: '?'
-> type(QUESTION);
COLON_OP
: ':'
-> type(COLON);
EQ_OP
: '=='
-> type(EQ);
LTE_OP
: '<='
-> type(LTE);
GTE_OP
: '>='
-> type(GTE);
NEQ_OP
: '!='
-> type(NEQ);
AND_OP
: ('and' | '&&')
{_type = AND; _text = "and";};
OR_OP
: ('or' | '||')
{_type = OR; _text = "or";};
XOR_BITWISE_OP
: '^'
-> type(XOR_BITWISE);
OR_BITWISE_OP
: '|'
-> type(OR_BITWISE);
AND_BITWISE_OP
: '&'
-> type(AND_BITWISE);
INC_OP
: '++'
-> type(INC);
DEC_OP
: '--'
-> type(DEC);
ADD_OP
: '+'
-> type(ADD);
SUB_OP
: '-'
-> type(SUB);
MUL_OP
: '*'
-> type(MUL);
DIV_OP
: '/'
-> type(DIV);
MOD_OP
: '%'
-> type(MOD);
INTERPOLATE_OP
: '$'
-> type(INTERPOLATE);
/*
* Misc
*/
AT_MISC
: '@'
-> type(AT);
/*
* Atoms
*/
GROOVY_ATOM
: 'groovy' (GROOVY_STRING_ATOM | GROOVY_ASCII_ATOM | LINE_COMMENT_FILTER | GROOVY_DELIMITED_COMMENT_FILTER | .)*? 'endgroovy'
{ filterGroovy(); }
;
fragment GROOVY_STRING_ATOM
: '"' (~["] | '\\"')* '"'
;
fragment GROOVY_ASCII_ATOM
: '\'' (~['] | '\\\'')* '\''
;
fragment GROOVY_DELIMITED_COMMENT_FILTER
: '/*' .*? '*/'
;
STRING_ATOM
: '"'
-> pushMode(inString), type(STRING_START);
NULL_ATOM
: 'null'
-> type(NULL);
BOOLEAN_ATOM
: ('true' | 'false')
-> type(BOOLEAN);
REAL_ATOM
: (SIGN_SUB? (([1-9] [0-9]* | '0') '.' [0-9]*))
-> type(REAL);
BIN_SUB
: SIGN_SUB? ('0' ('b' | 'B') [0-1]+)
{ parseBinary(); };
OCT_SUB
: SIGN_SUB? ('0' [0-7]+)
{ parseOctal(); };
DEC_SUB
: SIGN_SUB? ([1-9] [0-9]* | '0')
{ parseDecimal(); };
HEX_SUB
: SIGN_SUB? ('0' ('x' | 'X') [0-9a-fA-F]+)
{ parseHex(); };
ASCII_SUB
: '\'' ASCII_SUB_DIG+ '\''
{ parseAscii(); };
fragment ASCII_SUB_DIG
: ~['\\] | ('\\' ['\\]);
fragment SIGN_SUB
: ('+'|'-');
IDENTIFIER_ATOM
: [a-zA-Z_] [a-zA-Z0-9_]*
-> type(IDENTIFIER);
mode inDelimitedComment;
DELIMITED_COMMENT_START
: '/*'
-> pushMode(inDelimitedComment), more;
DELIMITED_COMMENT_END
: '*/'
{popMode(); if (_mode == inDelimitedComment) { more(); } else { _type = COMMENT; _channel = CHANNEL_COMMENTS; } };
DELIMITED_COMMENT_ERROR
: EOF
-> type(ERROR);
DELIMITED_COMMENT_TEXT
: .
-> more;
mode inString;
STRING_ATOM_ERROR
: EOF
-> type(ERROR);
STRING_ATOM_TEXT
: (~["\\$\Z] | ('\\' ["\\$]))+
-> type(STRING_CHUNK);
STRING_ATOM_END
: STRING_ATOM
{popMode(); _type = STRING_END;};
STRING_ATOM_INTERPOLATION
: INTERPOLATE_OP
-> type(INTERPOLATE), pushMode(inPartialInterpolationString);
mode inPartialInterpolationString;
PARTIAL_INTERPOLATION_STRING_LBRACK_SEP
: LBRACK_SEP
{_type = LBRACK; pushMode(DEFAULT_MODE); pushModeTerminal(LBRACK);};
PARTIAL_INTERPOLATION_STRING_LPAREN_SEP
: LPAREN_SEP
{_type = LPAREN; pushMode(DEFAULT_MODE); pushModeTerminal(LPAREN);};
PARTIAL_INTERPOLATION_STRING_LBRACE_SEP
: LBRACE_SEP
{_type = LBRACE; pushMode(DEFAULT_MODE); pushModeTerminal(LBRACE);};
PARTIAL_INTERPOLATION_STRING_DOT_SEP
: DOT_SEP
-> type(DOT);
PARTIAL_INTERPOLATION_STRING_NULL_ATOM
: NULL_ATOM
-> type(NULL);
PARTIAL_INTERPOLATION_STRING_BOOLEAN_ATOM
: BOOLEAN_ATOM
-> type(BOOLEAN);
PARTIAL_INTERPOLATION_STRING_BIN_SUB
: SIGN_SUB? ('0' ('b' | 'B') [0-1]+)
{ parseBinary(); };
PARTIAL_INTERPOLATION_STRING_OCT_SUB
: SIGN_SUB? ('0' [0-7]+)
{ parseOctal(); };
PARTIAL_INTERPOLATION_STRING_DEC_SUB
: SIGN_SUB? ([1-9] [0-9]* | '0')
{ parseDecimal(); };
PARTIAL_INTERPOLATION_STRING_HEX_SUB
: SIGN_SUB? ('0' ('x' | 'X') [0-9a-fA-F]+)
{ parseHex(); };
PARTIAL_INTERPOLATION_STRING_ASCII_SUB
: '\'' ASCII_SUB_DIG+ '\''
{ parseAscii(); };
PARTIAL_INTERPOLATION_STRING_REAL_ATOM
: REAL_ATOM
-> type(REAL);
PARTIAL_INTERPOLATION_STRING_IDENTIFIER_ATOM
: IDENTIFIER_ATOM
-> type(IDENTIFIER);
PARTIAL_INTERPOLATION_STRING_INTERPOLATE_OP
: INTERPOLATE_OP
-> type(INTERPOLATE);
PARTIAL_INTERPOLATION_STRING_STR
: STRING_ATOM
-> popMode, popMode, type(STRING_END);
PARTIAL_INTERPOLATION_STRING_ERROR
: EOF
-> type(ERROR);
PARTIAL_INTERPOLATION_STRING_POP
: .
-> popMode, type(STRING_CHUNK);
Attachments
Last edited: