Upgrade to OPENRNDR 0.4 snapshot
This commit is contained in:
46
orx-jvm/orx-kotlin-parser/build.gradle
Normal file
46
orx-jvm/orx-kotlin-parser/build.gradle
Normal file
@@ -0,0 +1,46 @@
|
||||
//plugins {
|
||||
// id 'antlr'
|
||||
//}
|
||||
|
||||
apply plugin: 'antlr'
|
||||
|
||||
sourceSets {
|
||||
demo {
|
||||
java {
|
||||
srcDirs = ["src/demo/kotlin"]
|
||||
compileClasspath += main.getCompileClasspath()
|
||||
runtimeClasspath += main.getRuntimeClasspath()
|
||||
}
|
||||
}
|
||||
main {
|
||||
java {
|
||||
srcDir("src/main/java")
|
||||
srcDir("src/main/kotlin")
|
||||
srcDir("build/generated-src/antlr")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
generateGrammarSource {
|
||||
maxHeapSize = "64m"
|
||||
arguments += ["-visitor", "-long-messages"]
|
||||
outputDirectory = file("${project.buildDir}/generated-src/antlr/org/openrndr/extra/kotlin/antlr".toString())
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
antlr("org.antlr:antlr4:$antlrVersion")
|
||||
implementation("org.antlr:antlr4-runtime:$antlrVersion")
|
||||
|
||||
demoImplementation(project(":orx-camera"))
|
||||
demoImplementation(project(":orx-panel"))
|
||||
demoImplementation("org.openrndr:openrndr-application:$openrndrVersion")
|
||||
demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion")
|
||||
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
|
||||
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")
|
||||
demoImplementation(sourceSets.getByName("main").output)
|
||||
}
|
||||
|
||||
tasks.getByName("compileKotlin").dependsOn("generateGrammarSource")
|
||||
527
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinLexer.g4
Executable file
527
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinLexer.g4
Executable file
@@ -0,0 +1,527 @@
|
||||
/**
|
||||
* Kotlin lexical grammar in ANTLR4 notation
|
||||
*/
|
||||
|
||||
|
||||
|
||||
lexer grammar KotlinLexer;
|
||||
|
||||
|
||||
|
||||
import UnicodeClasses;
|
||||
|
||||
// SECTION: lexicalGeneral
|
||||
|
||||
ShebangLine
|
||||
: '#!' ~[\r\n]*
|
||||
;
|
||||
|
||||
DelimitedComment
|
||||
: '/*' ( DelimitedComment | . )*? '*/'
|
||||
-> channel(HIDDEN)
|
||||
;
|
||||
|
||||
LineComment
|
||||
: '//' ~[\r\n]*
|
||||
-> channel(HIDDEN)
|
||||
;
|
||||
|
||||
WS
|
||||
: [\u0020\u0009\u000C]
|
||||
-> channel(HIDDEN)
|
||||
;
|
||||
|
||||
NL: '\n' | '\r' '\n'?;
|
||||
|
||||
fragment Hidden: DelimitedComment | LineComment | WS;
|
||||
|
||||
// SECTION: separatorsAndOperations
|
||||
|
||||
RESERVED: '...';
|
||||
DOT: '.';
|
||||
COMMA: ',';
|
||||
LPAREN: '(' -> pushMode(Inside);
|
||||
RPAREN: ')';
|
||||
LSQUARE: '[' -> pushMode(Inside);
|
||||
RSQUARE: ']';
|
||||
LCURL: '{' -> pushMode(DEFAULT_MODE);
|
||||
/*
|
||||
* When using another programming language (not Java) to generate a parser,
|
||||
* please replace this code with the corresponding code of a programming language you are using.
|
||||
*/
|
||||
RCURL: '}' { if (!_modeStack.isEmpty()) { popMode(); } };
|
||||
MULT: '*';
|
||||
MOD: '%';
|
||||
DIV: '/';
|
||||
ADD: '+';
|
||||
SUB: '-';
|
||||
INCR: '++';
|
||||
DECR: '--';
|
||||
CONJ: '&&';
|
||||
DISJ: '||';
|
||||
EXCL_WS: '!' Hidden;
|
||||
EXCL_NO_WS: '!';
|
||||
COLON: ':';
|
||||
SEMICOLON: ';';
|
||||
ASSIGNMENT: '=';
|
||||
ADD_ASSIGNMENT: '+=';
|
||||
SUB_ASSIGNMENT: '-=';
|
||||
MULT_ASSIGNMENT: '*=';
|
||||
DIV_ASSIGNMENT: '/=';
|
||||
MOD_ASSIGNMENT: '%=';
|
||||
ARROW: '->';
|
||||
DOUBLE_ARROW: '=>';
|
||||
RANGE: '..';
|
||||
COLONCOLON: '::';
|
||||
DOUBLE_SEMICOLON: ';;';
|
||||
HASH: '#';
|
||||
AT_NO_WS: '@';
|
||||
AT_POST_WS: '@' (Hidden | NL);
|
||||
AT_PRE_WS: (Hidden | NL) '@' ;
|
||||
AT_BOTH_WS: (Hidden | NL) '@' (Hidden | NL);
|
||||
QUEST_WS: '?' Hidden;
|
||||
QUEST_NO_WS: '?';
|
||||
LANGLE: '<';
|
||||
RANGLE: '>';
|
||||
LE: '<=';
|
||||
GE: '>=';
|
||||
EXCL_EQ: '!=';
|
||||
EXCL_EQEQ: '!==';
|
||||
AS_SAFE: 'as?';
|
||||
EQEQ: '==';
|
||||
EQEQEQ: '===';
|
||||
SINGLE_QUOTE: '\'';
|
||||
|
||||
// SECTION: keywords
|
||||
|
||||
RETURN_AT: 'return@' Identifier;
|
||||
CONTINUE_AT: 'continue@' Identifier;
|
||||
BREAK_AT: 'break@' Identifier;
|
||||
|
||||
THIS_AT: 'this@' Identifier;
|
||||
SUPER_AT: 'super@' Identifier;
|
||||
|
||||
FILE: 'file';
|
||||
FIELD: 'field';
|
||||
PROPERTY: 'property';
|
||||
GET: 'get';
|
||||
SET: 'set';
|
||||
RECEIVER: 'receiver';
|
||||
PARAM: 'param';
|
||||
SETPARAM: 'setparam';
|
||||
DELEGATE: 'delegate';
|
||||
|
||||
PACKAGE: 'package';
|
||||
IMPORT: 'import';
|
||||
CLASS: 'class';
|
||||
INTERFACE: 'interface';
|
||||
FUN: 'fun';
|
||||
OBJECT: 'object';
|
||||
VAL: 'val';
|
||||
VAR: 'var';
|
||||
TYPE_ALIAS: 'typealias';
|
||||
CONSTRUCTOR: 'constructor';
|
||||
BY: 'by';
|
||||
COMPANION: 'companion';
|
||||
INIT: 'init';
|
||||
THIS: 'this';
|
||||
SUPER: 'super';
|
||||
TYPEOF: 'typeof';
|
||||
WHERE: 'where';
|
||||
IF: 'if';
|
||||
ELSE: 'else';
|
||||
WHEN: 'when';
|
||||
TRY: 'try';
|
||||
CATCH: 'catch';
|
||||
FINALLY: 'finally';
|
||||
FOR: 'for';
|
||||
DO: 'do';
|
||||
WHILE: 'while';
|
||||
THROW: 'throw';
|
||||
RETURN: 'return';
|
||||
CONTINUE: 'continue';
|
||||
BREAK: 'break';
|
||||
AS: 'as';
|
||||
IS: 'is';
|
||||
IN: 'in';
|
||||
NOT_IS: '!is' (Hidden | NL);
|
||||
NOT_IN: '!in' (Hidden | NL);
|
||||
OUT: 'out';
|
||||
DYNAMIC: 'dynamic';
|
||||
|
||||
// SECTION: lexicalModifiers
|
||||
|
||||
PUBLIC: 'public';
|
||||
PRIVATE: 'private';
|
||||
PROTECTED: 'protected';
|
||||
INTERNAL: 'internal';
|
||||
ENUM: 'enum';
|
||||
SEALED: 'sealed';
|
||||
ANNOTATION: 'annotation';
|
||||
DATA: 'data';
|
||||
INNER: 'inner';
|
||||
TAILREC: 'tailrec';
|
||||
OPERATOR: 'operator';
|
||||
INLINE: 'inline';
|
||||
INFIX: 'infix';
|
||||
EXTERNAL: 'external';
|
||||
SUSPEND: 'suspend';
|
||||
OVERRIDE: 'override';
|
||||
ABSTRACT: 'abstract';
|
||||
FINAL: 'final';
|
||||
OPEN: 'open';
|
||||
CONST: 'const';
|
||||
LATEINIT: 'lateinit';
|
||||
VARARG: 'vararg';
|
||||
NOINLINE: 'noinline';
|
||||
CROSSINLINE: 'crossinline';
|
||||
REIFIED: 'reified';
|
||||
EXPECT: 'expect';
|
||||
ACTUAL: 'actual';
|
||||
|
||||
// SECTION: literals
|
||||
|
||||
fragment DecDigit: '0'..'9';
|
||||
fragment DecDigitNoZero: '1'..'9';
|
||||
fragment DecDigitOrSeparator: DecDigit | '_';
|
||||
|
||||
fragment DecDigits
|
||||
: DecDigit DecDigitOrSeparator* DecDigit
|
||||
| DecDigit
|
||||
;
|
||||
|
||||
fragment DoubleExponent: [eE] [+-]? DecDigits;
|
||||
|
||||
RealLiteral
|
||||
: FloatLiteral
|
||||
| DoubleLiteral
|
||||
;
|
||||
|
||||
FloatLiteral
|
||||
: DoubleLiteral [fF]
|
||||
| DecDigits [fF]
|
||||
;
|
||||
|
||||
DoubleLiteral
|
||||
: DecDigits? '.' DecDigits DoubleExponent?
|
||||
| DecDigits DoubleExponent
|
||||
;
|
||||
|
||||
IntegerLiteral
|
||||
: DecDigitNoZero DecDigitOrSeparator* DecDigit
|
||||
| DecDigit
|
||||
;
|
||||
|
||||
fragment HexDigit: [0-9a-fA-F];
|
||||
fragment HexDigitOrSeparator: HexDigit | '_';
|
||||
|
||||
HexLiteral
|
||||
: '0' [xX] HexDigit HexDigitOrSeparator* HexDigit
|
||||
| '0' [xX] HexDigit
|
||||
;
|
||||
|
||||
fragment BinDigit: [01];
|
||||
fragment BinDigitOrSeparator: BinDigit | '_';
|
||||
|
||||
BinLiteral
|
||||
: '0' [bB] BinDigit BinDigitOrSeparator* BinDigit
|
||||
| '0' [bB] BinDigit
|
||||
;
|
||||
|
||||
UnsignedLiteral
|
||||
: (IntegerLiteral | HexLiteral | BinLiteral) [uU] 'L'?
|
||||
;
|
||||
|
||||
LongLiteral
|
||||
: (IntegerLiteral | HexLiteral | BinLiteral) 'L'
|
||||
;
|
||||
|
||||
BooleanLiteral: 'true'| 'false';
|
||||
|
||||
NullLiteral: 'null';
|
||||
|
||||
CharacterLiteral
|
||||
: '\'' (EscapeSeq | ~[\n\r'\\]) '\''
|
||||
;
|
||||
|
||||
// SECTION: lexicalIdentifiers
|
||||
|
||||
fragment UnicodeDigit: UNICODE_CLASS_ND;
|
||||
|
||||
Identifier
|
||||
: (Letter | '_') (Letter | '_' | UnicodeDigit)*
|
||||
| '`' ~([\r\n] | '`')+ '`'
|
||||
;
|
||||
|
||||
IdentifierOrSoftKey
|
||||
: Identifier
|
||||
/* Soft keywords */
|
||||
| ABSTRACT
|
||||
| ANNOTATION
|
||||
| BY
|
||||
| CATCH
|
||||
| COMPANION
|
||||
| CONSTRUCTOR
|
||||
| CROSSINLINE
|
||||
| DATA
|
||||
| DYNAMIC
|
||||
| ENUM
|
||||
| EXTERNAL
|
||||
| FINAL
|
||||
| FINALLY
|
||||
| IMPORT
|
||||
| INFIX
|
||||
| INIT
|
||||
| INLINE
|
||||
| INNER
|
||||
| INTERNAL
|
||||
| LATEINIT
|
||||
| NOINLINE
|
||||
| OPEN
|
||||
| OPERATOR
|
||||
| OUT
|
||||
| OVERRIDE
|
||||
| PRIVATE
|
||||
| PROTECTED
|
||||
| PUBLIC
|
||||
| REIFIED
|
||||
| SEALED
|
||||
| TAILREC
|
||||
| VARARG
|
||||
| WHERE
|
||||
| GET
|
||||
| SET
|
||||
| FIELD
|
||||
| PROPERTY
|
||||
| RECEIVER
|
||||
| PARAM
|
||||
| SETPARAM
|
||||
| DELEGATE
|
||||
| FILE
|
||||
| EXPECT
|
||||
| ACTUAL
|
||||
/* Strong keywords */
|
||||
| CONST
|
||||
| SUSPEND
|
||||
;
|
||||
|
||||
FieldIdentifier
|
||||
: '$' IdentifierOrSoftKey
|
||||
;
|
||||
|
||||
fragment UniCharacterLiteral
|
||||
: '\\' 'u' HexDigit HexDigit HexDigit HexDigit
|
||||
;
|
||||
|
||||
fragment EscapedIdentifier
|
||||
: '\\' ('t' | 'b' | 'r' | 'n' | '\'' | '"' | '\\' | '$')
|
||||
;
|
||||
|
||||
fragment EscapeSeq
|
||||
: UniCharacterLiteral
|
||||
| EscapedIdentifier
|
||||
;
|
||||
|
||||
// SECTION: characters
|
||||
|
||||
fragment Letter
|
||||
: UNICODE_CLASS_LL
|
||||
| UNICODE_CLASS_LM
|
||||
| UNICODE_CLASS_LO
|
||||
| UNICODE_CLASS_LT
|
||||
| UNICODE_CLASS_LU
|
||||
| UNICODE_CLASS_NL
|
||||
;
|
||||
|
||||
// SECTION: strings
|
||||
|
||||
QUOTE_OPEN: '"' -> pushMode(LineString);
|
||||
|
||||
TRIPLE_QUOTE_OPEN: '"""' -> pushMode(MultiLineString);
|
||||
|
||||
mode LineString;
|
||||
|
||||
QUOTE_CLOSE
|
||||
: '"' -> popMode
|
||||
;
|
||||
|
||||
LineStrRef
|
||||
: FieldIdentifier
|
||||
;
|
||||
|
||||
LineStrText
|
||||
: ~('\\' | '"' | '$')+ | '$'
|
||||
;
|
||||
|
||||
LineStrEscapedChar
|
||||
: EscapedIdentifier
|
||||
| UniCharacterLiteral
|
||||
;
|
||||
|
||||
LineStrExprStart
|
||||
: '${' -> pushMode(DEFAULT_MODE)
|
||||
;
|
||||
|
||||
mode MultiLineString;
|
||||
|
||||
TRIPLE_QUOTE_CLOSE
|
||||
: MultiLineStringQuote? '"""' -> popMode
|
||||
;
|
||||
|
||||
MultiLineStringQuote
|
||||
: '"'+
|
||||
;
|
||||
|
||||
MultiLineStrRef
|
||||
: FieldIdentifier
|
||||
;
|
||||
|
||||
MultiLineStrText
|
||||
: ~('"' | '$')+ | '$'
|
||||
;
|
||||
|
||||
MultiLineStrExprStart
|
||||
: '${' -> pushMode(DEFAULT_MODE)
|
||||
;
|
||||
|
||||
// SECTION: inside
|
||||
|
||||
mode Inside;
|
||||
|
||||
Inside_RPAREN: RPAREN -> popMode, type(RPAREN);
|
||||
Inside_RSQUARE: RSQUARE -> popMode, type(RSQUARE);
|
||||
Inside_LPAREN: LPAREN -> pushMode(Inside), type(LPAREN);
|
||||
Inside_LSQUARE: LSQUARE -> pushMode(Inside), type(LSQUARE);
|
||||
Inside_LCURL: LCURL -> pushMode(DEFAULT_MODE), type(LCURL);
|
||||
Inside_RCURL: RCURL -> popMode, type(RCURL);
|
||||
|
||||
Inside_DOT: DOT -> type(DOT);
|
||||
Inside_COMMA: COMMA -> type(COMMA);
|
||||
Inside_MULT: MULT -> type(MULT);
|
||||
Inside_MOD: MOD -> type(MOD);
|
||||
Inside_DIV: DIV -> type(DIV);
|
||||
Inside_ADD: ADD -> type(ADD);
|
||||
Inside_SUB: SUB -> type(SUB);
|
||||
Inside_INCR: INCR -> type(INCR);
|
||||
Inside_DECR: DECR -> type(DECR);
|
||||
Inside_CONJ: CONJ -> type(CONJ);
|
||||
Inside_DISJ: DISJ -> type(DISJ);
|
||||
Inside_EXCL_WS: '!' (Hidden|NL) -> type(EXCL_WS);
|
||||
Inside_EXCL_NO_WS: EXCL_NO_WS -> type(EXCL_NO_WS);
|
||||
Inside_COLON: COLON -> type(COLON);
|
||||
Inside_SEMICOLON: SEMICOLON -> type(SEMICOLON);
|
||||
Inside_ASSIGNMENT: ASSIGNMENT -> type(ASSIGNMENT);
|
||||
Inside_ADD_ASSIGNMENT: ADD_ASSIGNMENT -> type(ADD_ASSIGNMENT);
|
||||
Inside_SUB_ASSIGNMENT: SUB_ASSIGNMENT -> type(SUB_ASSIGNMENT);
|
||||
Inside_MULT_ASSIGNMENT: MULT_ASSIGNMENT -> type(MULT_ASSIGNMENT);
|
||||
Inside_DIV_ASSIGNMENT: DIV_ASSIGNMENT -> type(DIV_ASSIGNMENT);
|
||||
Inside_MOD_ASSIGNMENT: MOD_ASSIGNMENT -> type(MOD_ASSIGNMENT);
|
||||
Inside_ARROW: ARROW -> type(ARROW);
|
||||
Inside_DOUBLE_ARROW: DOUBLE_ARROW -> type(DOUBLE_ARROW);
|
||||
Inside_RANGE: RANGE -> type(RANGE);
|
||||
Inside_RESERVED: RESERVED -> type(RESERVED);
|
||||
Inside_COLONCOLON: COLONCOLON -> type(COLONCOLON);
|
||||
Inside_DOUBLE_SEMICOLON: DOUBLE_SEMICOLON -> type(DOUBLE_SEMICOLON);
|
||||
Inside_HASH: HASH -> type(HASH);
|
||||
Inside_AT_NO_WS: AT_NO_WS -> type(AT_NO_WS);
|
||||
Inside_AT_POST_WS: AT_POST_WS -> type(AT_POST_WS);
|
||||
Inside_AT_PRE_WS: AT_PRE_WS -> type(AT_PRE_WS);
|
||||
Inside_AT_BOTH_WS: AT_BOTH_WS -> type(AT_BOTH_WS);
|
||||
Inside_QUEST_WS: '?' (Hidden | NL) -> type(QUEST_WS);
|
||||
Inside_QUEST_NO_WS: QUEST_NO_WS -> type(QUEST_NO_WS);
|
||||
Inside_LANGLE: LANGLE -> type(LANGLE);
|
||||
Inside_RANGLE: RANGLE -> type(RANGLE);
|
||||
Inside_LE: LE -> type(LE);
|
||||
Inside_GE: GE -> type(GE);
|
||||
Inside_EXCL_EQ: EXCL_EQ -> type(EXCL_EQ);
|
||||
Inside_EXCL_EQEQ: EXCL_EQEQ -> type(EXCL_EQEQ);
|
||||
Inside_IS: IS -> type(IS);
|
||||
Inside_NOT_IS: NOT_IS -> type(NOT_IS);
|
||||
Inside_NOT_IN: NOT_IN -> type(NOT_IN);
|
||||
Inside_AS: AS -> type(AS);
|
||||
Inside_AS_SAFE: AS_SAFE -> type(AS_SAFE);
|
||||
Inside_EQEQ: EQEQ -> type(EQEQ);
|
||||
Inside_EQEQEQ: EQEQEQ -> type(EQEQEQ);
|
||||
Inside_SINGLE_QUOTE: SINGLE_QUOTE -> type(SINGLE_QUOTE);
|
||||
Inside_QUOTE_OPEN: QUOTE_OPEN -> pushMode(LineString), type(QUOTE_OPEN);
|
||||
Inside_TRIPLE_QUOTE_OPEN: TRIPLE_QUOTE_OPEN -> pushMode(MultiLineString), type(TRIPLE_QUOTE_OPEN);
|
||||
|
||||
Inside_VAL: VAL -> type(VAL);
|
||||
Inside_VAR: VAR -> type(VAR);
|
||||
Inside_FUN: FUN -> type(FUN);
|
||||
Inside_OBJECT: OBJECT -> type(OBJECT);
|
||||
Inside_SUPER: SUPER -> type(SUPER);
|
||||
Inside_IN: IN -> type(IN);
|
||||
Inside_OUT: OUT -> type(OUT);
|
||||
Inside_FIELD: FIELD -> type(FIELD);
|
||||
Inside_FILE: FILE -> type(FILE);
|
||||
Inside_PROPERTY: PROPERTY -> type(PROPERTY);
|
||||
Inside_GET: GET -> type(GET);
|
||||
Inside_SET: SET -> type(SET);
|
||||
Inside_RECEIVER: RECEIVER -> type(RECEIVER);
|
||||
Inside_PARAM: PARAM -> type(PARAM);
|
||||
Inside_SETPARAM: SETPARAM -> type(SETPARAM);
|
||||
Inside_DELEGATE: DELEGATE -> type(DELEGATE);
|
||||
Inside_THROW: THROW -> type(THROW);
|
||||
Inside_RETURN: RETURN -> type(RETURN);
|
||||
Inside_CONTINUE: CONTINUE -> type(CONTINUE);
|
||||
Inside_BREAK: BREAK -> type(BREAK);
|
||||
Inside_RETURN_AT: RETURN_AT -> type(RETURN_AT);
|
||||
Inside_CONTINUE_AT: CONTINUE_AT -> type(CONTINUE_AT);
|
||||
Inside_BREAK_AT: BREAK_AT -> type(BREAK_AT);
|
||||
Inside_IF: IF -> type(IF);
|
||||
Inside_ELSE: ELSE -> type(ELSE);
|
||||
Inside_WHEN: WHEN -> type(WHEN);
|
||||
Inside_TRY: TRY -> type(TRY);
|
||||
Inside_CATCH: CATCH -> type(CATCH);
|
||||
Inside_FINALLY: FINALLY -> type(FINALLY);
|
||||
Inside_FOR: FOR -> type(FOR);
|
||||
Inside_DO: DO -> type(DO);
|
||||
Inside_WHILE: WHILE -> type(WHILE);
|
||||
|
||||
Inside_PUBLIC: PUBLIC -> type(PUBLIC);
|
||||
Inside_PRIVATE: PRIVATE -> type(PRIVATE);
|
||||
Inside_PROTECTED: PROTECTED -> type(PROTECTED);
|
||||
Inside_INTERNAL: INTERNAL -> type(INTERNAL);
|
||||
Inside_ENUM: ENUM -> type(ENUM);
|
||||
Inside_SEALED: SEALED -> type(SEALED);
|
||||
Inside_ANNOTATION: ANNOTATION -> type(ANNOTATION);
|
||||
Inside_DATA: DATA -> type(DATA);
|
||||
Inside_INNER: INNER -> type(INNER);
|
||||
Inside_TAILREC: TAILREC -> type(TAILREC);
|
||||
Inside_OPERATOR: OPERATOR -> type(OPERATOR);
|
||||
Inside_INLINE: INLINE -> type(INLINE);
|
||||
Inside_INFIX: INFIX -> type(INFIX);
|
||||
Inside_EXTERNAL: EXTERNAL -> type(EXTERNAL);
|
||||
Inside_SUSPEND: SUSPEND -> type(SUSPEND);
|
||||
Inside_OVERRIDE: OVERRIDE -> type(OVERRIDE);
|
||||
Inside_ABSTRACT: ABSTRACT -> type(ABSTRACT);
|
||||
Inside_FINAL: FINAL -> type(FINAL);
|
||||
Inside_OPEN: OPEN -> type(OPEN);
|
||||
Inside_CONST: CONST -> type(CONST);
|
||||
Inside_LATEINIT: LATEINIT -> type(LATEINIT);
|
||||
Inside_VARARG: VARARG -> type(VARARG);
|
||||
Inside_NOINLINE: NOINLINE -> type(NOINLINE);
|
||||
Inside_CROSSINLINE: CROSSINLINE -> type(CROSSINLINE);
|
||||
Inside_REIFIED: REIFIED -> type(REIFIED);
|
||||
Inside_EXPECT: EXPECT -> type(EXPECT);
|
||||
Inside_ACTUAL: ACTUAL -> type(ACTUAL);
|
||||
|
||||
Inside_BooleanLiteral: BooleanLiteral -> type(BooleanLiteral);
|
||||
Inside_IntegerLiteral: IntegerLiteral -> type(IntegerLiteral);
|
||||
Inside_HexLiteral: HexLiteral -> type(HexLiteral);
|
||||
Inside_BinLiteral: BinLiteral -> type(BinLiteral);
|
||||
Inside_CharacterLiteral: CharacterLiteral -> type(CharacterLiteral);
|
||||
Inside_RealLiteral: RealLiteral -> type(RealLiteral);
|
||||
Inside_NullLiteral: NullLiteral -> type(NullLiteral);
|
||||
Inside_LongLiteral: LongLiteral -> type(LongLiteral);
|
||||
Inside_UnsignedLiteral: UnsignedLiteral -> type(UnsignedLiteral);
|
||||
|
||||
Inside_Identifier: Identifier -> type(Identifier);
|
||||
Inside_Comment: (LineComment | DelimitedComment) -> channel(HIDDEN);
|
||||
Inside_WS: WS -> channel(HIDDEN);
|
||||
Inside_NL: NL -> channel(HIDDEN);
|
||||
|
||||
mode DEFAULT_MODE;
|
||||
|
||||
ErrorCharacter: .;
|
||||
288
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinLexer.tokens
Normal file
288
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinLexer.tokens
Normal file
@@ -0,0 +1,288 @@
|
||||
ShebangLine=1
|
||||
DelimitedComment=2
|
||||
LineComment=3
|
||||
WS=4
|
||||
NL=5
|
||||
RESERVED=6
|
||||
DOT=7
|
||||
COMMA=8
|
||||
LPAREN=9
|
||||
RPAREN=10
|
||||
LSQUARE=11
|
||||
RSQUARE=12
|
||||
LCURL=13
|
||||
RCURL=14
|
||||
MULT=15
|
||||
MOD=16
|
||||
DIV=17
|
||||
ADD=18
|
||||
SUB=19
|
||||
INCR=20
|
||||
DECR=21
|
||||
CONJ=22
|
||||
DISJ=23
|
||||
EXCL_WS=24
|
||||
EXCL_NO_WS=25
|
||||
COLON=26
|
||||
SEMICOLON=27
|
||||
ASSIGNMENT=28
|
||||
ADD_ASSIGNMENT=29
|
||||
SUB_ASSIGNMENT=30
|
||||
MULT_ASSIGNMENT=31
|
||||
DIV_ASSIGNMENT=32
|
||||
MOD_ASSIGNMENT=33
|
||||
ARROW=34
|
||||
DOUBLE_ARROW=35
|
||||
RANGE=36
|
||||
COLONCOLON=37
|
||||
DOUBLE_SEMICOLON=38
|
||||
HASH=39
|
||||
AT_NO_WS=40
|
||||
AT_POST_WS=41
|
||||
AT_PRE_WS=42
|
||||
AT_BOTH_WS=43
|
||||
QUEST_WS=44
|
||||
QUEST_NO_WS=45
|
||||
LANGLE=46
|
||||
RANGLE=47
|
||||
LE=48
|
||||
GE=49
|
||||
EXCL_EQ=50
|
||||
EXCL_EQEQ=51
|
||||
AS_SAFE=52
|
||||
EQEQ=53
|
||||
EQEQEQ=54
|
||||
SINGLE_QUOTE=55
|
||||
RETURN_AT=56
|
||||
CONTINUE_AT=57
|
||||
BREAK_AT=58
|
||||
THIS_AT=59
|
||||
SUPER_AT=60
|
||||
FILE=61
|
||||
FIELD=62
|
||||
PROPERTY=63
|
||||
GET=64
|
||||
SET=65
|
||||
RECEIVER=66
|
||||
PARAM=67
|
||||
SETPARAM=68
|
||||
DELEGATE=69
|
||||
PACKAGE=70
|
||||
IMPORT=71
|
||||
CLASS=72
|
||||
INTERFACE=73
|
||||
FUN=74
|
||||
OBJECT=75
|
||||
VAL=76
|
||||
VAR=77
|
||||
TYPE_ALIAS=78
|
||||
CONSTRUCTOR=79
|
||||
BY=80
|
||||
COMPANION=81
|
||||
INIT=82
|
||||
THIS=83
|
||||
SUPER=84
|
||||
TYPEOF=85
|
||||
WHERE=86
|
||||
IF=87
|
||||
ELSE=88
|
||||
WHEN=89
|
||||
TRY=90
|
||||
CATCH=91
|
||||
FINALLY=92
|
||||
FOR=93
|
||||
DO=94
|
||||
WHILE=95
|
||||
THROW=96
|
||||
RETURN=97
|
||||
CONTINUE=98
|
||||
BREAK=99
|
||||
AS=100
|
||||
IS=101
|
||||
IN=102
|
||||
NOT_IS=103
|
||||
NOT_IN=104
|
||||
OUT=105
|
||||
DYNAMIC=106
|
||||
PUBLIC=107
|
||||
PRIVATE=108
|
||||
PROTECTED=109
|
||||
INTERNAL=110
|
||||
ENUM=111
|
||||
SEALED=112
|
||||
ANNOTATION=113
|
||||
DATA=114
|
||||
INNER=115
|
||||
TAILREC=116
|
||||
OPERATOR=117
|
||||
INLINE=118
|
||||
INFIX=119
|
||||
EXTERNAL=120
|
||||
SUSPEND=121
|
||||
OVERRIDE=122
|
||||
ABSTRACT=123
|
||||
FINAL=124
|
||||
OPEN=125
|
||||
CONST=126
|
||||
LATEINIT=127
|
||||
VARARG=128
|
||||
NOINLINE=129
|
||||
CROSSINLINE=130
|
||||
REIFIED=131
|
||||
EXPECT=132
|
||||
ACTUAL=133
|
||||
RealLiteral=134
|
||||
FloatLiteral=135
|
||||
DoubleLiteral=136
|
||||
IntegerLiteral=137
|
||||
HexLiteral=138
|
||||
BinLiteral=139
|
||||
UnsignedLiteral=140
|
||||
LongLiteral=141
|
||||
BooleanLiteral=142
|
||||
NullLiteral=143
|
||||
CharacterLiteral=144
|
||||
Identifier=145
|
||||
IdentifierOrSoftKey=146
|
||||
FieldIdentifier=147
|
||||
QUOTE_OPEN=148
|
||||
TRIPLE_QUOTE_OPEN=149
|
||||
UNICODE_CLASS_LL=150
|
||||
UNICODE_CLASS_LM=151
|
||||
UNICODE_CLASS_LO=152
|
||||
UNICODE_CLASS_LT=153
|
||||
UNICODE_CLASS_LU=154
|
||||
UNICODE_CLASS_ND=155
|
||||
UNICODE_CLASS_NL=156
|
||||
QUOTE_CLOSE=157
|
||||
LineStrRef=158
|
||||
LineStrText=159
|
||||
LineStrEscapedChar=160
|
||||
LineStrExprStart=161
|
||||
TRIPLE_QUOTE_CLOSE=162
|
||||
MultiLineStringQuote=163
|
||||
MultiLineStrRef=164
|
||||
MultiLineStrText=165
|
||||
MultiLineStrExprStart=166
|
||||
Inside_Comment=167
|
||||
Inside_WS=168
|
||||
Inside_NL=169
|
||||
ErrorCharacter=170
|
||||
'...'=6
|
||||
'.'=7
|
||||
','=8
|
||||
'('=9
|
||||
')'=10
|
||||
'['=11
|
||||
']'=12
|
||||
'{'=13
|
||||
'}'=14
|
||||
'*'=15
|
||||
'%'=16
|
||||
'/'=17
|
||||
'+'=18
|
||||
'-'=19
|
||||
'++'=20
|
||||
'--'=21
|
||||
'&&'=22
|
||||
'||'=23
|
||||
'!'=25
|
||||
':'=26
|
||||
';'=27
|
||||
'='=28
|
||||
'+='=29
|
||||
'-='=30
|
||||
'*='=31
|
||||
'/='=32
|
||||
'%='=33
|
||||
'->'=34
|
||||
'=>'=35
|
||||
'..'=36
|
||||
'::'=37
|
||||
';;'=38
|
||||
'#'=39
|
||||
'@'=40
|
||||
'?'=45
|
||||
'<'=46
|
||||
'>'=47
|
||||
'<='=48
|
||||
'>='=49
|
||||
'!='=50
|
||||
'!=='=51
|
||||
'as?'=52
|
||||
'=='=53
|
||||
'==='=54
|
||||
'\''=55
|
||||
'file'=61
|
||||
'field'=62
|
||||
'property'=63
|
||||
'get'=64
|
||||
'set'=65
|
||||
'receiver'=66
|
||||
'param'=67
|
||||
'setparam'=68
|
||||
'delegate'=69
|
||||
'package'=70
|
||||
'import'=71
|
||||
'class'=72
|
||||
'interface'=73
|
||||
'fun'=74
|
||||
'object'=75
|
||||
'val'=76
|
||||
'var'=77
|
||||
'typealias'=78
|
||||
'constructor'=79
|
||||
'by'=80
|
||||
'companion'=81
|
||||
'init'=82
|
||||
'this'=83
|
||||
'super'=84
|
||||
'typeof'=85
|
||||
'where'=86
|
||||
'if'=87
|
||||
'else'=88
|
||||
'when'=89
|
||||
'try'=90
|
||||
'catch'=91
|
||||
'finally'=92
|
||||
'for'=93
|
||||
'do'=94
|
||||
'while'=95
|
||||
'throw'=96
|
||||
'return'=97
|
||||
'continue'=98
|
||||
'break'=99
|
||||
'as'=100
|
||||
'is'=101
|
||||
'in'=102
|
||||
'out'=105
|
||||
'dynamic'=106
|
||||
'public'=107
|
||||
'private'=108
|
||||
'protected'=109
|
||||
'internal'=110
|
||||
'enum'=111
|
||||
'sealed'=112
|
||||
'annotation'=113
|
||||
'data'=114
|
||||
'inner'=115
|
||||
'tailrec'=116
|
||||
'operator'=117
|
||||
'inline'=118
|
||||
'infix'=119
|
||||
'external'=120
|
||||
'suspend'=121
|
||||
'override'=122
|
||||
'abstract'=123
|
||||
'final'=124
|
||||
'open'=125
|
||||
'const'=126
|
||||
'lateinit'=127
|
||||
'vararg'=128
|
||||
'noinline'=129
|
||||
'crossinline'=130
|
||||
'reified'=131
|
||||
'expect'=132
|
||||
'actual'=133
|
||||
'null'=143
|
||||
'"""'=149
|
||||
930
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinParser.g4
Normal file
930
orx-jvm/orx-kotlin-parser/src/main/antlr/KotlinParser.g4
Normal file
@@ -0,0 +1,930 @@
|
||||
/**
|
||||
* Kotlin syntax grammar in ANTLR4 notation
|
||||
*/
|
||||
|
||||
parser grammar KotlinParser;
|
||||
|
||||
@header {
|
||||
package org.openrndr.extra.kotlin.antlr;
|
||||
}
|
||||
|
||||
|
||||
options { tokenVocab = KotlinLexer; }
|
||||
|
||||
// SECTION: general
|
||||
|
||||
kotlinFile
|
||||
: shebangLine? NL* fileAnnotation* packageHeader importList topLevelObject* EOF
|
||||
;
|
||||
|
||||
script
|
||||
: shebangLine? NL* fileAnnotation* packageHeader importList (statement semi)* EOF
|
||||
;
|
||||
|
||||
shebangLine
|
||||
: ShebangLine NL+
|
||||
;
|
||||
|
||||
fileAnnotation
|
||||
: (AT_NO_WS | AT_PRE_WS) FILE NL* COLON NL* (LSQUARE unescapedAnnotation+ RSQUARE | unescapedAnnotation) NL*
|
||||
;
|
||||
|
||||
packageHeader
|
||||
: (PACKAGE identifier semi?)?
|
||||
;
|
||||
|
||||
importList
|
||||
: importHeader*
|
||||
;
|
||||
|
||||
importHeader
|
||||
: IMPORT identifier (DOT MULT | importAlias)? semi?
|
||||
;
|
||||
|
||||
importAlias
|
||||
: AS simpleIdentifier
|
||||
;
|
||||
|
||||
topLevelObject
|
||||
: declaration semis?
|
||||
;
|
||||
|
||||
typeAlias
|
||||
: modifiers? TYPE_ALIAS NL* simpleIdentifier (NL* typeParameters)? NL* ASSIGNMENT NL* type
|
||||
;
|
||||
|
||||
declaration
|
||||
: classDeclaration
|
||||
| objectDeclaration
|
||||
| functionDeclaration
|
||||
| propertyDeclaration
|
||||
| typeAlias
|
||||
;
|
||||
|
||||
// SECTION: classes
|
||||
|
||||
classDeclaration
|
||||
: modifiers? (CLASS | (FUN NL*)? INTERFACE) NL* simpleIdentifier
|
||||
(NL* typeParameters)? (NL* primaryConstructor)?
|
||||
(NL* COLON NL* delegationSpecifiers)?
|
||||
(NL* typeConstraints)?
|
||||
(NL* classBody | NL* enumClassBody)?
|
||||
;
|
||||
|
||||
primaryConstructor
|
||||
: (modifiers? CONSTRUCTOR NL*)? classParameters
|
||||
;
|
||||
|
||||
classBody
|
||||
: LCURL NL* classMemberDeclarations NL* RCURL
|
||||
;
|
||||
|
||||
classParameters
|
||||
: LPAREN NL* (classParameter (NL* COMMA NL* classParameter)* (NL* COMMA)?)? NL* RPAREN
|
||||
;
|
||||
|
||||
classParameter
|
||||
: modifiers? (VAL | VAR)? NL* simpleIdentifier COLON NL* type (NL* ASSIGNMENT NL* expression)?
|
||||
;
|
||||
|
||||
delegationSpecifiers
|
||||
: annotatedDelegationSpecifier (NL* COMMA NL* annotatedDelegationSpecifier)*
|
||||
;
|
||||
|
||||
delegationSpecifier
|
||||
: constructorInvocation
|
||||
| explicitDelegation
|
||||
| userType
|
||||
| functionType
|
||||
;
|
||||
|
||||
constructorInvocation
|
||||
: userType valueArguments
|
||||
;
|
||||
|
||||
annotatedDelegationSpecifier
|
||||
: annotation* NL* delegationSpecifier
|
||||
;
|
||||
|
||||
explicitDelegation
|
||||
: (userType | functionType) NL* BY NL* expression
|
||||
;
|
||||
|
||||
typeParameters
|
||||
: LANGLE NL* typeParameter (NL* COMMA NL* typeParameter)* (NL* COMMA)? NL* RANGLE
|
||||
;
|
||||
|
||||
typeParameter
|
||||
: typeParameterModifiers? NL* simpleIdentifier (NL* COLON NL* type)?
|
||||
;
|
||||
|
||||
typeConstraints
|
||||
: WHERE NL* typeConstraint (NL* COMMA NL* typeConstraint)*
|
||||
;
|
||||
|
||||
typeConstraint
|
||||
: annotation* simpleIdentifier NL* COLON NL* type
|
||||
;
|
||||
|
||||
// SECTION: classMembers
|
||||
|
||||
classMemberDeclarations
|
||||
: (classMemberDeclaration semis?)*
|
||||
;
|
||||
|
||||
classMemberDeclaration
|
||||
: declaration
|
||||
| companionObject
|
||||
| anonymousInitializer
|
||||
| secondaryConstructor
|
||||
;
|
||||
|
||||
anonymousInitializer
|
||||
: INIT NL* block
|
||||
;
|
||||
|
||||
companionObject
|
||||
: modifiers? COMPANION NL* OBJECT
|
||||
(NL* simpleIdentifier)?
|
||||
(NL* COLON NL* delegationSpecifiers)?
|
||||
(NL* classBody)?
|
||||
;
|
||||
|
||||
functionValueParameters
|
||||
: LPAREN NL* (functionValueParameter (NL* COMMA NL* functionValueParameter)* (NL* COMMA)?)? NL* RPAREN
|
||||
;
|
||||
|
||||
functionValueParameter
|
||||
: parameterModifiers? parameter (NL* ASSIGNMENT NL* expression)?
|
||||
;
|
||||
|
||||
functionDeclaration
|
||||
: modifiers?
|
||||
FUN (NL* typeParameters)? (NL* receiverType NL* DOT)? NL* simpleIdentifier
|
||||
NL* functionValueParameters
|
||||
(NL* COLON NL* type)?
|
||||
(NL* typeConstraints)?
|
||||
(NL* functionBody)?
|
||||
;
|
||||
|
||||
functionBody
|
||||
: block
|
||||
| ASSIGNMENT NL* expression
|
||||
;
|
||||
|
||||
variableDeclaration
|
||||
: annotation* NL* simpleIdentifier (NL* COLON NL* type)?
|
||||
;
|
||||
|
||||
multiVariableDeclaration
|
||||
: LPAREN NL* variableDeclaration (NL* COMMA NL* variableDeclaration)* (NL* COMMA)? NL* RPAREN
|
||||
;
|
||||
|
||||
propertyDeclaration
|
||||
: modifiers? (VAL | VAR)
|
||||
(NL* typeParameters)?
|
||||
(NL* receiverType NL* DOT)?
|
||||
(NL* (multiVariableDeclaration | variableDeclaration))
|
||||
(NL* typeConstraints)?
|
||||
(NL* (ASSIGNMENT NL* expression | propertyDelegate))?
|
||||
(NL+ SEMICOLON)? NL* (getter? (NL* semi? setter)? | setter? (NL* semi? getter)?)
|
||||
;
|
||||
|
||||
propertyDelegate
|
||||
: BY NL* expression
|
||||
;
|
||||
|
||||
getter
|
||||
: modifiers? GET
|
||||
| modifiers? GET NL* LPAREN NL* RPAREN (NL* COLON NL* type)? NL* functionBody
|
||||
;
|
||||
|
||||
setter
|
||||
: modifiers? SET
|
||||
| modifiers? SET NL* LPAREN NL* parameterWithOptionalType (NL* COMMA)? NL* RPAREN (NL* COLON NL* type)? NL* functionBody
|
||||
;
|
||||
|
||||
parametersWithOptionalType
|
||||
: LPAREN NL* (parameterWithOptionalType (NL* COMMA NL* parameterWithOptionalType)* (NL* COMMA)?)? NL* RPAREN
|
||||
;
|
||||
|
||||
parameterWithOptionalType
|
||||
: parameterModifiers? simpleIdentifier NL* (COLON NL* type)?
|
||||
;
|
||||
|
||||
parameter
|
||||
: simpleIdentifier NL* COLON NL* type
|
||||
;
|
||||
|
||||
objectDeclaration
|
||||
: modifiers? OBJECT
|
||||
NL* simpleIdentifier
|
||||
(NL* COLON NL* delegationSpecifiers)?
|
||||
(NL* classBody)?
|
||||
;
|
||||
|
||||
secondaryConstructor
|
||||
: modifiers? CONSTRUCTOR NL* functionValueParameters (NL* COLON NL* constructorDelegationCall)? NL* block?
|
||||
;
|
||||
|
||||
constructorDelegationCall
|
||||
: THIS NL* valueArguments
|
||||
| SUPER NL* valueArguments
|
||||
;
|
||||
|
||||
// SECTION: enumClasses
|
||||
|
||||
enumClassBody
|
||||
: LCURL NL* enumEntries? (NL* SEMICOLON NL* classMemberDeclarations)? NL* RCURL
|
||||
;
|
||||
|
||||
enumEntries
|
||||
: enumEntry (NL* COMMA NL* enumEntry)* NL* COMMA?
|
||||
;
|
||||
|
||||
enumEntry
|
||||
: (modifiers NL*)? simpleIdentifier (NL* valueArguments)? (NL* classBody)?
|
||||
;
|
||||
|
||||
// SECTION: types
|
||||
|
||||
type
|
||||
: typeModifiers?
|
||||
( parenthesizedType
|
||||
| nullableType
|
||||
| typeReference
|
||||
| functionType)
|
||||
;
|
||||
|
||||
typeReference
|
||||
: userType
|
||||
| DYNAMIC
|
||||
;
|
||||
|
||||
nullableType
|
||||
: (typeReference | parenthesizedType) NL* quest+
|
||||
;
|
||||
|
||||
quest
|
||||
: QUEST_NO_WS
|
||||
| QUEST_WS
|
||||
;
|
||||
|
||||
userType
|
||||
: simpleUserType (NL* DOT NL* simpleUserType)*
|
||||
;
|
||||
|
||||
simpleUserType
|
||||
: simpleIdentifier (NL* typeArguments)?
|
||||
;
|
||||
|
||||
typeProjection
|
||||
: typeProjectionModifiers? type | MULT
|
||||
;
|
||||
|
||||
typeProjectionModifiers
|
||||
: typeProjectionModifier+
|
||||
;
|
||||
|
||||
typeProjectionModifier
|
||||
: varianceModifier NL*
|
||||
| annotation
|
||||
;
|
||||
|
||||
functionType
|
||||
: (receiverType NL* DOT NL*)? functionTypeParameters NL* ARROW NL* type
|
||||
;
|
||||
|
||||
functionTypeParameters
|
||||
: LPAREN NL* (parameter | type)? (NL* COMMA NL* (parameter | type))* (NL* COMMA)? NL* RPAREN
|
||||
;
|
||||
|
||||
parenthesizedType
|
||||
: LPAREN NL* type NL* RPAREN
|
||||
;
|
||||
|
||||
receiverType
|
||||
: typeModifiers?
|
||||
( parenthesizedType
|
||||
| nullableType
|
||||
| typeReference)
|
||||
;
|
||||
|
||||
parenthesizedUserType
|
||||
: LPAREN NL* userType NL* RPAREN
|
||||
| LPAREN NL* parenthesizedUserType NL* RPAREN
|
||||
;
|
||||
|
||||
// SECTION: statements
|
||||
|
||||
statements
|
||||
: (statement (semis statement)*)? semis?
|
||||
;
|
||||
|
||||
statement
|
||||
: (label | annotation)*
|
||||
( declaration
|
||||
| assignment
|
||||
| loopStatement
|
||||
| expression)
|
||||
;
|
||||
|
||||
label
|
||||
: simpleIdentifier (AT_NO_WS | AT_POST_WS) NL*
|
||||
;
|
||||
|
||||
controlStructureBody
|
||||
: block
|
||||
| statement
|
||||
;
|
||||
|
||||
block
|
||||
: LCURL NL* statements NL* RCURL
|
||||
;
|
||||
|
||||
loopStatement
|
||||
: forStatement
|
||||
| whileStatement
|
||||
| doWhileStatement
|
||||
;
|
||||
|
||||
forStatement
|
||||
: FOR NL* LPAREN annotation* (variableDeclaration | multiVariableDeclaration) IN expression RPAREN NL* controlStructureBody?
|
||||
;
|
||||
|
||||
whileStatement
|
||||
: WHILE NL* LPAREN expression RPAREN NL* controlStructureBody
|
||||
| WHILE NL* LPAREN expression RPAREN NL* SEMICOLON
|
||||
;
|
||||
|
||||
doWhileStatement
|
||||
: DO NL* controlStructureBody? NL* WHILE NL* LPAREN expression RPAREN
|
||||
;
|
||||
|
||||
assignment
|
||||
: directlyAssignableExpression ASSIGNMENT NL* expression
|
||||
| assignableExpression assignmentAndOperator NL* expression
|
||||
;
|
||||
|
||||
semi
|
||||
: (SEMICOLON | NL) NL*
|
||||
| EOF;
|
||||
|
||||
semis
|
||||
: (SEMICOLON | NL)+
|
||||
| EOF
|
||||
;
|
||||
|
||||
// SECTION: expressions
|
||||
|
||||
expression
|
||||
: disjunction
|
||||
;
|
||||
|
||||
disjunction
|
||||
: conjunction (NL* DISJ NL* conjunction)*
|
||||
;
|
||||
|
||||
conjunction
|
||||
: equality (NL* CONJ NL* equality)*
|
||||
;
|
||||
|
||||
equality
|
||||
: comparison (equalityOperator NL* comparison)*
|
||||
;
|
||||
|
||||
comparison
|
||||
: infixOperation (comparisonOperator NL* infixOperation)?
|
||||
;
|
||||
|
||||
infixOperation
|
||||
: elvisExpression (inOperator NL* elvisExpression | isOperator NL* type)*
|
||||
;
|
||||
|
||||
elvisExpression
|
||||
: infixFunctionCall (NL* elvis NL* infixFunctionCall)*
|
||||
;
|
||||
|
||||
elvis
|
||||
: QUEST_NO_WS COLON
|
||||
;
|
||||
|
||||
infixFunctionCall
|
||||
: rangeExpression (simpleIdentifier NL* rangeExpression)*
|
||||
;
|
||||
|
||||
rangeExpression
|
||||
: additiveExpression (RANGE NL* additiveExpression)*
|
||||
;
|
||||
|
||||
additiveExpression
|
||||
: multiplicativeExpression (additiveOperator NL* multiplicativeExpression)*
|
||||
;
|
||||
|
||||
multiplicativeExpression
|
||||
: asExpression (multiplicativeOperator NL* asExpression)*
|
||||
;
|
||||
|
||||
asExpression
|
||||
: comparisonWithLiteralRightSide (NL* asOperator NL* type)?
|
||||
;
|
||||
|
||||
comparisonWithLiteralRightSide
|
||||
: prefixUnaryExpression (NL* LANGLE NL* literalConstant NL* RANGLE NL* (expression | parenthesizedExpression))*
|
||||
;
|
||||
|
||||
prefixUnaryExpression
|
||||
: unaryPrefix* postfixUnaryExpression
|
||||
;
|
||||
|
||||
unaryPrefix
|
||||
: annotation
|
||||
| label
|
||||
| prefixUnaryOperator NL*
|
||||
;
|
||||
|
||||
postfixUnaryExpression
|
||||
: primaryExpression
|
||||
| primaryExpression postfixUnarySuffix+
|
||||
;
|
||||
|
||||
postfixUnarySuffix
|
||||
: postfixUnaryOperator
|
||||
| typeArguments
|
||||
| callSuffix
|
||||
| indexingSuffix
|
||||
| navigationSuffix
|
||||
;
|
||||
|
||||
directlyAssignableExpression
|
||||
: postfixUnaryExpression assignableSuffix
|
||||
| simpleIdentifier
|
||||
| parenthesizedDirectlyAssignableExpression
|
||||
;
|
||||
|
||||
parenthesizedDirectlyAssignableExpression
|
||||
: LPAREN NL* directlyAssignableExpression NL* RPAREN
|
||||
;
|
||||
|
||||
assignableExpression
|
||||
: prefixUnaryExpression | parenthesizedAssignableExpression
|
||||
;
|
||||
|
||||
parenthesizedAssignableExpression
|
||||
: LPAREN NL* assignableExpression NL* RPAREN
|
||||
;
|
||||
|
||||
assignableSuffix
|
||||
: typeArguments
|
||||
| indexingSuffix
|
||||
| navigationSuffix
|
||||
;
|
||||
|
||||
indexingSuffix
|
||||
: LSQUARE NL* expression (NL* COMMA NL* expression)* (NL* COMMA)? NL* RSQUARE
|
||||
;
|
||||
|
||||
navigationSuffix
|
||||
: NL* memberAccessOperator NL* (simpleIdentifier | parenthesizedExpression | CLASS)
|
||||
;
|
||||
|
||||
callSuffix
|
||||
: typeArguments? valueArguments? annotatedLambda
|
||||
| typeArguments? valueArguments
|
||||
;
|
||||
|
||||
annotatedLambda
|
||||
: annotation* label? NL* lambdaLiteral
|
||||
;
|
||||
|
||||
typeArguments
|
||||
: LANGLE NL* typeProjection (NL* COMMA NL* typeProjection)* (NL* COMMA)? NL* RANGLE
|
||||
;
|
||||
|
||||
valueArguments
|
||||
: LPAREN NL* RPAREN
|
||||
| LPAREN NL* valueArgument (NL* COMMA NL* valueArgument)* (NL* COMMA)? NL* RPAREN
|
||||
;
|
||||
|
||||
valueArgument
|
||||
: annotation? NL* (simpleIdentifier NL* ASSIGNMENT NL*)? MULT? NL* expression
|
||||
;
|
||||
|
||||
primaryExpression
|
||||
: parenthesizedExpression
|
||||
| simpleIdentifier
|
||||
| literalConstant
|
||||
| stringLiteral
|
||||
| callableReference
|
||||
| functionLiteral
|
||||
| objectLiteral
|
||||
| collectionLiteral
|
||||
| thisExpression
|
||||
| superExpression
|
||||
| ifExpression
|
||||
| whenExpression
|
||||
| tryExpression
|
||||
| jumpExpression
|
||||
;
|
||||
|
||||
parenthesizedExpression
|
||||
: LPAREN NL* expression NL* RPAREN
|
||||
;
|
||||
|
||||
collectionLiteral
|
||||
: LSQUARE NL* expression (NL* COMMA NL* expression)* (NL* COMMA)? NL* RSQUARE
|
||||
| LSQUARE NL* RSQUARE
|
||||
;
|
||||
|
||||
literalConstant
|
||||
: BooleanLiteral
|
||||
| IntegerLiteral
|
||||
| HexLiteral
|
||||
| BinLiteral
|
||||
| CharacterLiteral
|
||||
| RealLiteral
|
||||
| NullLiteral
|
||||
| LongLiteral
|
||||
| UnsignedLiteral
|
||||
;
|
||||
|
||||
stringLiteral
|
||||
: lineStringLiteral
|
||||
| multiLineStringLiteral
|
||||
;
|
||||
|
||||
lineStringLiteral
|
||||
: QUOTE_OPEN (lineStringContent | lineStringExpression)* QUOTE_CLOSE
|
||||
;
|
||||
|
||||
multiLineStringLiteral
|
||||
: TRIPLE_QUOTE_OPEN (multiLineStringContent | multiLineStringExpression | MultiLineStringQuote)* TRIPLE_QUOTE_CLOSE
|
||||
;
|
||||
|
||||
lineStringContent
|
||||
: LineStrText
|
||||
| LineStrEscapedChar
|
||||
| LineStrRef
|
||||
;
|
||||
|
||||
lineStringExpression
|
||||
: LineStrExprStart expression RCURL
|
||||
;
|
||||
|
||||
multiLineStringContent
|
||||
: MultiLineStrText
|
||||
| MultiLineStringQuote
|
||||
| MultiLineStrRef
|
||||
;
|
||||
|
||||
multiLineStringExpression
|
||||
: MultiLineStrExprStart NL* expression NL* RCURL
|
||||
;
|
||||
|
||||
lambdaLiteral
|
||||
: LCURL NL* statements NL* RCURL
|
||||
| LCURL NL* lambdaParameters? NL* ARROW NL* statements NL* RCURL
|
||||
;
|
||||
|
||||
lambdaParameters
|
||||
: lambdaParameter (NL* COMMA NL* lambdaParameter)* (NL* COMMA)?
|
||||
;
|
||||
|
||||
lambdaParameter
|
||||
: variableDeclaration
|
||||
| multiVariableDeclaration (NL* COLON NL* type)?
|
||||
;
|
||||
|
||||
anonymousFunction
|
||||
: FUN
|
||||
(NL* type NL* DOT)?
|
||||
NL* parametersWithOptionalType
|
||||
(NL* COLON NL* type)?
|
||||
(NL* typeConstraints)?
|
||||
(NL* functionBody)?
|
||||
;
|
||||
|
||||
functionLiteral
|
||||
: lambdaLiteral
|
||||
| anonymousFunction
|
||||
;
|
||||
|
||||
objectLiteral
|
||||
: OBJECT NL* COLON NL* delegationSpecifiers NL* classBody
|
||||
| OBJECT NL* classBody
|
||||
;
|
||||
|
||||
thisExpression
|
||||
: THIS
|
||||
| THIS_AT
|
||||
;
|
||||
|
||||
superExpression
|
||||
: SUPER (LANGLE NL* type NL* RANGLE)? (AT_NO_WS simpleIdentifier)?
|
||||
| SUPER_AT
|
||||
;
|
||||
|
||||
ifExpression
|
||||
: IF NL* LPAREN NL* expression NL* RPAREN NL* (controlStructureBody | SEMICOLON)
|
||||
| IF NL* LPAREN NL* expression NL* RPAREN NL* controlStructureBody? NL* SEMICOLON? NL* ELSE NL* (controlStructureBody | SEMICOLON)
|
||||
;
|
||||
|
||||
whenSubject
|
||||
: LPAREN (annotation* NL* VAL NL* variableDeclaration NL* ASSIGNMENT NL*)? expression RPAREN
|
||||
;
|
||||
|
||||
whenExpression
|
||||
: WHEN NL* whenSubject? NL* LCURL NL* (whenEntry NL*)* NL* RCURL
|
||||
;
|
||||
|
||||
whenEntry
|
||||
: whenCondition (NL* COMMA NL* whenCondition)* (NL* COMMA)? NL* ARROW NL* controlStructureBody semi?
|
||||
| ELSE NL* ARROW NL* controlStructureBody semi?
|
||||
;
|
||||
|
||||
whenCondition
|
||||
: expression
|
||||
| rangeTest
|
||||
| typeTest
|
||||
;
|
||||
|
||||
rangeTest
|
||||
: inOperator NL* expression
|
||||
;
|
||||
|
||||
typeTest
|
||||
: isOperator NL* type
|
||||
;
|
||||
|
||||
tryExpression
|
||||
: TRY NL* block ((NL* catchBlock)+ (NL* finallyBlock)? | NL* finallyBlock)
|
||||
;
|
||||
|
||||
catchBlock
|
||||
: CATCH NL* LPAREN annotation* simpleIdentifier COLON type (NL* COMMA)? RPAREN NL* block
|
||||
;
|
||||
|
||||
finallyBlock
|
||||
: FINALLY NL* block
|
||||
;
|
||||
|
||||
jumpExpression
|
||||
: THROW NL* expression
|
||||
| (RETURN | RETURN_AT) expression?
|
||||
| CONTINUE | CONTINUE_AT
|
||||
| BREAK | BREAK_AT
|
||||
;
|
||||
|
||||
callableReference
|
||||
: (receiverType? NL* COLONCOLON NL* (simpleIdentifier | CLASS))
|
||||
;
|
||||
|
||||
assignmentAndOperator
|
||||
: ADD_ASSIGNMENT
|
||||
| SUB_ASSIGNMENT
|
||||
| MULT_ASSIGNMENT
|
||||
| DIV_ASSIGNMENT
|
||||
| MOD_ASSIGNMENT
|
||||
;
|
||||
|
||||
equalityOperator
|
||||
: EXCL_EQ
|
||||
| EXCL_EQEQ
|
||||
| EQEQ
|
||||
| EQEQEQ
|
||||
;
|
||||
|
||||
comparisonOperator
|
||||
: LANGLE
|
||||
| RANGLE
|
||||
| LE
|
||||
| GE
|
||||
;
|
||||
|
||||
inOperator
|
||||
: IN | NOT_IN
|
||||
;
|
||||
|
||||
isOperator
|
||||
: IS | NOT_IS
|
||||
;
|
||||
|
||||
additiveOperator
|
||||
: ADD | SUB
|
||||
;
|
||||
|
||||
multiplicativeOperator
|
||||
: MULT
|
||||
| DIV
|
||||
| MOD
|
||||
;
|
||||
|
||||
asOperator
|
||||
: AS
|
||||
| AS_SAFE
|
||||
;
|
||||
|
||||
prefixUnaryOperator
|
||||
: INCR
|
||||
| DECR
|
||||
| SUB
|
||||
| ADD
|
||||
| excl
|
||||
;
|
||||
|
||||
postfixUnaryOperator
|
||||
: INCR
|
||||
| DECR
|
||||
| EXCL_NO_WS excl
|
||||
;
|
||||
|
||||
excl
|
||||
: EXCL_NO_WS
|
||||
| EXCL_WS
|
||||
;
|
||||
|
||||
memberAccessOperator
|
||||
: DOT | safeNav | COLONCOLON
|
||||
;
|
||||
|
||||
safeNav
|
||||
: QUEST_NO_WS DOT
|
||||
;
|
||||
|
||||
// SECTION: modifiers
|
||||
|
||||
modifiers
|
||||
: (annotation | modifier)+
|
||||
;
|
||||
|
||||
parameterModifiers
|
||||
: (annotation | parameterModifier)+
|
||||
;
|
||||
|
||||
modifier
|
||||
: (classModifier
|
||||
| memberModifier
|
||||
| visibilityModifier
|
||||
| functionModifier
|
||||
| propertyModifier
|
||||
| inheritanceModifier
|
||||
| parameterModifier
|
||||
| platformModifier) NL*
|
||||
;
|
||||
|
||||
typeModifiers
|
||||
: typeModifier+
|
||||
;
|
||||
|
||||
typeModifier
|
||||
: annotation | SUSPEND NL*
|
||||
;
|
||||
|
||||
classModifier
|
||||
: ENUM
|
||||
| SEALED
|
||||
| ANNOTATION
|
||||
| DATA
|
||||
| INNER
|
||||
;
|
||||
|
||||
memberModifier
|
||||
: OVERRIDE
|
||||
| LATEINIT
|
||||
;
|
||||
|
||||
visibilityModifier
|
||||
: PUBLIC
|
||||
| PRIVATE
|
||||
| INTERNAL
|
||||
| PROTECTED
|
||||
;
|
||||
|
||||
varianceModifier
|
||||
: IN
|
||||
| OUT
|
||||
;
|
||||
|
||||
typeParameterModifiers
|
||||
: typeParameterModifier+
|
||||
;
|
||||
|
||||
typeParameterModifier
|
||||
: reificationModifier NL*
|
||||
| varianceModifier NL*
|
||||
| annotation
|
||||
;
|
||||
|
||||
functionModifier
|
||||
: TAILREC
|
||||
| OPERATOR
|
||||
| INFIX
|
||||
| INLINE
|
||||
| EXTERNAL
|
||||
| SUSPEND
|
||||
;
|
||||
|
||||
propertyModifier
|
||||
: CONST
|
||||
;
|
||||
|
||||
inheritanceModifier
|
||||
: ABSTRACT
|
||||
| FINAL
|
||||
| OPEN
|
||||
;
|
||||
|
||||
parameterModifier
|
||||
: VARARG
|
||||
| NOINLINE
|
||||
| CROSSINLINE
|
||||
;
|
||||
|
||||
reificationModifier
|
||||
: REIFIED
|
||||
;
|
||||
|
||||
platformModifier
|
||||
: EXPECT
|
||||
| ACTUAL
|
||||
;
|
||||
|
||||
// SECTION: annotations
|
||||
|
||||
annotation
|
||||
: (singleAnnotation | multiAnnotation) NL*
|
||||
;
|
||||
|
||||
singleAnnotation
|
||||
: annotationUseSiteTarget NL* unescapedAnnotation
|
||||
| (AT_NO_WS | AT_PRE_WS) unescapedAnnotation
|
||||
;
|
||||
|
||||
multiAnnotation
|
||||
: annotationUseSiteTarget NL* LSQUARE unescapedAnnotation+ RSQUARE
|
||||
| (AT_NO_WS | AT_PRE_WS) LSQUARE unescapedAnnotation+ RSQUARE
|
||||
;
|
||||
|
||||
annotationUseSiteTarget
|
||||
: (AT_NO_WS | AT_PRE_WS) (FIELD | PROPERTY | GET | SET | RECEIVER | PARAM | SETPARAM | DELEGATE) NL* COLON
|
||||
;
|
||||
|
||||
unescapedAnnotation
|
||||
: constructorInvocation
|
||||
| userType
|
||||
;
|
||||
|
||||
// SECTION: identifiers
|
||||
|
||||
simpleIdentifier: Identifier
|
||||
| ABSTRACT
|
||||
| ANNOTATION
|
||||
| BY
|
||||
| CATCH
|
||||
| COMPANION
|
||||
| CONSTRUCTOR
|
||||
| CROSSINLINE
|
||||
| DATA
|
||||
| DYNAMIC
|
||||
| ENUM
|
||||
| EXTERNAL
|
||||
| FINAL
|
||||
| FINALLY
|
||||
| GET
|
||||
| IMPORT
|
||||
| INFIX
|
||||
| INIT
|
||||
| INLINE
|
||||
| INNER
|
||||
| INTERNAL
|
||||
| LATEINIT
|
||||
| NOINLINE
|
||||
| OPEN
|
||||
| OPERATOR
|
||||
| OUT
|
||||
| OVERRIDE
|
||||
| PRIVATE
|
||||
| PROTECTED
|
||||
| PUBLIC
|
||||
| REIFIED
|
||||
| SEALED
|
||||
| TAILREC
|
||||
| SET
|
||||
| VARARG
|
||||
| WHERE
|
||||
| FIELD
|
||||
| PROPERTY
|
||||
| RECEIVER
|
||||
| PARAM
|
||||
| SETPARAM
|
||||
| DELEGATE
|
||||
| FILE
|
||||
| EXPECT
|
||||
| ACTUAL
|
||||
| CONST
|
||||
| SUSPEND
|
||||
;
|
||||
|
||||
identifier
|
||||
: simpleIdentifier (NL* DOT simpleIdentifier)*
|
||||
;
|
||||
1654
orx-jvm/orx-kotlin-parser/src/main/antlr/UnicodeClasses.g4
Normal file
1654
orx-jvm/orx-kotlin-parser/src/main/antlr/UnicodeClasses.g4
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
UNICODE_CLASS_LL=1
|
||||
UNICODE_CLASS_LM=2
|
||||
UNICODE_CLASS_LO=3
|
||||
UNICODE_CLASS_LT=4
|
||||
UNICODE_CLASS_LU=5
|
||||
UNICODE_CLASS_ND=6
|
||||
UNICODE_CLASS_NL=7
|
||||
76
orx-jvm/orx-kotlin-parser/src/main/kotlin/ExtractProgram.kt
Normal file
76
orx-jvm/orx-kotlin-parser/src/main/kotlin/ExtractProgram.kt
Normal file
@@ -0,0 +1,76 @@
|
||||
package org.openrndr.extra.kotlinparser
|
||||
|
||||
import org.antlr.v4.runtime.CharStreams
|
||||
import org.antlr.v4.runtime.CommonTokenStream
|
||||
import org.antlr.v4.runtime.ParserRuleContext
|
||||
import org.antlr.v4.runtime.RuleContext
|
||||
import org.antlr.v4.runtime.misc.Interval
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker
|
||||
import org.openrndr.extra.kotlin.antlr.KotlinLexer
|
||||
import org.openrndr.extra.kotlin.antlr.KotlinParser
|
||||
import org.openrndr.extra.kotlin.antlr.KotlinParserBaseListener
|
||||
|
||||
fun ParserRuleContext.verbatimText(marginLeft: Int = 0, marginRight: Int = 0): String {
|
||||
if (start == null || stop == null) {
|
||||
return ""
|
||||
}
|
||||
|
||||
val startIndex = start.startIndex + marginLeft
|
||||
val stopIndex = stop.stopIndex - marginRight
|
||||
val interval = Interval(startIndex, stopIndex)
|
||||
return start.inputStream.getText(interval)
|
||||
}
|
||||
|
||||
class PackageExtractor() : KotlinParserBaseListener() {
|
||||
var result: String? = null
|
||||
override fun enterPackageHeader(ctx: KotlinParser.PackageHeaderContext) {
|
||||
result = ctx.verbatimText()
|
||||
}
|
||||
}
|
||||
|
||||
class ImportsExtractor(val ruleNames: List<String>) : KotlinParserBaseListener() {
|
||||
var result: String? = null
|
||||
|
||||
override fun enterImportList(ctx: KotlinParser.ImportListContext) {
|
||||
result = ctx.verbatimText()
|
||||
}
|
||||
}
|
||||
|
||||
class LambdaExtractor(val ruleNames: List<String>, val lambdaName: String) : KotlinParserBaseListener() {
|
||||
fun RuleContext.named(): String {
|
||||
return ruleNames[this.ruleIndex]
|
||||
}
|
||||
|
||||
var result: String? = null
|
||||
override fun enterAnnotatedLambda(ctx: KotlinParser.AnnotatedLambdaContext?) {
|
||||
val puec = ctx?.parent?.parent?.parent as? KotlinParser.PostfixUnaryExpressionContext
|
||||
if (puec != null) {
|
||||
val identifier = puec.primaryExpression()?.simpleIdentifier()?.Identifier()?.text
|
||||
if (identifier == lambdaName) {
|
||||
if (result == null) {
|
||||
result = ctx.verbatimText(1, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProgramSource(val packageName: String?, val imports: String, val programLambda: String)
|
||||
|
||||
fun extractProgram(source: String, programIdentifier: String = "program"): ProgramSource {
|
||||
val parser = KotlinParser(CommonTokenStream(KotlinLexer(CharStreams.fromString(source))))
|
||||
val root = parser.kotlinFile()
|
||||
// val rules = parser.ruleNames.toList()
|
||||
// val pt = TreeUtils.toPrettyTree(root, rules)
|
||||
val ruleNames = parser.ruleNames.toList()
|
||||
|
||||
val packageExtractor = PackageExtractor()
|
||||
ParseTreeWalker.DEFAULT.walk(packageExtractor, root)
|
||||
|
||||
val importsExtractor = ImportsExtractor(ruleNames)
|
||||
ParseTreeWalker.DEFAULT.walk(importsExtractor, root)
|
||||
|
||||
val lambdaExtractor = LambdaExtractor(ruleNames, programIdentifier)
|
||||
ParseTreeWalker.DEFAULT.walk(lambdaExtractor, root)
|
||||
return ProgramSource(packageExtractor.result, importsExtractor.result ?: "", lambdaExtractor.result ?: "")
|
||||
}
|
||||
49
orx-jvm/orx-kotlin-parser/src/main/kotlin/TreeUtils.kt
Normal file
49
orx-jvm/orx-kotlin-parser/src/main/kotlin/TreeUtils.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.openrndr.extra.kotlinparser
|
||||
|
||||
import org.antlr.v4.runtime.misc.Utils
|
||||
import org.antlr.v4.runtime.tree.Tree
|
||||
import org.antlr.v4.runtime.tree.Trees
|
||||
|
||||
object TreeUtils {
|
||||
/** Platform dependent end-of-line marker */
|
||||
val Eol = System.lineSeparator()
|
||||
|
||||
/** The literal indent char(s) used for pretty-printing */
|
||||
const val Indents = " "
|
||||
private var level = 0
|
||||
|
||||
/**
|
||||
* Pretty print out a whole tree. [.getNodeText] is used on the node payloads to get the text
|
||||
* for the nodes. (Derived from Trees.toStringTree(....))
|
||||
*/
|
||||
fun toPrettyTree(t: Tree, ruleNames: List<String>): String {
|
||||
level = 0
|
||||
return process(t, ruleNames).replace("(?m)^\\s+$".toRegex(), "").replace("\\r?\\n\\r?\\n".toRegex(), Eol)
|
||||
}
|
||||
|
||||
private fun process(t: Tree, ruleNames: List<String>): String {
|
||||
if (t.getChildCount() == 0) return Utils.escapeWhitespace(Trees.getNodeText(t, ruleNames), false)
|
||||
val sb = StringBuilder()
|
||||
sb.append(lead(level))
|
||||
level++
|
||||
val s: String = Utils.escapeWhitespace(Trees.getNodeText(t, ruleNames), false)
|
||||
sb.append("$s ")
|
||||
for (i in 0 until t.getChildCount()) {
|
||||
sb.append(process(t.getChild(i), ruleNames))
|
||||
}
|
||||
level--
|
||||
sb.append(lead(level))
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun lead(level: Int): String {
|
||||
val sb = StringBuilder()
|
||||
if (level > 0) {
|
||||
sb.append(Eol)
|
||||
for (cnt in 0 until level) {
|
||||
sb.append(Indents)
|
||||
}
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user