├── .gitignore ├── src ├── index.ts ├── types.ts ├── symbol-table-visitor.ts ├── compute-token-position.ts └── completion.ts ├── tsconfig.json ├── README.md ├── tests ├── suggestions.basic.test.ts ├── suggestions.variables.test.ts ├── compute-token-position.test.ts └── parser.test.ts ├── package.json └── grammar ├── KotlinLexer.g4 ├── KotlinParser.g4 └── UnicodeClasses.g4 /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .idea/ 3 | gen/ 4 | grammar/KotlinLexer.tokens 5 | node_modules/ 6 | out/ 7 | #The parser is automatically generated 8 | src/parser/ 9 | *.vsix -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './completion'; 2 | export * from './compute-token-position'; 3 | export * from './types'; 4 | export * from './symbol-table-visitor'; 5 | export * from './parser/KotlinLexer'; 6 | export * from './parser/KotlinParser'; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "outDir": "out", 8 | "rootDir": "src", 9 | "declaration": true 10 | }, 11 | "include": ["src"], 12 | "exclude": ["node_modules", ".vscode-test"] 13 | } 14 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import {ParseTree} from "antlr4ts/tree"; 2 | import {TokenStream} from "antlr4ts"; 3 | 4 | export type CaretPosition = { line: number, column: number }; 5 | export type TokenPosition = { index: number, context: ParseTree, text: string }; 6 | export type ComputeTokenPositionFunction = 7 | (parseTree: ParseTree, tokens: TokenStream, caretPosition: CaretPosition) => TokenPosition; 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code Completion with antlr4-c3 2 | This repository contains the code for the article, [Code Completion with antlr4-c3](https://tomassetti.me/code-completion-with-antlr4-c3/), published on the Strumenta blog. 3 | 4 | The code includes subsequent updates released in support of other articles, including [Integrating Code Completion in Visual Studio Code – With the Language Server Protocol](https://tomassetti.me/integrating-code-completion-in-visual-studio-code-with-the-language-server-protocol/). 5 | 6 | The code is released under the Apache license and is intended for demonstration purposes only. 7 | -------------------------------------------------------------------------------- /tests/suggestions.basic.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from "chai"; 2 | 3 | import { computeTokenPosition, getSuggestions, setTokenMatcher, filterTokens, filterTokens_fuzzySearch } from "../src"; 4 | 5 | const suite = function() { 6 | it("are suggested", 7 | function() { 8 | const code = `fun test() { 9 | try { 10 | doSomething() 11 | } 12 | }`; 13 | let suggestions = getSuggestions(code, { line: 4, column: 7 }, computeTokenPosition); 14 | expect(suggestions.length).to.equal(51); 15 | }); 16 | it("are suggested with partial match", 17 | function() { 18 | const code = `fun test() { 19 | try { 20 | doSomething() 21 | } ca 22 | }`; 23 | let suggestions = getSuggestions(code, { line: 4, column: 8 }, computeTokenPosition); 24 | expect(suggestions.indexOf('catch')).to.be.greaterThan(-1); 25 | }); 26 | }; 27 | 28 | describe('Keywords', suite); 29 | describe('Keywords w/fuzzy completion', function() { 30 | let oldMatcher = filterTokens; 31 | beforeEach(() => setTokenMatcher(filterTokens_fuzzySearch)); 32 | suite(); 33 | afterEach(() => setTokenMatcher(oldMatcher)); 34 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "toy-kotlin-language-server", 3 | "description": "Simple Language Server component for the Kotlin language, to demonstrate code completion with antlr4-c3.", 4 | "version": "1.2.0", 5 | "author": "Strumenta s.r.l.", 6 | "license": "Apache", 7 | "repository": { 8 | "url": "https://github.com/Strumenta/article-antlr4-c3" 9 | }, 10 | "engines": { 11 | "node": "*" 12 | }, 13 | "main": "out/index.js", 14 | "files": [ 15 | "*.md", 16 | "out", 17 | "src" 18 | ], 19 | "dependencies": { 20 | "@types/node": "^13.9.8", 21 | "antlr4-c3": "^1.1.12", 22 | "antlr4ts": "^0.5.0-alpha.3", 23 | "fuzzysort": "^1.1.4" 24 | }, 25 | "scripts": { 26 | "antlr4ts": "antlr4ts -o src/parser -Xexact-output-dir -visitor grammar/KotlinParser.g4 grammar/KotlinLexer.g4", 27 | "build": "npm run antlr4ts && tsc -b", 28 | "test": "mocha -r ts-node/register tests/**/*.test.ts" 29 | }, 30 | "devDependencies": { 31 | "@types/chai": "^4.2.11", 32 | "@types/mocha": "^5.2.7", 33 | "@typescript-eslint/parser": "^2.3.0", 34 | "antlr4ts-cli": "^0.5.0-alpha.3", 35 | "chai": "^4.2.0", 36 | "eslint": "^6.4.0", 37 | "merge-options": "^2.0.0", 38 | "mocha": "^6.2.2", 39 | "rimraf": "^3.0.0", 40 | "ts-loader": "^6.2.2", 41 | "ts-node": "^8.8.2", 42 | "typescript": "^3.9.7", 43 | "webpack": "^4.42.1", 44 | "webpack-cli": "^3.3.11" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/symbol-table-visitor.ts: -------------------------------------------------------------------------------- 1 | import {KotlinParserVisitor} from "./parser/KotlinParserVisitor"; 2 | import {RoutineSymbol, ScopedSymbol, SymbolTable, VariableSymbol} from "antlr4-c3"; 3 | import {AbstractParseTreeVisitor, ParseTree} from "antlr4ts/tree"; 4 | import {FunctionDeclarationContext, VariableDeclarationContext} from "./parser/KotlinParser"; 5 | 6 | export class SymbolTableVisitor extends AbstractParseTreeVisitor implements KotlinParserVisitor { 7 | constructor( 8 | protected readonly symbolTable = new SymbolTable("", {}), 9 | protected scope = symbolTable.addNewSymbolOfType(ScopedSymbol, undefined)) { 10 | super(); 11 | } 12 | 13 | protected defaultResult(): SymbolTable { 14 | return this.symbolTable; 15 | } 16 | 17 | visitVariableDeclaration = (ctx: VariableDeclarationContext) => { 18 | this.symbolTable.addNewSymbolOfType(VariableSymbol, this.scope, ctx.simpleIdentifier().text); 19 | return this.visitChildren(ctx); 20 | }; 21 | 22 | visitFunctionDeclaration = (ctx: FunctionDeclarationContext) => { 23 | return this.withScope(ctx, RoutineSymbol, [ctx.identifier().text], () => this.visitChildren(ctx)); 24 | }; 25 | 26 | protected withScope(tree: ParseTree, type: new (...args: any[]) => ScopedSymbol, args: any[], action: () => T): T { 27 | const scope = this.symbolTable.addNewSymbolOfType(type, this.scope, ...args); 28 | scope.context = tree; 29 | this.scope = scope; 30 | try { 31 | return action(); 32 | } finally { 33 | this.scope = scope.parent as ScopedSymbol; 34 | } 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/compute-token-position.ts: -------------------------------------------------------------------------------- 1 | import {ParseTree, TerminalNode} from "antlr4ts/tree"; 2 | import {CaretPosition, TokenPosition} from "./types"; 3 | import {ParserRuleContext, Token, TokenStream} from "antlr4ts"; 4 | 5 | export function tokenPositionComputer(identifierTokenTypes: number[] = []) { 6 | return (parseTree: ParseTree, tokens: TokenStream, caretPosition: CaretPosition) => 7 | computeTokenPosition(parseTree, tokens, caretPosition, identifierTokenTypes); 8 | } 9 | 10 | export function computeTokenPosition( 11 | parseTree: ParseTree, tokens: TokenStream, caretPosition: CaretPosition, identifierTokenTypes: number[] = []): TokenPosition { 12 | if(parseTree instanceof TerminalNode) { 13 | return computeTokenPositionOfTerminal(parseTree, tokens, caretPosition, identifierTokenTypes); 14 | } else { 15 | return computeTokenPositionOfChildNode(parseTree as ParserRuleContext, tokens, caretPosition, identifierTokenTypes); 16 | } 17 | } 18 | 19 | function positionOfToken(token: Token, text: string, caretPosition: CaretPosition, identifierTokenTypes: number[], parseTree: ParseTree) { 20 | let start = token.charPositionInLine; 21 | let stop = token.charPositionInLine + text.length; 22 | if (token.line == caretPosition.line && start <= caretPosition.column && stop >= caretPosition.column) { 23 | let index = token.tokenIndex; 24 | if (identifierTokenTypes.includes(token.type)) { 25 | index--; 26 | } 27 | return { 28 | index: index, 29 | context: parseTree, 30 | text: text.substring(0, caretPosition.column - start) 31 | }; 32 | } else { 33 | return undefined; 34 | } 35 | } 36 | 37 | function computeTokenPositionOfTerminal( 38 | parseTree: TerminalNode, tokens: TokenStream, caretPosition: CaretPosition, identifierTokenTypes: number[]) { 39 | let token = parseTree.symbol; 40 | let text = parseTree.text; 41 | return positionOfToken(token, text, caretPosition, identifierTokenTypes, parseTree); 42 | } 43 | 44 | function computeTokenPositionOfChildNode( 45 | parseTree: ParserRuleContext, tokens: TokenStream, caretPosition: CaretPosition, identifierTokenTypes: number[]) { 46 | if((parseTree.start && parseTree.start.line > caretPosition.line) || 47 | (parseTree.stop && parseTree.stop.line < caretPosition.line)) { 48 | return undefined; 49 | } 50 | for (let i = 0; i < parseTree.childCount; i++) { 51 | let position = computeTokenPosition(parseTree.getChild(i), tokens, caretPosition, identifierTokenTypes); 52 | if (position !== undefined) { 53 | return position; 54 | } 55 | } 56 | if(parseTree.start && parseTree.stop) { 57 | for(let i = parseTree.start.tokenIndex; i <= parseTree.stop.tokenIndex; i++) { 58 | let pos = positionOfToken(tokens.get(i), tokens.get(i).text, caretPosition, identifierTokenTypes, parseTree); 59 | if(pos) { 60 | return pos; 61 | } 62 | } 63 | } 64 | return undefined; 65 | } 66 | -------------------------------------------------------------------------------- /tests/suggestions.variables.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from "chai"; 2 | 3 | import {computeTokenPosition, getSuggestions, setTokenMatcher, filterTokens, filterTokens_fuzzySearch} from "../src"; 4 | import {it} from "mocha"; 5 | 6 | const localVariablesSuite = function() { 7 | it("are suggested", 8 | function() { 9 | const code = 10 | `fun test() { 11 | val v = 1 12 | val z = 13 | }`; 14 | let suggestions = getSuggestions(code, { line: 3, column: 13 }, computeTokenPosition); 15 | expect(suggestions.indexOf("v")).to.not.equal(-1); 16 | expect(suggestions.indexOf("some random name")).to.equal(-1); 17 | }); 18 | 19 | it("are suggested respecting function scope", 20 | function() { 21 | const code = 22 | `fun test1() { 23 | val k = 'a' 24 | } 25 | 26 | fun test2() { 27 | val v = 1 28 | val z = 29 | }`; 30 | let suggestions = getSuggestions(code, { line: 7, column: 13 }, computeTokenPosition); 31 | expect(suggestions.indexOf("v")).to.not.equal(-1); 32 | expect(suggestions.indexOf("k")).to.equal(-1); 33 | }); 34 | 35 | it("are suggested with partial match", 36 | function() { 37 | const code = 38 | `fun test() { 39 | val someVariable = 1 40 | val anotherVariable = 2 41 | val z = so 42 | }`; 43 | let suggestions = getSuggestions(code, { line: 4, column: 14 }, computeTokenPosition); 44 | expect(suggestions.indexOf("someVariable")).to.not.equal(-1); 45 | expect(suggestions.indexOf("anotherVariable")).to.equal(-1); 46 | }); 47 | }; 48 | describe('Local variables', localVariablesSuite); 49 | 50 | describe('Local variables w/fuzzy search', function() { 51 | let oldMatcher = filterTokens; 52 | beforeEach(() => setTokenMatcher(filterTokens_fuzzySearch)); 53 | context("Standard local variables tests", localVariablesSuite); 54 | context("Fuzzy search-specific local variables tests", function () { 55 | it("are suggested with fuzzy match", 56 | function() { 57 | const code = 58 | `fun test() { 59 | val aVariable = 1 60 | val anotherOne = 2 61 | val z = av 62 | }`; 63 | let suggestions = getSuggestions(code, { line: 4, column: 14 }, computeTokenPosition); 64 | expect(suggestions.indexOf("aVariable")).to.not.equal(-1); 65 | expect(suggestions.indexOf("anotherOne")).to.equal(-1); 66 | }); 67 | }); 68 | afterEach(() => setTokenMatcher(oldMatcher)); 69 | }); 70 | 71 | describe('Global variables', function() { 72 | it("are suggested in the right-hand side of assignments", 73 | function() { 74 | const code = 75 | `val v = 1 76 | fun test() { 77 | val z = 78 | }`; 79 | let suggestions = getSuggestions(code, { line: 3, column: 13 }, computeTokenPosition); 80 | expect(suggestions.indexOf("v")).to.not.equal(-1); 81 | expect(suggestions.indexOf("some random name")).to.equal(-1); 82 | }); 83 | it("are suggested as function parameters", 84 | function() { 85 | const code = 86 | `val v = 1 87 | fun test() { 88 | print( ) 89 | }`; 90 | let suggestions = getSuggestions(code, { line: 3, column: 11 }, computeTokenPosition); 91 | expect(suggestions.indexOf("v")).to.not.equal(-1); 92 | expect(suggestions.indexOf("some random name")).to.equal(-1); 93 | }); 94 | }); -------------------------------------------------------------------------------- /tests/compute-token-position.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from "chai"; 2 | import {CharStreams, CommonTokenStream} from "antlr4ts"; 3 | import {KotlinLexer} from "../src/parser/KotlinLexer"; 4 | import {KotlinParser} from "../src/parser/KotlinParser"; 5 | import {computeTokenPosition} from "../src/compute-token-position"; 6 | 7 | describe('Token position', function() { 8 | const code = 9 | `fun test() { 10 | try { 11 | doSomething() 12 | } 13 | }`; 14 | it("has the right index", 15 | function() { 16 | let input = CharStreams.fromString(code); 17 | let lexer = new KotlinLexer(input); 18 | let tokenStream = new CommonTokenStream(lexer); 19 | let parser = new KotlinParser(tokenStream); 20 | let parseTree = parser.kotlinFile(); 21 | expect(parser.numberOfSyntaxErrors).to.equal(0); 22 | expect(input.index).to.equal(input.size); 23 | const tokenPosition = computeTokenPosition(parseTree, tokenStream,{ line: 4, column: 7 }); 24 | expect(tokenPosition).to.not.be.undefined; 25 | expect(tokenPosition.index).to.equal(34); 26 | }); 27 | it("includes partial text match ('fun' keyword)", 28 | function() { 29 | let input = CharStreams.fromString(code); 30 | let lexer = new KotlinLexer(input); 31 | let tokenStream = new CommonTokenStream(lexer); 32 | let parser = new KotlinParser(tokenStream); 33 | let parseTree = parser.kotlinFile(); 34 | expect(parser.numberOfSyntaxErrors).to.equal(0); 35 | expect(input.index).to.equal(input.size); 36 | const tokenPosition = computeTokenPosition(parseTree, tokenStream, { line: 1, column: 2 }); 37 | expect(tokenPosition).to.not.be.undefined; 38 | expect(tokenPosition.index).to.equal(0); 39 | expect(tokenPosition.text).to.equal("fu"); 40 | }); 41 | it("includes partial text match (function name)", 42 | function() { 43 | let input = CharStreams.fromString(code); 44 | let lexer = new KotlinLexer(input); 45 | let tokenStream = new CommonTokenStream(lexer); 46 | let parser = new KotlinParser(tokenStream); 47 | let parseTree = parser.kotlinFile(); 48 | expect(parser.numberOfSyntaxErrors).to.equal(0); 49 | expect(input.index).to.equal(input.size); 50 | const tokenPosition = computeTokenPosition(parseTree, tokenStream, { line: 1, column: 7 }); 51 | expect(tokenPosition).to.not.be.undefined; 52 | expect(tokenPosition.index).to.equal(2); 53 | expect(tokenPosition.text).to.equal("tes"); 54 | }); 55 | it("is correctly computed even in stream with errors", 56 | function() { 57 | let input = CharStreams.fromString(`fun test() { 58 | for(i on foo) { 59 | doSomething() 60 | } 61 | }`); 62 | let lexer = new KotlinLexer(input); 63 | let tokenStream = new CommonTokenStream(lexer); 64 | let parser = new KotlinParser(tokenStream); 65 | let parseTree = parser.kotlinFile(); 66 | expect(parser.numberOfSyntaxErrors).to.equal(3); 67 | expect(input.index).to.equal(input.size); 68 | const tokenPosition = computeTokenPosition(parseTree, tokenStream,{ line: 4, column: 7 }); 69 | expect(tokenPosition).to.not.be.undefined; 70 | expect(tokenPosition.index).to.equal(41); 71 | }); 72 | }); -------------------------------------------------------------------------------- /tests/parser.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from "chai"; 2 | 3 | import {CharStreams, CommonTokenStream} from "antlr4ts"; 4 | import {KotlinLexer} from "../src/parser/KotlinLexer"; 5 | import {KotlinParser} from "../src/parser/KotlinParser"; 6 | 7 | describe('variableRead rule refactoring', function() { 8 | it("parses variables", 9 | function() { 10 | const code = `x`; 11 | let input = CharStreams.fromString(code); 12 | let lexer = new KotlinLexer(input); 13 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 14 | 15 | parser.variableRead(); 16 | expect(parser.numberOfSyntaxErrors).to.equal(0); 17 | expect(input.index).to.equal(input.size); 18 | }); 19 | it("parses variables with infix operators as expressions", 20 | function() { 21 | const code = `x++`; 22 | let input = CharStreams.fromString(code); 23 | let lexer = new KotlinLexer(input); 24 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 25 | 26 | parser.expression(); 27 | expect(parser.numberOfSyntaxErrors).to.equal(0); 28 | expect(input.index).to.equal(input.size); 29 | }); 30 | it("parses variables with infix operators as variable reads", 31 | function() { 32 | const code = `x++`; 33 | let input = CharStreams.fromString(code); 34 | let lexer = new KotlinLexer(input); 35 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 36 | 37 | const tree = parser.postfixUnaryExpression(); 38 | expect(parser.numberOfSyntaxErrors).to.equal(0); 39 | expect(input.index).to.equal(input.size); 40 | expect(tree.variableRead()).not.to.be.undefined; 41 | expect(tree.variableRead().text).to.equal("x"); 42 | }); 43 | it("parses parenthesized variables as expressions", 44 | function() { 45 | const code = `(x)`; 46 | let input = CharStreams.fromString(code); 47 | let lexer = new KotlinLexer(input); 48 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 49 | 50 | parser.expression(); 51 | expect(parser.numberOfSyntaxErrors).to.equal(0); 52 | expect(input.index).to.equal(input.size); 53 | }); 54 | it("parses parenthesized variables as variable reads", 55 | function() { 56 | const code = `(x)`; 57 | let input = CharStreams.fromString(code); 58 | let lexer = new KotlinLexer(input); 59 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 60 | 61 | const tree = parser.atomicExpression(); 62 | expect(parser.numberOfSyntaxErrors).to.equal(0); 63 | expect(input.index).to.equal(input.size); 64 | expect(tree.parenthesizedExpression().expression()).not.to.be.undefined; 65 | }); 66 | it("parses function calls as expressions", 67 | function() { 68 | const code = `f()`; 69 | let input = CharStreams.fromString(code); 70 | let lexer = new KotlinLexer(input); 71 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 72 | 73 | const tree = parser.expression(); 74 | expect(parser.numberOfSyntaxErrors).to.equal(0); 75 | expect(input.index).to.equal(input.size); 76 | }); 77 | it("parses identifiers in function calls as simpleIdentifiers", 78 | function() { 79 | const code = `f()`; 80 | let input = CharStreams.fromString(code); 81 | let lexer = new KotlinLexer(input); 82 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 83 | 84 | const tree = parser.postfixUnaryExpression(); 85 | expect(parser.numberOfSyntaxErrors).to.equal(0); 86 | expect(input.index).to.equal(input.size); 87 | expect(tree.variableRead()).to.be.undefined; 88 | expect(tree.simpleIdentifier()).not.to.be.undefined; 89 | expect(tree.simpleIdentifier().text).to.equal("f"); 90 | }); 91 | it("parses import statements", 92 | function() { 93 | const code = `import foo 94 | 95 | fun bar() {}`; 96 | let input = CharStreams.fromString(code); 97 | let lexer = new KotlinLexer(input); 98 | let parser = new KotlinParser(new CommonTokenStream(lexer)); 99 | 100 | const tree = parser.kotlinFile(); 101 | expect(parser.numberOfSyntaxErrors).to.equal(0); 102 | expect(input.index).to.equal(input.size); 103 | expect(tree.preamble().importList().importHeader().length).to.equal(1); 104 | }); 105 | }); -------------------------------------------------------------------------------- /src/completion.ts: -------------------------------------------------------------------------------- 1 | import {KotlinLexer} from "./parser/KotlinLexer"; 2 | import {CharStreams, CommonTokenStream} from "antlr4ts"; 3 | import {KotlinParser, VariableReadContext} from "./parser/KotlinParser"; 4 | import {CodeCompletionCore, ScopedSymbol, SymbolTable, VariableSymbol} from "antlr4-c3"; 5 | import {ParseTree, TerminalNode} from "antlr4ts/tree"; 6 | import {SymbolTableVisitor} from "./symbol-table-visitor"; 7 | import {Symbol} from "antlr4-c3/out/src/SymbolTable"; 8 | import {CaretPosition, ComputeTokenPositionFunction, TokenPosition} from "./types"; 9 | import * as fuzzysort from 'fuzzysort'; 10 | 11 | export function getScope(context: ParseTree, symbolTable: SymbolTable) { 12 | if(!context) { 13 | return undefined; 14 | } 15 | const scope = symbolTable.symbolWithContext(context); 16 | if(scope) { 17 | return scope; 18 | } else { 19 | return getScope(context.parent, symbolTable); 20 | } 21 | } 22 | 23 | export function getAllSymbolsOfType(scope: ScopedSymbol, type: new (...args: any[]) => T): T[] { 24 | let symbols = scope.getSymbolsOfType(type); 25 | let parent = scope.parent; 26 | while(parent && !(parent instanceof ScopedSymbol)) { 27 | parent = parent.parent; 28 | } 29 | if(parent) { 30 | symbols.push(...getAllSymbolsOfType(parent as ScopedSymbol, type)); 31 | } 32 | return symbols; 33 | } 34 | 35 | function suggestVariables(symbolTable: SymbolTable, position: TokenPosition) { 36 | const context = position.context; 37 | const scope = getScope(context, symbolTable); 38 | let symbols: Symbol[]; 39 | if(scope instanceof ScopedSymbol) { //Local scope 40 | symbols = getAllSymbolsOfType(scope, VariableSymbol); 41 | } else { //Global scope 42 | symbols = symbolTable.getSymbolsOfType(VariableSymbol); 43 | } 44 | let variable = position.context; 45 | while(!(variable instanceof VariableReadContext) && variable.parent) { 46 | variable = variable.parent; 47 | } 48 | return filterTokens(variable ? position.text : '', symbols.map(s => s.name)); 49 | } 50 | 51 | export function filterTokens_startsWith(text: string, candidates: string[]) { 52 | if(text.trim().length == 0) { 53 | return candidates; 54 | } else { 55 | return candidates.filter(c => c.toLowerCase().startsWith(text.toLowerCase())); 56 | } 57 | } 58 | 59 | export function filterTokens_fuzzySearch(text: string, candidates: string[]) { 60 | if(text.trim().length == 0) { 61 | return candidates; 62 | } else { 63 | return fuzzysort.go(text, candidates).map(r => r.target); 64 | } 65 | } 66 | 67 | export let filterTokens = filterTokens_startsWith; 68 | export function setTokenMatcher(fn) { 69 | filterTokens = fn; 70 | } 71 | 72 | export function getSuggestionsForParseTree( 73 | parser: KotlinParser, parseTree: ParseTree, symbolTableFn: () => SymbolTable, position: TokenPosition) { 74 | let core = new CodeCompletionCore(parser); 75 | // Luckily, the Kotlin lexer defines all keywords and identifiers after operators, 76 | // so we can simply exclude the first non-keyword tokens 77 | let ignored = Array.from(Array(KotlinParser.FILE).keys()); 78 | ignored.push( 79 | KotlinParser.BinLiteral, KotlinParser.BooleanLiteral, KotlinParser.CharacterLiteral, KotlinParser.DoubleLiteral, 80 | KotlinParser.HexLiteral, KotlinParser.IntegerLiteral, KotlinParser.LongLiteral, KotlinParser.NullLiteral, 81 | KotlinParser.RealLiteral, 82 | KotlinParser.DelimitedComment, KotlinParser.LineComment); 83 | ignored.push(KotlinParser.QUOTE_OPEN, KotlinParser.QUOTE_CLOSE, KotlinParser.TRIPLE_QUOTE_OPEN) 84 | ignored.push(KotlinParser.LabelDefinition, KotlinParser.LabelReference); //We don't handle labels for simplicity 85 | core.ignoredTokens = new Set(ignored); 86 | core.preferredRules = new Set([KotlinParser.RULE_variableRead, KotlinParser.RULE_suggestArgument]); 87 | let candidates = core.collectCandidates(position.index); 88 | 89 | let completions = []; 90 | if (candidates.rules.has(KotlinParser.RULE_variableRead) || 91 | candidates.rules.has(KotlinParser.RULE_suggestArgument)) { 92 | completions.push(...suggestVariables(symbolTableFn(), position)); 93 | } 94 | let tokens = []; 95 | candidates.tokens.forEach((_, k) => { 96 | if (k == KotlinParser.Identifier) { 97 | //Skip, we’ve already handled it above 98 | } else if (k == KotlinParser.NOT_IN) { 99 | tokens.push("!in"); 100 | } else if (k == KotlinParser.NOT_IS) { 101 | tokens.push("!is"); 102 | } else { 103 | const symbolicName = parser.vocabulary.getSymbolicName(k); 104 | if (symbolicName) { 105 | tokens.push(symbolicName.toLowerCase()); 106 | } 107 | } 108 | }); 109 | const isIgnoredToken = 110 | position.context instanceof TerminalNode && 111 | ignored.indexOf(position.context.symbol.type) >= 0; 112 | const textToMatch = isIgnoredToken ? '' : position.text; 113 | completions.push(...filterTokens(textToMatch, tokens)); 114 | return completions; 115 | } 116 | 117 | export function getSuggestions( 118 | code: string, caretPosition: CaretPosition, computeTokenPosition: ComputeTokenPositionFunction) { 119 | let input = CharStreams.fromString(code); 120 | let lexer = new KotlinLexer(input); 121 | let tokenStream = new CommonTokenStream(lexer); 122 | let parser = new KotlinParser(tokenStream); 123 | 124 | let parseTree = parser.kotlinFile(); 125 | 126 | let position = computeTokenPosition(parseTree, tokenStream, caretPosition); 127 | if(!position) { 128 | return []; 129 | } 130 | return getSuggestionsForParseTree( 131 | parser, parseTree, () => new SymbolTableVisitor().visit(parseTree), position); 132 | } -------------------------------------------------------------------------------- /grammar/KotlinLexer.g4: -------------------------------------------------------------------------------- 1 | /** 2 | * Kotlin Grammar for ANTLR v4 3 | * 4 | * Based on: 5 | * http://jetbrains.github.io/kotlin-spec/#_grammars_and_parsing 6 | * and 7 | * http://kotlinlang.org/docs/reference/grammar.html 8 | * 9 | * Tested on 10 | * https://github.com/JetBrains/kotlin/tree/master/compiler/testData/psi 11 | */ 12 | 13 | lexer grammar KotlinLexer; 14 | 15 | import UnicodeClasses; 16 | 17 | ShebangLine 18 | : '#!' ~[\u000A\u000D]* 19 | -> channel(HIDDEN) 20 | ; 21 | 22 | DelimitedComment 23 | : '/*' ( DelimitedComment | . )*? '*/' 24 | -> channel(HIDDEN) 25 | ; 26 | 27 | LineComment 28 | : '//' ~[\u000A\u000D]* 29 | -> channel(HIDDEN) 30 | ; 31 | 32 | WS 33 | : [\u0020\u0009\u000C] 34 | -> channel(HIDDEN) 35 | ; 36 | 37 | NL: '\u000A' | '\u000D' '\u000A' ; 38 | 39 | //SEPARATORS & OPERATIONS 40 | 41 | RESERVED: '...' ; 42 | DOT: '.' ; 43 | COMMA: ',' ; 44 | LPAREN: '(' -> pushMode(Inside) ; 45 | RPAREN: ')' ; 46 | LSQUARE: '[' -> pushMode(Inside) ; 47 | RSQUARE: ']' ; 48 | LCURL: '{' ; 49 | RCURL: '}' ; 50 | MULT: '*' ; 51 | MOD: '%' ; 52 | DIV: '/' ; 53 | ADD: '+' ; 54 | SUB: '-' ; 55 | INCR: '++' ; 56 | DECR: '--' ; 57 | CONJ: '&&' ; 58 | DISJ: '||' ; 59 | EXCL: '!' ; 60 | COLON: ':' ; 61 | SEMICOLON: ';' ; 62 | ASSIGNMENT: '=' ; 63 | ADD_ASSIGNMENT: '+=' ; 64 | SUB_ASSIGNMENT: '-=' ; 65 | MULT_ASSIGNMENT: '*=' ; 66 | DIV_ASSIGNMENT: '/=' ; 67 | MOD_ASSIGNMENT: '%=' ; 68 | ARROW: '->' ; 69 | DOUBLE_ARROW: '=>' ; 70 | RANGE: '..' ; 71 | COLONCOLON: '::' ; 72 | Q_COLONCOLON: '?::' ; 73 | DOUBLE_SEMICOLON: ';;' ; 74 | HASH: '#' ; 75 | AT: '@' ; 76 | QUEST: '?' ; 77 | ELVIS: '?:' ; 78 | LANGLE: '<' ; 79 | RANGLE: '>' ; 80 | LE: '<=' ; 81 | GE: '>=' ; 82 | EXCL_EQ: '!=' ; 83 | EXCL_EQEQ: '!==' ; 84 | AS_SAFE: 'as?' ; 85 | EQEQ: '==' ; 86 | EQEQEQ: '===' ; 87 | SINGLE_QUOTE: '\'' ; 88 | 89 | //KEYWORDS 90 | 91 | RETURN_AT: 'return@' Identifier ; 92 | CONTINUE_AT: 'continue@' Identifier ; 93 | BREAK_AT: 'break@' Identifier ; 94 | 95 | FILE: '@file' ; 96 | PACKAGE: 'package' ; 97 | IMPORT: 'import' ; 98 | CLASS: 'class' ; 99 | INTERFACE: 'interface' ; 100 | FUN: 'fun' ; 101 | OBJECT: 'object' ; 102 | VAL: 'val' ; 103 | VAR: 'var' ; 104 | TYPE_ALIAS: 'typealias' ; 105 | CONSTRUCTOR: 'constructor' ; 106 | BY: 'by' ; 107 | COMPANION: 'companion' ; 108 | INIT: 'init' ; 109 | THIS: 'this' ; 110 | SUPER: 'super' ; 111 | TYPEOF: 'typeof' ; 112 | WHERE: 'where' ; 113 | IF: 'if' ; 114 | ELSE: 'else' ; 115 | WHEN: 'when' ; 116 | TRY: 'try' ; 117 | CATCH: 'catch' ; 118 | FINALLY: 'finally' ; 119 | FOR: 'for' ; 120 | DO: 'do' ; 121 | WHILE: 'while' ; 122 | THROW: 'throw' ; 123 | RETURN: 'return' ; 124 | CONTINUE: 'continue' ; 125 | BREAK: 'break' ; 126 | AS: 'as' ; 127 | IS: 'is' ; 128 | IN: 'in' ; 129 | NOT_IS: '!is' (WS | NL)+ ; 130 | NOT_IN: '!in' (WS | NL)+ ; 131 | OUT: 'out' ; 132 | FIELD: '@field' ; 133 | PROPERTY: '@property' ; 134 | GET: '@get' ; 135 | SET: '@set' ; 136 | GETTER: 'get' ; 137 | SETTER: 'set' ; 138 | RECEIVER: '@receiver' ; 139 | PARAM: '@param' ; 140 | SETPARAM: '@setparam' ; 141 | DELEGATE: '@delegate' ; 142 | DYNAMIC: 'dynamic' ; 143 | 144 | //MODIFIERS 145 | 146 | PUBLIC: 'public' ; 147 | PRIVATE: 'private' ; 148 | PROTECTED: 'protected' ; 149 | INTERNAL: 'internal' ; 150 | ENUM: 'enum' ; 151 | SEALED: 'sealed' ; 152 | ANNOTATION: 'annotation' ; 153 | DATA: 'data' ; 154 | INNER: 'inner' ; 155 | TAILREC: 'tailrec' ; 156 | OPERATOR: 'operator' ; 157 | INLINE: 'inline' ; 158 | INFIX: 'infix' ; 159 | EXTERNAL: 'external' ; 160 | SUSPEND: 'suspend' ; 161 | OVERRIDE: 'override' ; 162 | ABSTRACT: 'abstract' ; 163 | FINAL: 'final' ; 164 | OPEN: 'open' ; 165 | CONST: 'const' ; 166 | LATEINIT: 'lateinit' ; 167 | VARARG: 'vararg' ; 168 | NOINLINE: 'noinline' ; 169 | CROSSINLINE: 'crossinline' ; 170 | REIFIED: 'reified' ; 171 | 172 | // 173 | 174 | QUOTE_OPEN: '"' -> pushMode(LineString) ; 175 | TRIPLE_QUOTE_OPEN: '"""' -> pushMode(MultiLineString) ; 176 | 177 | RealLiteral 178 | : FloatLiteral 179 | | DoubleLiteral 180 | ; 181 | 182 | FloatLiteral 183 | : (DoubleLiteral | IntegerLiteral) [fF] 184 | ; 185 | 186 | DoubleLiteral 187 | : ( (DecDigitNoZero DecDigit*)? '.' 188 | | (DecDigitNoZero (DecDigit | '_')* DecDigit)? '.') 189 | ( DecDigit+ 190 | | DecDigit (DecDigit | '_')+ DecDigit 191 | | DecDigit+ [eE] ('+' | '-')? DecDigit+ 192 | | DecDigit+ [eE] ('+' | '-')? DecDigit (DecDigit | '_')+ DecDigit 193 | | DecDigit (DecDigit | '_')+ DecDigit [eE] ('+' | '-')? DecDigit+ 194 | | DecDigit (DecDigit | '_')+ DecDigit [eE] ('+' | '-')? DecDigit (DecDigit | '_')+ DecDigit 195 | ) 196 | ; 197 | 198 | LongLiteral 199 | : (IntegerLiteral | HexLiteral | BinLiteral) 'L' 200 | ; 201 | 202 | IntegerLiteral 203 | : ('0' 204 | | DecDigitNoZero DecDigit* 205 | | DecDigitNoZero (DecDigit | '_')+ DecDigit 206 | | DecDigitNoZero DecDigit* [eE] ('+' | '-')? DecDigit+ 207 | | DecDigitNoZero DecDigit* [eE] ('+' | '-')? DecDigit (DecDigit | '_')+ DecDigit 208 | | DecDigitNoZero (DecDigit | '_')+ DecDigit [eE] ('+' | '-')? DecDigit+ 209 | | DecDigitNoZero (DecDigit | '_')+ DecDigit [eE] ('+' | '-')? DecDigit (DecDigit | '_')+ DecDigit 210 | ) 211 | ; 212 | 213 | fragment DecDigit 214 | : UNICODE_CLASS_ND 215 | ; 216 | 217 | fragment DecDigitNoZero 218 | : UNICODE_CLASS_ND_NoZeros 219 | ; 220 | 221 | fragment UNICODE_CLASS_ND_NoZeros 222 | : '\u0031'..'\u0039' 223 | | '\u0661'..'\u0669' 224 | | '\u06f1'..'\u06f9' 225 | | '\u07c1'..'\u07c9' 226 | | '\u0967'..'\u096f' 227 | | '\u09e7'..'\u09ef' 228 | | '\u0a67'..'\u0a6f' 229 | | '\u0ae7'..'\u0aef' 230 | | '\u0b67'..'\u0b6f' 231 | | '\u0be7'..'\u0bef' 232 | | '\u0c67'..'\u0c6f' 233 | | '\u0ce7'..'\u0cef' 234 | | '\u0d67'..'\u0d6f' 235 | | '\u0de7'..'\u0def' 236 | | '\u0e51'..'\u0e59' 237 | | '\u0ed1'..'\u0ed9' 238 | | '\u0f21'..'\u0f29' 239 | | '\u1041'..'\u1049' 240 | | '\u1091'..'\u1099' 241 | | '\u17e1'..'\u17e9' 242 | | '\u1811'..'\u1819' 243 | | '\u1947'..'\u194f' 244 | | '\u19d1'..'\u19d9' 245 | | '\u1a81'..'\u1a89' 246 | | '\u1a91'..'\u1a99' 247 | | '\u1b51'..'\u1b59' 248 | | '\u1bb1'..'\u1bb9' 249 | | '\u1c41'..'\u1c49' 250 | | '\u1c51'..'\u1c59' 251 | | '\ua621'..'\ua629' 252 | | '\ua8d1'..'\ua8d9' 253 | | '\ua901'..'\ua909' 254 | | '\ua9d1'..'\ua9d9' 255 | | '\ua9f1'..'\ua9f9' 256 | | '\uaa51'..'\uaa59' 257 | | '\uabf1'..'\uabf9' 258 | | '\uff11'..'\uff19' 259 | ; 260 | 261 | HexLiteral 262 | : '0' [xX] HexDigit (HexDigit | '_')* 263 | ; 264 | 265 | fragment HexDigit 266 | : [0-9a-fA-F] 267 | ; 268 | 269 | BinLiteral 270 | : '0' [bB] BinDigit (BinDigit | '_')* 271 | ; 272 | 273 | fragment BinDigit 274 | : [01] 275 | ; 276 | 277 | BooleanLiteral 278 | : 'true' 279 | | 'false' 280 | ; 281 | 282 | NullLiteral 283 | : 'null' 284 | ; 285 | 286 | Identifier 287 | : (Letter | '_') (Letter | '_' | DecDigit)* 288 | | '`' ~('`')+ '`' 289 | ; 290 | 291 | LabelReference 292 | : '@' Identifier 293 | ; 294 | 295 | LabelDefinition 296 | : Identifier '@' 297 | ; 298 | 299 | FieldIdentifier 300 | : '$' Identifier 301 | ; 302 | 303 | CharacterLiteral 304 | : '\'' (EscapeSeq | .) '\'' 305 | ; 306 | 307 | fragment EscapeSeq 308 | : UniCharacterLiteral 309 | | EscapedIdentifier 310 | ; 311 | 312 | fragment UniCharacterLiteral 313 | : '\\' 'u' HexDigit HexDigit HexDigit HexDigit 314 | ; 315 | 316 | fragment EscapedIdentifier 317 | : '\\' ('t' | 'b' | 'r' | 'n' | '\'' | '"' | '\\' | '$') 318 | ; 319 | 320 | fragment Letter 321 | : UNICODE_CLASS_LL 322 | | UNICODE_CLASS_LM 323 | | UNICODE_CLASS_LO 324 | | UNICODE_CLASS_LT 325 | | UNICODE_CLASS_LU 326 | | UNICODE_CLASS_NL 327 | ; 328 | 329 | 330 | mode Inside ; 331 | 332 | Inside_RPAREN: ')' -> popMode, type(RPAREN) ; 333 | Inside_RSQUARE: ']' -> popMode, type(RSQUARE); 334 | 335 | Inside_LPAREN: LPAREN -> pushMode(Inside), type(LPAREN) ; 336 | Inside_LSQUARE: LSQUARE -> pushMode(Inside), type(LSQUARE) ; 337 | 338 | Inside_LCURL: LCURL -> type(LCURL) ; 339 | Inside_RCURL: RCURL -> type(RCURL) ; 340 | Inside_DOT: DOT -> type(DOT) ; 341 | Inside_COMMA: COMMA -> type(COMMA) ; 342 | Inside_MULT: MULT -> type(MULT) ; 343 | Inside_MOD: MOD -> type(MOD) ; 344 | Inside_DIV: DIV -> type(DIV) ; 345 | Inside_ADD: ADD -> type(ADD) ; 346 | Inside_SUB: SUB -> type(SUB) ; 347 | Inside_INCR: INCR -> type(INCR) ; 348 | Inside_DECR: DECR -> type(DECR) ; 349 | Inside_CONJ: CONJ -> type(CONJ) ; 350 | Inside_DISJ: DISJ -> type(DISJ) ; 351 | Inside_EXCL: EXCL -> type(EXCL) ; 352 | Inside_COLON: COLON -> type(COLON) ; 353 | Inside_SEMICOLON: SEMICOLON -> type(SEMICOLON) ; 354 | Inside_ASSIGNMENT: ASSIGNMENT -> type(ASSIGNMENT) ; 355 | Inside_ADD_ASSIGNMENT: ADD_ASSIGNMENT -> type(ADD_ASSIGNMENT) ; 356 | Inside_SUB_ASSIGNMENT: SUB_ASSIGNMENT -> type(SUB_ASSIGNMENT) ; 357 | Inside_MULT_ASSIGNMENT: MULT_ASSIGNMENT -> type(MULT_ASSIGNMENT) ; 358 | Inside_DIV_ASSIGNMENT: DIV_ASSIGNMENT -> type(DIV_ASSIGNMENT) ; 359 | Inside_MOD_ASSIGNMENT: MOD_ASSIGNMENT -> type(MOD_ASSIGNMENT) ; 360 | Inside_ARROW: ARROW -> type(ARROW) ; 361 | Inside_DOUBLE_ARROW: DOUBLE_ARROW -> type(DOUBLE_ARROW) ; 362 | Inside_RANGE: RANGE -> type(RANGE) ; 363 | Inside_RESERVED: RESERVED -> type(RESERVED) ; 364 | Inside_COLONCOLON: COLONCOLON -> type(COLONCOLON) ; 365 | Inside_Q_COLONCOLON: Q_COLONCOLON -> type(Q_COLONCOLON) ; 366 | Inside_DOUBLE_SEMICOLON: DOUBLE_SEMICOLON -> type(DOUBLE_SEMICOLON) ; 367 | Inside_HASH: HASH -> type(HASH) ; 368 | Inside_AT: AT -> type(AT) ; 369 | Inside_QUEST: QUEST -> type(QUEST) ; 370 | Inside_ELVIS: ELVIS -> type(ELVIS) ; 371 | Inside_LANGLE: LANGLE -> type(LANGLE) ; 372 | Inside_RANGLE: RANGLE -> type(RANGLE) ; 373 | Inside_LE: LE -> type(LE) ; 374 | Inside_GE: GE -> type(GE) ; 375 | Inside_EXCL_EQ: EXCL_EQ -> type(EXCL_EQ) ; 376 | Inside_EXCL_EQEQ: EXCL_EQEQ -> type(EXCL_EQEQ) ; 377 | Inside_NOT_IS: NOT_IS -> type(NOT_IS) ; 378 | Inside_NOT_IN: NOT_IN -> type(NOT_IN) ; 379 | Inside_AS_SAFE: AS_SAFE -> type(AS_SAFE) ; 380 | Inside_EQEQ: EQEQ -> type(EQEQ) ; 381 | Inside_EQEQEQ: EQEQEQ -> type(EQEQEQ) ; 382 | Inside_SINGLE_QUOTE: SINGLE_QUOTE -> type(SINGLE_QUOTE) ; 383 | Inside_QUOTE_OPEN: QUOTE_OPEN -> pushMode(LineString), type(QUOTE_OPEN) ; 384 | Inside_TRIPLE_QUOTE_OPEN: TRIPLE_QUOTE_OPEN -> pushMode(MultiLineString), type(TRIPLE_QUOTE_OPEN) ; 385 | 386 | Inside_VAL: VAL -> type(VAL) ; 387 | Inside_VAR: VAR -> type(VAR) ; 388 | Inside_OBJECT: OBJECT -> type(OBJECT) ; 389 | Inside_SUPER: SUPER -> type(SUPER) ; 390 | Inside_IN: IN -> type(IN) ; 391 | Inside_OUT: OUT -> type(OUT) ; 392 | Inside_FIELD: FIELD -> type(FIELD) ; 393 | Inside_FILE: FILE -> type(FILE) ; 394 | Inside_PROPERTY: PROPERTY -> type(PROPERTY) ; 395 | Inside_GET: GET -> type(GET) ; 396 | Inside_SET: SET -> type(SET) ; 397 | Inside_RECEIVER: RECEIVER -> type(RECEIVER) ; 398 | Inside_PARAM: PARAM -> type(PARAM) ; 399 | Inside_SETPARAM: SETPARAM -> type(SETPARAM) ; 400 | Inside_DELEGATE: DELEGATE -> type(DELEGATE) ; 401 | Inside_THROW: THROW -> type(THROW) ; 402 | Inside_RETURN: RETURN -> type(RETURN) ; 403 | Inside_CONTINUE: CONTINUE -> type(CONTINUE) ; 404 | Inside_BREAK: BREAK -> type(BREAK) ; 405 | Inside_RETURN_AT: RETURN_AT -> type(RETURN_AT) ; 406 | Inside_CONTINUE_AT: CONTINUE_AT -> type(CONTINUE_AT) ; 407 | Inside_BREAK_AT: BREAK_AT -> type(BREAK_AT) ; 408 | Inside_IF: IF -> type(IF) ; 409 | Inside_ELSE: ELSE -> type(ELSE) ; 410 | Inside_WHEN: WHEN -> type(WHEN) ; 411 | Inside_TRY: TRY -> type(TRY) ; 412 | Inside_CATCH: CATCH -> type(CATCH) ; 413 | Inside_FINALLY: FINALLY -> type(FINALLY) ; 414 | Inside_FOR: FOR -> type(FOR) ; 415 | Inside_DO: DO -> type(DO) ; 416 | Inside_WHILE: WHILE -> type(WHILE) ; 417 | 418 | Inside_PUBLIC: PUBLIC -> type(PUBLIC) ; 419 | Inside_PRIVATE: PRIVATE -> type(PRIVATE) ; 420 | Inside_PROTECTED: PROTECTED -> type(PROTECTED) ; 421 | Inside_INTERNAL: INTERNAL -> type(INTERNAL) ; 422 | Inside_ENUM: ENUM -> type(ENUM) ; 423 | Inside_SEALED: SEALED -> type(SEALED) ; 424 | Inside_ANNOTATION: ANNOTATION -> type(ANNOTATION) ; 425 | Inside_DATA: DATA -> type(DATA) ; 426 | Inside_INNER: INNER -> type(INNER) ; 427 | Inside_TAILREC: TAILREC -> type(TAILREC) ; 428 | Inside_OPERATOR: OPERATOR -> type(OPERATOR) ; 429 | Inside_INLINE: INLINE -> type(INLINE) ; 430 | Inside_INFIX: INFIX -> type(INFIX) ; 431 | Inside_EXTERNAL: EXTERNAL -> type(EXTERNAL) ; 432 | Inside_SUSPEND: SUSPEND -> type(SUSPEND) ; 433 | Inside_OVERRIDE: OVERRIDE -> type(OVERRIDE) ; 434 | Inside_ABSTRACT: ABSTRACT -> type(ABSTRACT) ; 435 | Inside_FINAL: FINAL -> type(FINAL) ; 436 | Inside_OPEN: OPEN -> type(OPEN) ; 437 | Inside_CONST: CONST -> type(CONST) ; 438 | Inside_LATEINIT: LATEINIT -> type(LATEINIT) ; 439 | Inside_VARARG: VARARG -> type(VARARG) ; 440 | Inside_NOINLINE: NOINLINE -> type(NOINLINE) ; 441 | Inside_CROSSINLINE: CROSSINLINE -> type(CROSSINLINE) ; 442 | Inside_REIFIED: REIFIED -> type(REIFIED) ; 443 | 444 | Inside_BooleanLiteral: BooleanLiteral -> type(BooleanLiteral) ; 445 | Inside_IntegerLiteral: IntegerLiteral -> type(IntegerLiteral) ; 446 | Inside_HexLiteral: HexLiteral -> type(HexLiteral) ; 447 | Inside_BinLiteral: BinLiteral -> type(BinLiteral) ; 448 | Inside_CharacterLiteral: CharacterLiteral -> type(CharacterLiteral) ; 449 | Inside_RealLiteral: RealLiteral -> type(RealLiteral) ; 450 | Inside_NullLiteral: NullLiteral -> type(NullLiteral) ; 451 | 452 | Inside_LongLiteral: LongLiteral -> type(LongLiteral) ; 453 | 454 | Inside_Identifier: Identifier -> type(Identifier) ; 455 | Inside_LabelReference: LabelReference -> type(LabelReference) ; 456 | Inside_LabelDefinition: LabelDefinition -> type(LabelDefinition) ; 457 | Inside_Comment: (LineComment | DelimitedComment) -> channel(HIDDEN) ; 458 | Inside_WS: WS -> channel(HIDDEN) ; 459 | Inside_NL: NL -> channel(HIDDEN) ; 460 | 461 | 462 | mode LineString ; 463 | 464 | QUOTE_CLOSE 465 | : '"' -> popMode 466 | ; 467 | 468 | LineStrRef 469 | : FieldIdentifier 470 | ; 471 | 472 | LineStrText 473 | : ~('\\' | '"' | '$')+ | '$' 474 | ; 475 | 476 | LineStrEscapedChar 477 | : '\\' . 478 | | UniCharacterLiteral 479 | ; 480 | 481 | LineStrExprStart 482 | : '${' -> pushMode(StringExpression) 483 | ; 484 | 485 | 486 | mode MultiLineString ; 487 | 488 | TRIPLE_QUOTE_CLOSE 489 | : MultiLineStringQuote? '"""' -> popMode 490 | ; 491 | 492 | MultiLineStringQuote 493 | : '"'+ 494 | ; 495 | 496 | MultiLineStrRef 497 | : FieldIdentifier 498 | ; 499 | 500 | MultiLineStrText 501 | : ~('\\' | '"' | '$')+ | '$' 502 | ; 503 | 504 | MultiLineStrEscapedChar 505 | : '\\' . 506 | ; 507 | 508 | MultiLineStrExprStart 509 | : '${' -> pushMode(StringExpression) 510 | ; 511 | 512 | MultiLineNL: NL -> channel(HIDDEN) ; 513 | 514 | 515 | mode StringExpression ; 516 | 517 | StrExpr_RCURL: RCURL -> popMode, type(RCURL) ; 518 | 519 | StrExpr_LPAREN: LPAREN -> pushMode(Inside), type(LPAREN) ; 520 | StrExpr_LSQUARE: LSQUARE -> pushMode(Inside), type(LSQUARE) ; 521 | 522 | StrExpr_RPAREN: ')' -> type(RPAREN) ; 523 | StrExpr_RSQUARE: ']' -> type(RSQUARE); 524 | StrExpr_LCURL: LCURL -> pushMode(StringExpression), type(LCURL) ; 525 | StrExpr_DOT: DOT -> type(DOT) ; 526 | StrExpr_COMMA: COMMA -> type(COMMA) ; 527 | StrExpr_MULT: MULT -> type(MULT) ; 528 | StrExpr_MOD: MOD -> type(MOD) ; 529 | StrExpr_DIV: DIV -> type(DIV) ; 530 | StrExpr_ADD: ADD -> type(ADD) ; 531 | StrExpr_SUB: SUB -> type(SUB) ; 532 | StrExpr_INCR: INCR -> type(INCR) ; 533 | StrExpr_DECR: DECR -> type(DECR) ; 534 | StrExpr_CONJ: CONJ -> type(CONJ) ; 535 | StrExpr_DISJ: DISJ -> type(DISJ) ; 536 | StrExpr_EXCL: EXCL -> type(EXCL) ; 537 | StrExpr_COLON: COLON -> type(COLON) ; 538 | StrExpr_SEMICOLON: SEMICOLON -> type(SEMICOLON) ; 539 | StrExpr_ASSIGNMENT: ASSIGNMENT -> type(ASSIGNMENT) ; 540 | StrExpr_ADD_ASSIGNMENT: ADD_ASSIGNMENT -> type(ADD_ASSIGNMENT) ; 541 | StrExpr_SUB_ASSIGNMENT: SUB_ASSIGNMENT -> type(SUB_ASSIGNMENT) ; 542 | StrExpr_MULT_ASSIGNMENT: MULT_ASSIGNMENT -> type(MULT_ASSIGNMENT) ; 543 | StrExpr_DIV_ASSIGNMENT: DIV_ASSIGNMENT -> type(DIV_ASSIGNMENT) ; 544 | StrExpr_MOD_ASSIGNMENT: MOD_ASSIGNMENT -> type(MOD_ASSIGNMENT) ; 545 | StrExpr_ARROW: ARROW -> type(ARROW) ; 546 | StrExpr_DOUBLE_ARROW: DOUBLE_ARROW -> type(DOUBLE_ARROW) ; 547 | StrExpr_RANGE: RANGE -> type(RANGE) ; 548 | StrExpr_COLONCOLON: COLONCOLON -> type(COLONCOLON) ; 549 | StrExpr_Q_COLONCOLON: Q_COLONCOLON -> type(Q_COLONCOLON) ; 550 | StrExpr_DOUBLE_SEMICOLON: DOUBLE_SEMICOLON -> type(DOUBLE_SEMICOLON) ; 551 | StrExpr_HASH: HASH -> type(HASH) ; 552 | StrExpr_AT: AT -> type(AT) ; 553 | StrExpr_QUEST: QUEST -> type(QUEST) ; 554 | StrExpr_ELVIS: ELVIS -> type(ELVIS) ; 555 | StrExpr_LANGLE: LANGLE -> type(LANGLE) ; 556 | StrExpr_RANGLE: RANGLE -> type(RANGLE) ; 557 | StrExpr_LE: LE -> type(LE) ; 558 | StrExpr_GE: GE -> type(GE) ; 559 | StrExpr_EXCL_EQ: EXCL_EQ -> type(EXCL_EQ) ; 560 | StrExpr_EXCL_EQEQ: EXCL_EQEQ -> type(EXCL_EQEQ) ; 561 | StrExpr_AS: AS -> type(IS) ; 562 | StrExpr_IS: IS -> type(IN) ; 563 | StrExpr_IN: IN ; 564 | StrExpr_NOT_IS: NOT_IS -> type(NOT_IS) ; 565 | StrExpr_NOT_IN: NOT_IN -> type(NOT_IN) ; 566 | StrExpr_AS_SAFE: AS_SAFE -> type(AS_SAFE) ; 567 | StrExpr_EQEQ: EQEQ -> type(EQEQ) ; 568 | StrExpr_EQEQEQ: EQEQEQ -> type(EQEQEQ) ; 569 | StrExpr_SINGLE_QUOTE: SINGLE_QUOTE -> type(SINGLE_QUOTE) ; 570 | StrExpr_QUOTE_OPEN: QUOTE_OPEN -> pushMode(LineString), type(QUOTE_OPEN) ; 571 | StrExpr_TRIPLE_QUOTE_OPEN: TRIPLE_QUOTE_OPEN -> pushMode(MultiLineString), type(TRIPLE_QUOTE_OPEN) ; 572 | 573 | StrExpr_BooleanLiteral: BooleanLiteral -> type(BooleanLiteral) ; 574 | StrExpr_IntegerLiteral: IntegerLiteral -> type(IntegerLiteral) ; 575 | StrExpr_HexLiteral: HexLiteral -> type(HexLiteral) ; 576 | StrExpr_BinLiteral: BinLiteral -> type(BinLiteral) ; 577 | StrExpr_CharacterLiteral: CharacterLiteral -> type(CharacterLiteral) ; 578 | StrExpr_RealLiteral: RealLiteral -> type(RealLiteral) ; 579 | StrExpr_NullLiteral: NullLiteral -> type(NullLiteral) ; 580 | StrExpr_LongLiteral: LongLiteral -> type(LongLiteral) ; 581 | 582 | StrExpr_Identifier: Identifier -> type(Identifier) ; 583 | StrExpr_LabelReference: LabelReference -> type(LabelReference) ; 584 | StrExpr_LabelDefinition: LabelDefinition -> type(LabelDefinition) ; 585 | StrExpr_Comment: (LineComment | DelimitedComment) -> channel(HIDDEN) ; 586 | StrExpr_WS: WS -> channel(HIDDEN) ; 587 | StrExpr_NL: NL -> channel(HIDDEN) ; -------------------------------------------------------------------------------- /grammar/KotlinParser.g4: -------------------------------------------------------------------------------- 1 | /** 2 | * Kotlin Grammar for ANTLR v4 3 | * 4 | * Based on: 5 | * http://jetbrains.github.io/kotlin-spec/#_grammars_and_parsing 6 | * and 7 | * http://kotlinlang.org/docs/reference/grammar.html 8 | * 9 | * Tested on 10 | * https://github.com/JetBrains/kotlin/tree/master/compiler/testData/psi 11 | */ 12 | 13 | parser grammar KotlinParser; 14 | 15 | options { tokenVocab = KotlinLexer; } 16 | 17 | kotlinFile 18 | : NL* preamble anysemi* (topLevelObject (anysemi+ topLevelObject?)*)? EOF 19 | ; 20 | 21 | script 22 | : NL* preamble anysemi* (expression (anysemi+ expression?)*)? EOF 23 | ; 24 | 25 | preamble 26 | : fileAnnotations? packageHeader importList 27 | ; 28 | 29 | fileAnnotations 30 | : fileAnnotation+ 31 | ; 32 | 33 | fileAnnotation 34 | : (FILE COLON (LSQUARE unescapedAnnotation+ RSQUARE | unescapedAnnotation) semi?)+ 35 | ; 36 | 37 | packageHeader 38 | : (modifierList? PACKAGE identifier semi?)? 39 | ; 40 | 41 | importList 42 | : importHeader* 43 | ; 44 | 45 | importHeader 46 | : IMPORT identifier (DOT MULT | importAlias)? semi? 47 | ; 48 | 49 | importAlias 50 | : AS simpleIdentifier 51 | ; 52 | 53 | topLevelObject 54 | : classDeclaration 55 | | objectDeclaration 56 | | functionDeclaration 57 | | propertyDeclaration 58 | | typeAlias 59 | ; 60 | 61 | classDeclaration 62 | : modifierList? (CLASS | INTERFACE) NL* simpleIdentifier 63 | (NL* typeParameters)? (NL* primaryConstructor)? 64 | (NL* COLON NL* delegationSpecifiers)? 65 | (NL* typeConstraints)? 66 | (NL* classBody | NL* enumClassBody)? 67 | ; 68 | 69 | primaryConstructor 70 | : modifierList? (CONSTRUCTOR NL*)? classParameters 71 | ; 72 | 73 | classParameters 74 | : LPAREN (classParameter (COMMA classParameter)*)? RPAREN 75 | ; 76 | 77 | classParameter 78 | : modifierList? (VAL | VAR)? simpleIdentifier COLON type (ASSIGNMENT expression)? 79 | ; 80 | 81 | delegationSpecifiers 82 | : annotations* delegationSpecifier (NL* COMMA NL* delegationSpecifier)* 83 | ; 84 | 85 | delegationSpecifier 86 | : constructorInvocation 87 | | userType 88 | | explicitDelegation 89 | ; 90 | 91 | constructorInvocation 92 | : userType callSuffix 93 | ; 94 | 95 | explicitDelegation 96 | : userType NL* BY NL* expression 97 | ; 98 | 99 | classBody 100 | : LCURL NL* classMemberDeclaration* NL* RCURL 101 | ; 102 | 103 | classMemberDeclaration 104 | : (classDeclaration 105 | | functionDeclaration 106 | | objectDeclaration 107 | | companionObject 108 | | propertyDeclaration 109 | | anonymousInitializer 110 | | secondaryConstructor 111 | | typeAlias) anysemi* 112 | ; 113 | 114 | anonymousInitializer 115 | : INIT NL* block 116 | ; 117 | 118 | secondaryConstructor 119 | : modifierList? CONSTRUCTOR NL* functionValueParameters (NL* COLON NL* constructorDelegationCall)? NL* block 120 | ; 121 | 122 | constructorDelegationCall 123 | : THIS NL* valueArguments 124 | | SUPER NL* valueArguments 125 | ; 126 | 127 | enumClassBody 128 | : LCURL NL* enumEntries? (NL* SEMICOLON NL* classMemberDeclaration*)? NL* RCURL 129 | ; 130 | 131 | enumEntries 132 | : (enumEntry NL*)+ SEMICOLON? 133 | ; 134 | 135 | enumEntry 136 | : simpleIdentifier (NL* valueArguments)? (NL* classBody)? (NL* COMMA)? 137 | ; 138 | 139 | functionDeclaration 140 | : modifierList? FUN 141 | (NL* type NL* DOT)? 142 | (NL* typeParameters)? 143 | (NL* identifier)? 144 | NL* functionValueParameters 145 | (NL* COLON NL* type)? 146 | (NL* typeConstraints)? 147 | (NL* functionBody)? 148 | ; 149 | 150 | functionValueParameters 151 | : LPAREN (functionValueParameter (COMMA functionValueParameter)*)? RPAREN 152 | ; 153 | 154 | functionValueParameter 155 | : modifierList? parameter (ASSIGNMENT expression)? 156 | ; 157 | 158 | parameter 159 | : simpleIdentifier COLON type 160 | ; 161 | 162 | functionBody 163 | : block 164 | | ASSIGNMENT NL* expression 165 | ; 166 | 167 | objectDeclaration 168 | : modifierList? OBJECT 169 | NL* simpleIdentifier 170 | (NL* primaryConstructor)? 171 | (NL* COLON NL* delegationSpecifiers)? 172 | (NL* classBody)? 173 | ; 174 | 175 | companionObject 176 | : modifierList? COMPANION NL* modifierList? OBJECT 177 | (NL* simpleIdentifier)? 178 | (NL* COLON NL* delegationSpecifiers)? 179 | (NL* classBody)? 180 | ; 181 | 182 | propertyDeclaration 183 | : modifierList? (VAL | VAR) 184 | (NL* typeParameters)? 185 | (NL* type NL* DOT)? 186 | (NL* (multiVariableDeclaration | variableDeclaration)) 187 | (NL* typeConstraints)? 188 | (NL* (BY | ASSIGNMENT) NL* expression)? 189 | (getter (semi setter)? | setter (semi getter)?)? 190 | ; 191 | 192 | multiVariableDeclaration 193 | : LPAREN variableDeclaration (COMMA variableDeclaration)* RPAREN 194 | ; 195 | 196 | variableDeclaration 197 | : simpleIdentifier (COLON type)? 198 | ; 199 | 200 | getter 201 | : modifierList? GETTER 202 | | modifierList? GETTER NL* LPAREN RPAREN (NL* COLON NL* type)? NL* (block | ASSIGNMENT NL* expression) 203 | ; 204 | 205 | setter 206 | : modifierList? SETTER 207 | | modifierList? SETTER NL* LPAREN (annotations | parameterModifier)* (simpleIdentifier | parameter) RPAREN NL* functionBody 208 | ; 209 | 210 | typeAlias 211 | : modifierList? TYPE_ALIAS NL* simpleIdentifier (NL* typeParameters)? NL* ASSIGNMENT NL* type 212 | ; 213 | 214 | typeParameters 215 | : LANGLE NL* typeParameter (NL* COMMA NL* typeParameter)* NL* RANGLE 216 | ; 217 | 218 | typeParameter 219 | : modifierList? NL* simpleIdentifier (NL* COLON NL* type)? 220 | ; 221 | 222 | type 223 | : typeModifierList? 224 | ( functionType 225 | | parenthesizedType 226 | | nullableType 227 | | typeReference) 228 | ; 229 | 230 | typeModifierList 231 | : (annotations | SUSPEND NL*)+ 232 | ; 233 | 234 | parenthesizedType 235 | : LPAREN type RPAREN 236 | ; 237 | 238 | nullableType 239 | : (typeReference | parenthesizedType) NL* QUEST+ 240 | ; 241 | 242 | typeReference 243 | : LPAREN typeReference RPAREN 244 | | userType 245 | | DYNAMIC 246 | ; 247 | 248 | functionType 249 | : (functionTypeReceiver NL* DOT NL*)? functionTypeParameters NL* ARROW (NL* type) 250 | ; 251 | 252 | functionTypeReceiver 253 | : parenthesizedType 254 | | nullableType 255 | | typeReference 256 | ; 257 | 258 | userType 259 | : simpleUserType (NL* DOT NL* simpleUserType)* 260 | ; 261 | 262 | simpleUserType 263 | : simpleIdentifier (NL* typeArguments)? 264 | ; 265 | 266 | //parameters for functionType 267 | functionTypeParameters 268 | : LPAREN (parameter | type)? (COMMA (parameter | type))* RPAREN 269 | ; 270 | 271 | typeConstraints 272 | : WHERE NL* typeConstraint (NL* COMMA NL* typeConstraint)* 273 | ; 274 | 275 | typeConstraint 276 | : annotations* simpleIdentifier NL* COLON NL* type 277 | ; 278 | 279 | block 280 | : LCURL statements RCURL 281 | ; 282 | 283 | statements 284 | : anysemi* (statement (anysemi+ statement?)*)? 285 | ; 286 | 287 | statement 288 | : declaration 289 | | blockLevelExpression 290 | ; 291 | 292 | blockLevelExpression 293 | : annotations* NL* expression 294 | ; 295 | 296 | declaration 297 | : labelDefinition* 298 | ( classDeclaration 299 | | functionDeclaration 300 | | propertyDeclaration 301 | | typeAlias) 302 | ; 303 | 304 | expression 305 | : disjunction (assignmentOperator disjunction)* 306 | ; 307 | 308 | disjunction 309 | : conjunction (NL* DISJ NL* conjunction)* 310 | ; 311 | 312 | conjunction 313 | : equalityComparison (NL* CONJ NL* equalityComparison)* 314 | ; 315 | 316 | equalityComparison 317 | : comparison (equalityOperation NL* comparison)* 318 | ; 319 | 320 | comparison 321 | : namedInfix (comparisonOperator NL* namedInfix)? 322 | ; 323 | 324 | namedInfix 325 | : elvisExpression ((inOperator NL* elvisExpression)+ | (isOperator NL* type))? 326 | ; 327 | 328 | elvisExpression 329 | : infixFunctionCall (NL* ELVIS NL* infixFunctionCall)* 330 | ; 331 | 332 | infixFunctionCall 333 | : rangeExpression (simpleIdentifier NL* rangeExpression)* 334 | ; 335 | 336 | rangeExpression 337 | : additiveExpression (RANGE NL* additiveExpression)* 338 | ; 339 | 340 | additiveExpression 341 | : multiplicativeExpression (additiveOperator NL* multiplicativeExpression)* 342 | ; 343 | 344 | multiplicativeExpression 345 | : typeRHS (multiplicativeOperation NL* typeRHS)* 346 | ; 347 | 348 | typeRHS 349 | : prefixUnaryExpression (NL* typeOperation prefixUnaryExpression)* 350 | ; 351 | 352 | prefixUnaryExpression 353 | : prefixUnaryOperation* postfixUnaryExpression 354 | ; 355 | 356 | postfixUnaryExpression 357 | : (variableRead | atomicExpression) postfixUnaryOperation* 358 | | (simpleIdentifier | callableReference | atomicExpression) (postfixUnaryOperation | callSuffix)* 359 | ; 360 | 361 | variableRead: simpleIdentifier; 362 | 363 | atomicExpression 364 | : parenthesizedExpression 365 | | literalConstant 366 | | functionLiteral 367 | | thisExpression // THIS labelReference? 368 | | superExpression // SUPER (LANGLE type RANGLE)? labelReference? 369 | | conditionalExpression // ifExpression, whenExpression 370 | | tryExpression 371 | | objectLiteral 372 | | jumpExpression 373 | | loopExpression 374 | | collectionLiteral 375 | ; 376 | 377 | parenthesizedExpression 378 | : LPAREN expression RPAREN 379 | ; 380 | 381 | callSuffix 382 | : typeArguments valueArguments? annotatedLambda* 383 | | valueArguments annotatedLambda* 384 | | annotatedLambda+ 385 | ; 386 | 387 | annotatedLambda 388 | : unescapedAnnotation* LabelDefinition? NL* functionLiteral 389 | ; 390 | 391 | arrayAccess 392 | : LSQUARE (expression (COMMA expression)*)? RSQUARE 393 | ; 394 | 395 | valueArguments 396 | : LPAREN (suggestArgument valueArgument (COMMA suggestArgument valueArgument)*)? RPAREN 397 | ; 398 | 399 | suggestArgument: /* Placeholder for code completion */; 400 | 401 | typeArguments 402 | : LANGLE NL* typeProjection (NL* COMMA typeProjection)* NL* RANGLE 403 | ; 404 | 405 | typeProjection 406 | : typeProjectionModifierList? type | MULT 407 | ; 408 | 409 | typeProjectionModifierList 410 | : varianceAnnotation+ 411 | ; 412 | 413 | valueArgument 414 | : (simpleIdentifier NL* ASSIGNMENT NL*)? MULT? NL* expression 415 | ; 416 | 417 | literalConstant 418 | : BooleanLiteral 419 | | IntegerLiteral 420 | | stringLiteral 421 | | HexLiteral 422 | | BinLiteral 423 | | CharacterLiteral 424 | | RealLiteral 425 | | NullLiteral 426 | | LongLiteral 427 | ; 428 | 429 | stringLiteral 430 | : lineStringLiteral 431 | | multiLineStringLiteral 432 | ; 433 | 434 | lineStringLiteral 435 | : QUOTE_OPEN (lineStringContent | lineStringExpression)* QUOTE_CLOSE 436 | ; 437 | 438 | multiLineStringLiteral 439 | : TRIPLE_QUOTE_OPEN (multiLineStringContent | multiLineStringExpression | lineStringLiteral | MultiLineStringQuote)* TRIPLE_QUOTE_CLOSE 440 | ; 441 | 442 | lineStringContent 443 | : LineStrText 444 | | LineStrEscapedChar 445 | | LineStrRef 446 | ; 447 | 448 | lineStringExpression 449 | : LineStrExprStart expression RCURL 450 | ; 451 | 452 | multiLineStringContent 453 | : MultiLineStrText 454 | | MultiLineStrEscapedChar 455 | | MultiLineStrRef 456 | ; 457 | 458 | multiLineStringExpression 459 | : MultiLineStrExprStart expression RCURL 460 | ; 461 | 462 | functionLiteral 463 | : annotations* 464 | ( LCURL NL* statements NL* RCURL 465 | | LCURL NL* lambdaParameters NL* ARROW NL* statements NL* RCURL ) 466 | ; 467 | 468 | lambdaParameters 469 | : lambdaParameter? (NL* COMMA NL* lambdaParameter)* 470 | ; 471 | 472 | lambdaParameter 473 | : variableDeclaration 474 | | multiVariableDeclaration (NL* COLON NL* type)? 475 | ; 476 | 477 | objectLiteral 478 | : OBJECT (NL* COLON NL* delegationSpecifiers)? NL* classBody 479 | ; 480 | 481 | collectionLiteral 482 | : LSQUARE expression? (COMMA expression)* RSQUARE 483 | ; 484 | 485 | thisExpression 486 | : THIS LabelReference? 487 | ; 488 | 489 | superExpression 490 | : SUPER (LANGLE NL* type NL* RANGLE)? LabelReference? 491 | ; 492 | 493 | conditionalExpression 494 | : ifExpression 495 | | whenExpression 496 | ; 497 | 498 | ifExpression 499 | : IF NL* LPAREN expression RPAREN NL* controlStructureBody? SEMICOLON? 500 | (NL* ELSE NL* controlStructureBody?)? 501 | ; 502 | 503 | controlStructureBody 504 | : block 505 | | expression 506 | ; 507 | 508 | whenExpression 509 | : WHEN NL* (LPAREN expression RPAREN)? NL* LCURL NL* (whenEntry NL*)* NL* RCURL 510 | ; 511 | 512 | whenEntry 513 | : whenCondition (NL* COMMA NL* whenCondition)* NL* ARROW NL* controlStructureBody semi? 514 | | ELSE NL* ARROW NL* controlStructureBody 515 | ; 516 | 517 | whenCondition 518 | : expression 519 | | rangeTest 520 | | typeTest 521 | ; 522 | 523 | rangeTest 524 | : inOperator NL* expression 525 | ; 526 | 527 | typeTest 528 | : isOperator NL* type 529 | ; 530 | 531 | tryExpression 532 | : TRY NL* block (NL* catchBlock)* (NL* finallyBlock)? 533 | ; 534 | 535 | catchBlock 536 | : CATCH NL* LPAREN annotations* simpleIdentifier COLON userType RPAREN NL* block 537 | ; 538 | 539 | finallyBlock 540 | : FINALLY NL* block 541 | ; 542 | 543 | loopExpression 544 | : forExpression 545 | | whileExpression 546 | | doWhileExpression 547 | ; 548 | 549 | forExpression 550 | : FOR NL* LPAREN annotations* (variableDeclaration | multiVariableDeclaration) IN expression RPAREN NL* controlStructureBody? 551 | ; 552 | 553 | whileExpression 554 | : WHILE NL* LPAREN expression RPAREN NL* controlStructureBody? 555 | ; 556 | 557 | doWhileExpression 558 | : DO NL* controlStructureBody? NL* WHILE NL* LPAREN expression RPAREN 559 | ; 560 | 561 | jumpExpression 562 | : THROW NL* expression 563 | | (RETURN | RETURN_AT) expression? 564 | | CONTINUE | CONTINUE_AT 565 | | BREAK | BREAK_AT 566 | ; 567 | 568 | callableReference 569 | : (userType (QUEST NL*)*)? NL* (COLONCOLON | Q_COLONCOLON) NL* (identifier | CLASS) 570 | ; 571 | 572 | assignmentOperator 573 | : ASSIGNMENT 574 | | ADD_ASSIGNMENT 575 | | SUB_ASSIGNMENT 576 | | MULT_ASSIGNMENT 577 | | DIV_ASSIGNMENT 578 | | MOD_ASSIGNMENT 579 | ; 580 | 581 | equalityOperation 582 | : EXCL_EQ 583 | | EXCL_EQEQ 584 | | EQEQ 585 | | EQEQEQ 586 | ; 587 | 588 | comparisonOperator 589 | : LANGLE 590 | | RANGLE 591 | | LE 592 | | GE 593 | ; 594 | 595 | inOperator 596 | : IN | NOT_IN 597 | ; 598 | 599 | isOperator 600 | : IS | NOT_IS 601 | ; 602 | 603 | additiveOperator 604 | : ADD | SUB 605 | ; 606 | 607 | multiplicativeOperation 608 | : MULT 609 | | DIV 610 | | MOD 611 | ; 612 | 613 | typeOperation 614 | : AS 615 | | AS_SAFE 616 | | COLON 617 | ; 618 | 619 | prefixUnaryOperation 620 | : INCR 621 | | DECR 622 | | ADD 623 | | SUB 624 | | EXCL 625 | | annotations 626 | | labelDefinition 627 | ; 628 | 629 | postfixUnaryOperation 630 | : INCR | DECR | EXCL EXCL 631 | | arrayAccess 632 | | NL* memberAccessOperator postfixUnaryExpression 633 | ; 634 | 635 | memberAccessOperator 636 | : DOT | QUEST DOT 637 | ; 638 | 639 | modifierList 640 | : (annotations | modifier)+ 641 | ; 642 | 643 | modifier 644 | : (classModifier 645 | | memberModifier 646 | | visibilityModifier 647 | | varianceAnnotation 648 | | functionModifier 649 | | propertyModifier 650 | | inheritanceModifier 651 | | parameterModifier 652 | | typeParameterModifier) NL* 653 | ; 654 | 655 | classModifier 656 | : ENUM 657 | | SEALED 658 | | ANNOTATION 659 | | DATA 660 | | INNER 661 | ; 662 | 663 | memberModifier 664 | : OVERRIDE 665 | | LATEINIT 666 | ; 667 | 668 | visibilityModifier 669 | : PUBLIC 670 | | PRIVATE 671 | | INTERNAL 672 | | PROTECTED 673 | ; 674 | 675 | varianceAnnotation 676 | : IN | OUT 677 | ; 678 | 679 | functionModifier 680 | : TAILREC 681 | | OPERATOR 682 | | INFIX 683 | | INLINE 684 | | EXTERNAL 685 | | SUSPEND 686 | ; 687 | 688 | propertyModifier 689 | : CONST 690 | ; 691 | 692 | inheritanceModifier 693 | : ABSTRACT 694 | | FINAL 695 | | OPEN 696 | ; 697 | 698 | parameterModifier 699 | : VARARG 700 | | NOINLINE 701 | | CROSSINLINE 702 | ; 703 | 704 | typeParameterModifier 705 | : REIFIED 706 | ; 707 | 708 | labelDefinition 709 | : LabelDefinition NL* 710 | ; 711 | 712 | annotations 713 | : (annotation | annotationList) NL* 714 | ; 715 | 716 | annotation 717 | : annotationUseSiteTarget NL* COLON NL* unescapedAnnotation 718 | | LabelReference (NL* typeArguments)? (NL* valueArguments)? 719 | ; 720 | 721 | annotationList 722 | : annotationUseSiteTarget COLON LSQUARE unescapedAnnotation+ RSQUARE 723 | | AT LSQUARE unescapedAnnotation+ RSQUARE 724 | ; 725 | 726 | annotationUseSiteTarget 727 | : FIELD 728 | | FILE 729 | | PROPERTY 730 | | GET 731 | | SET 732 | | RECEIVER 733 | | PARAM 734 | | SETPARAM 735 | | DELEGATE 736 | ; 737 | 738 | unescapedAnnotation 739 | : identifier typeArguments? valueArguments? 740 | ; 741 | 742 | identifier 743 | : simpleIdentifier (NL* DOT simpleIdentifier)* 744 | ; 745 | 746 | simpleIdentifier 747 | : Identifier 748 | //soft keywords: 749 | | ABSTRACT 750 | | ANNOTATION 751 | | BY 752 | | CATCH 753 | | COMPANION 754 | | CONSTRUCTOR 755 | | CROSSINLINE 756 | | DATA 757 | | DYNAMIC 758 | | ENUM 759 | | EXTERNAL 760 | | FINAL 761 | | FINALLY 762 | | GETTER 763 | | IMPORT 764 | | INFIX 765 | | INIT 766 | | INLINE 767 | | INNER 768 | | INTERNAL 769 | | LATEINIT 770 | | NOINLINE 771 | | OPEN 772 | | OPERATOR 773 | | OUT 774 | | OVERRIDE 775 | | PRIVATE 776 | | PROTECTED 777 | | PUBLIC 778 | | REIFIED 779 | | SEALED 780 | | TAILREC 781 | | SETTER 782 | | VARARG 783 | | WHERE 784 | //strong keywords 785 | | CONST 786 | | SUSPEND 787 | ; 788 | 789 | semi: NL+ | NL* SEMICOLON NL*; 790 | 791 | anysemi: NL | SEMICOLON; 792 | -------------------------------------------------------------------------------- /grammar/UnicodeClasses.g4: -------------------------------------------------------------------------------- 1 | /** 2 | * Taken from http://www.antlr3.org/grammar/1345144569663/AntlrUnicode.txt 3 | */ 4 | 5 | lexer grammar UnicodeClasses; 6 | 7 | UNICODE_CLASS_LL: 8 | '\u0061'..'\u007A' | 9 | '\u00B5' | 10 | '\u00DF'..'\u00F6' | 11 | '\u00F8'..'\u00FF' | 12 | '\u0101' | 13 | '\u0103' | 14 | '\u0105' | 15 | '\u0107' | 16 | '\u0109' | 17 | '\u010B' | 18 | '\u010D' | 19 | '\u010F' | 20 | '\u0111' | 21 | '\u0113' | 22 | '\u0115' | 23 | '\u0117' | 24 | '\u0119' | 25 | '\u011B' | 26 | '\u011D' | 27 | '\u011F' | 28 | '\u0121' | 29 | '\u0123' | 30 | '\u0125' | 31 | '\u0127' | 32 | '\u0129' | 33 | '\u012B' | 34 | '\u012D' | 35 | '\u012F' | 36 | '\u0131' | 37 | '\u0133' | 38 | '\u0135' | 39 | '\u0137' | 40 | '\u0138' | 41 | '\u013A' | 42 | '\u013C' | 43 | '\u013E' | 44 | '\u0140' | 45 | '\u0142' | 46 | '\u0144' | 47 | '\u0146' | 48 | '\u0148' | 49 | '\u0149' | 50 | '\u014B' | 51 | '\u014D' | 52 | '\u014F' | 53 | '\u0151' | 54 | '\u0153' | 55 | '\u0155' | 56 | '\u0157' | 57 | '\u0159' | 58 | '\u015B' | 59 | '\u015D' | 60 | '\u015F' | 61 | '\u0161' | 62 | '\u0163' | 63 | '\u0165' | 64 | '\u0167' | 65 | '\u0169' | 66 | '\u016B' | 67 | '\u016D' | 68 | '\u016F' | 69 | '\u0171' | 70 | '\u0173' | 71 | '\u0175' | 72 | '\u0177' | 73 | '\u017A' | 74 | '\u017C' | 75 | '\u017E'..'\u0180' | 76 | '\u0183' | 77 | '\u0185' | 78 | '\u0188' | 79 | '\u018C' | 80 | '\u018D' | 81 | '\u0192' | 82 | '\u0195' | 83 | '\u0199'..'\u019B' | 84 | '\u019E' | 85 | '\u01A1' | 86 | '\u01A3' | 87 | '\u01A5' | 88 | '\u01A8' | 89 | '\u01AA' | 90 | '\u01AB' | 91 | '\u01AD' | 92 | '\u01B0' | 93 | '\u01B4' | 94 | '\u01B6' | 95 | '\u01B9' | 96 | '\u01BA' | 97 | '\u01BD'..'\u01BF' | 98 | '\u01C6' | 99 | '\u01C9' | 100 | '\u01CC' | 101 | '\u01CE' | 102 | '\u01D0' | 103 | '\u01D2' | 104 | '\u01D4' | 105 | '\u01D6' | 106 | '\u01D8' | 107 | '\u01DA' | 108 | '\u01DC' | 109 | '\u01DD' | 110 | '\u01DF' | 111 | '\u01E1' | 112 | '\u01E3' | 113 | '\u01E5' | 114 | '\u01E7' | 115 | '\u01E9' | 116 | '\u01EB' | 117 | '\u01ED' | 118 | '\u01EF' | 119 | '\u01F0' | 120 | '\u01F3' | 121 | '\u01F5' | 122 | '\u01F9' | 123 | '\u01FB' | 124 | '\u01FD' | 125 | '\u01FF' | 126 | '\u0201' | 127 | '\u0203' | 128 | '\u0205' | 129 | '\u0207' | 130 | '\u0209' | 131 | '\u020B' | 132 | '\u020D' | 133 | '\u020F' | 134 | '\u0211' | 135 | '\u0213' | 136 | '\u0215' | 137 | '\u0217' | 138 | '\u0219' | 139 | '\u021B' | 140 | '\u021D' | 141 | '\u021F' | 142 | '\u0221' | 143 | '\u0223' | 144 | '\u0225' | 145 | '\u0227' | 146 | '\u0229' | 147 | '\u022B' | 148 | '\u022D' | 149 | '\u022F' | 150 | '\u0231' | 151 | '\u0233'..'\u0239' | 152 | '\u023C' | 153 | '\u023F' | 154 | '\u0240' | 155 | '\u0242' | 156 | '\u0247' | 157 | '\u0249' | 158 | '\u024B' | 159 | '\u024D' | 160 | '\u024F'..'\u0293' | 161 | '\u0295'..'\u02AF' | 162 | '\u0371' | 163 | '\u0373' | 164 | '\u0377' | 165 | '\u037B'..'\u037D' | 166 | '\u0390' | 167 | '\u03AC'..'\u03CE' | 168 | '\u03D0' | 169 | '\u03D1' | 170 | '\u03D5'..'\u03D7' | 171 | '\u03D9' | 172 | '\u03DB' | 173 | '\u03DD' | 174 | '\u03DF' | 175 | '\u03E1' | 176 | '\u03E3' | 177 | '\u03E5' | 178 | '\u03E7' | 179 | '\u03E9' | 180 | '\u03EB' | 181 | '\u03ED' | 182 | '\u03EF'..'\u03F3' | 183 | '\u03F5' | 184 | '\u03F8' | 185 | '\u03FB' | 186 | '\u03FC' | 187 | '\u0430'..'\u045F' | 188 | '\u0461' | 189 | '\u0463' | 190 | '\u0465' | 191 | '\u0467' | 192 | '\u0469' | 193 | '\u046B' | 194 | '\u046D' | 195 | '\u046F' | 196 | '\u0471' | 197 | '\u0473' | 198 | '\u0475' | 199 | '\u0477' | 200 | '\u0479' | 201 | '\u047B' | 202 | '\u047D' | 203 | '\u047F' | 204 | '\u0481' | 205 | '\u048B' | 206 | '\u048D' | 207 | '\u048F' | 208 | '\u0491' | 209 | '\u0493' | 210 | '\u0495' | 211 | '\u0497' | 212 | '\u0499' | 213 | '\u049B' | 214 | '\u049D' | 215 | '\u049F' | 216 | '\u04A1' | 217 | '\u04A3' | 218 | '\u04A5' | 219 | '\u04A7' | 220 | '\u04A9' | 221 | '\u04AB' | 222 | '\u04AD' | 223 | '\u04AF' | 224 | '\u04B1' | 225 | '\u04B3' | 226 | '\u04B5' | 227 | '\u04B7' | 228 | '\u04B9' | 229 | '\u04BB' | 230 | '\u04BD' | 231 | '\u04BF' | 232 | '\u04C2' | 233 | '\u04C4' | 234 | '\u04C6' | 235 | '\u04C8' | 236 | '\u04CA' | 237 | '\u04CC' | 238 | '\u04CE' | 239 | '\u04CF' | 240 | '\u04D1' | 241 | '\u04D3' | 242 | '\u04D5' | 243 | '\u04D7' | 244 | '\u04D9' | 245 | '\u04DB' | 246 | '\u04DD' | 247 | '\u04DF' | 248 | '\u04E1' | 249 | '\u04E3' | 250 | '\u04E5' | 251 | '\u04E7' | 252 | '\u04E9' | 253 | '\u04EB' | 254 | '\u04ED' | 255 | '\u04EF' | 256 | '\u04F1' | 257 | '\u04F3' | 258 | '\u04F5' | 259 | '\u04F7' | 260 | '\u04F9' | 261 | '\u04FB' | 262 | '\u04FD' | 263 | '\u04FF' | 264 | '\u0501' | 265 | '\u0503' | 266 | '\u0505' | 267 | '\u0507' | 268 | '\u0509' | 269 | '\u050B' | 270 | '\u050D' | 271 | '\u050F' | 272 | '\u0511' | 273 | '\u0513' | 274 | '\u0515' | 275 | '\u0517' | 276 | '\u0519' | 277 | '\u051B' | 278 | '\u051D' | 279 | '\u051F' | 280 | '\u0521' | 281 | '\u0523' | 282 | '\u0525' | 283 | '\u0527' | 284 | '\u0561'..'\u0587' | 285 | '\u1D00'..'\u1D2B' | 286 | '\u1D6B'..'\u1D77' | 287 | '\u1D79'..'\u1D9A' | 288 | '\u1E01' | 289 | '\u1E03' | 290 | '\u1E05' | 291 | '\u1E07' | 292 | '\u1E09' | 293 | '\u1E0B' | 294 | '\u1E0D' | 295 | '\u1E0F' | 296 | '\u1E11' | 297 | '\u1E13' | 298 | '\u1E15' | 299 | '\u1E17' | 300 | '\u1E19' | 301 | '\u1E1B' | 302 | '\u1E1D' | 303 | '\u1E1F' | 304 | '\u1E21' | 305 | '\u1E23' | 306 | '\u1E25' | 307 | '\u1E27' | 308 | '\u1E29' | 309 | '\u1E2B' | 310 | '\u1E2D' | 311 | '\u1E2F' | 312 | '\u1E31' | 313 | '\u1E33' | 314 | '\u1E35' | 315 | '\u1E37' | 316 | '\u1E39' | 317 | '\u1E3B' | 318 | '\u1E3D' | 319 | '\u1E3F' | 320 | '\u1E41' | 321 | '\u1E43' | 322 | '\u1E45' | 323 | '\u1E47' | 324 | '\u1E49' | 325 | '\u1E4B' | 326 | '\u1E4D' | 327 | '\u1E4F' | 328 | '\u1E51' | 329 | '\u1E53' | 330 | '\u1E55' | 331 | '\u1E57' | 332 | '\u1E59' | 333 | '\u1E5B' | 334 | '\u1E5D' | 335 | '\u1E5F' | 336 | '\u1E61' | 337 | '\u1E63' | 338 | '\u1E65' | 339 | '\u1E67' | 340 | '\u1E69' | 341 | '\u1E6B' | 342 | '\u1E6D' | 343 | '\u1E6F' | 344 | '\u1E71' | 345 | '\u1E73' | 346 | '\u1E75' | 347 | '\u1E77' | 348 | '\u1E79' | 349 | '\u1E7B' | 350 | '\u1E7D' | 351 | '\u1E7F' | 352 | '\u1E81' | 353 | '\u1E83' | 354 | '\u1E85' | 355 | '\u1E87' | 356 | '\u1E89' | 357 | '\u1E8B' | 358 | '\u1E8D' | 359 | '\u1E8F' | 360 | '\u1E91' | 361 | '\u1E93' | 362 | '\u1E95'..'\u1E9D' | 363 | '\u1E9F' | 364 | '\u1EA1' | 365 | '\u1EA3' | 366 | '\u1EA5' | 367 | '\u1EA7' | 368 | '\u1EA9' | 369 | '\u1EAB' | 370 | '\u1EAD' | 371 | '\u1EAF' | 372 | '\u1EB1' | 373 | '\u1EB3' | 374 | '\u1EB5' | 375 | '\u1EB7' | 376 | '\u1EB9' | 377 | '\u1EBB' | 378 | '\u1EBD' | 379 | '\u1EBF' | 380 | '\u1EC1' | 381 | '\u1EC3' | 382 | '\u1EC5' | 383 | '\u1EC7' | 384 | '\u1EC9' | 385 | '\u1ECB' | 386 | '\u1ECD' | 387 | '\u1ECF' | 388 | '\u1ED1' | 389 | '\u1ED3' | 390 | '\u1ED5' | 391 | '\u1ED7' | 392 | '\u1ED9' | 393 | '\u1EDB' | 394 | '\u1EDD' | 395 | '\u1EDF' | 396 | '\u1EE1' | 397 | '\u1EE3' | 398 | '\u1EE5' | 399 | '\u1EE7' | 400 | '\u1EE9' | 401 | '\u1EEB' | 402 | '\u1EED' | 403 | '\u1EEF' | 404 | '\u1EF1' | 405 | '\u1EF3' | 406 | '\u1EF5' | 407 | '\u1EF7' | 408 | '\u1EF9' | 409 | '\u1EFB' | 410 | '\u1EFD' | 411 | '\u1EFF'..'\u1F07' | 412 | '\u1F10'..'\u1F15' | 413 | '\u1F20'..'\u1F27' | 414 | '\u1F30'..'\u1F37' | 415 | '\u1F40'..'\u1F45' | 416 | '\u1F50'..'\u1F57' | 417 | '\u1F60'..'\u1F67' | 418 | '\u1F70'..'\u1F7D' | 419 | '\u1F80'..'\u1F87' | 420 | '\u1F90'..'\u1F97' | 421 | '\u1FA0'..'\u1FA7' | 422 | '\u1FB0'..'\u1FB4' | 423 | '\u1FB6' | 424 | '\u1FB7' | 425 | '\u1FBE' | 426 | '\u1FC2'..'\u1FC4' | 427 | '\u1FC6' | 428 | '\u1FC7' | 429 | '\u1FD0'..'\u1FD3' | 430 | '\u1FD6' | 431 | '\u1FD7' | 432 | '\u1FE0'..'\u1FE7' | 433 | '\u1FF2'..'\u1FF4' | 434 | '\u1FF6' | 435 | '\u1FF7' | 436 | '\u210A' | 437 | '\u210E' | 438 | '\u210F' | 439 | '\u2113' | 440 | '\u212F' | 441 | '\u2134' | 442 | '\u2139' | 443 | '\u213C' | 444 | '\u213D' | 445 | '\u2146'..'\u2149' | 446 | '\u214E' | 447 | '\u2184' | 448 | '\u2C30'..'\u2C5E' | 449 | '\u2C61' | 450 | '\u2C65' | 451 | '\u2C66' | 452 | '\u2C68' | 453 | '\u2C6A' | 454 | '\u2C6C' | 455 | '\u2C71' | 456 | '\u2C73' | 457 | '\u2C74' | 458 | '\u2C76'..'\u2C7B' | 459 | '\u2C81' | 460 | '\u2C83' | 461 | '\u2C85' | 462 | '\u2C87' | 463 | '\u2C89' | 464 | '\u2C8B' | 465 | '\u2C8D' | 466 | '\u2C8F' | 467 | '\u2C91' | 468 | '\u2C93' | 469 | '\u2C95' | 470 | '\u2C97' | 471 | '\u2C99' | 472 | '\u2C9B' | 473 | '\u2C9D' | 474 | '\u2C9F' | 475 | '\u2CA1' | 476 | '\u2CA3' | 477 | '\u2CA5' | 478 | '\u2CA7' | 479 | '\u2CA9' | 480 | '\u2CAB' | 481 | '\u2CAD' | 482 | '\u2CAF' | 483 | '\u2CB1' | 484 | '\u2CB3' | 485 | '\u2CB5' | 486 | '\u2CB7' | 487 | '\u2CB9' | 488 | '\u2CBB' | 489 | '\u2CBD' | 490 | '\u2CBF' | 491 | '\u2CC1' | 492 | '\u2CC3' | 493 | '\u2CC5' | 494 | '\u2CC7' | 495 | '\u2CC9' | 496 | '\u2CCB' | 497 | '\u2CCD' | 498 | '\u2CCF' | 499 | '\u2CD1' | 500 | '\u2CD3' | 501 | '\u2CD5' | 502 | '\u2CD7' | 503 | '\u2CD9' | 504 | '\u2CDB' | 505 | '\u2CDD' | 506 | '\u2CDF' | 507 | '\u2CE1' | 508 | '\u2CE3' | 509 | '\u2CE4' | 510 | '\u2CEC' | 511 | '\u2CEE' | 512 | '\u2CF3' | 513 | '\u2D00'..'\u2D25' | 514 | '\u2D27' | 515 | '\u2D2D' | 516 | '\uA641' | 517 | '\uA643' | 518 | '\uA645' | 519 | '\uA647' | 520 | '\uA649' | 521 | '\uA64B' | 522 | '\uA64D' | 523 | '\uA64F' | 524 | '\uA651' | 525 | '\uA653' | 526 | '\uA655' | 527 | '\uA657' | 528 | '\uA659' | 529 | '\uA65B' | 530 | '\uA65D' | 531 | '\uA65F' | 532 | '\uA661' | 533 | '\uA663' | 534 | '\uA665' | 535 | '\uA667' | 536 | '\uA669' | 537 | '\uA66B' | 538 | '\uA66D' | 539 | '\uA681' | 540 | '\uA683' | 541 | '\uA685' | 542 | '\uA687' | 543 | '\uA689' | 544 | '\uA68B' | 545 | '\uA68D' | 546 | '\uA68F' | 547 | '\uA691' | 548 | '\uA693' | 549 | '\uA695' | 550 | '\uA697' | 551 | '\uA723' | 552 | '\uA725' | 553 | '\uA727' | 554 | '\uA729' | 555 | '\uA72B' | 556 | '\uA72D' | 557 | '\uA72F'..'\uA731' | 558 | '\uA733' | 559 | '\uA735' | 560 | '\uA737' | 561 | '\uA739' | 562 | '\uA73B' | 563 | '\uA73D' | 564 | '\uA73F' | 565 | '\uA741' | 566 | '\uA743' | 567 | '\uA745' | 568 | '\uA747' | 569 | '\uA749' | 570 | '\uA74B' | 571 | '\uA74D' | 572 | '\uA74F' | 573 | '\uA751' | 574 | '\uA753' | 575 | '\uA755' | 576 | '\uA757' | 577 | '\uA759' | 578 | '\uA75B' | 579 | '\uA75D' | 580 | '\uA75F' | 581 | '\uA761' | 582 | '\uA763' | 583 | '\uA765' | 584 | '\uA767' | 585 | '\uA769' | 586 | '\uA76B' | 587 | '\uA76D' | 588 | '\uA76F' | 589 | '\uA771'..'\uA778' | 590 | '\uA77A' | 591 | '\uA77C' | 592 | '\uA77F' | 593 | '\uA781' | 594 | '\uA783' | 595 | '\uA785' | 596 | '\uA787' | 597 | '\uA78C' | 598 | '\uA78E' | 599 | '\uA791' | 600 | '\uA793' | 601 | '\uA7A1' | 602 | '\uA7A3' | 603 | '\uA7A5' | 604 | '\uA7A7' | 605 | '\uA7A9' | 606 | '\uA7FA' | 607 | '\uFB00'..'\uFB06' | 608 | '\uFB13'..'\uFB17' | 609 | '\uFF41'..'\uFF5A'; 610 | 611 | UNICODE_CLASS_LM: 612 | '\u02B0'..'\u02C1' | 613 | '\u02C6'..'\u02D1' | 614 | '\u02E0'..'\u02E4' | 615 | '\u02EC' | 616 | '\u02EE' | 617 | '\u0374' | 618 | '\u037A' | 619 | '\u0559' | 620 | '\u0640' | 621 | '\u06E5' | 622 | '\u06E6' | 623 | '\u07F4' | 624 | '\u07F5' | 625 | '\u07FA' | 626 | '\u081A' | 627 | '\u0824' | 628 | '\u0828' | 629 | '\u0971' | 630 | '\u0E46' | 631 | '\u0EC6' | 632 | '\u10FC' | 633 | '\u17D7' | 634 | '\u1843' | 635 | '\u1AA7' | 636 | '\u1C78'..'\u1C7D' | 637 | '\u1D2C'..'\u1D6A' | 638 | '\u1D78' | 639 | '\u1D9B'..'\u1DBF' | 640 | '\u2071' | 641 | '\u207F' | 642 | '\u2090'..'\u209C' | 643 | '\u2C7C' | 644 | '\u2C7D' | 645 | '\u2D6F' | 646 | '\u2E2F' | 647 | '\u3005' | 648 | '\u3031'..'\u3035' | 649 | '\u303B' | 650 | '\u309D' | 651 | '\u309E' | 652 | '\u30FC'..'\u30FE' | 653 | '\uA015' | 654 | '\uA4F8'..'\uA4FD' | 655 | '\uA60C' | 656 | '\uA67F' | 657 | '\uA717'..'\uA71F' | 658 | '\uA770' | 659 | '\uA788' | 660 | '\uA7F8' | 661 | '\uA7F9' | 662 | '\uA9CF' | 663 | '\uAA70' | 664 | '\uAADD' | 665 | '\uAAF3' | 666 | '\uAAF4' | 667 | '\uFF70' | 668 | '\uFF9E' | 669 | '\uFF9F'; 670 | 671 | UNICODE_CLASS_LO: 672 | '\u00AA' | 673 | '\u00BA' | 674 | '\u01BB' | 675 | '\u01C0'..'\u01C3' | 676 | '\u0294' | 677 | '\u05D0'..'\u05EA' | 678 | '\u05F0'..'\u05F2' | 679 | '\u0620'..'\u063F' | 680 | '\u0641'..'\u064A' | 681 | '\u066E' | 682 | '\u066F' | 683 | '\u0671'..'\u06D3' | 684 | '\u06D5' | 685 | '\u06EE' | 686 | '\u06EF' | 687 | '\u06FA'..'\u06FC' | 688 | '\u06FF' | 689 | '\u0710' | 690 | '\u0712'..'\u072F' | 691 | '\u074D'..'\u07A5' | 692 | '\u07B1' | 693 | '\u07CA'..'\u07EA' | 694 | '\u0800'..'\u0815' | 695 | '\u0840'..'\u0858' | 696 | '\u08A0' | 697 | '\u08A2'..'\u08AC' | 698 | '\u0904'..'\u0939' | 699 | '\u093D' | 700 | '\u0950' | 701 | '\u0958'..'\u0961' | 702 | '\u0972'..'\u0977' | 703 | '\u0979'..'\u097F' | 704 | '\u0985'..'\u098C' | 705 | '\u098F' | 706 | '\u0990' | 707 | '\u0993'..'\u09A8' | 708 | '\u09AA'..'\u09B0' | 709 | '\u09B2' | 710 | '\u09B6'..'\u09B9' | 711 | '\u09BD' | 712 | '\u09CE' | 713 | '\u09DC' | 714 | '\u09DD' | 715 | '\u09DF'..'\u09E1' | 716 | '\u09F0' | 717 | '\u09F1' | 718 | '\u0A05'..'\u0A0A' | 719 | '\u0A0F' | 720 | '\u0A10' | 721 | '\u0A13'..'\u0A28' | 722 | '\u0A2A'..'\u0A30' | 723 | '\u0A32' | 724 | '\u0A33' | 725 | '\u0A35' | 726 | '\u0A36' | 727 | '\u0A38' | 728 | '\u0A39' | 729 | '\u0A59'..'\u0A5C' | 730 | '\u0A5E' | 731 | '\u0A72'..'\u0A74' | 732 | '\u0A85'..'\u0A8D' | 733 | '\u0A8F'..'\u0A91' | 734 | '\u0A93'..'\u0AA8' | 735 | '\u0AAA'..'\u0AB0' | 736 | '\u0AB2' | 737 | '\u0AB3' | 738 | '\u0AB5'..'\u0AB9' | 739 | '\u0ABD' | 740 | '\u0AD0' | 741 | '\u0AE0' | 742 | '\u0AE1' | 743 | '\u0B05'..'\u0B0C' | 744 | '\u0B0F' | 745 | '\u0B10' | 746 | '\u0B13'..'\u0B28' | 747 | '\u0B2A'..'\u0B30' | 748 | '\u0B32' | 749 | '\u0B33' | 750 | '\u0B35'..'\u0B39' | 751 | '\u0B3D' | 752 | '\u0B5C' | 753 | '\u0B5D' | 754 | '\u0B5F'..'\u0B61' | 755 | '\u0B71' | 756 | '\u0B83' | 757 | '\u0B85'..'\u0B8A' | 758 | '\u0B8E'..'\u0B90' | 759 | '\u0B92'..'\u0B95' | 760 | '\u0B99' | 761 | '\u0B9A' | 762 | '\u0B9C' | 763 | '\u0B9E' | 764 | '\u0B9F' | 765 | '\u0BA3' | 766 | '\u0BA4' | 767 | '\u0BA8'..'\u0BAA' | 768 | '\u0BAE'..'\u0BB9' | 769 | '\u0BD0' | 770 | '\u0C05'..'\u0C0C' | 771 | '\u0C0E'..'\u0C10' | 772 | '\u0C12'..'\u0C28' | 773 | '\u0C2A'..'\u0C33' | 774 | '\u0C35'..'\u0C39' | 775 | '\u0C3D' | 776 | '\u0C58' | 777 | '\u0C59' | 778 | '\u0C60' | 779 | '\u0C61' | 780 | '\u0C85'..'\u0C8C' | 781 | '\u0C8E'..'\u0C90' | 782 | '\u0C92'..'\u0CA8' | 783 | '\u0CAA'..'\u0CB3' | 784 | '\u0CB5'..'\u0CB9' | 785 | '\u0CBD' | 786 | '\u0CDE' | 787 | '\u0CE0' | 788 | '\u0CE1' | 789 | '\u0CF1' | 790 | '\u0CF2' | 791 | '\u0D05'..'\u0D0C' | 792 | '\u0D0E'..'\u0D10' | 793 | '\u0D12'..'\u0D3A' | 794 | '\u0D3D' | 795 | '\u0D4E' | 796 | '\u0D60' | 797 | '\u0D61' | 798 | '\u0D7A'..'\u0D7F' | 799 | '\u0D85'..'\u0D96' | 800 | '\u0D9A'..'\u0DB1' | 801 | '\u0DB3'..'\u0DBB' | 802 | '\u0DBD' | 803 | '\u0DC0'..'\u0DC6' | 804 | '\u0E01'..'\u0E30' | 805 | '\u0E32' | 806 | '\u0E33' | 807 | '\u0E40'..'\u0E45' | 808 | '\u0E81' | 809 | '\u0E82' | 810 | '\u0E84' | 811 | '\u0E87' | 812 | '\u0E88' | 813 | '\u0E8A' | 814 | '\u0E8D' | 815 | '\u0E94'..'\u0E97' | 816 | '\u0E99'..'\u0E9F' | 817 | '\u0EA1'..'\u0EA3' | 818 | '\u0EA5' | 819 | '\u0EA7' | 820 | '\u0EAA' | 821 | '\u0EAB' | 822 | '\u0EAD'..'\u0EB0' | 823 | '\u0EB2' | 824 | '\u0EB3' | 825 | '\u0EBD' | 826 | '\u0EC0'..'\u0EC4' | 827 | '\u0EDC'..'\u0EDF' | 828 | '\u0F00' | 829 | '\u0F40'..'\u0F47' | 830 | '\u0F49'..'\u0F6C' | 831 | '\u0F88'..'\u0F8C' | 832 | '\u1000'..'\u102A' | 833 | '\u103F' | 834 | '\u1050'..'\u1055' | 835 | '\u105A'..'\u105D' | 836 | '\u1061' | 837 | '\u1065' | 838 | '\u1066' | 839 | '\u106E'..'\u1070' | 840 | '\u1075'..'\u1081' | 841 | '\u108E' | 842 | '\u10D0'..'\u10FA' | 843 | '\u10FD'..'\u1248' | 844 | '\u124A'..'\u124D' | 845 | '\u1250'..'\u1256' | 846 | '\u1258' | 847 | '\u125A'..'\u125D' | 848 | '\u1260'..'\u1288' | 849 | '\u128A'..'\u128D' | 850 | '\u1290'..'\u12B0' | 851 | '\u12B2'..'\u12B5' | 852 | '\u12B8'..'\u12BE' | 853 | '\u12C0' | 854 | '\u12C2'..'\u12C5' | 855 | '\u12C8'..'\u12D6' | 856 | '\u12D8'..'\u1310' | 857 | '\u1312'..'\u1315' | 858 | '\u1318'..'\u135A' | 859 | '\u1380'..'\u138F' | 860 | '\u13A0'..'\u13F4' | 861 | '\u1401'..'\u166C' | 862 | '\u166F'..'\u167F' | 863 | '\u1681'..'\u169A' | 864 | '\u16A0'..'\u16EA' | 865 | '\u1700'..'\u170C' | 866 | '\u170E'..'\u1711' | 867 | '\u1720'..'\u1731' | 868 | '\u1740'..'\u1751' | 869 | '\u1760'..'\u176C' | 870 | '\u176E'..'\u1770' | 871 | '\u1780'..'\u17B3' | 872 | '\u17DC' | 873 | '\u1820'..'\u1842' | 874 | '\u1844'..'\u1877' | 875 | '\u1880'..'\u18A8' | 876 | '\u18AA' | 877 | '\u18B0'..'\u18F5' | 878 | '\u1900'..'\u191C' | 879 | '\u1950'..'\u196D' | 880 | '\u1970'..'\u1974' | 881 | '\u1980'..'\u19AB' | 882 | '\u19C1'..'\u19C7' | 883 | '\u1A00'..'\u1A16' | 884 | '\u1A20'..'\u1A54' | 885 | '\u1B05'..'\u1B33' | 886 | '\u1B45'..'\u1B4B' | 887 | '\u1B83'..'\u1BA0' | 888 | '\u1BAE' | 889 | '\u1BAF' | 890 | '\u1BBA'..'\u1BE5' | 891 | '\u1C00'..'\u1C23' | 892 | '\u1C4D'..'\u1C4F' | 893 | '\u1C5A'..'\u1C77' | 894 | '\u1CE9'..'\u1CEC' | 895 | '\u1CEE'..'\u1CF1' | 896 | '\u1CF5' | 897 | '\u1CF6' | 898 | '\u2135'..'\u2138' | 899 | '\u2D30'..'\u2D67' | 900 | '\u2D80'..'\u2D96' | 901 | '\u2DA0'..'\u2DA6' | 902 | '\u2DA8'..'\u2DAE' | 903 | '\u2DB0'..'\u2DB6' | 904 | '\u2DB8'..'\u2DBE' | 905 | '\u2DC0'..'\u2DC6' | 906 | '\u2DC8'..'\u2DCE' | 907 | '\u2DD0'..'\u2DD6' | 908 | '\u2DD8'..'\u2DDE' | 909 | '\u3006' | 910 | '\u303C' | 911 | '\u3041'..'\u3096' | 912 | '\u309F' | 913 | '\u30A1'..'\u30FA' | 914 | '\u30FF' | 915 | '\u3105'..'\u312D' | 916 | '\u3131'..'\u318E' | 917 | '\u31A0'..'\u31BA' | 918 | '\u31F0'..'\u31FF' | 919 | '\u3400' | 920 | '\u4DB5' | 921 | '\u4E00' | 922 | '\u9FCC' | 923 | '\uA000'..'\uA014' | 924 | '\uA016'..'\uA48C' | 925 | '\uA4D0'..'\uA4F7' | 926 | '\uA500'..'\uA60B' | 927 | '\uA610'..'\uA61F' | 928 | '\uA62A' | 929 | '\uA62B' | 930 | '\uA66E' | 931 | '\uA6A0'..'\uA6E5' | 932 | '\uA7FB'..'\uA801' | 933 | '\uA803'..'\uA805' | 934 | '\uA807'..'\uA80A' | 935 | '\uA80C'..'\uA822' | 936 | '\uA840'..'\uA873' | 937 | '\uA882'..'\uA8B3' | 938 | '\uA8F2'..'\uA8F7' | 939 | '\uA8FB' | 940 | '\uA90A'..'\uA925' | 941 | '\uA930'..'\uA946' | 942 | '\uA960'..'\uA97C' | 943 | '\uA984'..'\uA9B2' | 944 | '\uAA00'..'\uAA28' | 945 | '\uAA40'..'\uAA42' | 946 | '\uAA44'..'\uAA4B' | 947 | '\uAA60'..'\uAA6F' | 948 | '\uAA71'..'\uAA76' | 949 | '\uAA7A' | 950 | '\uAA80'..'\uAAAF' | 951 | '\uAAB1' | 952 | '\uAAB5' | 953 | '\uAAB6' | 954 | '\uAAB9'..'\uAABD' | 955 | '\uAAC0' | 956 | '\uAAC2' | 957 | '\uAADB' | 958 | '\uAADC' | 959 | '\uAAE0'..'\uAAEA' | 960 | '\uAAF2' | 961 | '\uAB01'..'\uAB06' | 962 | '\uAB09'..'\uAB0E' | 963 | '\uAB11'..'\uAB16' | 964 | '\uAB20'..'\uAB26' | 965 | '\uAB28'..'\uAB2E' | 966 | '\uABC0'..'\uABE2' | 967 | '\uAC00' | 968 | '\uD7A3' | 969 | '\uD7B0'..'\uD7C6' | 970 | '\uD7CB'..'\uD7FB' | 971 | '\uF900'..'\uFA6D' | 972 | '\uFA70'..'\uFAD9' | 973 | '\uFB1D' | 974 | '\uFB1F'..'\uFB28' | 975 | '\uFB2A'..'\uFB36' | 976 | '\uFB38'..'\uFB3C' | 977 | '\uFB3E' | 978 | '\uFB40' | 979 | '\uFB41' | 980 | '\uFB43' | 981 | '\uFB44' | 982 | '\uFB46'..'\uFBB1' | 983 | '\uFBD3'..'\uFD3D' | 984 | '\uFD50'..'\uFD8F' | 985 | '\uFD92'..'\uFDC7' | 986 | '\uFDF0'..'\uFDFB' | 987 | '\uFE70'..'\uFE74' | 988 | '\uFE76'..'\uFEFC' | 989 | '\uFF66'..'\uFF6F' | 990 | '\uFF71'..'\uFF9D' | 991 | '\uFFA0'..'\uFFBE' | 992 | '\uFFC2'..'\uFFC7' | 993 | '\uFFCA'..'\uFFCF' | 994 | '\uFFD2'..'\uFFD7' | 995 | '\uFFDA'..'\uFFDC'; 996 | 997 | UNICODE_CLASS_LT: 998 | '\u01C5' | 999 | '\u01C8' | 1000 | '\u01CB' | 1001 | '\u01F2' | 1002 | '\u1F88'..'\u1F8F' | 1003 | '\u1F98'..'\u1F9F' | 1004 | '\u1FA8'..'\u1FAF' | 1005 | '\u1FBC' | 1006 | '\u1FCC' | 1007 | '\u1FFC'; 1008 | 1009 | UNICODE_CLASS_LU: 1010 | '\u0041'..'\u005A' | 1011 | '\u00C0'..'\u00D6' | 1012 | '\u00D8'..'\u00DE' | 1013 | '\u0100' | 1014 | '\u0102' | 1015 | '\u0104' | 1016 | '\u0106' | 1017 | '\u0108' | 1018 | '\u010A' | 1019 | '\u010C' | 1020 | '\u010E' | 1021 | '\u0110' | 1022 | '\u0112' | 1023 | '\u0114' | 1024 | '\u0116' | 1025 | '\u0118' | 1026 | '\u011A' | 1027 | '\u011C' | 1028 | '\u011E' | 1029 | '\u0120' | 1030 | '\u0122' | 1031 | '\u0124' | 1032 | '\u0126' | 1033 | '\u0128' | 1034 | '\u012A' | 1035 | '\u012C' | 1036 | '\u012E' | 1037 | '\u0130' | 1038 | '\u0132' | 1039 | '\u0134' | 1040 | '\u0136' | 1041 | '\u0139' | 1042 | '\u013B' | 1043 | '\u013D' | 1044 | '\u013F' | 1045 | '\u0141' | 1046 | '\u0143' | 1047 | '\u0145' | 1048 | '\u0147' | 1049 | '\u014A' | 1050 | '\u014C' | 1051 | '\u014E' | 1052 | '\u0150' | 1053 | '\u0152' | 1054 | '\u0154' | 1055 | '\u0156' | 1056 | '\u0158' | 1057 | '\u015A' | 1058 | '\u015C' | 1059 | '\u015E' | 1060 | '\u0160' | 1061 | '\u0162' | 1062 | '\u0164' | 1063 | '\u0166' | 1064 | '\u0168' | 1065 | '\u016A' | 1066 | '\u016C' | 1067 | '\u016E' | 1068 | '\u0170' | 1069 | '\u0172' | 1070 | '\u0174' | 1071 | '\u0176' | 1072 | '\u0178' | 1073 | '\u0179' | 1074 | '\u017B' | 1075 | '\u017D' | 1076 | '\u0181' | 1077 | '\u0182' | 1078 | '\u0184' | 1079 | '\u0186' | 1080 | '\u0187' | 1081 | '\u0189'..'\u018B' | 1082 | '\u018E'..'\u0191' | 1083 | '\u0193' | 1084 | '\u0194' | 1085 | '\u0196'..'\u0198' | 1086 | '\u019C' | 1087 | '\u019D' | 1088 | '\u019F' | 1089 | '\u01A0' | 1090 | '\u01A2' | 1091 | '\u01A4' | 1092 | '\u01A6' | 1093 | '\u01A7' | 1094 | '\u01A9' | 1095 | '\u01AC' | 1096 | '\u01AE' | 1097 | '\u01AF' | 1098 | '\u01B1'..'\u01B3' | 1099 | '\u01B5' | 1100 | '\u01B7' | 1101 | '\u01B8' | 1102 | '\u01BC' | 1103 | '\u01C4' | 1104 | '\u01C7' | 1105 | '\u01CA' | 1106 | '\u01CD' | 1107 | '\u01CF' | 1108 | '\u01D1' | 1109 | '\u01D3' | 1110 | '\u01D5' | 1111 | '\u01D7' | 1112 | '\u01D9' | 1113 | '\u01DB' | 1114 | '\u01DE' | 1115 | '\u01E0' | 1116 | '\u01E2' | 1117 | '\u01E4' | 1118 | '\u01E6' | 1119 | '\u01E8' | 1120 | '\u01EA' | 1121 | '\u01EC' | 1122 | '\u01EE' | 1123 | '\u01F1' | 1124 | '\u01F4' | 1125 | '\u01F6'..'\u01F8' | 1126 | '\u01FA' | 1127 | '\u01FC' | 1128 | '\u01FE' | 1129 | '\u0200' | 1130 | '\u0202' | 1131 | '\u0204' | 1132 | '\u0206' | 1133 | '\u0208' | 1134 | '\u020A' | 1135 | '\u020C' | 1136 | '\u020E' | 1137 | '\u0210' | 1138 | '\u0212' | 1139 | '\u0214' | 1140 | '\u0216' | 1141 | '\u0218' | 1142 | '\u021A' | 1143 | '\u021C' | 1144 | '\u021E' | 1145 | '\u0220' | 1146 | '\u0222' | 1147 | '\u0224' | 1148 | '\u0226' | 1149 | '\u0228' | 1150 | '\u022A' | 1151 | '\u022C' | 1152 | '\u022E' | 1153 | '\u0230' | 1154 | '\u0232' | 1155 | '\u023A' | 1156 | '\u023B' | 1157 | '\u023D' | 1158 | '\u023E' | 1159 | '\u0241' | 1160 | '\u0243'..'\u0246' | 1161 | '\u0248' | 1162 | '\u024A' | 1163 | '\u024C' | 1164 | '\u024E' | 1165 | '\u0370' | 1166 | '\u0372' | 1167 | '\u0376' | 1168 | '\u0386' | 1169 | '\u0388'..'\u038A' | 1170 | '\u038C' | 1171 | '\u038E' | 1172 | '\u038F' | 1173 | '\u0391'..'\u03A1' | 1174 | '\u03A3'..'\u03AB' | 1175 | '\u03CF' | 1176 | '\u03D2'..'\u03D4' | 1177 | '\u03D8' | 1178 | '\u03DA' | 1179 | '\u03DC' | 1180 | '\u03DE' | 1181 | '\u03E0' | 1182 | '\u03E2' | 1183 | '\u03E4' | 1184 | '\u03E6' | 1185 | '\u03E8' | 1186 | '\u03EA' | 1187 | '\u03EC' | 1188 | '\u03EE' | 1189 | '\u03F4' | 1190 | '\u03F7' | 1191 | '\u03F9' | 1192 | '\u03FA' | 1193 | '\u03FD'..'\u042F' | 1194 | '\u0460' | 1195 | '\u0462' | 1196 | '\u0464' | 1197 | '\u0466' | 1198 | '\u0468' | 1199 | '\u046A' | 1200 | '\u046C' | 1201 | '\u046E' | 1202 | '\u0470' | 1203 | '\u0472' | 1204 | '\u0474' | 1205 | '\u0476' | 1206 | '\u0478' | 1207 | '\u047A' | 1208 | '\u047C' | 1209 | '\u047E' | 1210 | '\u0480' | 1211 | '\u048A' | 1212 | '\u048C' | 1213 | '\u048E' | 1214 | '\u0490' | 1215 | '\u0492' | 1216 | '\u0494' | 1217 | '\u0496' | 1218 | '\u0498' | 1219 | '\u049A' | 1220 | '\u049C' | 1221 | '\u049E' | 1222 | '\u04A0' | 1223 | '\u04A2' | 1224 | '\u04A4' | 1225 | '\u04A6' | 1226 | '\u04A8' | 1227 | '\u04AA' | 1228 | '\u04AC' | 1229 | '\u04AE' | 1230 | '\u04B0' | 1231 | '\u04B2' | 1232 | '\u04B4' | 1233 | '\u04B6' | 1234 | '\u04B8' | 1235 | '\u04BA' | 1236 | '\u04BC' | 1237 | '\u04BE' | 1238 | '\u04C0' | 1239 | '\u04C1' | 1240 | '\u04C3' | 1241 | '\u04C5' | 1242 | '\u04C7' | 1243 | '\u04C9' | 1244 | '\u04CB' | 1245 | '\u04CD' | 1246 | '\u04D0' | 1247 | '\u04D2' | 1248 | '\u04D4' | 1249 | '\u04D6' | 1250 | '\u04D8' | 1251 | '\u04DA' | 1252 | '\u04DC' | 1253 | '\u04DE' | 1254 | '\u04E0' | 1255 | '\u04E2' | 1256 | '\u04E4' | 1257 | '\u04E6' | 1258 | '\u04E8' | 1259 | '\u04EA' | 1260 | '\u04EC' | 1261 | '\u04EE' | 1262 | '\u04F0' | 1263 | '\u04F2' | 1264 | '\u04F4' | 1265 | '\u04F6' | 1266 | '\u04F8' | 1267 | '\u04FA' | 1268 | '\u04FC' | 1269 | '\u04FE' | 1270 | '\u0500' | 1271 | '\u0502' | 1272 | '\u0504' | 1273 | '\u0506' | 1274 | '\u0508' | 1275 | '\u050A' | 1276 | '\u050C' | 1277 | '\u050E' | 1278 | '\u0510' | 1279 | '\u0512' | 1280 | '\u0514' | 1281 | '\u0516' | 1282 | '\u0518' | 1283 | '\u051A' | 1284 | '\u051C' | 1285 | '\u051E' | 1286 | '\u0520' | 1287 | '\u0522' | 1288 | '\u0524' | 1289 | '\u0526' | 1290 | '\u0531'..'\u0556' | 1291 | '\u10A0'..'\u10C5' | 1292 | '\u10C7' | 1293 | '\u10CD' | 1294 | '\u1E00' | 1295 | '\u1E02' | 1296 | '\u1E04' | 1297 | '\u1E06' | 1298 | '\u1E08' | 1299 | '\u1E0A' | 1300 | '\u1E0C' | 1301 | '\u1E0E' | 1302 | '\u1E10' | 1303 | '\u1E12' | 1304 | '\u1E14' | 1305 | '\u1E16' | 1306 | '\u1E18' | 1307 | '\u1E1A' | 1308 | '\u1E1C' | 1309 | '\u1E1E' | 1310 | '\u1E20' | 1311 | '\u1E22' | 1312 | '\u1E24' | 1313 | '\u1E26' | 1314 | '\u1E28' | 1315 | '\u1E2A' | 1316 | '\u1E2C' | 1317 | '\u1E2E' | 1318 | '\u1E30' | 1319 | '\u1E32' | 1320 | '\u1E34' | 1321 | '\u1E36' | 1322 | '\u1E38' | 1323 | '\u1E3A' | 1324 | '\u1E3C' | 1325 | '\u1E3E' | 1326 | '\u1E40' | 1327 | '\u1E42' | 1328 | '\u1E44' | 1329 | '\u1E46' | 1330 | '\u1E48' | 1331 | '\u1E4A' | 1332 | '\u1E4C' | 1333 | '\u1E4E' | 1334 | '\u1E50' | 1335 | '\u1E52' | 1336 | '\u1E54' | 1337 | '\u1E56' | 1338 | '\u1E58' | 1339 | '\u1E5A' | 1340 | '\u1E5C' | 1341 | '\u1E5E' | 1342 | '\u1E60' | 1343 | '\u1E62' | 1344 | '\u1E64' | 1345 | '\u1E66' | 1346 | '\u1E68' | 1347 | '\u1E6A' | 1348 | '\u1E6C' | 1349 | '\u1E6E' | 1350 | '\u1E70' | 1351 | '\u1E72' | 1352 | '\u1E74' | 1353 | '\u1E76' | 1354 | '\u1E78' | 1355 | '\u1E7A' | 1356 | '\u1E7C' | 1357 | '\u1E7E' | 1358 | '\u1E80' | 1359 | '\u1E82' | 1360 | '\u1E84' | 1361 | '\u1E86' | 1362 | '\u1E88' | 1363 | '\u1E8A' | 1364 | '\u1E8C' | 1365 | '\u1E8E' | 1366 | '\u1E90' | 1367 | '\u1E92' | 1368 | '\u1E94' | 1369 | '\u1E9E' | 1370 | '\u1EA0' | 1371 | '\u1EA2' | 1372 | '\u1EA4' | 1373 | '\u1EA6' | 1374 | '\u1EA8' | 1375 | '\u1EAA' | 1376 | '\u1EAC' | 1377 | '\u1EAE' | 1378 | '\u1EB0' | 1379 | '\u1EB2' | 1380 | '\u1EB4' | 1381 | '\u1EB6' | 1382 | '\u1EB8' | 1383 | '\u1EBA' | 1384 | '\u1EBC' | 1385 | '\u1EBE' | 1386 | '\u1EC0' | 1387 | '\u1EC2' | 1388 | '\u1EC4' | 1389 | '\u1EC6' | 1390 | '\u1EC8' | 1391 | '\u1ECA' | 1392 | '\u1ECC' | 1393 | '\u1ECE' | 1394 | '\u1ED0' | 1395 | '\u1ED2' | 1396 | '\u1ED4' | 1397 | '\u1ED6' | 1398 | '\u1ED8' | 1399 | '\u1EDA' | 1400 | '\u1EDC' | 1401 | '\u1EDE' | 1402 | '\u1EE0' | 1403 | '\u1EE2' | 1404 | '\u1EE4' | 1405 | '\u1EE6' | 1406 | '\u1EE8' | 1407 | '\u1EEA' | 1408 | '\u1EEC' | 1409 | '\u1EEE' | 1410 | '\u1EF0' | 1411 | '\u1EF2' | 1412 | '\u1EF4' | 1413 | '\u1EF6' | 1414 | '\u1EF8' | 1415 | '\u1EFA' | 1416 | '\u1EFC' | 1417 | '\u1EFE' | 1418 | '\u1F08'..'\u1F0F' | 1419 | '\u1F18'..'\u1F1D' | 1420 | '\u1F28'..'\u1F2F' | 1421 | '\u1F38'..'\u1F3F' | 1422 | '\u1F48'..'\u1F4D' | 1423 | '\u1F59' | 1424 | '\u1F5B' | 1425 | '\u1F5D' | 1426 | '\u1F5F' | 1427 | '\u1F68'..'\u1F6F' | 1428 | '\u1FB8'..'\u1FBB' | 1429 | '\u1FC8'..'\u1FCB' | 1430 | '\u1FD8'..'\u1FDB' | 1431 | '\u1FE8'..'\u1FEC' | 1432 | '\u1FF8'..'\u1FFB' | 1433 | '\u2102' | 1434 | '\u2107' | 1435 | '\u210B'..'\u210D' | 1436 | '\u2110'..'\u2112' | 1437 | '\u2115' | 1438 | '\u2119'..'\u211D' | 1439 | '\u2124' | 1440 | '\u2126' | 1441 | '\u2128' | 1442 | '\u212A'..'\u212D' | 1443 | '\u2130'..'\u2133' | 1444 | '\u213E' | 1445 | '\u213F' | 1446 | '\u2145' | 1447 | '\u2183' | 1448 | '\u2C00'..'\u2C2E' | 1449 | '\u2C60' | 1450 | '\u2C62'..'\u2C64' | 1451 | '\u2C67' | 1452 | '\u2C69' | 1453 | '\u2C6B' | 1454 | '\u2C6D'..'\u2C70' | 1455 | '\u2C72' | 1456 | '\u2C75' | 1457 | '\u2C7E'..'\u2C80' | 1458 | '\u2C82' | 1459 | '\u2C84' | 1460 | '\u2C86' | 1461 | '\u2C88' | 1462 | '\u2C8A' | 1463 | '\u2C8C' | 1464 | '\u2C8E' | 1465 | '\u2C90' | 1466 | '\u2C92' | 1467 | '\u2C94' | 1468 | '\u2C96' | 1469 | '\u2C98' | 1470 | '\u2C9A' | 1471 | '\u2C9C' | 1472 | '\u2C9E' | 1473 | '\u2CA0' | 1474 | '\u2CA2' | 1475 | '\u2CA4' | 1476 | '\u2CA6' | 1477 | '\u2CA8' | 1478 | '\u2CAA' | 1479 | '\u2CAC' | 1480 | '\u2CAE' | 1481 | '\u2CB0' | 1482 | '\u2CB2' | 1483 | '\u2CB4' | 1484 | '\u2CB6' | 1485 | '\u2CB8' | 1486 | '\u2CBA' | 1487 | '\u2CBC' | 1488 | '\u2CBE' | 1489 | '\u2CC0' | 1490 | '\u2CC2' | 1491 | '\u2CC4' | 1492 | '\u2CC6' | 1493 | '\u2CC8' | 1494 | '\u2CCA' | 1495 | '\u2CCC' | 1496 | '\u2CCE' | 1497 | '\u2CD0' | 1498 | '\u2CD2' | 1499 | '\u2CD4' | 1500 | '\u2CD6' | 1501 | '\u2CD8' | 1502 | '\u2CDA' | 1503 | '\u2CDC' | 1504 | '\u2CDE' | 1505 | '\u2CE0' | 1506 | '\u2CE2' | 1507 | '\u2CEB' | 1508 | '\u2CED' | 1509 | '\u2CF2' | 1510 | '\uA640' | 1511 | '\uA642' | 1512 | '\uA644' | 1513 | '\uA646' | 1514 | '\uA648' | 1515 | '\uA64A' | 1516 | '\uA64C' | 1517 | '\uA64E' | 1518 | '\uA650' | 1519 | '\uA652' | 1520 | '\uA654' | 1521 | '\uA656' | 1522 | '\uA658' | 1523 | '\uA65A' | 1524 | '\uA65C' | 1525 | '\uA65E' | 1526 | '\uA660' | 1527 | '\uA662' | 1528 | '\uA664' | 1529 | '\uA666' | 1530 | '\uA668' | 1531 | '\uA66A' | 1532 | '\uA66C' | 1533 | '\uA680' | 1534 | '\uA682' | 1535 | '\uA684' | 1536 | '\uA686' | 1537 | '\uA688' | 1538 | '\uA68A' | 1539 | '\uA68C' | 1540 | '\uA68E' | 1541 | '\uA690' | 1542 | '\uA692' | 1543 | '\uA694' | 1544 | '\uA696' | 1545 | '\uA722' | 1546 | '\uA724' | 1547 | '\uA726' | 1548 | '\uA728' | 1549 | '\uA72A' | 1550 | '\uA72C' | 1551 | '\uA72E' | 1552 | '\uA732' | 1553 | '\uA734' | 1554 | '\uA736' | 1555 | '\uA738' | 1556 | '\uA73A' | 1557 | '\uA73C' | 1558 | '\uA73E' | 1559 | '\uA740' | 1560 | '\uA742' | 1561 | '\uA744' | 1562 | '\uA746' | 1563 | '\uA748' | 1564 | '\uA74A' | 1565 | '\uA74C' | 1566 | '\uA74E' | 1567 | '\uA750' | 1568 | '\uA752' | 1569 | '\uA754' | 1570 | '\uA756' | 1571 | '\uA758' | 1572 | '\uA75A' | 1573 | '\uA75C' | 1574 | '\uA75E' | 1575 | '\uA760' | 1576 | '\uA762' | 1577 | '\uA764' | 1578 | '\uA766' | 1579 | '\uA768' | 1580 | '\uA76A' | 1581 | '\uA76C' | 1582 | '\uA76E' | 1583 | '\uA779' | 1584 | '\uA77B' | 1585 | '\uA77D' | 1586 | '\uA77E' | 1587 | '\uA780' | 1588 | '\uA782' | 1589 | '\uA784' | 1590 | '\uA786' | 1591 | '\uA78B' | 1592 | '\uA78D' | 1593 | '\uA790' | 1594 | '\uA792' | 1595 | '\uA7A0' | 1596 | '\uA7A2' | 1597 | '\uA7A4' | 1598 | '\uA7A6' | 1599 | '\uA7A8' | 1600 | '\uA7AA' | 1601 | '\uFF21'..'\uFF3A'; 1602 | 1603 | UNICODE_CLASS_ND: 1604 | '\u0030'..'\u0039' | 1605 | '\u0660'..'\u0669' | 1606 | '\u06F0'..'\u06F9' | 1607 | '\u07C0'..'\u07C9' | 1608 | '\u0966'..'\u096F' | 1609 | '\u09E6'..'\u09EF' | 1610 | '\u0A66'..'\u0A6F' | 1611 | '\u0AE6'..'\u0AEF' | 1612 | '\u0B66'..'\u0B6F' | 1613 | '\u0BE6'..'\u0BEF' | 1614 | '\u0C66'..'\u0C6F' | 1615 | '\u0CE6'..'\u0CEF' | 1616 | '\u0D66'..'\u0D6F' | 1617 | '\u0E50'..'\u0E59' | 1618 | '\u0ED0'..'\u0ED9' | 1619 | '\u0F20'..'\u0F29' | 1620 | '\u1040'..'\u1049' | 1621 | '\u1090'..'\u1099' | 1622 | '\u17E0'..'\u17E9' | 1623 | '\u1810'..'\u1819' | 1624 | '\u1946'..'\u194F' | 1625 | '\u19D0'..'\u19D9' | 1626 | '\u1A80'..'\u1A89' | 1627 | '\u1A90'..'\u1A99' | 1628 | '\u1B50'..'\u1B59' | 1629 | '\u1BB0'..'\u1BB9' | 1630 | '\u1C40'..'\u1C49' | 1631 | '\u1C50'..'\u1C59' | 1632 | '\uA620'..'\uA629' | 1633 | '\uA8D0'..'\uA8D9' | 1634 | '\uA900'..'\uA909' | 1635 | '\uA9D0'..'\uA9D9' | 1636 | '\uAA50'..'\uAA59' | 1637 | '\uABF0'..'\uABF9' | 1638 | '\uFF10'..'\uFF19'; 1639 | 1640 | UNICODE_CLASS_NL: 1641 | '\u16EE'..'\u16F0' | 1642 | '\u2160'..'\u2182' | 1643 | '\u2185'..'\u2188' | 1644 | '\u3007' | 1645 | '\u3021'..'\u3029' | 1646 | '\u3038'..'\u303A' | 1647 | '\uA6E6'..'\uA6EF'; --------------------------------------------------------------------------------