├── .gitattributes ├── .vscode ├── settings.json └── launch.json ├── .gitignore ├── .npmignore ├── .eslintrc.json ├── fetch └── index.js ├── src ├── debug.js ├── index.js ├── csharp │ ├── README.md │ ├── CSharpPreprocessorParser.g4 │ ├── CSharpParser.g4 │ └── CSharpLexer.g4 └── parser.js ├── test ├── index.js ├── AllInOne.cs └── AllInOne.Formatted.cs ├── .travis.yml ├── LICENSE ├── package.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[csharp]": { 3 | "files.trimTrailingWhitespace": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | .antlr 4 | bin 5 | 6 | src/csharp/*.interp 7 | src/csharp/*.tokens 8 | src/csharp/*.js 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.java 3 | *.interp 4 | *.tokens 5 | *.g4 6 | *.cs 7 | .eslintrc.json 8 | .gitignore 9 | .npmignore 10 | .travis.yml 11 | yarn-error.log 12 | yarn.lock 13 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "extends": ["eslint:recommended", "prettier"], 6 | "parserOptions": { 7 | "ecmaVersion": 2018 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /fetch/index.js: -------------------------------------------------------------------------------- 1 | const https = require("https"); 2 | var fs = require("fs"); 3 | var bin = "./bin"; 4 | 5 | if (!fs.existsSync(bin)) { 6 | fs.mkdirSync(bin); 7 | } 8 | 9 | const file = fs.createWriteStream("bin/antlr-4.7.2-complete.jar"); 10 | https.get("https://www.antlr.org/download/antlr-4.7.2-complete.jar", response => 11 | response.pipe(file) 12 | ); 13 | -------------------------------------------------------------------------------- /src/debug.js: -------------------------------------------------------------------------------- 1 | const prettier = require("prettier"); 2 | const fs = require("fs"); 3 | 4 | if (process.argc < 3) { 5 | throw new Error("Missing file to format"); 6 | } 7 | 8 | const file = process.argv[2]; 9 | 10 | const referenceCode = fs.readFileSync(file, "utf8"); 11 | 12 | const formattedCode = prettier.format(referenceCode, { 13 | parser: "cs", 14 | plugins: ["."], 15 | printWidth: 120 16 | }); 17 | 18 | fs.writeFileSync(file, formattedCode, "utf8"); 19 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const prettier = require("prettier"); 2 | const fs = require("fs"); 3 | 4 | const tests = ["AllInOne"]; 5 | 6 | for (let test of tests) { 7 | const referenceFile = `test/${test}.cs`; 8 | const formattedFile = `test/${test}.Formatted.cs`; 9 | 10 | const referenceCode = fs.readFileSync(referenceFile, "utf8"); 11 | 12 | const formattedCode = prettier.format(referenceCode, { 13 | parser: "cs", 14 | plugins: ["."] 15 | }); 16 | 17 | fs.writeFileSync(formattedFile, formattedCode, "utf8"); 18 | } 19 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const parser = require("./parser"); 4 | const printer = require("./printer"); 5 | 6 | const languages = [ 7 | { 8 | name: "C#", 9 | parsers: ["cs"], 10 | tmScope: "source.cs", 11 | aceMode: "csharp", 12 | codemirrorMode: "clike", 13 | extensions: [".cs", ".cake", ".cshtml", ".csx"], 14 | vscodeLanguageIds: ["csharp"], 15 | linguistLanguageId: 42 16 | } 17 | ]; 18 | 19 | const parsers = { 20 | cs: parser 21 | }; 22 | 23 | const printers = { 24 | cs: printer 25 | }; 26 | 27 | const options = {}; 28 | 29 | module.exports = { 30 | languages, 31 | printers, 32 | parsers, 33 | options, 34 | defaultOptions: { 35 | tabWidth: 4 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Debug regression tests", 11 | "runtimeExecutable": "yarn", 12 | "runtimeArgs": ["test:debug"], 13 | "port": 9229, 14 | "outputCapture": "std" 15 | }, 16 | { 17 | "type": "node", 18 | "request": "launch", 19 | "name": "Debug on a real-life file", 20 | "runtimeExecutable": "yarn", 21 | "runtimeArgs": ["prettier:debug", "File.cs"], 22 | "port": 9229, 23 | "outputCapture": "std" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: 2 | - node_js 3 | - java 4 | jdk: 5 | - openjdk11 6 | node_js: 7 | - stable 8 | cache: 9 | yarn: true 10 | directories: 11 | - node_modules 12 | script: 13 | - yarn fetch-antlr && yarn generate-parser && yarn test 14 | deploy: 15 | provider: npm 16 | email: warren.seine@gmail.com 17 | api_key: 18 | secure: iBiBmHEI0ZSa+JQM/ccvvraGUqOoqPEdZUfg5BBOG36/fc1pST9W83PAQS3qseygnHbFJ6aNh5tDSkoovQyhMYusywH9Sb8Ay48bdBcEqj+j66x64zit/sVZMGPERzBee1sGXP0MLn8ZPo+Me6nnctVoJvAABHV06wNzEer2RBVbjtDO3u5Fz1Sun1J9otFMeDkF0+HrrBJB+/0CytfYncW4S12NMbDjRl3noVWMKMG8TrbWpnfP7dDqU6WyH7y77L881ZjvbrYYVBoAdAnKgJCItQs9Ks4a/W3dSd1RSHk5paeL2+ULaOXkh12xGkEMu4+t09XZe2gsgRbfs8pK6TmZv8q5mi2cP79c81GLddxVK1cxlb5BXL1JVRVcjKitnJWswV8BBPjGl/U1zyIHruwgG4Eo5bgM/NzMS4G3MqI40bMR4hRJaFhwm6QrGMMqmmVbovYAoza+Eho/lYI6GmNOwFqRCmawC0cU7EMgfGNbo+8H+i0OBzepd8zku1MwbmA73E/9q5YoX7NgTQzaTOIb0YdE9HTi9qLaMKY3MlJt9Jnfi5KQ69cPAVeYJmcNgT/hfZSf/gJVXby4/Yc8tCV7TRwv67gpfdcrJNKZdIPwsqJKN8jx5vG8rdfhyUNqalWPfoNFKfYwr+MZWBJrId0tTUG9wm9e7yCLHI1/IUY= 19 | on: 20 | tags: true 21 | repo: warrenseine/prettier-plugin-csharp 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Warren Seine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettier-plugin-csharp", 3 | "version": "0.6.0-development", 4 | "description": "Prettier C# Plugin", 5 | "repository": "warrenseine/prettier-plugin-csharp", 6 | "author": "Warren Seine <@warrenseine>", 7 | "license": "MIT", 8 | "main": "src", 9 | "dependencies": { 10 | "antlr4": "^4.7.2", 11 | "is-alphanumerical": "^1.0.2", 12 | "lodash": "^4.17.11", 13 | "prettier": "^1.15.3" 14 | }, 15 | "scripts": { 16 | "format": "prettier --write \"{src,test}/**/*.js\"", 17 | "lint": "eslint src/**", 18 | "test:debug": "node --lazy --inspect-brk test", 19 | "test": "node test && git diff --exit-code -- test/*.Formatted.cs", 20 | "fetch-antlr": "node fetch", 21 | "generate-parser": "java -jar bin/antlr-4.7.2-complete.jar -Dlanguage=JavaScript src/csharp/*.g4", 22 | "prettier": "prettier --plugin=. --parser=cs", 23 | "prettier:debug": "node --lazy --inspect-brk src/debug.js" 24 | }, 25 | "devDependencies": { 26 | "eslint": "^5.11.1", 27 | "eslint-config-prettier": "^3.3.0", 28 | "husky": "^1.3.1", 29 | "lint-staged": "^8.1.0" 30 | }, 31 | "husky": { 32 | "hooks": { 33 | "pre-commit": "lint-staged" 34 | } 35 | }, 36 | "lint-staged": { 37 | "*.{js,json,css,md}": [ 38 | "prettier --write", 39 | "git add" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/csharp/README.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | C# grammar with full support of 4 | [C# 6 features](https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6) and below. 5 | CSharpLexer.g4 and CSharpPreprocessor.g4 are runtime dependent (contains specific actions), 6 | because of directive preprocessors and string interpolation (these things make grammar context-sensitive). 7 | C# and Java versions supported. But CSharpParser.g4 is runtime independent. 8 | This ANTLR 4 C# grammar is based on the C# ANTLR 3 grammar from 9 | [ChristianWulf/CSharpGrammar](https://github.com/ChristianWulf/CSharpGrammar). 10 | 11 | ## Using 12 | 13 | Due to uncompiled code can be placed after such preprocessor directives: 14 | 15 | ```CSharp 16 | #if SILVERLIGHT && WINDOWS_PHONE || DEBUG || foo == true 17 | // Some code 18 | #endif 19 | ``` 20 | 21 | at first stage it's necessary to calculate whether condition satisfied in directive. 22 | This step performed by runtime code in gist: 23 | [CSharpAntlrParser](https://gist.github.com/KvanTTT/d95579de257531a3cc15). 24 | 25 | ## Testing 26 | 27 | I put into repository **AllInOne.cs** file (from Roslyn) with most common syntax and also 28 | I tested this grammar on the following most popular .NET projects: 29 | 30 | - [Roslyn-1.1.1](https://github.com/dotnet/roslyn). 31 | - [Corefx-1.0.0-rc2](https://github.com/dotnet/corefx). 32 | - [EntityFramework-7.0.0-rc1](https://github.com/aspnet/EntityFramework). 33 | - [aspnet-mvc-6.0.0-rc1](https://github.com/aspnet/Mvc). 34 | - [ImageProcessor-2.3.0](https://github.com/JimBobSquarePants/ImageProcessor). 35 | - [Newtonsoft.Json-8.0.2](https://github.com/JamesNK/Newtonsoft.Json). 36 | 37 | There are some problems with deep recursion ([TestData.g.cs in CoreFx](https://github.com/dotnet/corefx/blob/master/src/Common/tests/System/Xml/XmlCoreTest/TestData.g.cs)), 38 | unicode chars 39 | ([sjis.cs in Roslyn](https://github.com/dotnet/roslyn/blob/master/src/Compilers/Test/Resources/Core/Encoding/sjis.cs)) 40 | and preprocessor directives. 41 | 42 | ANTLR parser from this grammar approximately ~5-7 slowly than Roslyn parser. 43 | 44 | ## License 45 | 46 | [Eclipse Public License - v 1.0](http://www.eclipse.org/legal/epl-v10.html) 47 | -------------------------------------------------------------------------------- /src/parser.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const antlr4 = require("antlr4"); 4 | const { ErrorListener } = require("antlr4/error/ErrorListener"); 5 | const CSharpLexer = require("./csharp/CSharpLexer"); 6 | const CSharpParser = require("./csharp/CSharpParser"); 7 | const _ = require("lodash"); 8 | 9 | class ThrowingErrorListener extends ErrorListener { 10 | syntaxError(recognizer, offendingSymbol, line, column, msg, e) { 11 | const error = new SyntaxError(msg + " (" + line + ":" + column + ")"); 12 | error.loc = { 13 | start: { 14 | line, 15 | column 16 | } 17 | }; 18 | throw error; 19 | } 20 | } 21 | 22 | function parseCSharp(text) { 23 | const errorListener = new ThrowingErrorListener(); 24 | const chars = new antlr4.InputStream(text); 25 | const lexer = new CSharpLexer.CSharpLexer(chars); 26 | lexer.removeErrorListeners(); 27 | lexer.addErrorListener(errorListener); 28 | 29 | const tokens = new antlr4.CommonTokenStream(lexer); 30 | const parser = new CSharpParser.CSharpParser(tokens); 31 | parser.removeErrorListeners(); 32 | parser.addErrorListener(errorListener); 33 | 34 | const compilationUnit = parser.compilation_unit(); 35 | const result = simplifyTree(compilationUnit); 36 | result.comments = tokens.tokens 37 | .filter( 38 | token => 39 | token.channel == CSharpLexer.CSharpLexer.COMMENTS_CHANNEL || 40 | token.channel == CSharpLexer.CSharpLexer.DIRECTIVE 41 | ) 42 | .map(token => buildComment(token)); 43 | return result; 44 | } 45 | 46 | function getNodeTypeFromChannel(token) { 47 | switch (token.channel) { 48 | case CSharpLexer.CSharpLexer.COMMENTS_CHANNEL: 49 | return "comment"; 50 | case CSharpLexer.CSharpLexer.DIRECTIVE: 51 | return "directive"; 52 | } 53 | return "unknown"; 54 | } 55 | 56 | function buildComment(token) { 57 | return { 58 | nodeType: getNodeTypeFromChannel(token), 59 | start: token.start, 60 | end: token.stop, 61 | lineStart: token.line, 62 | lineEnd: token.line, 63 | value: token.text 64 | }; 65 | } 66 | 67 | const nodeNameRegex = /Context$|NodeImpl$/; 68 | 69 | function simplifyTree(node) { 70 | const nodeType = _.snakeCase( 71 | node.constructor.name.replace(nodeNameRegex, "") 72 | ); 73 | 74 | if (!node.children) { 75 | if (node.symbol) { 76 | return { 77 | nodeType, 78 | start: node.symbol.start, 79 | end: node.symbol.stop, 80 | lineStart: node.symbol.line, 81 | lineEnd: node.symbol.line, 82 | value: node.symbol.text 83 | }; 84 | } 85 | } 86 | 87 | const children = {}; 88 | const orderedChildren = []; 89 | 90 | for (let child of node.children) { 91 | child = simplifyTree(child); 92 | if (!children[child.nodeType]) { 93 | children[child.nodeType] = []; 94 | } 95 | children[child.nodeType].push(child); 96 | orderedChildren.push(child); 97 | } 98 | 99 | return { 100 | ...children, 101 | children: orderedChildren, 102 | nodeType, 103 | start: node.start.start, 104 | end: node.stop.stop, 105 | lineStart: node.start.line, 106 | lineEnd: node.stop.line 107 | }; 108 | } 109 | 110 | function loc(prop) { 111 | return function(node) { 112 | return node[prop]; 113 | }; 114 | } 115 | 116 | module.exports = { 117 | parse: parseCSharp, 118 | astFormat: "cs", 119 | locStart: loc("start"), 120 | locEnd: loc("end") 121 | }; 122 | -------------------------------------------------------------------------------- /src/csharp/CSharpPreprocessorParser.g4: -------------------------------------------------------------------------------- 1 | // Eclipse Public License - v 1.0, http://www.eclipse.org/legal/epl-v10.html 2 | // Copyright (c) 2013, Christian Wulf (chwchw@gmx.de) 3 | // Copyright (c) 2016-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. 4 | 5 | parser grammar CSharpPreprocessorParser; 6 | 7 | options { tokenVocab=CSharpLexer; } 8 | 9 | @parser::members 10 | { 11 | this.conditions = [true]; 12 | this.conditionalSymbols = new Set(["DEBUG"]); 13 | 14 | this.prototype.allConditions = function() { 15 | return this.conditions.indexOf(false) < 0; 16 | } 17 | } 18 | 19 | preprocessor_directive returns [boolean value] 20 | : DEFINE CONDITIONAL_SYMBOL directive_new_line_or_sharp{ this.conditionalSymbols.add($CONDITIONAL_SYMBOL.text); 21 | $value = this.allConditions(); } #preprocessorDeclaration 22 | 23 | | UNDEF CONDITIONAL_SYMBOL directive_new_line_or_sharp{ this.conditionalSymbols.remove($CONDITIONAL_SYMBOL.text); 24 | $value = this.allConditions(); } #preprocessorDeclaration 25 | 26 | | IF expr=preprocessor_expression directive_new_line_or_sharp 27 | { $value = $expr.value === "true" && this.allConditions();; this.conditions.push($expr.value === "true"); } 28 | #preprocessorConditional 29 | 30 | | ELIF expr=preprocessor_expression directive_new_line_or_sharp 31 | { if (!this.conditions[this.conditions.length - 1]) { this.conditions.pop(); $value = $expr.value === "true" && this.allConditions();; 32 | this.conditions.push($expr.value === "true"); } else $value = false;; } 33 | #preprocessorConditional 34 | 35 | | ELSE directive_new_line_or_sharp 36 | { if (!this.conditions[this.conditions.length - 1]) { this.conditions.pop(); $value = true && this.allConditions();; this.conditions.push(true); } 37 | else $value = false;; } #preprocessorConditional 38 | 39 | | ENDIF directive_new_line_or_sharp { this.conditions.pop(); $value = this.conditions.peek();; } 40 | #preprocessorConditional 41 | | LINE (DIGITS STRING? | DEFAULT | DIRECTIVE_HIDDEN) directive_new_line_or_sharp { $value = this.allConditions(); } 42 | #preprocessorLine 43 | 44 | | ERROR TEXT directive_new_line_or_sharp { $value = this.allConditions(); } #preprocessorDiagnostic 45 | 46 | | WARNING TEXT directive_new_line_or_sharp { $value = this.allConditions(); } #preprocessorDiagnostic 47 | 48 | | REGION TEXT? directive_new_line_or_sharp { $value = this.allConditions(); } #preprocessorRegion 49 | 50 | | ENDREGION TEXT? directive_new_line_or_sharp { $value = this.allConditions(); } #preprocessorRegion 51 | 52 | | PRAGMA TEXT directive_new_line_or_sharp { $value = this.allConditions(); } #preprocessorPragma 53 | ; 54 | 55 | directive_new_line_or_sharp 56 | : DIRECTIVE_NEW_LINE 57 | | EOF 58 | ; 59 | 60 | preprocessor_expression returns [String value] 61 | : TRUE { $value = "true"; } 62 | | FALSE { $value = "false"; } 63 | | CONDITIONAL_SYMBOL { $value = this.conditionalSymbols.has($CONDITIONAL_SYMBOL.text) ? "true" : "false"; } 64 | | OPEN_PARENS expr=preprocessor_expression CLOSE_PARENS { $value = $expr.value; } 65 | | BANG expr=preprocessor_expression { $value = $expr.value === "true" ? "false" : "true"; } 66 | | expr1=preprocessor_expression OP_EQ expr2=preprocessor_expression 67 | { $value = ($expr1.value == $expr2.value ? "true" : "false"); } 68 | | expr1=preprocessor_expression OP_NE expr2=preprocessor_expression 69 | { $value = ($expr1.value != $expr2.value ? "true" : "false"); } 70 | | expr1=preprocessor_expression OP_AND expr2=preprocessor_expression 71 | { $value = ($expr1.value === "true" && $expr2.value === "true" ? "true" : "false"); } 72 | | expr1=preprocessor_expression OP_OR expr2=preprocessor_expression 73 | { $value = ($expr1.value === "true" || $expr2.value === "true" ? "true" : "false"); } 74 | ; 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | ❌ This repository is unmaintained and the project is incomplete, don't expect anything else than a toy C# project to reformat correctly! ❌ 3 |

4 |

5 | Have a look at CSharpier instead. 6 |

7 |
8 | 9 |
10 | Prettier 12 | C# 16 |
17 | 18 |

Prettier C# Plugin

19 | 20 |

21 | 22 | Gitter 23 | 24 | 25 | Travis 26 | 27 | 28 | npm version 29 | 30 | 31 | code style: prettier 32 | 33 | 34 | Follow+Prettier+on+Twitter 35 | 36 |

37 | 38 | ## Intro 39 | 40 | Prettier C# adds C# support to the [Prettier](https://github.com/prettier/prettier) code formatter. Like Prettier, it is opinionated and restricts style options to a minimum. It runs where Prettier runs, including CI and pre-commit hooks. 41 | 42 | ## Unmaintained 43 | 44 | This repository is unmaintained and the project is incomplete, don't expect anything else than a toy C# project to reformat correctly! **It will break your code.** 45 | 46 | Preview the result with this [diff example](https://github.com/warrenseine/prettier-csharp-demo/pull/1/commits/8652271a499740b726e6342346e97447abd23162). 47 | 48 | ## Install 49 | 50 | ```bash 51 | yarn add --dev --exact prettier prettier-plugin-csharp 52 | ``` 53 | 54 | ## Use 55 | 56 | ```bash 57 | prettier --write "**/*.cs" 58 | ``` 59 | 60 | ## How it works 61 | 62 | The plugin is written in JavaScript. It depends on the JavaScript port of ANTLR and relies on a fork of an [unofficial C# 6 grammar from ANTLR](https://github.com/antlr/grammars-v4/tree/master/csharp). The grammar is precompiled to plain JavaScript and ready to use in the project. 63 | 64 | ## Contributing 65 | 66 | ### Installing dependencies 67 | 68 | Use your favorite Node package manager: 69 | 70 | ```bash 71 | yarn 72 | ``` 73 | 74 | ### Updating the grammar 75 | 76 | The grammar supports C# 6 as a baseline, and tries to catch up with recent additions. Contributions are welcome. To update the grammar: 77 | 78 | - Update `src/csharp/*.g4` files. 79 | - Ensure you have Java 8+ installed on your machine. 80 | - Fetch a local copy of ANTLR: 81 | 82 | ```bash 83 | yarn fetch-antlr 84 | ``` 85 | 86 | - Generate the JavaScript parser: 87 | 88 | ```bash 89 | yarn generate-parser 90 | ``` 91 | 92 | ### Testing 93 | 94 | The project is developed against a single grammar-complete regression test. There are no unit tests for the moment. 95 | 96 | Run the test with: 97 | 98 | ```bash 99 | yarn test 100 | ``` 101 | 102 | To test it out on an actual C# file: 103 | 104 | - Clone this repository. 105 | - Run `yarn`. 106 | - Run `yarn prettier Your/File.cs` to check the output. 107 | 108 | ## Maintainers 109 | 110 | 111 | 112 | 113 | 120 | 121 | 122 |
114 | 115 | 116 |
117 | Warren Seine 118 |
119 |
123 | -------------------------------------------------------------------------------- /test/AllInOne.cs: -------------------------------------------------------------------------------- 1 | #error Error message 2 | #warning Warning message 3 | #pragma warning disable 414, 3021 4 | #pragma warning restore 3021 5 | #pragma checksum "file.txt" "{00000000-0000-0000-0000-000000000000}" "2453" 6 | #define foo // Comment in directive 7 | #if foo 8 | #else 9 | #endif 10 | #undef foo 11 | 12 | extern alias Foo; 13 | 14 | using System; 15 | using System.Collections.Generic; 16 | using System.Linq; 17 | 18 | using ConsoleApplication2.Test; 19 | using System.Linq.Expressions; 20 | using System.Text; 21 | using M = System.Math; 22 | 23 | #if DEBUG || TRACE 24 | using System.Diagnostics; 25 | #elif SILVERLIGHT && WINDOWS_PHONE || DEBUG || foo == true || foo != false 26 | using System.Diagnostics; 27 | #else 28 | using System.Diagnostics; 29 | #endif 30 | 31 | #region Region 32 | 33 | #region more 34 | using ConsoleApplication2.Test; 35 | #endregion 36 | using X = int1; 37 | using Y = ABC.X; 38 | 39 | using static System.Math; 40 | using static System.DayOfWeek; 41 | using static System.Linq.Enumerable; 42 | 43 | #endregion 44 | 45 | [assembly: System.Copyright(@"(C)"" 46 | 47 | 2009")] 48 | [module: System.Copyright("\n\t\u0123(C) \"2009" - ("\u0123" + "foo"))] 49 | 50 | class TopLevelType : IDisposable, Foo 51 | { 52 | void IDisposable.Dispose(int x, int y) { } 53 | } 54 | 55 | namespace My.Moy 56 | { 57 | using A.B; 58 | 59 | interface CoContra { } 60 | delegate void CoContra2<[System.Obsolete()] out T, in K> (int i) where T : struct; 61 | 62 | public unsafe partial class A : C, I 63 | { 64 | [DllImport("kernel32", SetLastError = true)] 65 | static extern bool CreateDirectory(string name, SecurityAttribute sa); 66 | 67 | private const int global = int.MinValue - 1; 68 | 69 | static A() 70 | { 71 | a.a.d().e().a->c.a++.b().a; 72 | 73 | var x = 1 * 1 + 1 * 1 + (1+(1+1)) + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1; 74 | 75 | var y = a is Dictionary dict ? 42 : 51; 76 | } 77 | 78 | [method: Obsolete] 79 | public A([param: Obsolete] int foo, [param: Obsolete] int foo, [param: Obsolete] int foo, [param: Obsolete] int foo) : 80 | base(1) 81 | { 82 | L: 83 | { 84 | int i = sizeof(int); 85 | ++i; 86 | var s0 = $"foo{1,2}"; 87 | var s1 = $"x {1 , -2 :d}"; 88 | var s2 = $@"x {1 , -2 :d}"; 89 | } 90 | 91 | #if DEBUG 92 | Console.WriteLine(export.iefSupplied.command); 93 | #endif 94 | const int? local = int.MaxValue; 95 | const Guid? local0 = new Guid(r.ToString()); 96 | 97 | var привет = local; 98 | var мир = local; 99 | var local3 = 0, local4 = 1; 100 | local3 = local4 = 1; 101 | var local5 = null as Action ?? null; 102 | var local6 = local5 is Action; 103 | string local7 = default; 104 | 105 | var u = 1u; 106 | var U = 1U; 107 | long hex = 0xBADC0DE, Hex = 0XDEADBEEF, l = -1L, L = 1L, l2 = 2l; 108 | ulong ul = 1ul, Ul = 1Ul, uL = 1uL, UL = 1UL, 109 | lu = 1lu, Lu = 1Lu, lU = 1lU, LU = 1LU; 110 | int minInt32Value = -2147483648; 111 | int minInt64Value = -9223372036854775808L; 112 | 113 | bool @bool; 114 | byte @byte; 115 | char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char)0xBAD; 116 | string \U00000065 = "\U00000065"; 117 | decimal @decimal = 1.44M; 118 | @decimal = 1.2m; 119 | dynamic @dynamic; 120 | double @double = M.PI; 121 | @double = 1d; 122 | @double = 1D; 123 | @double = -1.2e3; 124 | float @float = 1.2f; 125 | @float = 1.44F; 126 | int @int = local ?? -1; 127 | long @long; 128 | object @object; 129 | sbyte @sbyte; 130 | short @short; 131 | string @string = @"""/*"; 132 | uint @uint; 133 | ulong @ulong; 134 | ushort @ushort; 135 | 136 | dynamic dynamic = local5; 137 | var add = 0; 138 | var alias = 0; 139 | var arglist = 0; 140 | var ascending = 0; 141 | var async = 0; 142 | var await = 0; 143 | var by = 0; 144 | var descending = 0; 145 | var dynamic = 0; 146 | var equals = 0; 147 | var from = 0; 148 | var get = 0; 149 | var group = 0; 150 | var into = 0; 151 | var join = 0; 152 | var let = 0; 153 | var nameof = 0; 154 | var on = 0; 155 | var orderby = 0; 156 | var partial = 0; 157 | var remove = 0; 158 | var select = 0; 159 | var set = 0; 160 | var var = 0; 161 | var when = 0; 162 | var where = 0; 163 | var yield = 0; 164 | var __ = 0; 165 | where = yield = 0; 166 | 167 | if (i > 0) 168 | { 169 | return; 170 | } 171 | else if (i == 0) 172 | { 173 | throw new Exception(); 174 | } 175 | var o1 = new MyObject(); 176 | var o2 = new MyObject(var); 177 | var o3 = new MyObject { A = i }; 178 | var o4 = new MyObject(@dynamic) 179 | { 180 | A = 0, 181 | B = 0, 182 | C = 0 183 | }; 184 | var o5 = new { A = 0 }; 185 | var dictionaryInitializer = new Dictionary 186 | { 187 | {1, ""}, 188 | {2, "a"} 189 | }; 190 | float[] a = new float[] 191 | { 192 | 0f, 193 | 1.1f 194 | }; 195 | int[, ,] cube = { { { 1111, 1121, }, { 1211, 1221 } }, { { 2111, 2121 }, { 2211, 2221 } } }; 196 | int[][] jagged = { { 111 }, { 121, 122 } }; 197 | int[][,] arr = new int[5][,]; // as opposed to new int[][5,5] 198 | arr[0] = new int[5,5]; // as opposed to arr[0,0] = new int[5]; 199 | arr[0][0,0] = 47; 200 | int[] arrayTypeInference = new[] { 0, 1, }; 201 | switch (3) { } 202 | switch (i) 203 | { 204 | case 0: 205 | case 1: 206 | { 207 | goto case 2; 208 | } 209 | case 2 + 3: 210 | { 211 | goto default; 212 | break; 213 | } 214 | default: 215 | { 216 | return; 217 | } 218 | } 219 | switch(shape) 220 | { 221 | case Circle c: 222 | WriteLine($"circle with radius {c.Radius}"); 223 | break; 224 | case Rectangle s when (s.Length == s.Height): 225 | WriteLine($"{s.Length} x {s.Height} square"); 226 | break; 227 | case null: 228 | throw new ArgumentNullException(nameof(shape)); 229 | } 230 | while (i < 10) 231 | { 232 | ++i; 233 | if (true) continue; 234 | break; 235 | } 236 | do 237 | { 238 | ++i; 239 | if (true) continue; 240 | break; 241 | } 242 | while (i < 10); 243 | for (int j = 0; j < 100; ++j) 244 | { 245 | for(;;) 246 | { 247 | for (int i = 0, j = 0; i < length; i++, j++) { } 248 | if (true) continue; 249 | break; 250 | } 251 | } 252 | label: 253 | goto label; 254 | label2: ; 255 | foreach (var i in Items()) 256 | { 257 | if (i == 7) 258 | return; 259 | else 260 | continue; 261 | } 262 | checked 263 | { 264 | checked(++i); 265 | } 266 | unchecked 267 | { 268 | unchecked(++i); 269 | } 270 | lock (sync) 271 | process(); 272 | using (var v = BeginScope()) 273 | using (A a = new A()) 274 | using (A a = new A(), b = new A()) 275 | using (BeginScope()) 276 | return; 277 | yield return this.items[3]; 278 | yield break; 279 | fixed (int* p = stackalloc int[100], q = &y) 280 | { 281 | *intref = 1; 282 | } 283 | fixed (int* p = stackalloc int[100]) 284 | { 285 | *intref = 1; 286 | } 287 | unsafe 288 | { 289 | int* p = null; 290 | } 291 | try 292 | { 293 | throw null; 294 | } 295 | catch (System.AccessViolationException av) 296 | { 297 | throw av; 298 | } 299 | catch (Exception) 300 | { 301 | throw; 302 | } 303 | finally 304 | { 305 | try { } catch { } 306 | } 307 | var anonymous = 308 | { 309 | A = 1, 310 | B = 2, 311 | C = 3, 312 | }; 313 | var query = from c in customers 314 | let d = c 315 | where d != null 316 | join c1 in customers on c1.GetHashCode() equals c.GetHashCode() 317 | join c1 in customers on c1.GetHashCode() equals c.GetHashCode() into e 318 | group c by c.Country 319 | into g 320 | orderby g.Count() ascending 321 | orderby g.Key descending 322 | select new { Country = g.Key, CustCount = g.Count() }; 323 | query = from c in customers 324 | select c into d 325 | select d; 326 | } 327 | ~A() 328 | { 329 | } 330 | private readonly int f1; 331 | [Obsolete] 332 | [NonExisting] 333 | [Foo::NonExisting(var, 5)] 334 | [CLSCompliant(false)] 335 | [Obsolete, System.NonSerialized, NonSerialized, CLSCompliant(true || false & true)] 336 | private volatile int f2; 337 | [return: Obsolete] 338 | [method: Obsolete] 339 | public void Handler(object value) 340 | { 341 | } 342 | 343 | public int m(T t) 344 | where T : class, new() 345 | { 346 | base.m(t); 347 | return 1; 348 | } 349 | public string P 350 | { 351 | get 352 | { 353 | return "A"; 354 | } 355 | set; 356 | } 357 | public abstract string P 358 | { 359 | get; 360 | } 361 | public abstract int this[int index] 362 | { 363 | protected internal get; 364 | internal protected set; 365 | } 366 | [method: Obsolete] 367 | [field: Obsolete] 368 | [event: Obsolete] 369 | public readonly event Event E; 370 | [event: Test] 371 | public event Action E1 372 | { 373 | [Obsolete] 374 | add { value = value; } 375 | [Obsolete] 376 | [return: Obsolete] 377 | remove { E += Handler; E -= Handler; } 378 | } 379 | public static A operator +(A first, A second) 380 | { 381 | Delegate handler = new Delegate(Handler); 382 | return first.Add(second); 383 | } 384 | [method: Obsolete] 385 | [return: Obsolete] 386 | public static bool operator true(A a) 387 | { 388 | return true; 389 | } 390 | public static bool operator false(A a) 391 | { 392 | return false; 393 | } 394 | class C 395 | { 396 | } 397 | } 398 | public struct S : I 399 | { 400 | public S() 401 | { 402 | } 403 | private int f1; 404 | [Obsolete("Use Script instead", error: false)] 405 | private volatile int f2; 406 | public abstract int m(T t) 407 | where T : struct 408 | { 409 | return 1; 410 | } 411 | public string P 412 | { 413 | get 414 | { 415 | int value = 0; 416 | return "A"; 417 | } 418 | set; 419 | } 420 | public abstract string P 421 | { 422 | get; 423 | } 424 | public abstract int this[int index] 425 | { 426 | get; 427 | internal protected set; 428 | } 429 | public event Event E; 430 | public static A operator +(A first, A second) 431 | { 432 | return first.Add(second); 433 | } 434 | fixed int field[10]; 435 | class C 436 | { 437 | } 438 | } 439 | public interface I : J 440 | { 441 | void A(int value); 442 | string Value 443 | { 444 | get; 445 | set; 446 | } 447 | unsafe void UpdateSignatureByHashingContent([In]byte* buffer, int size); 448 | } 449 | [type: Flags] 450 | public enum E 451 | { 452 | A, 453 | B = A, 454 | C = 2 + A, 455 | #if DEBUG 456 | D, 457 | } 458 | #else 459 | E, 460 | } 461 | #endif 462 | 463 | 464 | public delegate void Delegate(object P); 465 | namespace Test 466 | { 467 | using System; 468 | using System.Collections; 469 | public class Список 470 | { 471 | public static IEnumerable Power(int number, int exponent) 472 | { 473 | Список Список = new Список(); 474 | Список.Main(); 475 | int counter = (0 + 0); 476 | int אתר = 0; 477 | while (++counter++ < --exponent--) 478 | { 479 | result = result * number + +number+++++number; 480 | yield return result; 481 | } 482 | } 483 | static void Main() 484 | { 485 | foreach (int i in Power(2, 8)) 486 | { 487 | Console.Write("{0} ", i); 488 | } 489 | } 490 | async void Wait() 491 | { 492 | // await System.Threading.Tasks.Task.Foooooooooooooooooooo.Delay(0); 493 | await SystemxThreadingxTasksxTaskxFooooooooooooooooooooxDelay(0); 494 | } 495 | void AsyncAnonymous() // C # 5 feature 496 | { 497 | var task = Task.Factory.StartNew(async () => 498 | { 499 | return await new WebClient().DownloadStringTaskAsync("http://example.com"); 500 | }); 501 | } 502 | } 503 | } 504 | } 505 | 506 | namespace ConsoleApplication1 507 | { 508 | namespace RecursiveGenericBaseType 509 | { 510 | class A : B, A> where T : A 511 | { 512 | protected virtual A M() { } 513 | protected abstract B, A> N() { } 514 | static B, A> O() { } 515 | } 516 | 517 | sealed class B : A> 518 | { 519 | protected override A M() { } 520 | protected sealed override B, A> N() { } 521 | new static A O() { } 522 | } 523 | } 524 | 525 | namespace Boo 526 | { 527 | public class Bar where T : IComparable 528 | { 529 | public T f; 530 | public class Foo : IEnumerable 531 | { 532 | public void Method(K k, T t, U u) 533 | where K : IList, IList, IList 534 | where V : IList 535 | { 536 | A a; 537 | M(A(5)); 538 | } 539 | }; 540 | }; 541 | }; 542 | 543 | class Test 544 | { 545 | void Bar3() 546 | { 547 | var x = new Boo.Bar.Foo(); 548 | x.Method(" ", 5, new object()); 549 | 550 | var q = from i in new int[] { 1, 2, 3, 4 } 551 | where i > 5 552 | select i; 553 | } 554 | 555 | public static implicit operator Test(string s) 556 | { 557 | return new ConsoleApplication1.Test(); 558 | } 559 | public static explicit operator Test(string s = "") 560 | { 561 | return new Test(); 562 | } 563 | 564 | public int foo = 5; 565 | void Bar2() 566 | { 567 | foo = 6; 568 | this.Foo = 5.GetType(); Test t = "sss"; 569 | } 570 | 571 | public event EventHandler MyEvent = delegate { }; 572 | 573 | void Blah() 574 | { 575 | int i = 5; 576 | int? j = 6; 577 | 578 | Expression> e = () => i; 579 | Expression> e2 = b => () => { return; }; 580 | Func f = async delegate (bool a) 581 | { 582 | return await !a; 583 | }; 584 | Func f2 = (a, b) => 0; 585 | f2 = (int a, int b) => 1; 586 | Action a = Blah; 587 | f2 = () => {}; 588 | f2 = () => {;}; 589 | } 590 | 591 | delegate Recursive Recursive(Recursive r); 592 | delegate Recursive Recursive(Recursive r); 593 | 594 | public Type Foo 595 | { 596 | [Obsolete("Name", error = false)] 597 | get 598 | { 599 | var result = typeof(IEnumerable); 600 | var t = typeof(int?) == typeof(Nullable); 601 | t = typeof(IEnumerable); 602 | return typeof(IEnumerable<>); 603 | } 604 | set 605 | { 606 | var t = typeof(System.Int32); 607 | t.ToString(); 608 | t = value; 609 | } 610 | } 611 | 612 | public void Constants() 613 | { 614 | int i = 1 + 2 + 3 + 5; 615 | global::System.String s = "a" + (System.String)"a" + "a" + "a" + "a" + "A"; 616 | } 617 | 618 | public void ConstructedType() 619 | { 620 | List i = null; 621 | int c = i.Count; 622 | } 623 | 624 | class Foo : IDisposable 625 | { 626 | public int N; 627 | public void Dispose(){} 628 | } 629 | 630 | unsafe void EmptyEmbeddedStatment() 631 | { 632 | // useless empty statements get deleted 633 | ; 634 | // but nontrivial ones remain 635 | if (true) ; else if (true); else ; 636 | while(false) ; 637 | do ; while (false); 638 | for(;;); 639 | foreach(var x in ""); 640 | lock(new object()); 641 | using(var d = new Foo()) ; 642 | var o = new Foo(); 643 | fixed(int* d = &o.N); 644 | } 645 | } 646 | } 647 | 648 | namespace Comments.XmlComments.UndocumentedKeywords 649 | { 650 | /// 651 | /// Whatever 652 | /// 653 | /// 654 | /// // 655 | /// /* */ 656 | /// 657 | /// 658 | /// 659 | /// 660 | /// 661 | /// 662 | /// 663 | /// 664 | /// 665 | /// 666 | class /*///*/C 667 | { 668 | void M(T t, U u) 669 | { 670 | // comment 671 | /* *** / */ 672 | /* // 673 | */ 674 | /*s*///comment 675 | // /***/ 676 | /*s*/int /*s*/intValue = 0; 677 | intValue = intValue /*s*/+ 1; 678 | string strValue = /*s*/"hello"; 679 | /*s*/MyClass c = new MyClass(); 680 | string verbatimStr = /*s*/@"\\\\"; 681 | int i = 0 // foo 682 | + 1 // bar 683 | + 2; // qux 684 | i = 3 // foo 685 | + 4 // bar 686 | + 5; // qux 687 | i = strValue != null ? 688 | 6 : // bar 689 | 7; // qux 690 | } 691 | } 692 | 693 | //General Test F. Type a very long class name, verify colorization happens correctly only upto the correct size (118324) 694 | class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/*Scen8*/{ } 695 | 696 | class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX22/*Scen9*/{ } 697 | 698 | class yield 699 | { 700 | void Foo(__arglist) 701 | { 702 | C c = null; 703 | c.M(5, default(U)); 704 | TypedReference tr = __makeref(c); 705 | Type t = __reftype(tr); 706 | int j = __refvalue(tr, int); 707 | Params(a: t, b: t); 708 | Params(ref c, out c); 709 | Params(out var d, out Test d); 710 | } 711 | void Params(ref dynamic a, out dynamic b, params dynamic[] c) {} 712 | void Params(out dynamic a = 2, ref dynamic c = default(dynamic), params dynamic[][] c) {} 713 | 714 | public override string ToString() { return base.ToString(); } 715 | 716 | public partial void OnError(); 717 | 718 | public partial void method() 719 | { 720 | int?[] a = new int?[5];/*[] bug*/ // YES [] 721 | int[] var = { 1, 2, 3, 4, 5 };/*,;*/ 722 | int i = a[i];/*[]*/ 723 | Foo f = new Foo();/*<> ()*/ 724 | f.method();/*().*/ 725 | i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/ 726 | bool b = true & false | true ^ false;/*& | ^*/ 727 | b = !b;/*!*/ 728 | i = ~i;/*~i*/ 729 | b = i < i && i > i;/*< && >*/ 730 | int? ii = 5;/*? bug*/ // NO ? 731 | int f = true ? 1 : 0;/*? :*/ // YES : 732 | i++;/*++*/ 733 | i--;/*--*/ 734 | b = true && false || true;/*&& ||*/ 735 | i << 5;/*<<*/ 736 | i >> 5;/*>>*/ 737 | b = i == i && i != i && i <= i && i >= i;/*= == && != <= >=*/ 738 | i += 5.0;/*+=*/ 739 | i -= i;/*-=*/ 740 | i *= i;/**=*/ 741 | i /= i;/*/=*/ 742 | i %= i;/*%=*/ 743 | i &= i;/*&=*/ 744 | i |= i;/*|=*/ 745 | i ^= i;/*^=*/ 746 | i <<= i;/*<<=*/ 747 | i >>= i;/*>>=*/ 748 | object s = x => x + 1;/*=>*/ 749 | double d = .3; 750 | ; 751 | Point point; 752 | unsafe 753 | { 754 | Point* p = &point;/** &*/ 755 | p->x = 10;/*->*/ 756 | } 757 | IO::BinaryReader br = null; 758 | x[i: 1] = 3; 759 | x[i: 1, j: 5] = "str"; 760 | } 761 | 762 | struct Point { public int X; public int Y; public void ThisAccess() { this = this; } } 763 | } 764 | 765 | // From here:https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6 766 | class CSharp6Features 767 | { 768 | // Initializers for auto-properties 769 | public string First { get; set; } = "Jane"; 770 | public string Last { get; set; } = "Doe"; 771 | 772 | // Getter-only auto-properties 773 | public string Third { get; } = "Jane"; 774 | public string Fourth { get; } = "Doe"; 775 | 776 | // Expression bodies on method-like members 777 | public Point Move(int dx, int dy) => new Point(x + dx, y + dy); 778 | public static Complex operator +(Complex a, Complex b) => a.Add(b); 779 | public static implicit operator string(Person p) => p.First + " " + p.Last; 780 | public void Print() => Console.WriteLine(First + " " + Last); 781 | 782 | // Expression bodies on property-like function members 783 | public string Name => First + " " + Last; 784 | public int this[long id] => id; 785 | 786 | private void NoOp() 787 | { 788 | // Empty body. 789 | } 790 | 791 | async void Test() 792 | { 793 | // Using static 794 | WriteLine(Sqrt(3*3 + 4*4)); 795 | WriteLine(Friday - Monday); 796 | var range = Range(5, 17); // Ok: not extension 797 | var even = range.Where(i => i % 2 == 0); // Ok 798 | 799 | // Null-conditional operators 800 | int? length = customers?.Length; // null if customers is null 801 | Customer first = customers?[0]; // null if customers is null 802 | int length = customers?.Length ?? 0; // 0 if customers is null 803 | int? first = customers?[0]?.Orders?.Count(); 804 | PropertyChanged?.Invoke(this, args); 805 | 806 | // String interpolation 807 | string s = $"{p.Name, 20} is {p.Age:D3} year{{s}} old #"; 808 | s = $"{p.Name} is \"{p.Age} year{(p.Age == 1 ? "" : "s")} old"; 809 | s = $"{(p.Age == 2 ? $"{new Person { } }" : "")}"; 810 | s = $@"\{p.Name} 811 | ""\"; 812 | s = $"Color [ R={func(b: 3):#0.##}, G={G:#0.##}, B={B:#0.##}, A={A:#0.##} ]"; 813 | 814 | Logging.Log.Error($"Some error message text: ({someVariableValue} did not work)"); 815 | 816 | // nameof expressions 817 | if (x == null) 818 | throw new ArgumentNullException(nameof(x)); 819 | WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode" 820 | 821 | // Index initializers 822 | var numbers = new Dictionary { 823 | [7] = "seven", 824 | [9] = "nine", 825 | [13] = "thirteen" 826 | }; 827 | 828 | string LocalFunction(string arg) 829 | { 830 | return arg; 831 | } 832 | 833 | // Exception filters 834 | try {} 835 | catch (MyException e) when (myfilter(e)) 836 | { } 837 | 838 | // Await in catch and finally blocks 839 | Resource res = null; 840 | try 841 | { 842 | res = await Resource.OpenAsync(); // You could do this. 843 | } 844 | catch(ResourceException e) 845 | { 846 | await Resource.LogAsync(res, e); // Now you can do this … 847 | } 848 | finally 849 | { 850 | if (res != null) 851 | await res.CloseAsync(); // … and this. 852 | } 853 | } 854 | } 855 | 856 | class CSharp7Features 857 | { 858 | (string, string, long) Tuples(long id) 859 | { 860 | int a; 861 | // variable assignment is valid inside a tuple literal. 862 | var foo = (2, a=1); 863 | 864 | var unnamed = ("one", "two", "three"); 865 | var named = (first: "one", second: "two"); 866 | (string, long) foo = ("foo", 42); 867 | (int? a, int? b) nullableMembers = (5, 10); 868 | (int, (int, int)) nestedTuple = (1, (2, 3)); 869 | var (a, b, c) = Tuples(42); 870 | (a, b, c) = (a, b, c); 871 | return (named.first, named.second, id); 872 | } 873 | 874 | int ThrowExpressionExample() => 875 | 3 == 3 ? 2 : throw new Exception(); 876 | 877 | class C : Exception 878 | { 879 | public static C operator +(C c1, C c2) => default; 880 | void ThrowBinaryExpression() 881 | { 882 | throw new C() + new C(); 883 | } 884 | } 885 | 886 | void IsPatternMatch() { 887 | if (3 is int foo) {} 888 | if (3 is var bar) {} 889 | if (3 is 3) {} 890 | if (new object() is null) {} 891 | if (0 is default(int) - 3) {} 892 | if (true is false ^ false) {} 893 | if (8 is sizeof(long)) {} 894 | } 895 | 896 | void UnmanagedConstraint() where T : unmanaged { } 897 | } 898 | } 899 | 900 | namespace Empty 901 | { 902 | // Don't forget this comment! 903 | } 904 | 905 | #line 6 906 | #line 2 "test.cs" 907 | #line default 908 | #line hidden 909 | -------------------------------------------------------------------------------- /src/csharp/CSharpParser.g4: -------------------------------------------------------------------------------- 1 | // Eclipse Public License - v 1.0, http://www.eclipse.org/legal/epl-v10.html 2 | // Copyright (c) 2013, Christian Wulf (chwchw@gmx.de) 3 | // Copyright (c) 2016-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. 4 | 5 | parser grammar CSharpParser; 6 | 7 | options { tokenVocab=CSharpLexer; } 8 | 9 | // entry point 10 | compilation_unit 11 | : BYTE_ORDER_MARK? extern_alias_directives? using_directives? 12 | global_attribute_section* namespace_member_declarations? EOF 13 | ; 14 | 15 | //B.2 Syntactic grammar 16 | 17 | //B.2.1 Basic concepts 18 | 19 | namespace_or_type_name 20 | : (identifier type_argument_list? | qualified_alias_member) ('.' identifier type_argument_list?)* 21 | ; 22 | 23 | //B.2.2 Types 24 | type 25 | : base_type ('?' | rank_specifier | '*')* 26 | ; 27 | 28 | base_type 29 | : simple_type 30 | | class_type // represents types: enum, class, interface, delegate, type_parameter 31 | | tuple_type 32 | | VOID '*' 33 | ; 34 | 35 | simple_type 36 | : numeric_type 37 | | BOOL 38 | ; 39 | 40 | numeric_type 41 | : integral_type 42 | | floating_point_type 43 | | DECIMAL 44 | ; 45 | 46 | integral_type 47 | : SBYTE 48 | | BYTE 49 | | SHORT 50 | | USHORT 51 | | INT 52 | | UINT 53 | | LONG 54 | | ULONG 55 | | CHAR 56 | ; 57 | 58 | floating_point_type 59 | : FLOAT 60 | | DOUBLE 61 | ; 62 | 63 | tuple_type 64 | : OPEN_PARENS tuple_element_type ( ',' tuple_element_type)* CLOSE_PARENS 65 | ; 66 | 67 | tuple_element_type 68 | : type identifier? 69 | ; 70 | 71 | /** namespace_or_type_name, OBJECT, STRING */ 72 | class_type 73 | : namespace_or_type_name 74 | | OBJECT 75 | | DYNAMIC 76 | | STRING 77 | ; 78 | 79 | type_argument_list 80 | : '<' type ( ',' type)* '>' 81 | ; 82 | 83 | //B.2.4 Expressions 84 | argument_list 85 | : argument ( ',' argument)* 86 | ; 87 | 88 | argument 89 | : (identifier ':')? refout=(REF | OUT)? typed_argument 90 | ; 91 | 92 | typed_argument 93 | : expression 94 | | (VAR | type) expression 95 | ; 96 | 97 | expression 98 | : assignment 99 | | non_assignment_expression 100 | ; 101 | 102 | non_assignment_expression 103 | : lambda_expression 104 | | query_expression 105 | | conditional_expression 106 | | throw_expression 107 | ; 108 | 109 | throw_expression 110 | : THROW expression 111 | ; 112 | 113 | assignment 114 | : unary_expression assignment_operator expression 115 | ; 116 | 117 | assignment_operator 118 | : '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | right_shift_assignment 119 | ; 120 | 121 | conditional_expression 122 | : null_coalescing_expression ('?' expression ':' expression)? 123 | ; 124 | 125 | null_coalescing_expression 126 | : conditional_or_expression ('??' null_coalescing_expression)? 127 | ; 128 | 129 | conditional_or_expression 130 | : conditional_and_expression (OP_OR conditional_and_expression)* 131 | ; 132 | 133 | conditional_and_expression 134 | : inclusive_or_expression (OP_AND inclusive_or_expression)* 135 | ; 136 | 137 | inclusive_or_expression 138 | : exclusive_or_expression ('|' exclusive_or_expression)* 139 | ; 140 | 141 | exclusive_or_expression 142 | : and_expression ('^' and_expression)* 143 | ; 144 | 145 | and_expression 146 | : equality_expression ('&' equality_expression)* 147 | ; 148 | 149 | equality_expression 150 | : relational_expression ((OP_EQ | OP_NE) relational_expression)* 151 | ; 152 | 153 | relational_expression 154 | : shift_expression (('<' | '>' | '<=' | '>=') shift_expression | IS pattern | AS type)* 155 | ; 156 | 157 | shift_expression 158 | : additive_expression (('<<' | right_shift) additive_expression)* 159 | ; 160 | 161 | additive_expression 162 | : multiplicative_expression (('+' | '-') multiplicative_expression)* 163 | ; 164 | 165 | multiplicative_expression 166 | : unary_expression (('*' | '/' | '%') unary_expression)* 167 | ; 168 | 169 | // https://msdn.microsoft.com/library/6a71f45d(v=vs.110).aspx 170 | unary_expression 171 | : primary_expression 172 | | '+' unary_expression 173 | | '-' unary_expression 174 | | BANG unary_expression 175 | | '~' unary_expression 176 | | '++' unary_expression 177 | | '--' unary_expression 178 | | OPEN_PARENS type CLOSE_PARENS unary_expression 179 | | AWAIT unary_expression 180 | | '&' unary_expression 181 | | '*' unary_expression 182 | ; 183 | 184 | primary_expression 185 | : primary_expression_start bracket_expression* 186 | ((('?'? '.' simple_name) | method_invocation | '++' | '--' | '->' identifier) bracket_expression*)* 187 | ; 188 | 189 | primary_expression_start 190 | : literal #literalExpression 191 | | simple_name #simpleNameExpression 192 | | OPEN_PARENS expression CLOSE_PARENS #parenthesisExpressions 193 | | tuple_literal #tupleExpression 194 | | predefined_type #predefinedTypeExpression 195 | | qualified_alias_member #qualifiedAliasMemberExpression 196 | | LITERAL_ACCESS #literalAccessExpression 197 | | THIS #thisReferenceExpression 198 | | BASE ('.' identifier type_argument_list? | '[' expression_list ']') #baseAccessExpression 199 | | NEW (type (object_creation_expression 200 | | object_or_collection_initializer 201 | | '[' expression_list ']' rank_specifier* array_initializer? 202 | | rank_specifier+ array_initializer) 203 | | anonymous_object_initializer 204 | | rank_specifier array_initializer) #newExpression 205 | | TYPEOF OPEN_PARENS (unbound_type_name | type | VOID) CLOSE_PARENS #typeofExpression 206 | | CHECKED OPEN_PARENS expression CLOSE_PARENS #checkedExpression 207 | | UNCHECKED OPEN_PARENS expression CLOSE_PARENS #uncheckedExpression 208 | | DEFAULT (OPEN_PARENS type CLOSE_PARENS)? #defaultValueExpression 209 | | ASYNC? DELEGATE (OPEN_PARENS 210 | explicit_anonymous_function_parameter_list? CLOSE_PARENS)? block #anonymousMethodExpression 211 | | SIZEOF OPEN_PARENS type CLOSE_PARENS #sizeofExpression 212 | | NAMEOF OPEN_PARENS (identifier '.')* identifier CLOSE_PARENS #nameofExpression 213 | ; 214 | 215 | simple_name 216 | : identifier type_argument_list? 217 | ; 218 | 219 | bracket_expression 220 | : '?'? '[' indexer_argument ( ',' indexer_argument)* ']' 221 | ; 222 | 223 | indexer_argument 224 | : (identifier ':')? expression 225 | ; 226 | 227 | predefined_type 228 | : BOOL | BYTE | CHAR | DECIMAL | DOUBLE | FLOAT | INT | LONG 229 | | OBJECT | SBYTE | SHORT | STRING | UINT | ULONG | USHORT 230 | ; 231 | 232 | expression_list 233 | : expression (',' expression)* 234 | ; 235 | 236 | object_or_collection_initializer 237 | : object_initializer 238 | | collection_initializer 239 | ; 240 | 241 | object_initializer 242 | : OPEN_BRACE (member_initializer_list ','?)? CLOSE_BRACE 243 | ; 244 | 245 | member_initializer_list 246 | : member_initializer (',' member_initializer)* 247 | ; 248 | 249 | member_initializer 250 | : (identifier | '[' expression ']') '=' initializer_value 251 | ; 252 | 253 | initializer_value 254 | : expression 255 | | object_or_collection_initializer 256 | ; 257 | 258 | collection_initializer 259 | : OPEN_BRACE element_initializer (',' element_initializer)* ','? CLOSE_BRACE 260 | ; 261 | 262 | tuple_literal 263 | : OPEN_PARENS tuple_element_initializer (',' tuple_element_initializer)+ CLOSE_PARENS 264 | ; 265 | 266 | tuple_element_initializer 267 | : (identifier ':')? expression 268 | ; 269 | 270 | element_initializer 271 | : non_assignment_expression 272 | | OPEN_BRACE expression_list CLOSE_BRACE 273 | ; 274 | 275 | anonymous_object_initializer 276 | : OPEN_BRACE (member_declarator_list ','?)? CLOSE_BRACE 277 | ; 278 | 279 | member_declarator_list 280 | : member_declarator ( ',' member_declarator)* 281 | ; 282 | 283 | member_declarator 284 | : primary_expression 285 | | identifier '=' expression 286 | ; 287 | 288 | unbound_type_name 289 | : identifier ( generic_dimension_specifier? | '::' identifier generic_dimension_specifier?) 290 | ('.' identifier generic_dimension_specifier?)* 291 | ; 292 | 293 | generic_dimension_specifier 294 | : '<' ','* '>' 295 | ; 296 | 297 | pattern 298 | : conditional_or_expression #constantPattern 299 | | type identifier? #typePattern 300 | | VAR identifier #varPattern 301 | ; 302 | 303 | local_function_declaration 304 | : typed_member_declaration 305 | | VOID method_declaration 306 | ; 307 | 308 | lambda_expression 309 | : ASYNC? anonymous_function_signature right_arrow anonymous_function_body 310 | ; 311 | 312 | anonymous_function_signature 313 | : OPEN_PARENS CLOSE_PARENS 314 | | OPEN_PARENS explicit_anonymous_function_parameter_list CLOSE_PARENS 315 | | OPEN_PARENS implicit_anonymous_function_parameter_list CLOSE_PARENS 316 | | identifier 317 | ; 318 | 319 | explicit_anonymous_function_parameter_list 320 | : explicit_anonymous_function_parameter ( ',' explicit_anonymous_function_parameter)* 321 | ; 322 | 323 | explicit_anonymous_function_parameter 324 | : refout=(REF | OUT)? type identifier 325 | ; 326 | 327 | implicit_anonymous_function_parameter_list 328 | : identifier (',' identifier)* 329 | ; 330 | 331 | anonymous_function_body 332 | : expression 333 | | block 334 | ; 335 | 336 | query_expression 337 | : from_clause query_body 338 | ; 339 | 340 | from_clause 341 | : FROM type? identifier IN expression 342 | ; 343 | 344 | query_body 345 | : query_body_clause* select_or_group_clause query_continuation? 346 | ; 347 | 348 | query_body_clause 349 | : from_clause 350 | | let_clause 351 | | where_clause 352 | | combined_join_clause 353 | | orderby_clause 354 | ; 355 | 356 | let_clause 357 | : LET identifier '=' expression 358 | ; 359 | 360 | where_clause 361 | : WHERE expression 362 | ; 363 | 364 | combined_join_clause 365 | : JOIN type? identifier IN expression ON expression EQUALS expression (INTO identifier)? 366 | ; 367 | 368 | orderby_clause 369 | : ORDERBY ordering (',' ordering)* 370 | ; 371 | 372 | ordering 373 | : expression dir=(ASCENDING | DESCENDING)? 374 | ; 375 | 376 | select_or_group_clause 377 | : SELECT expression 378 | | GROUP expression BY expression 379 | ; 380 | 381 | query_continuation 382 | : INTO identifier query_body 383 | ; 384 | 385 | //B.2.5 Statements 386 | statement 387 | : ';' #emptyStatement 388 | | labeled_statement #labeledStatement 389 | | (local_variable_declaration | local_constant_declaration) ';' #variableDeclarationStatement 390 | | local_function_declaration #functionDeclarationStatement 391 | | embedded_statement #embeddedStatement 392 | ; 393 | 394 | labeled_statement 395 | : identifier ':' statement 396 | ; 397 | 398 | empty_embedded_statement 399 | : ';' 400 | ; 401 | 402 | embedded_statement 403 | : empty_embedded_statement 404 | | block 405 | | simple_embedded_statement 406 | ; 407 | 408 | simple_embedded_statement 409 | : expression ';' #expressionStatement 410 | 411 | // selection statements 412 | | IF OPEN_PARENS expression CLOSE_PARENS embedded_statement (ELSE embedded_statement)? #ifStatement 413 | | SWITCH OPEN_PARENS expression CLOSE_PARENS OPEN_BRACE switch_section* CLOSE_BRACE #switchStatement 414 | 415 | // iteration statements 416 | | WHILE OPEN_PARENS expression CLOSE_PARENS embedded_statement #whileStatement 417 | | DO embedded_statement WHILE OPEN_PARENS expression CLOSE_PARENS ';' #doStatement 418 | | FOR OPEN_PARENS for_initializer? ';' expression? ';' for_iterator? CLOSE_PARENS embedded_statement #forStatement 419 | | FOREACH OPEN_PARENS local_variable_type identifier IN expression CLOSE_PARENS embedded_statement #foreachStatement 420 | 421 | // jump statements 422 | | BREAK ';' #breakStatement 423 | | CONTINUE ';' #continueStatement 424 | | GOTO (identifier | CASE expression | DEFAULT) ';' #gotoStatement 425 | | RETURN expression? ';' #returnStatement 426 | | THROW expression? ';' #throwStatement 427 | 428 | | TRY block (catch_clauses finally_clause? | finally_clause) #tryStatement 429 | | CHECKED block #checkedStatement 430 | | UNCHECKED block #uncheckedStatement 431 | | LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement #lockStatement 432 | | USING OPEN_PARENS resource_acquisition CLOSE_PARENS embedded_statement #usingStatement 433 | | YIELD (RETURN expression | BREAK) ';' #yieldStatement 434 | 435 | // unsafe statements 436 | | UNSAFE block #unsafeStatement 437 | | FIXED OPEN_PARENS pointer_type fixed_pointer_declarators CLOSE_PARENS embedded_statement #fixedStatement 438 | ; 439 | 440 | block 441 | : OPEN_BRACE statement_list? CLOSE_BRACE 442 | ; 443 | 444 | local_variable_declaration 445 | : local_variable_type local_variable_declarator ( ',' local_variable_declarator)* 446 | ; 447 | 448 | local_variable_type 449 | : VAR 450 | | type 451 | ; 452 | 453 | local_variable_declarator 454 | : local_variable_identifier ('=' local_variable_initializer)? 455 | ; 456 | 457 | local_variable_identifier 458 | : identifier 459 | | OPEN_PARENS identifier (',' identifier)* CLOSE_PARENS 460 | ; 461 | 462 | local_variable_initializer 463 | : expression 464 | | array_initializer 465 | | local_variable_initializer_unsafe 466 | ; 467 | 468 | local_constant_declaration 469 | : CONST type constant_declarators 470 | ; 471 | 472 | switch_section 473 | : switch_label+ statement_list 474 | ; 475 | 476 | switch_label 477 | : CASE type? expression switch_filter? ':' 478 | | DEFAULT ':' 479 | ; 480 | 481 | switch_filter 482 | : WHEN conditional_expression 483 | ; 484 | 485 | statement_list 486 | : statement+ 487 | ; 488 | 489 | for_initializer 490 | : local_variable_declaration 491 | | expression (',' expression)* 492 | ; 493 | 494 | for_iterator 495 | : expression (',' expression)* 496 | ; 497 | 498 | catch_clauses 499 | : specific_catch_clause (specific_catch_clause)* general_catch_clause? 500 | | general_catch_clause 501 | ; 502 | 503 | specific_catch_clause 504 | : CATCH OPEN_PARENS class_type identifier? CLOSE_PARENS exception_filter? block 505 | ; 506 | 507 | general_catch_clause 508 | : CATCH exception_filter? block 509 | ; 510 | 511 | exception_filter 512 | : WHEN OPEN_PARENS expression CLOSE_PARENS 513 | ; 514 | 515 | finally_clause 516 | : FINALLY block 517 | ; 518 | 519 | resource_acquisition 520 | : local_variable_declaration 521 | | expression 522 | ; 523 | 524 | //B.2.6 Namespaces; 525 | namespace_declaration 526 | : NAMESPACE qi=qualified_identifier namespace_body ';'? 527 | ; 528 | 529 | qualified_identifier 530 | : identifier ( '.' identifier )* 531 | ; 532 | 533 | namespace_body 534 | : OPEN_BRACE extern_alias_directives? using_directives? namespace_member_declarations? CLOSE_BRACE 535 | ; 536 | 537 | extern_alias_directives 538 | : extern_alias_directive+ 539 | ; 540 | 541 | extern_alias_directive 542 | : EXTERN ALIAS identifier ';' 543 | ; 544 | 545 | using_directives 546 | : using_directive+ 547 | ; 548 | 549 | using_directive 550 | : USING identifier '=' namespace_or_type_name ';' #usingAliasDirective 551 | | USING namespace_or_type_name ';' #usingNamespaceDirective 552 | | USING STATIC namespace_or_type_name ';' #usingStaticDirective 553 | ; 554 | 555 | namespace_member_declarations 556 | : namespace_member_declaration+ 557 | ; 558 | 559 | namespace_member_declaration 560 | : namespace_declaration 561 | | type_declaration 562 | ; 563 | 564 | type_declaration 565 | : attributes? all_member_modifiers? 566 | (class_definition | struct_definition | interface_definition | enum_definition | delegate_definition) 567 | ; 568 | 569 | qualified_alias_member 570 | : identifier '::' identifier type_argument_list? 571 | ; 572 | 573 | //B.2.7 Classes; 574 | type_parameter_list 575 | : '<' type_parameter (',' type_parameter)* '>' 576 | ; 577 | 578 | type_parameter 579 | : attributes? identifier 580 | ; 581 | 582 | class_base 583 | : ':' class_type (',' namespace_or_type_name)* 584 | ; 585 | 586 | interface_type_list 587 | : namespace_or_type_name (',' namespace_or_type_name)* 588 | ; 589 | 590 | type_parameter_constraints_clauses 591 | : type_parameter_constraints_clause+ 592 | ; 593 | 594 | type_parameter_constraints_clause 595 | : WHERE identifier ':' type_parameter_constraints 596 | ; 597 | 598 | type_parameter_constraints 599 | : constructor_constraint 600 | | primary_constraint (',' secondary_constraints)? (',' constructor_constraint)? 601 | ; 602 | 603 | primary_constraint 604 | : class_type 605 | | CLASS 606 | | STRUCT 607 | | UNMANAGED 608 | ; 609 | 610 | // namespace_or_type_name includes identifier 611 | secondary_constraints 612 | : namespace_or_type_name (',' namespace_or_type_name)* 613 | ; 614 | 615 | constructor_constraint 616 | : NEW OPEN_PARENS CLOSE_PARENS 617 | ; 618 | 619 | class_body 620 | : OPEN_BRACE class_member_declarations? CLOSE_BRACE 621 | ; 622 | 623 | class_member_declarations 624 | : class_member_declaration+ 625 | ; 626 | 627 | class_member_declaration 628 | : attributes? all_member_modifiers? (common_member_declaration | destructor_definition) 629 | ; 630 | 631 | all_member_modifiers 632 | : all_member_modifier+ 633 | ; 634 | 635 | all_member_modifier 636 | : NEW 637 | | PUBLIC 638 | | PROTECTED 639 | | INTERNAL 640 | | PRIVATE 641 | | READONLY 642 | | VOLATILE 643 | | VIRTUAL 644 | | SEALED 645 | | OVERRIDE 646 | | ABSTRACT 647 | | STATIC 648 | | UNSAFE 649 | | EXTERN 650 | | PARTIAL 651 | | ASYNC 652 | ; 653 | 654 | // represents the intersection of struct_member_declaration and class_member_declaration 655 | common_member_declaration 656 | : constant_declaration 657 | | typed_member_declaration 658 | | event_declaration 659 | | conversion_operator_declarator (body | right_arrow expression ';') 660 | | constructor_declaration 661 | | VOID method_declaration 662 | | class_definition 663 | | struct_definition 664 | | interface_definition 665 | | enum_definition 666 | | delegate_definition 667 | ; 668 | 669 | typed_member_declaration 670 | : type 671 | ( namespace_or_type_name '.' indexer_declaration 672 | | method_declaration 673 | | property_declaration 674 | | indexer_declaration 675 | | operator_declaration 676 | | field_declaration 677 | ) 678 | ; 679 | 680 | constant_declarators 681 | : constant_declarator (',' constant_declarator)* 682 | ; 683 | 684 | constant_declarator 685 | : identifier '=' expression 686 | ; 687 | 688 | variable_declarators 689 | : variable_declarator (',' variable_declarator)* 690 | ; 691 | 692 | variable_declarator 693 | : identifier ('=' variable_initializer)? 694 | ; 695 | 696 | variable_initializer 697 | : expression 698 | | array_initializer 699 | ; 700 | 701 | return_type 702 | : type 703 | | VOID 704 | ; 705 | 706 | member_name 707 | : namespace_or_type_name 708 | ; 709 | 710 | method_body 711 | : block 712 | | ';' 713 | ; 714 | 715 | formal_parameter_list 716 | : parameter_array 717 | | fixed_parameters (',' parameter_array)? 718 | ; 719 | 720 | fixed_parameters 721 | : fixed_parameter ( ',' fixed_parameter )* 722 | ; 723 | 724 | fixed_parameter 725 | : attributes? parameter_modifier? arg_declaration 726 | | ARGLIST 727 | ; 728 | 729 | parameter_modifier 730 | : REF 731 | | OUT 732 | | THIS 733 | ; 734 | 735 | parameter_array 736 | : attributes? PARAMS array_type identifier 737 | ; 738 | 739 | accessor_declarations 740 | : attrs=attributes? mods=accessor_modifier? 741 | (GET accessor_body set_accessor_declaration? | SET accessor_body get_accessor_declaration?) 742 | ; 743 | 744 | get_accessor_declaration 745 | : attributes? accessor_modifier? GET accessor_body 746 | ; 747 | 748 | set_accessor_declaration 749 | : attributes? accessor_modifier? SET accessor_body 750 | ; 751 | 752 | accessor_modifier 753 | : PROTECTED 754 | | INTERNAL 755 | | PRIVATE 756 | | PROTECTED INTERNAL 757 | | INTERNAL PROTECTED 758 | ; 759 | 760 | accessor_body 761 | : block 762 | | ';' 763 | ; 764 | 765 | event_accessor_declarations 766 | : attributes? (ADD block remove_accessor_declaration | REMOVE block add_accessor_declaration) 767 | ; 768 | 769 | add_accessor_declaration 770 | : attributes? ADD block 771 | ; 772 | 773 | remove_accessor_declaration 774 | : attributes? REMOVE block 775 | ; 776 | 777 | overloadable_operator 778 | : '+' 779 | | '-' 780 | | BANG 781 | | '~' 782 | | '++' 783 | | '--' 784 | | TRUE 785 | | FALSE 786 | | '*' 787 | | '/' 788 | | '%' 789 | | '&' 790 | | '|' 791 | | '^' 792 | | '<<' 793 | | right_shift 794 | | OP_EQ 795 | | OP_NE 796 | | '>' 797 | | '<' 798 | | '>=' 799 | | '<=' 800 | ; 801 | 802 | conversion_operator_declarator 803 | : (IMPLICIT | EXPLICIT) OPERATOR type OPEN_PARENS arg_declaration CLOSE_PARENS 804 | ; 805 | 806 | constructor_initializer 807 | : ':' (BASE | THIS) OPEN_PARENS argument_list? CLOSE_PARENS 808 | ; 809 | 810 | body 811 | : block 812 | | ';' 813 | ; 814 | 815 | //B.2.8 Structs 816 | struct_interfaces 817 | : ':' interface_type_list 818 | ; 819 | 820 | struct_body 821 | : OPEN_BRACE struct_member_declaration* CLOSE_BRACE 822 | ; 823 | 824 | struct_member_declaration 825 | : attributes? all_member_modifiers? 826 | (common_member_declaration | FIXED type fixed_size_buffer_declarator+ ';') 827 | ; 828 | 829 | //B.2.9 Arrays 830 | array_type 831 | : base_type (('*' | '?')* rank_specifier)+ 832 | ; 833 | 834 | rank_specifier 835 | : '[' ','* ']' 836 | ; 837 | 838 | array_initializer 839 | : OPEN_BRACE (variable_initializer (',' variable_initializer)* ','?)? CLOSE_BRACE 840 | ; 841 | 842 | //B.2.10 Interfaces 843 | variant_type_parameter_list 844 | : '<' variant_type_parameter (',' variant_type_parameter)* '>' 845 | ; 846 | 847 | variant_type_parameter 848 | : attributes? variance_annotation? identifier 849 | ; 850 | 851 | variance_annotation 852 | : IN | OUT 853 | ; 854 | 855 | interface_base 856 | : ':' interface_type_list 857 | ; 858 | 859 | interface_body 860 | : OPEN_BRACE interface_member_declaration* CLOSE_BRACE 861 | ; 862 | 863 | interface_member_declaration 864 | : attributes? NEW? 865 | (UNSAFE? type 866 | ( identifier type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ';' 867 | | identifier OPEN_BRACE interface_accessors CLOSE_BRACE 868 | | THIS '[' formal_parameter_list ']' OPEN_BRACE interface_accessors CLOSE_BRACE) 869 | | UNSAFE? VOID identifier type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ';' 870 | | EVENT type identifier ';') 871 | ; 872 | 873 | interface_accessors 874 | : attributes? (GET ';' (attributes? SET ';')? | SET ';' (attributes? GET ';')?) 875 | ; 876 | 877 | //B.2.11 Enums 878 | enum_base 879 | : ':' type 880 | ; 881 | 882 | enum_body 883 | : OPEN_BRACE (enum_member_declaration (',' enum_member_declaration)* ','?)? CLOSE_BRACE 884 | ; 885 | 886 | enum_member_declaration 887 | : attributes? identifier ('=' expression)? 888 | ; 889 | 890 | //B.2.12 Delegates 891 | 892 | //B.2.13 Attributes 893 | global_attribute_section 894 | : '[' global_attribute_target ':' attribute_list ','? ']' 895 | ; 896 | 897 | global_attribute_target 898 | : keyword 899 | | identifier 900 | ; 901 | 902 | attributes 903 | : attribute_section+ 904 | ; 905 | 906 | attribute_section 907 | : '[' (attribute_target ':')? attribute_list ','? ']' 908 | ; 909 | 910 | attribute_target 911 | : keyword 912 | | identifier 913 | ; 914 | 915 | attribute_list 916 | : attribute (',' attribute)* 917 | ; 918 | 919 | attribute 920 | : namespace_or_type_name (OPEN_PARENS (attribute_argument (',' attribute_argument)*)? CLOSE_PARENS)? 921 | ; 922 | 923 | attribute_argument 924 | : (identifier ':')? expression 925 | ; 926 | 927 | //B.3 Grammar extensions for unsafe code 928 | pointer_type 929 | : (simple_type | class_type) (rank_specifier | '?')* '*' 930 | | VOID '*' 931 | ; 932 | 933 | fixed_pointer_declarators 934 | : fixed_pointer_declarator (',' fixed_pointer_declarator)* 935 | ; 936 | 937 | fixed_pointer_declarator 938 | : identifier '=' fixed_pointer_initializer 939 | ; 940 | 941 | fixed_pointer_initializer 942 | : '&'? expression 943 | | local_variable_initializer_unsafe 944 | ; 945 | 946 | fixed_size_buffer_declarator 947 | : identifier '[' expression ']' 948 | ; 949 | 950 | local_variable_initializer_unsafe 951 | : STACKALLOC type '[' expression ']' 952 | ; 953 | 954 | right_arrow 955 | : first='=' second='>' {$first.index + 1 == $second.index}? // Nothing between the tokens? 956 | ; 957 | 958 | right_shift 959 | : first='>' second='>' {$first.index + 1 == $second.index}? // Nothing between the tokens? 960 | ; 961 | 962 | right_shift_assignment 963 | : first='>' second='>=' {$first.index + 1 == $second.index}? // Nothing between the tokens? 964 | ; 965 | 966 | literal 967 | : boolean_literal 968 | | string_literal 969 | | INTEGER_LITERAL 970 | | HEX_INTEGER_LITERAL 971 | | REAL_LITERAL 972 | | CHARACTER_LITERAL 973 | | NULL 974 | ; 975 | 976 | boolean_literal 977 | : TRUE 978 | | FALSE 979 | ; 980 | 981 | string_literal 982 | : interpolated_regular_string 983 | | interpolated_verbatim_string 984 | | REGULAR_STRING 985 | | VERBATIM_STRING 986 | ; 987 | 988 | interpolated_regular_string 989 | : INTERPOLATED_REGULAR_STRING_START interpolated_regular_string_part* DOUBLE_QUOTE_INSIDE 990 | ; 991 | 992 | 993 | interpolated_verbatim_string 994 | : INTERPOLATED_VERBATIM_STRING_START interpolated_verbatim_string_part* DOUBLE_QUOTE_INSIDE 995 | ; 996 | 997 | interpolated_regular_string_part 998 | : interpolated_string_expression 999 | | DOUBLE_CURLY_INSIDE 1000 | | REGULAR_CHAR_INSIDE 1001 | | REGULAR_STRING_INSIDE 1002 | ; 1003 | 1004 | interpolated_verbatim_string_part 1005 | : interpolated_string_expression 1006 | | DOUBLE_CURLY_INSIDE 1007 | | VERBATIM_DOUBLE_QUOTE_INSIDE 1008 | | VERBATIM_INSIDE_STRING 1009 | ; 1010 | 1011 | interpolated_string_expression 1012 | : expression (',' expression)* (':' FORMAT_STRING+)? 1013 | ; 1014 | 1015 | //B.1.7 Keywords 1016 | keyword 1017 | : ABSTRACT 1018 | | AS 1019 | | BASE 1020 | | BOOL 1021 | | BREAK 1022 | | BYTE 1023 | | CASE 1024 | | CATCH 1025 | | CHAR 1026 | | CHECKED 1027 | | CLASS 1028 | | CONST 1029 | | CONTINUE 1030 | | DECIMAL 1031 | | DEFAULT 1032 | | DELEGATE 1033 | | DO 1034 | | DOUBLE 1035 | | ELSE 1036 | | ENUM 1037 | | EVENT 1038 | | EXPLICIT 1039 | | EXTERN 1040 | | FALSE 1041 | | FINALLY 1042 | | FIXED 1043 | | FLOAT 1044 | | FOR 1045 | | FOREACH 1046 | | GOTO 1047 | | IF 1048 | | IMPLICIT 1049 | | IN 1050 | | INT 1051 | | INTERFACE 1052 | | INTERNAL 1053 | | IS 1054 | | LOCK 1055 | | LONG 1056 | | NAMESPACE 1057 | | NEW 1058 | | NULL 1059 | | OBJECT 1060 | | OPERATOR 1061 | | OUT 1062 | | OVERRIDE 1063 | | PARAMS 1064 | | PRIVATE 1065 | | PROTECTED 1066 | | PUBLIC 1067 | | READONLY 1068 | | REF 1069 | | RETURN 1070 | | SBYTE 1071 | | SEALED 1072 | | SHORT 1073 | | SIZEOF 1074 | | STACKALLOC 1075 | | STATIC 1076 | | STRING 1077 | | STRUCT 1078 | | SWITCH 1079 | | THIS 1080 | | THROW 1081 | | TRUE 1082 | | TRY 1083 | | TYPEOF 1084 | | UINT 1085 | | ULONG 1086 | | UNCHECKED 1087 | | UNSAFE 1088 | | USHORT 1089 | | USING 1090 | | VIRTUAL 1091 | | VOID 1092 | | VOLATILE 1093 | | WHILE 1094 | ; 1095 | 1096 | // -------------------- extra rules for modularization -------------------------------- 1097 | 1098 | class_definition 1099 | : CLASS identifier type_parameter_list? class_base? type_parameter_constraints_clauses? 1100 | class_body ';'? 1101 | ; 1102 | 1103 | struct_definition 1104 | : STRUCT identifier type_parameter_list? struct_interfaces? type_parameter_constraints_clauses? 1105 | struct_body ';'? 1106 | ; 1107 | 1108 | interface_definition 1109 | : INTERFACE identifier variant_type_parameter_list? interface_base? 1110 | type_parameter_constraints_clauses? interface_body ';'? 1111 | ; 1112 | 1113 | enum_definition 1114 | : ENUM identifier enum_base? enum_body ';'? 1115 | ; 1116 | 1117 | delegate_definition 1118 | : DELEGATE return_type identifier variant_type_parameter_list? 1119 | OPEN_PARENS formal_parameter_list? CLOSE_PARENS type_parameter_constraints_clauses? ';' 1120 | ; 1121 | 1122 | event_declaration 1123 | : EVENT type (variable_declarators ';' | member_name OPEN_BRACE event_accessor_declarations CLOSE_BRACE) 1124 | ; 1125 | 1126 | field_declaration 1127 | : variable_declarators ';' 1128 | ; 1129 | 1130 | property_declaration 1131 | : member_name (OPEN_BRACE accessor_declarations CLOSE_BRACE ('=' variable_initializer ';')? | right_arrow expression ';') 1132 | ; 1133 | 1134 | constant_declaration 1135 | : CONST type constant_declarators ';' 1136 | ; 1137 | 1138 | indexer_declaration 1139 | : THIS '[' formal_parameter_list ']' (OPEN_BRACE accessor_declarations CLOSE_BRACE | right_arrow expression ';') 1140 | ; 1141 | 1142 | destructor_definition 1143 | : '~' identifier OPEN_PARENS CLOSE_PARENS body 1144 | ; 1145 | 1146 | constructor_declaration 1147 | : identifier OPEN_PARENS formal_parameter_list? CLOSE_PARENS constructor_initializer? body 1148 | ; 1149 | 1150 | method_declaration 1151 | : method_member_name type_parameter_list? OPEN_PARENS formal_parameter_list? CLOSE_PARENS 1152 | type_parameter_constraints_clauses? (method_body | right_arrow expression ';') 1153 | ; 1154 | 1155 | method_member_name 1156 | : (identifier | identifier '::' identifier) (type_argument_list? '.' identifier)* 1157 | ; 1158 | 1159 | operator_declaration 1160 | : OPERATOR overloadable_operator OPEN_PARENS arg_declaration 1161 | (',' arg_declaration)? CLOSE_PARENS (body | right_arrow expression ';') 1162 | ; 1163 | 1164 | arg_declaration 1165 | : type identifier ('=' expression)? 1166 | ; 1167 | 1168 | method_invocation 1169 | : OPEN_PARENS argument_list? CLOSE_PARENS 1170 | ; 1171 | 1172 | object_creation_expression 1173 | : OPEN_PARENS argument_list? CLOSE_PARENS object_or_collection_initializer? 1174 | ; 1175 | 1176 | identifier 1177 | : IDENTIFIER 1178 | | ADD 1179 | | ALIAS 1180 | | ARGLIST 1181 | | ASCENDING 1182 | | ASYNC 1183 | | AWAIT 1184 | | BY 1185 | | DESCENDING 1186 | | DYNAMIC 1187 | | EQUALS 1188 | | FROM 1189 | | GET 1190 | | GROUP 1191 | | INTO 1192 | | JOIN 1193 | | LET 1194 | | NAMEOF 1195 | | ON 1196 | | ORDERBY 1197 | | PARTIAL 1198 | | REMOVE 1199 | | SELECT 1200 | | SET 1201 | | VAR 1202 | | WHEN 1203 | | WHERE 1204 | | YIELD 1205 | ; 1206 | -------------------------------------------------------------------------------- /test/AllInOne.Formatted.cs: -------------------------------------------------------------------------------- 1 | #error Error message 2 | #warning Warning message 3 | #pragma warning disable 414, 3021 4 | #pragma warning restore 3021 5 | #pragma checksum "file.txt" "{00000000-0000-0000-0000-000000000000}" "2453" 6 | #define foo // Comment in directive 7 | #if foo 8 | #else 9 | #endif 10 | #undef foo 11 | 12 | extern alias Foo; 13 | 14 | using System; 15 | using System.Collections.Generic; 16 | using System.Linq; 17 | using ConsoleApplication2.Test; 18 | using System.Linq.Expressions; 19 | using System.Text; 20 | using M = System.Math; 21 | 22 | #if DEBUG || TRACE 23 | using System.Diagnostics; 24 | #elif SILVERLIGHT && WINDOWS_PHONE || DEBUG || foo == true || foo != false 25 | using System.Diagnostics; 26 | #else 27 | using System.Diagnostics; 28 | #endif 29 | 30 | 31 | #region Region 32 | 33 | #region more 34 | using ConsoleApplication2.Test; 35 | #endregion 36 | using X = int1; 37 | using Y = ABC.X; 38 | using static System.Math; 39 | using static System.DayOfWeek; 40 | using static System.Linq.Enumerable; 41 | 42 | 43 | #endregion 44 | 45 | 46 | [assembly: System.Copyright(@"(C)"" 47 | 48 | 2009")] 49 | [module: System.Copyright("\n\t\u0123(C) \"2009" - ("\u0123" + "foo"))] 50 | 51 | class TopLevelType : IDisposable, Foo 52 | { 53 | void IDisposable.Dispose(int x, int y) 54 | { 55 | } 56 | } 57 | 58 | namespace My.Moy 59 | { 60 | using A.B; 61 | 62 | interface CoContra { } 63 | 64 | delegate void 65 | CoContra2<[System.Obsolete()] out T, in K>(int i) where T : struct; 66 | 67 | public unsafe partial class A : C, I 68 | { 69 | [DllImport("kernel32", SetLastError = true)] 70 | static extern bool CreateDirectory(string name, SecurityAttribute sa); 71 | 72 | private const int global = int.MinValue - 1; 73 | 74 | static A() 75 | { 76 | a.a.d().e().a->c.a++.b().a; 77 | 78 | var x = 79 | 1 * 1 + 80 | 1 * 1 + 81 | (1 + (1 + 1)) + 82 | 1 + 83 | 1 + 84 | 1 + 85 | 1 + 86 | 1 + 87 | 1 + 88 | 1 + 89 | 1 + 90 | 1 + 91 | 1 + 92 | 1 + 93 | 1 + 94 | 1; 95 | 96 | var y = a is Dictionary dict ? 42 : 51; 97 | } 98 | 99 | [method: Obsolete] 100 | public A( 101 | [param: Obsolete] int foo, 102 | [param: Obsolete] int foo, 103 | [param: Obsolete] int foo, 104 | [param: Obsolete] int foo 105 | ) : 106 | base(1) 107 | { 108 | L: 109 | { 110 | int i = sizeof(int); 111 | ++i; 112 | var s0 = $"foo{1, 2}"; 113 | var s1 = $"x {1, -2:d}"; 114 | var s2 = $@"x {1, -2:d}"; 115 | } 116 | 117 | 118 | #if DEBUG 119 | Console.WriteLine(export.iefSupplied.command); 120 | #endif 121 | 122 | const int? local = int.MaxValue; 123 | const Guid? local0 = new Guid(r.ToString()); 124 | 125 | var привет = local; 126 | var мир = local; 127 | var 128 | local3 = 0, 129 | local4 = 1; 130 | local3 = local4 = 1; 131 | var local5 = null as Action ?? null; 132 | var local6 = local5 is Action; 133 | string local7 = default; 134 | 135 | var u = 1u; 136 | var U = 1U; 137 | long 138 | hex = 0xBADC0DE, 139 | Hex = 0XDEADBEEF, 140 | l = -1L, 141 | L = 1L, 142 | l2 = 2l; 143 | ulong 144 | ul = 1ul, 145 | Ul = 1Ul, 146 | uL = 1uL, 147 | UL = 1UL, 148 | lu = 1lu, 149 | Lu = 1Lu, 150 | lU = 1lU, 151 | LU = 1LU; 152 | int minInt32Value = -2147483648; 153 | int minInt64Value = -9223372036854775808L; 154 | 155 | bool @bool; 156 | byte @byte; 157 | char 158 | @char = 'c', 159 | \u0066 = '\u0066', 160 | hexchar = '\x0130', 161 | hexchar2 = (char) 0xBAD; 162 | string \U00000065 = "\U00000065"; 163 | decimal @decimal = 1.44M; 164 | @decimal = 1.2m; 165 | dynamic @dynamic; 166 | double @double = M.PI; 167 | @double = 1d; 168 | @double = 1D; 169 | @double = -1.2e3; 170 | float @float = 1.2f; 171 | @float = 1.44F; 172 | int @int = local ?? -1; 173 | long @long; 174 | object @object; 175 | sbyte @sbyte; 176 | short @short; 177 | string @string = @"""/*"; 178 | uint @uint; 179 | ulong @ulong; 180 | ushort @ushort; 181 | 182 | dynamic dynamic = local5; 183 | var add = 0; 184 | var alias = 0; 185 | var arglist = 0; 186 | var ascending = 0; 187 | var async = 0; 188 | var await = 0; 189 | var by = 0; 190 | var descending = 0; 191 | var dynamic = 0; 192 | var equals = 0; 193 | var from = 0; 194 | var get = 0; 195 | var group = 0; 196 | var into = 0; 197 | var join = 0; 198 | var let = 0; 199 | var nameof = 0; 200 | var on = 0; 201 | var orderby = 0; 202 | var partial = 0; 203 | var remove = 0; 204 | var select = 0; 205 | var set = 0; 206 | var var = 0; 207 | var when = 0; 208 | var where = 0; 209 | var yield = 0; 210 | var __ = 0; 211 | where = yield = 0; 212 | 213 | if (i > 0) 214 | { 215 | return; 216 | } 217 | else if (i == 0) 218 | { 219 | throw new Exception(); 220 | } 221 | var o1 = new MyObject(); 222 | var o2 = new MyObject(var); 223 | var o3 = new MyObject { A = i }; 224 | var o4 = new MyObject(@dynamic) { A = 0, B = 0, C = 0 }; 225 | var o5 = new { A = 0 }; 226 | var dictionaryInitializer = 227 | new Dictionary { { 1, "" }, { 2, "a" } }; 228 | float[] a = new float[] { 0f, 1.1f }; 229 | int[,,] cube = 230 | { 231 | { { 1111, 1121 }, { 1211, 1221 } }, 232 | { { 2111, 2121 }, { 2211, 2221 } } 233 | }; 234 | int[][] jagged = { { 111 }, { 121, 122 } }; 235 | int[][,] arr = new int[5][,]; // as opposed to new int[][5,5] 236 | arr[0] = new int[5, 5]; // as opposed to arr[0,0] = new int[5]; 237 | arr[0][0, 0] = 47; 238 | int[] arrayTypeInference = new [] { 0, 1 }; 239 | switch (3) { } 240 | switch (i) 241 | { 242 | case 0: 243 | case 1: 244 | { 245 | goto case 2; 246 | } 247 | case 2 + 3: 248 | { 249 | goto default; 250 | break; 251 | } 252 | default: 253 | { 254 | return; 255 | } 256 | } 257 | switch (shape) 258 | { 259 | case Circle c: 260 | WriteLine($"circle with radius {c.Radius}"); 261 | break; 262 | case Rectangle s: 263 | WriteLine($"{s.Length} x {s.Height} square"); 264 | break; 265 | case null: 266 | throw new ArgumentNullException(nameof(shape)); 267 | } 268 | while (i < 10) 269 | { 270 | ++i; 271 | if (true) continue; 272 | break; 273 | } 274 | do 275 | { 276 | ++i; 277 | if (true) continue; 278 | break; 279 | } 280 | while (i < 10); 281 | for (int j = 0; j < 100; ++j) 282 | { 283 | for (; ; ) 284 | { 285 | for ( 286 | int 287 | i = 0, 288 | j = 0; 289 | i < length; 290 | i++, j++ 291 | ) 292 | { 293 | } 294 | if (true) continue; 295 | break; 296 | } 297 | } 298 | label: 299 | goto label; 300 | label2: 301 | 302 | foreach (var i in Items()) 303 | { 304 | if (i == 7) 305 | return; 306 | else 307 | continue; 308 | } 309 | checked 310 | { 311 | checked(++i); 312 | } 313 | unchecked 314 | { 315 | unchecked(++i); 316 | } 317 | lock (sync) 318 | process(); 319 | using (var v = BeginScope()) 320 | using (A a = new A()) 321 | using ( 322 | A 323 | a = new A(), 324 | b = new A() 325 | ) 326 | using (BeginScope()) 327 | return; 328 | yield return this.items[3]; 329 | yield break; 330 | fixed (int* p = stackalloc int[100], q = &y) 331 | { 332 | *intref = 1; 333 | } 334 | fixed (int* p = stackalloc int[100]) 335 | { 336 | *intref = 1; 337 | } 338 | unsafe 339 | { 340 | int* p = null; 341 | } 342 | try 343 | { 344 | throw null; 345 | } 346 | catch (System.AccessViolationException av) 347 | { 348 | throw av; 349 | } 350 | catch (Exception) 351 | { 352 | throw; 353 | } 354 | finally 355 | { 356 | try 357 | { 358 | } 359 | catch 360 | { 361 | } 362 | } 363 | var anonymous = { A = 1, B = 2, C = 3 }; 364 | var query = 365 | from c in customers 366 | let d = c 367 | where d != null 368 | join c1 in customers on c1.GetHashCode() equals c.GetHashCode() 369 | join c1 370 | in customers 371 | on c1.GetHashCode() 372 | equals c.GetHashCode() 373 | into e 374 | group c by c.Country 375 | into 376 | g 377 | orderby g.Count() ascending 378 | orderby g.Key descending 379 | select new { Country = g.Key, CustCount = g.Count() }; 380 | query = from c in customers select c into d select d; 381 | } 382 | 383 | A() 384 | { 385 | } 386 | 387 | private readonly int f1; 388 | 389 | [Obsolete] 390 | [NonExisting] 391 | [Foo::NonExisting(var, 5)] 392 | [CLSCompliant(false)] 393 | [ 394 | Obsolete, 395 | System.NonSerialized, 396 | NonSerialized, 397 | CLSCompliant(true || false & true) 398 | ] 399 | private volatile int f2; 400 | 401 | [return: Obsolete] 402 | [method: Obsolete] 403 | public void Handler(object value) 404 | { 405 | } 406 | 407 | public int m(T t) 408 | where T : class, new() 409 | { 410 | base.m(t); 411 | return 1; 412 | } 413 | 414 | public string P 415 | { 416 | get 417 | { 418 | return "A"; 419 | } 420 | set; 421 | } 422 | 423 | public abstract string P { get; } 424 | 425 | public abstract int this[int index] 426 | { 427 | protected internal get; protected internal set; 428 | } 429 | 430 | [method: Obsolete] 431 | [field: Obsolete] 432 | [event: Obsolete] 433 | public readonly event Event E; 434 | 435 | [event: Test] 436 | public event Action 437 | E1 438 | { 439 | [Obsolete] 440 | add 441 | { 442 | value = value; 443 | } 444 | [Obsolete] 445 | [return: Obsolete] 446 | remove 447 | { 448 | E += Handler; 449 | E -= Handler; 450 | } 451 | } 452 | 453 | public static A operator +(A first, A second) 454 | { 455 | Delegate handler = new Delegate(Handler); 456 | return first.Add(second); 457 | } 458 | 459 | [method: Obsolete] 460 | [return: Obsolete] 461 | public static bool operator true(A a) 462 | { 463 | return true; 464 | } 465 | 466 | public static bool operator false(A a) 467 | { 468 | return false; 469 | } 470 | 471 | class C { } 472 | } 473 | 474 | public struct S : I 475 | { 476 | public S() 477 | { 478 | } 479 | 480 | private int f1; 481 | 482 | [Obsolete("Use Script instead", error: false)] 483 | private volatile int f2; 484 | 485 | public abstract int m(T t) 486 | where T : struct 487 | { 488 | return 1; 489 | } 490 | 491 | public string P 492 | { 493 | get 494 | { 495 | int value = 0; 496 | return "A"; 497 | } 498 | set; 499 | } 500 | 501 | public abstract string P { get; } 502 | 503 | public abstract int this[int index] 504 | { 505 | get; protected internal set; 506 | } 507 | 508 | public event Event E; 509 | 510 | public static A operator +(A first, A second) 511 | { 512 | return first.Add(second); 513 | } 514 | 515 | fixed int field[10]; 516 | 517 | class C { } 518 | } 519 | 520 | public interface I : J 521 | { 522 | void A(int value); 523 | 524 | string Value { get; set; } 525 | 526 | unsafe void 527 | UpdateSignatureByHashingContent( 528 | [In] byte* buffer, int size 529 | ); 530 | } 531 | 532 | [type: Flags] 533 | public enum E 534 | { 535 | A, 536 | B = A, 537 | C = 2 + A, 538 | #if DEBUG 539 | D 540 | } 541 | #else 542 | E, 543 | } 544 | #endif 545 | 546 | 547 | public delegate void Delegate(object P); 548 | 549 | namespace Test 550 | { 551 | using System; 552 | using System.Collections; 553 | 554 | public class Список 555 | { 556 | public static IEnumerable Power(int number, int exponent) 557 | { 558 | Список Список = new Список(); 559 | Список.Main(); 560 | int counter = (0 + 0); 561 | int אתר = 0; 562 | while (++counter++ < --exponent--) 563 | { 564 | result = result * number + +number++++ + number; 565 | yield return result; 566 | } 567 | } 568 | 569 | static void Main() 570 | { 571 | foreach (int i in Power(2, 8)) 572 | { 573 | Console.Write("{0} ", i); 574 | } 575 | } 576 | 577 | async void Wait() 578 | { 579 | // await System.Threading.Tasks.Task.Foooooooooooooooooooo.Delay(0); 580 | await SystemxThreadingxTasksxTaskxFooooooooooooooooooooxDelay(0); 581 | } 582 | 583 | void AsyncAnonymous() // C # 5 feature 584 | { 585 | var task = 586 | Task 587 | .Factory 588 | .StartNew(async () => 589 | { 590 | return await new WebClient() 591 | .DownloadStringTaskAsync("http://example.com"); 592 | }); 593 | } 594 | } 595 | } 596 | } 597 | 598 | namespace ConsoleApplication1 599 | { 600 | namespace RecursiveGenericBaseType 601 | { 602 | class A : B, A> where T : A 603 | { 604 | protected virtual A M() 605 | { 606 | } 607 | 608 | protected abstract B, A> N() 609 | { 610 | } 611 | 612 | static B, A> O() 613 | { 614 | } 615 | } 616 | 617 | sealed class B : A> 618 | { 619 | protected override A M() 620 | { 621 | } 622 | 623 | protected override sealed B, A> N() 624 | { 625 | } 626 | 627 | new static A O() 628 | { 629 | } 630 | } 631 | } 632 | 633 | namespace Boo 634 | { 635 | public class Bar where T : IComparable 636 | { 637 | public T f; 638 | 639 | public class Foo : IEnumerable 640 | { 641 | public void Method(K k, T t, U u) 642 | where K : IList, IList, IList 643 | where V : IList 644 | { 645 | A a; 646 | M(A(5)); 647 | } 648 | } 649 | } 650 | } 651 | 652 | class Test 653 | { 654 | void Bar3() 655 | { 656 | var x = new Boo.Bar.Foo(); 657 | x.Method(" ", 5, new object()); 658 | 659 | var q = from i in new int[] { 1, 2, 3, 4 } where i > 5 select i; 660 | } 661 | 662 | public static implicit operator Test(string s) 663 | 664 | { 665 | return new ConsoleApplication1.Test(); 666 | } 667 | 668 | public static explicit operator Test(string s = "") 669 | 670 | { 671 | return new Test(); 672 | } 673 | 674 | public int foo = 5; 675 | 676 | void Bar2() 677 | { 678 | foo = 6; 679 | this.Foo = 5.GetType(); 680 | Test t = "sss"; 681 | } 682 | 683 | public event EventHandler 684 | MyEvent = 685 | delegate () 686 | { 687 | }; 688 | 689 | void Blah() 690 | { 691 | int i = 5; 692 | int? j = 6; 693 | 694 | Expression> e = () => i; 695 | Expression> e2 = 696 | b => 697 | () => 698 | { 699 | return; 700 | }; 701 | Func f = 702 | async delegate (bool a) 703 | { 704 | return await !a; 705 | }; 706 | Func f2 = (a, b) => 0; 707 | f2 = (int a, int b) => 1; 708 | Action a = Blah; 709 | f2 = () => 710 | { 711 | }; 712 | f2 = () => 713 | { 714 | 715 | }; 716 | } 717 | 718 | delegate Recursive Recursive(Recursive r); 719 | 720 | delegate Recursive Recursive(Recursive r); 721 | 722 | public Type Foo 723 | { 724 | [Obsolete("Name", error = false)] 725 | get 726 | { 727 | var result = typeof (IEnumerable); 728 | var t = typeof (int?) == typeof (Nullable); 729 | t = typeof (IEnumerable); 730 | return typeof (IEnumerable<>); 731 | } 732 | set 733 | { 734 | var t = typeof (System.Int32); 735 | t.ToString(); 736 | t = value; 737 | } 738 | } 739 | 740 | public void Constants() 741 | { 742 | int i = 1 + 2 + 3 + 5; 743 | global::System.String s = 744 | "a" + (System.String) "a" + "a" + "a" + "a" + "A"; 745 | } 746 | 747 | public void ConstructedType() 748 | { 749 | List i = null; 750 | int c = i.Count; 751 | } 752 | 753 | class Foo : IDisposable 754 | { 755 | public int N; 756 | 757 | public void Dispose() 758 | { 759 | } 760 | } 761 | 762 | unsafe void EmptyEmbeddedStatment() 763 | { 764 | // useless empty statements get deleted 765 | 766 | 767 | // but nontrivial ones remain 768 | if (true) 769 | ; 770 | else if (true) 771 | ; 772 | else 773 | ; 774 | while (false) ; 775 | do ; while (false); 776 | for (; ; ) ; 777 | foreach (var x in "") ; 778 | lock (new object()) 779 | ; 780 | using (var d = new Foo()) 781 | ; 782 | var o = new Foo(); 783 | fixed (int* d = &o.N) 784 | ; 785 | } 786 | } 787 | } 788 | 789 | namespace Comments.XmlComments.UndocumentedKeywords 790 | { 791 | /// 792 | /// Whatever 793 | /// 794 | /// 795 | /// // 796 | /// /* */ 797 | /// 798 | /// 799 | /// 800 | /// 801 | /// 802 | /// 803 | /// 804 | /// 805 | /// 806 | /// 807 | class 808 | /*///*/ 809 | C 810 | { 811 | void M(T t, U u) 812 | { 813 | // comment 814 | /* *** / */ 815 | /* // 816 | */ 817 | /*s*/ 818 | //comment 819 | // /***/ 820 | /*s*/ 821 | int intValue = 0; /*s*/ 822 | intValue = 823 | intValue + /*s*/ 824 | 1; 825 | string strValue = "hello"; /*s*/ 826 | /*s*/ 827 | MyClass c = new MyClass(); 828 | string verbatimStr = @"\\\\"; /*s*/ 829 | int i = 830 | 0 + // foo 831 | 1 + // bar 832 | 2; // qux 833 | i = 834 | 3 + // foo 835 | 4 + // bar 836 | 5; // qux 837 | i = 838 | strValue != null 839 | ? 6 // bar 840 | : 7; // qux 841 | } 842 | } 843 | 844 | //General Test F. Type a very long class name, verify colorization happens correctly only upto the correct size (118324) 845 | class 846 | TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /*Scen8*/ 847 | { } 848 | 849 | class 850 | TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX22 /*Scen9*/ 851 | { } 852 | 853 | class yield 854 | { 855 | void Foo(__arglist) 856 | { 857 | C c = null; 858 | c.M(5, default(U)); 859 | TypedReference tr = __makeref(c); 860 | Type t = __reftype(tr); 861 | int j = __refvalue(tr, int); 862 | Params(a: t, b: t); 863 | Params(ref c, out c); 864 | Params(out var d, out Test d); 865 | } 866 | 867 | void Params(ref dynamic a, out dynamic b, params dynamic[] c) 868 | { 869 | } 870 | 871 | void Params( 872 | out dynamic a = 2, 873 | ref dynamic c = default(dynamic), 874 | params dynamic[][] c 875 | ) 876 | { 877 | } 878 | 879 | public override string ToString() 880 | { 881 | return base.ToString(); 882 | } 883 | 884 | public partial void OnError(); 885 | 886 | public partial void method() 887 | { 888 | int?[] a = new int?[5]; /*[] bug*/ // YES [] 889 | int[] var = { 1, 2, 3, 4, 5 }; /*,;*/ 890 | int i = a[i]; /*[]*/ 891 | Foo f = new Foo(); /*<> ()*/ 892 | f.method(); /*().*/ 893 | i = i + i - i * i / i % i & i | i ^ i; /*+ - * / % & | ^*/ 894 | bool b = true & false | true ^ false; /*& | ^*/ 895 | b = !b; /*!*/ 896 | i = ~i; /*~i*/ 897 | b = i < i && i > i; /*< && >*/ 898 | int? ii = 5; /*? bug*/ // NO ? 899 | int f = true ? 1 : 0; /*? :*/ // YES : 900 | i++; /*++*/ 901 | i--; /*--*/ 902 | b = true && false || true; /*&& ||*/ 903 | i << 5; /*<<*/ 904 | i >> 5; /*>>*/ 905 | b = i == i && i != i && i <= i && i >= i; /*= == && != <= >=*/ 906 | i += 5.0; /*+=*/ 907 | i -= i; /*-=*/ 908 | i *= i; /**=*/ 909 | i /= i; /*/=*/ 910 | i %= i; /*%=*/ 911 | i &= i; /*&=*/ 912 | i |= i; /*|=*/ 913 | i ^= i; /*^=*/ 914 | i <<= i; /*<<=*/ 915 | i >>= i; /*>>=*/ 916 | object s = x => x + 1; /*=>*/ 917 | double d = .3; 918 | 919 | Point point; 920 | unsafe 921 | { 922 | Point* p = &point; /** &*/ 923 | p->x = 10; /*->*/ 924 | } 925 | IO::BinaryReader br = null; 926 | x[i: 1] = 3; 927 | x[i: 1, j: 5] = "str"; 928 | } 929 | 930 | struct Point 931 | { 932 | public int X; 933 | 934 | public int Y; 935 | 936 | public void ThisAccess() 937 | { 938 | this = this; 939 | } 940 | } 941 | } 942 | 943 | // From here:https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6 944 | class CSharp6Features 945 | { 946 | // Initializers for auto-properties 947 | public string First { get; set; } = "Jane"; 948 | 949 | public string Last { get; set; } = "Doe"; 950 | 951 | // Getter-only auto-properties 952 | public string Third { get; } = "Jane"; 953 | 954 | public string Fourth { get; } = "Doe"; 955 | 956 | // Expression bodies on method-like members 957 | public Point Move(int dx, int dy) => new Point(x + dx, y + dy); 958 | 959 | public static Complex operator +(Complex a, Complex b) => a.Add(b); 960 | 961 | public static implicit operator string(Person p) 962 | => p.First + " " + p.Last; 963 | 964 | public void Print() => Console.WriteLine(First + " " + Last); 965 | 966 | // Expression bodies on property-like function members 967 | public string Name => First + " " + Last; 968 | 969 | public int this[long id] => id; 970 | 971 | private void NoOp() 972 | { 973 | // Empty body. 974 | } 975 | 976 | async void Test() 977 | { 978 | // Using static 979 | WriteLine(Sqrt(3 * 3 + 4 * 4)); 980 | WriteLine(Friday - Monday); 981 | var range = Range(5, 17); // Ok: not extension 982 | var even = range.Where(i => i % 2 == 0); // Ok 983 | 984 | // Null-conditional operators 985 | int? length = customers?.Length; // null if customers is null 986 | Customer first = customers?[0]; // null if customers is null 987 | int length = customers?.Length ?? 0; // 0 if customers is null 988 | int? first = customers?[0]?.Orders?.Count(); 989 | PropertyChanged?.Invoke(this, args); 990 | 991 | // String interpolation 992 | string s = $"{p.Name, 20} is {p.Age:D3} year{{s}} old #"; 993 | s = $"{p.Name} is \"{p.Age} year{(p.Age == 1 ? "" : "s")} old"; 994 | s = $"{(p.Age == 2 ? $"{new Person { }}" : "")}"; 995 | s = $@"\{p.Name} 996 | ""\"; 997 | s = 998 | $"Color [ R={func(b: 3):#0.##}, G={G:#0.##}, B={B:#0.##}, A={A:#0.##} ]"; 999 | 1000 | Logging 1001 | .Log 1002 | .Error($"Some error message text: ({someVariableValue} did not work)"); 1003 | 1004 | // nameof expressions 1005 | if (x == null) throw new ArgumentNullException(nameof(x)); 1006 | WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode" 1007 | 1008 | // Index initializers 1009 | var numbers = 1010 | new Dictionary { 1011 | [7] = "seven", 1012 | [9] = "nine", 1013 | [13] = "thirteen" 1014 | }; 1015 | 1016 | string LocalFunction(string arg) 1017 | { 1018 | return arg; 1019 | } 1020 | 1021 | // Exception filters 1022 | try 1023 | { 1024 | } 1025 | catch (MyException e) when (myfilter(e)) 1026 | { 1027 | } 1028 | 1029 | // Await in catch and finally blocks 1030 | Resource res = null; 1031 | try 1032 | { 1033 | res = await Resource.OpenAsync(); // You could do this. 1034 | } 1035 | catch (ResourceException e) 1036 | { 1037 | await Resource.LogAsync(res, e); // Now you can do this … 1038 | } 1039 | finally 1040 | { 1041 | if (res != null) await res.CloseAsync(); // … and this. 1042 | } 1043 | } 1044 | } 1045 | 1046 | class CSharp7Features 1047 | { 1048 | (string, string, long) Tuples(long id) 1049 | { 1050 | int a; 1051 | 1052 | // variable assignment is valid inside a tuple literal. 1053 | var foo = (2, a = 1); 1054 | 1055 | var unnamed = ("one", "two", "three"); 1056 | var named = (first: "one", second: "two"); 1057 | (string, long) foo = ("foo", 42); 1058 | (int? a, int? b) nullableMembers = (5, 10); 1059 | (int, (int, int)) nestedTuple = (1, (2, 3)); 1060 | var (a, b, c) = Tuples(42); 1061 | (a, b, c) = (a, b, c); 1062 | return (named.first, named.second, id); 1063 | } 1064 | 1065 | int ThrowExpressionExample() => 3 == 3 ? 2 : throw new Exception(); 1066 | 1067 | class C : Exception 1068 | { 1069 | public static C operator +(C c1, C c2) => default; 1070 | 1071 | void ThrowBinaryExpression() 1072 | { 1073 | throw new C() + new C(); 1074 | } 1075 | } 1076 | 1077 | void IsPatternMatch() 1078 | { 1079 | if (3 is int foo) 1080 | { 1081 | } 1082 | if (3 is var bar) 1083 | { 1084 | } 1085 | if (3 is 3) 1086 | { 1087 | } 1088 | if (new object() is null) 1089 | { 1090 | } 1091 | if (0 is default(int) - 3) 1092 | { 1093 | } 1094 | if (true is false ^ false) 1095 | { 1096 | } 1097 | if (8 is sizeof(long)) 1098 | { 1099 | } 1100 | } 1101 | 1102 | void UnmanagedConstraint() 1103 | where T : unmanaged 1104 | { 1105 | } 1106 | } 1107 | } 1108 | 1109 | namespace Empty 1110 | { 1111 | // Don't forget this comment! 1112 | } 1113 | 1114 | 1115 | #line 6 1116 | #line 2 "test.cs" 1117 | #line default 1118 | #line hidden 1119 | -------------------------------------------------------------------------------- /src/csharp/CSharpLexer.g4: -------------------------------------------------------------------------------- 1 | // Eclipse Public License - v 1.0, http://www.eclipse.org/legal/epl-v10.html 2 | // Copyright (c) 2013, Christian Wulf (chwchw@gmx.de) 3 | // Copyright (c) 2016-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. 4 | 5 | lexer grammar CSharpLexer; 6 | 7 | channels { COMMENTS_CHANNEL, DIRECTIVE } 8 | 9 | @lexer::members 10 | {var interpolatedStringLevel = 0; 11 | var interpolatedVerbatims = []; // new Stack(); 12 | var curlyLevels = []; //new Stack(); 13 | var verbatim = false; 14 | } 15 | 16 | BYTE_ORDER_MARK: '\u00EF\u00BB\u00BF'; 17 | 18 | SINGLE_LINE_DOC_COMMENT: '///' InputCharacter* -> channel(COMMENTS_CHANNEL); 19 | DELIMITED_DOC_COMMENT: '/**' .*? '*/' -> channel(COMMENTS_CHANNEL); 20 | SINGLE_LINE_COMMENT: '//' InputCharacter* -> channel(COMMENTS_CHANNEL); 21 | DELIMITED_COMMENT: '/*' .*? '*/' -> channel(COMMENTS_CHANNEL); 22 | SINGLE_LINE_DIRECTIVE: '#' (IF|DEFINE|UNDEF|LINE|ERROR|WARNING|REGION|ENDREGION|PRAGMA) InputCharacter* -> channel(DIRECTIVE); 23 | ELSEIF_DIRECTIVE: ('#' (ELSE|ELIF) .*?)* '#' ENDIF -> channel(DIRECTIVE); 24 | 25 | WHITESPACES: (Whitespace | NewLine)+ -> channel(HIDDEN); 26 | SHARP: '#'; 27 | 28 | ABSTRACT: 'abstract'; 29 | ADD: 'add'; 30 | ALIAS: 'alias'; 31 | ARGLIST: '__arglist'; 32 | AS: 'as'; 33 | ASCENDING: 'ascending'; 34 | ASYNC: 'async'; 35 | AWAIT: 'await'; 36 | BASE: 'base'; 37 | BOOL: 'bool'; 38 | BREAK: 'break'; 39 | BY: 'by'; 40 | BYTE: 'byte'; 41 | CASE: 'case'; 42 | CATCH: 'catch'; 43 | CHAR: 'char'; 44 | CHECKED: 'checked'; 45 | CLASS: 'class'; 46 | CONST: 'const'; 47 | CONTINUE: 'continue'; 48 | DECIMAL: 'decimal'; 49 | DEFAULT: 'default'; 50 | DELEGATE: 'delegate'; 51 | DESCENDING: 'descending'; 52 | DO: 'do'; 53 | DOUBLE: 'double'; 54 | DYNAMIC: 'dynamic'; 55 | ELSE: 'else'; 56 | ENUM: 'enum'; 57 | EQUALS: 'equals'; 58 | EVENT: 'event'; 59 | EXPLICIT: 'explicit'; 60 | EXTERN: 'extern'; 61 | FALSE: 'false'; 62 | FINALLY: 'finally'; 63 | FIXED: 'fixed'; 64 | FLOAT: 'float'; 65 | FOR: 'for'; 66 | FOREACH: 'foreach'; 67 | FROM: 'from'; 68 | GET: 'get'; 69 | GOTO: 'goto'; 70 | GROUP: 'group'; 71 | IF: 'if'; 72 | IMPLICIT: 'implicit'; 73 | IN: 'in'; 74 | INT: 'int'; 75 | INTERFACE: 'interface'; 76 | INTERNAL: 'internal'; 77 | INTO: 'into'; 78 | IS: 'is'; 79 | JOIN: 'join'; 80 | LET: 'let'; 81 | LOCK: 'lock'; 82 | LONG: 'long'; 83 | NAMEOF: 'nameof'; 84 | NAMESPACE: 'namespace'; 85 | NEW: 'new'; 86 | NULL: 'null'; 87 | OBJECT: 'object'; 88 | ON: 'on'; 89 | OPERATOR: 'operator'; 90 | ORDERBY: 'orderby'; 91 | OUT: 'out'; 92 | OVERRIDE: 'override'; 93 | PARAMS: 'params'; 94 | PARTIAL: 'partial'; 95 | PRIVATE: 'private'; 96 | PROTECTED: 'protected'; 97 | PUBLIC: 'public'; 98 | READONLY: 'readonly'; 99 | REF: 'ref'; 100 | REMOVE: 'remove'; 101 | RETURN: 'return'; 102 | SBYTE: 'sbyte'; 103 | SEALED: 'sealed'; 104 | SELECT: 'select'; 105 | SET: 'set'; 106 | SHORT: 'short'; 107 | SIZEOF: 'sizeof'; 108 | STACKALLOC: 'stackalloc'; 109 | STATIC: 'static'; 110 | STRING: 'string'; 111 | STRUCT: 'struct'; 112 | SWITCH: 'switch'; 113 | THIS: 'this'; 114 | THROW: 'throw'; 115 | TRUE: 'true'; 116 | TRY: 'try'; 117 | TYPEOF: 'typeof'; 118 | UINT: 'uint'; 119 | ULONG: 'ulong'; 120 | UNCHECKED: 'unchecked'; 121 | UNMANAGED: 'unmanaged'; 122 | UNSAFE: 'unsafe'; 123 | USHORT: 'ushort'; 124 | USING: 'using'; 125 | VAR: 'var'; 126 | VIRTUAL: 'virtual'; 127 | VOID: 'void'; 128 | VOLATILE: 'volatile'; 129 | WHEN: 'when'; 130 | WHERE: 'where'; 131 | WHILE: 'while'; 132 | YIELD: 'yield'; 133 | 134 | //B.1.6 Identifiers 135 | // must be defined after all keywords so the first branch (Available_identifier) does not match keywords 136 | // https://msdn.microsoft.com/en-us/library/aa664670(v=vs.71).aspx 137 | IDENTIFIER: '@'? IdentifierOrKeyword; 138 | 139 | //B.1.8 Literals 140 | // 0.Equals() would be parsed as an invalid real (1. branch) causing a lexer error 141 | LITERAL_ACCESS: [0-9]+ IntegerTypeSuffix? '.' '@'? IdentifierOrKeyword; 142 | INTEGER_LITERAL: [0-9]+ IntegerTypeSuffix?; 143 | HEX_INTEGER_LITERAL: '0' [xX] HexDigit+ IntegerTypeSuffix?; 144 | REAL_LITERAL: [0-9]* '.' [0-9]+ ExponentPart? [FfDdMm]? | [0-9]+ ([FfDdMm] | ExponentPart [FfDdMm]?); 145 | 146 | CHARACTER_LITERAL: '\'' (~['\\\r\n\u0085\u2028\u2029] | CommonCharacter) '\''; 147 | REGULAR_STRING: '"' (~["\\\r\n\u0085\u2028\u2029] | CommonCharacter)* '"'; 148 | VERBATIM_STRING: '@"' (~'"' | '""')* '"'; 149 | INTERPOLATED_REGULAR_STRING_START: '$"' 150 | { interpolatedStringLevel++; interpolatedVerbatims.push(false); verbatim = false; } -> pushMode(INTERPOLATION_STRING); 151 | INTERPOLATED_VERBATIM_STRING_START: '$@"' 152 | { interpolatedStringLevel++; interpolatedVerbatims.push(true); verbatim = true; } -> pushMode(INTERPOLATION_STRING); 153 | 154 | //B.1.9 Operators And Punctuators 155 | OPEN_BRACE: '{' 156 | { 157 | if (interpolatedStringLevel > 0) 158 | { 159 | curlyLevels.push(curlyLevels.pop() + 1); 160 | }}; 161 | CLOSE_BRACE: '}' 162 | { 163 | if (interpolatedStringLevel > 0) 164 | { 165 | curlyLevels.push(curlyLevels.pop() - 1); 166 | if (curlyLevels[curlyLevels.length - 1] == 0) 167 | { 168 | curlyLevels.pop(); 169 | this.skip(); 170 | this.popMode(); 171 | } 172 | } 173 | }; 174 | OPEN_BRACKET: '['; 175 | CLOSE_BRACKET: ']'; 176 | OPEN_PARENS: '('; 177 | CLOSE_PARENS: ')'; 178 | DOT: '.'; 179 | COMMA: ','; 180 | COLON: ':' 181 | { 182 | if (interpolatedStringLevel > 0) 183 | { 184 | var ind = 1; 185 | var switchToFormatString = true; 186 | var la; 187 | while ((la = String.fromCharCode(this._input.LA(ind))) != '}') 188 | { 189 | if (la == ':' || la == ')') 190 | { 191 | switchToFormatString = false; 192 | break; 193 | } 194 | ind++; 195 | } 196 | if (switchToFormatString) 197 | { 198 | this.mode(CSharpLexer.INTERPOLATION_FORMAT); 199 | } 200 | } 201 | }; 202 | SEMICOLON: ';'; 203 | PLUS: '+'; 204 | MINUS: '-'; 205 | STAR: '*'; 206 | DIV: '/'; 207 | PERCENT: '%'; 208 | AMP: '&'; 209 | BITWISE_OR: '|'; 210 | CARET: '^'; 211 | BANG: '!'; 212 | TILDE: '~'; 213 | ASSIGNMENT: '='; 214 | LT: '<'; 215 | GT: '>'; 216 | INTERR: '?'; 217 | DOUBLE_COLON: '::'; 218 | OP_COALESCING: '??'; 219 | OP_INC: '++'; 220 | OP_DEC: '--'; 221 | OP_AND: '&&'; 222 | OP_OR: '||'; 223 | OP_PTR: '->'; 224 | OP_EQ: '=='; 225 | OP_NE: '!='; 226 | OP_LE: '<='; 227 | OP_GE: '>='; 228 | OP_ADD_ASSIGNMENT: '+='; 229 | OP_SUB_ASSIGNMENT: '-='; 230 | OP_MULT_ASSIGNMENT: '*='; 231 | OP_DIV_ASSIGNMENT: '/='; 232 | OP_MOD_ASSIGNMENT: '%='; 233 | OP_AND_ASSIGNMENT: '&='; 234 | OP_OR_ASSIGNMENT: '|='; 235 | OP_XOR_ASSIGNMENT: '^='; 236 | OP_LEFT_SHIFT: '<<'; 237 | OP_LEFT_SHIFT_ASSIGNMENT: '<<='; 238 | 239 | // https://msdn.microsoft.com/en-us/library/dn961160.aspx 240 | mode INTERPOLATION_STRING; 241 | 242 | DOUBLE_CURLY_INSIDE: '{{'; 243 | OPEN_BRACE_INSIDE: '{' { curlyLevels.push(1); } -> skip, pushMode(DEFAULT_MODE); 244 | REGULAR_CHAR_INSIDE: { !verbatim }? SimpleEscapeSequence; 245 | VERBATIM_DOUBLE_QUOTE_INSIDE: { verbatim }? '""'; 246 | DOUBLE_QUOTE_INSIDE: '"' { interpolatedStringLevel--; interpolatedVerbatims.pop(); 247 | verbatim = (interpolatedVerbatims.length > 0 ? interpolatedVerbatims[interpolatedVerbatims.length - 1] : false); } -> popMode; 248 | REGULAR_STRING_INSIDE: { !verbatim }? ~('{' | '\\' | '"')+; 249 | VERBATIM_INSIDE_STRING: { verbatim }? ~('{' | '"')+; 250 | 251 | mode INTERPOLATION_FORMAT; 252 | 253 | DOUBLE_CURLY_CLOSE_INSIDE: '}}' -> type(FORMAT_STRING); 254 | CLOSE_BRACE_INSIDE: '}' { curlyLevels.pop(); } -> skip, popMode; 255 | FORMAT_STRING: ~'}'+; 256 | 257 | mode DIRECTIVE_MODE; 258 | 259 | DIRECTIVE_WHITESPACES: Whitespace+ -> channel(HIDDEN); 260 | DIGITS: [0-9]+ -> channel(DIRECTIVE); 261 | DIRECTIVE_TRUE: 'true' -> channel(DIRECTIVE), type(TRUE); 262 | DIRECTIVE_FALSE: 'false' -> channel(DIRECTIVE), type(FALSE); 263 | DEFINE: 'define' -> channel(DIRECTIVE); 264 | UNDEF: 'undef' -> channel(DIRECTIVE); 265 | DIRECTIVE_IF: 'if' -> channel(DIRECTIVE), type(IF); 266 | ELIF: 'elif' -> channel(DIRECTIVE); 267 | DIRECTIVE_ELSE: 'else' -> channel(DIRECTIVE), type(ELSE); 268 | ENDIF: 'endif' -> channel(DIRECTIVE); 269 | LINE: 'line' -> channel(DIRECTIVE); 270 | ERROR: 'error' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); 271 | WARNING: 'warning' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); 272 | REGION: 'region' Whitespace* -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); 273 | ENDREGION: 'endregion' Whitespace* -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); 274 | PRAGMA: 'pragma' Whitespace+ -> channel(DIRECTIVE), mode(DIRECTIVE_TEXT); 275 | DIRECTIVE_DEFAULT: 'default' -> channel(DIRECTIVE), type(DEFAULT); 276 | DIRECTIVE_HIDDEN: 'hidden' -> channel(DIRECTIVE); 277 | DIRECTIVE_OPEN_PARENS: '(' -> channel(DIRECTIVE), type(OPEN_PARENS); 278 | DIRECTIVE_CLOSE_PARENS: ')' -> channel(DIRECTIVE), type(CLOSE_PARENS); 279 | DIRECTIVE_BANG: '!' -> channel(DIRECTIVE), type(BANG); 280 | DIRECTIVE_OP_EQ: '==' -> channel(DIRECTIVE), type(OP_EQ); 281 | DIRECTIVE_OP_NE: '!=' -> channel(DIRECTIVE), type(OP_NE); 282 | DIRECTIVE_OP_AND: '&&' -> channel(DIRECTIVE), type(OP_AND); 283 | DIRECTIVE_OP_OR: '||' -> channel(DIRECTIVE), type(OP_OR); 284 | DIRECTIVE_STRING: '"' ~('"' | [\r\n\u0085\u2028\u2029])* '"' -> channel(DIRECTIVE), type(STRING); 285 | CONDITIONAL_SYMBOL: IdentifierOrKeyword -> channel(DIRECTIVE); 286 | DIRECTIVE_SINGLE_LINE_COMMENT: '//' ~[\r\n\u0085\u2028\u2029]* -> channel(COMMENTS_CHANNEL), type(SINGLE_LINE_COMMENT); 287 | DIRECTIVE_NEW_LINE: NewLine -> channel(DIRECTIVE), mode(DEFAULT_MODE); 288 | 289 | mode DIRECTIVE_TEXT; 290 | 291 | TEXT: ~[\r\n\u0085\u2028\u2029]+ -> channel(DIRECTIVE); 292 | TEXT_NEW_LINE: NewLine -> channel(DIRECTIVE), type(DIRECTIVE_NEW_LINE), mode(DEFAULT_MODE); 293 | 294 | // Fragments 295 | 296 | fragment InputCharacter: ~[\r\n\u0085\u2028\u2029]; 297 | 298 | fragment NewLineCharacter 299 | : '\u000D' //'' 300 | | '\u000A' //'' 301 | | '\u0085' //'' 302 | | '\u2028' //'' 303 | | '\u2029' //'' 304 | ; 305 | 306 | fragment IntegerTypeSuffix: [lL]? [uU] | [uU]? [lL]; 307 | fragment ExponentPart: [eE] ('+' | '-')? [0-9]+; 308 | 309 | fragment CommonCharacter 310 | : SimpleEscapeSequence 311 | | HexEscapeSequence 312 | | UnicodeEscapeSequence 313 | ; 314 | 315 | fragment SimpleEscapeSequence 316 | : '\\\'' 317 | | '\\"' 318 | | '\\\\' 319 | | '\\0' 320 | | '\\a' 321 | | '\\b' 322 | | '\\f' 323 | | '\\n' 324 | | '\\r' 325 | | '\\t' 326 | | '\\v' 327 | ; 328 | 329 | fragment HexEscapeSequence 330 | : '\\x' HexDigit 331 | | '\\x' HexDigit HexDigit 332 | | '\\x' HexDigit HexDigit HexDigit 333 | | '\\x' HexDigit HexDigit HexDigit HexDigit 334 | ; 335 | 336 | fragment NewLine 337 | : '\r\n' | '\r' | '\n' 338 | | '\u0085' // ' 339 | | '\u2028' //'' 340 | | '\u2029' //'' 341 | ; 342 | 343 | fragment Whitespace 344 | : UnicodeClassZS //'' 345 | | '\u0009' //'' 346 | | '\u000B' //'' 347 | | '\u000C' //'
' 348 | ; 349 | 350 | fragment UnicodeClassZS 351 | : '\u0020' // SPACE 352 | | '\u00A0' // NO_BREAK SPACE 353 | | '\u1680' // OGHAM SPACE MARK 354 | | '\u180E' // MONGOLIAN VOWEL SEPARATOR 355 | | '\u2000' // EN QUAD 356 | | '\u2001' // EM QUAD 357 | | '\u2002' // EN SPACE 358 | | '\u2003' // EM SPACE 359 | | '\u2004' // THREE_PER_EM SPACE 360 | | '\u2005' // FOUR_PER_EM SPACE 361 | | '\u2006' // SIX_PER_EM SPACE 362 | | '\u2008' // PUNCTUATION SPACE 363 | | '\u2009' // THIN SPACE 364 | | '\u200A' // HAIR SPACE 365 | | '\u202F' // NARROW NO_BREAK SPACE 366 | | '\u3000' // IDEOGRAPHIC SPACE 367 | | '\u205F' // MEDIUM MATHEMATICAL SPACE 368 | ; 369 | 370 | fragment IdentifierOrKeyword 371 | : IdentifierStartCharacter IdentifierPartCharacter* 372 | ; 373 | 374 | fragment IdentifierStartCharacter 375 | : LetterCharacter 376 | | '_' 377 | ; 378 | 379 | fragment IdentifierPartCharacter 380 | : LetterCharacter 381 | | DecimalDigitCharacter 382 | | ConnectingCharacter 383 | | CombiningCharacter 384 | | FormattingCharacter 385 | ; 386 | 387 | //'' 388 | // WARNING: ignores UnicodeEscapeSequence 389 | fragment LetterCharacter 390 | : UnicodeClassLU 391 | | UnicodeClassLL 392 | | UnicodeClassLT 393 | | UnicodeClassLM 394 | | UnicodeClassLO 395 | | UnicodeClassNL 396 | | UnicodeEscapeSequence 397 | ; 398 | 399 | //'' 400 | // WARNING: ignores UnicodeEscapeSequence 401 | fragment DecimalDigitCharacter 402 | : UnicodeClassND 403 | | UnicodeEscapeSequence 404 | ; 405 | 406 | //'' 407 | // WARNING: ignores UnicodeEscapeSequence 408 | fragment ConnectingCharacter 409 | : UnicodeClassPC 410 | | UnicodeEscapeSequence 411 | ; 412 | 413 | //'' 414 | // WARNING: ignores UnicodeEscapeSequence 415 | fragment CombiningCharacter 416 | : UnicodeClassMN 417 | | UnicodeClassMC 418 | | UnicodeEscapeSequence 419 | ; 420 | 421 | //'' 422 | // WARNING: ignores UnicodeEscapeSequence 423 | fragment FormattingCharacter 424 | : UnicodeClassCF 425 | | UnicodeEscapeSequence 426 | ; 427 | 428 | //B.1.5 Unicode Character Escape Sequences 429 | fragment UnicodeEscapeSequence 430 | : '\\u' HexDigit HexDigit HexDigit HexDigit 431 | | '\\U' HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit 432 | ; 433 | 434 | fragment HexDigit : [0-9] | [A-F] | [a-f]; 435 | 436 | // Unicode character classes 437 | fragment UnicodeClassLU 438 | : '\u0041'..'\u005a' 439 | | '\u00c0'..'\u00d6' 440 | | '\u00d8'..'\u00de' 441 | | '\u0100'..'\u0136' 442 | | '\u0139'..'\u0147' 443 | | '\u014a'..'\u0178' 444 | | '\u0179'..'\u017d' 445 | | '\u0181'..'\u0182' 446 | | '\u0184'..'\u0186' 447 | | '\u0187'..'\u0189' 448 | | '\u018a'..'\u018b' 449 | | '\u018e'..'\u0191' 450 | | '\u0193'..'\u0194' 451 | | '\u0196'..'\u0198' 452 | | '\u019c'..'\u019d' 453 | | '\u019f'..'\u01a0' 454 | | '\u01a2'..'\u01a6' 455 | | '\u01a7'..'\u01a9' 456 | | '\u01ac'..'\u01ae' 457 | | '\u01af'..'\u01b1' 458 | | '\u01b2'..'\u01b3' 459 | | '\u01b5'..'\u01b7' 460 | | '\u01b8'..'\u01bc' 461 | | '\u01c4'..'\u01cd' 462 | | '\u01cf'..'\u01db' 463 | | '\u01de'..'\u01ee' 464 | | '\u01f1'..'\u01f4' 465 | | '\u01f6'..'\u01f8' 466 | | '\u01fa'..'\u0232' 467 | | '\u023a'..'\u023b' 468 | | '\u023d'..'\u023e' 469 | | '\u0241'..'\u0243' 470 | | '\u0244'..'\u0246' 471 | | '\u0248'..'\u024e' 472 | | '\u0370'..'\u0372' 473 | | '\u0376'..'\u037f' 474 | | '\u0386'..'\u0388' 475 | | '\u0389'..'\u038a' 476 | | '\u038c'..'\u038e' 477 | | '\u038f'..'\u0391' 478 | | '\u0392'..'\u03a1' 479 | | '\u03a3'..'\u03ab' 480 | | '\u03cf'..'\u03d2' 481 | | '\u03d3'..'\u03d4' 482 | | '\u03d8'..'\u03ee' 483 | | '\u03f4'..'\u03f7' 484 | | '\u03f9'..'\u03fa' 485 | | '\u03fd'..'\u042f' 486 | | '\u0460'..'\u0480' 487 | | '\u048a'..'\u04c0' 488 | | '\u04c1'..'\u04cd' 489 | | '\u04d0'..'\u052e' 490 | | '\u0531'..'\u0556' 491 | | '\u10a0'..'\u10c5' 492 | | '\u10c7'..'\u10cd' 493 | | '\u1e00'..'\u1e94' 494 | | '\u1e9e'..'\u1efe' 495 | | '\u1f08'..'\u1f0f' 496 | | '\u1f18'..'\u1f1d' 497 | | '\u1f28'..'\u1f2f' 498 | | '\u1f38'..'\u1f3f' 499 | | '\u1f48'..'\u1f4d' 500 | | '\u1f59'..'\u1f5f' 501 | | '\u1f68'..'\u1f6f' 502 | | '\u1fb8'..'\u1fbb' 503 | | '\u1fc8'..'\u1fcb' 504 | | '\u1fd8'..'\u1fdb' 505 | | '\u1fe8'..'\u1fec' 506 | | '\u1ff8'..'\u1ffb' 507 | | '\u2102'..'\u2107' 508 | | '\u210b'..'\u210d' 509 | | '\u2110'..'\u2112' 510 | | '\u2115'..'\u2119' 511 | | '\u211a'..'\u211d' 512 | | '\u2124'..'\u212a' 513 | | '\u212b'..'\u212d' 514 | | '\u2130'..'\u2133' 515 | | '\u213e'..'\u213f' 516 | | '\u2145'..'\u2183' 517 | | '\u2c00'..'\u2c2e' 518 | | '\u2c60'..'\u2c62' 519 | | '\u2c63'..'\u2c64' 520 | | '\u2c67'..'\u2c6d' 521 | | '\u2c6e'..'\u2c70' 522 | | '\u2c72'..'\u2c75' 523 | | '\u2c7e'..'\u2c80' 524 | | '\u2c82'..'\u2ce2' 525 | | '\u2ceb'..'\u2ced' 526 | | '\u2cf2'..'\ua640' 527 | | '\ua642'..'\ua66c' 528 | | '\ua680'..'\ua69a' 529 | | '\ua722'..'\ua72e' 530 | | '\ua732'..'\ua76e' 531 | | '\ua779'..'\ua77d' 532 | | '\ua77e'..'\ua786' 533 | | '\ua78b'..'\ua78d' 534 | | '\ua790'..'\ua792' 535 | | '\ua796'..'\ua7aa' 536 | | '\ua7ab'..'\ua7ad' 537 | | '\ua7b0'..'\ua7b1' 538 | | '\uff21'..'\uff3a' 539 | ; 540 | 541 | fragment UnicodeClassLL 542 | : '\u0061'..'\u007A' 543 | | '\u00b5'..'\u00df' 544 | | '\u00e0'..'\u00f6' 545 | | '\u00f8'..'\u00ff' 546 | | '\u0101'..'\u0137' 547 | | '\u0138'..'\u0148' 548 | | '\u0149'..'\u0177' 549 | | '\u017a'..'\u017e' 550 | | '\u017f'..'\u0180' 551 | | '\u0183'..'\u0185' 552 | | '\u0188'..'\u018c' 553 | | '\u018d'..'\u0192' 554 | | '\u0195'..'\u0199' 555 | | '\u019a'..'\u019b' 556 | | '\u019e'..'\u01a1' 557 | | '\u01a3'..'\u01a5' 558 | | '\u01a8'..'\u01aa' 559 | | '\u01ab'..'\u01ad' 560 | | '\u01b0'..'\u01b4' 561 | | '\u01b6'..'\u01b9' 562 | | '\u01ba'..'\u01bd' 563 | | '\u01be'..'\u01bf' 564 | | '\u01c6'..'\u01cc' 565 | | '\u01ce'..'\u01dc' 566 | | '\u01dd'..'\u01ef' 567 | | '\u01f0'..'\u01f3' 568 | | '\u01f5'..'\u01f9' 569 | | '\u01fb'..'\u0233' 570 | | '\u0234'..'\u0239' 571 | | '\u023c'..'\u023f' 572 | | '\u0240'..'\u0242' 573 | | '\u0247'..'\u024f' 574 | | '\u0250'..'\u0293' 575 | | '\u0295'..'\u02af' 576 | | '\u0371'..'\u0373' 577 | | '\u0377'..'\u037b' 578 | | '\u037c'..'\u037d' 579 | | '\u0390'..'\u03ac' 580 | | '\u03ad'..'\u03ce' 581 | | '\u03d0'..'\u03d1' 582 | | '\u03d5'..'\u03d7' 583 | | '\u03d9'..'\u03ef' 584 | | '\u03f0'..'\u03f3' 585 | | '\u03f5'..'\u03fb' 586 | | '\u03fc'..'\u0430' 587 | | '\u0431'..'\u045f' 588 | | '\u0461'..'\u0481' 589 | | '\u048b'..'\u04bf' 590 | | '\u04c2'..'\u04ce' 591 | | '\u04cf'..'\u052f' 592 | | '\u0561'..'\u0587' 593 | | '\u1d00'..'\u1d2b' 594 | | '\u1d6b'..'\u1d77' 595 | | '\u1d79'..'\u1d9a' 596 | | '\u1e01'..'\u1e95' 597 | | '\u1e96'..'\u1e9d' 598 | | '\u1e9f'..'\u1eff' 599 | | '\u1f00'..'\u1f07' 600 | | '\u1f10'..'\u1f15' 601 | | '\u1f20'..'\u1f27' 602 | | '\u1f30'..'\u1f37' 603 | | '\u1f40'..'\u1f45' 604 | | '\u1f50'..'\u1f57' 605 | | '\u1f60'..'\u1f67' 606 | | '\u1f70'..'\u1f7d' 607 | | '\u1f80'..'\u1f87' 608 | | '\u1f90'..'\u1f97' 609 | | '\u1fa0'..'\u1fa7' 610 | | '\u1fb0'..'\u1fb4' 611 | | '\u1fb6'..'\u1fb7' 612 | | '\u1fbe'..'\u1fc2' 613 | | '\u1fc3'..'\u1fc4' 614 | | '\u1fc6'..'\u1fc7' 615 | | '\u1fd0'..'\u1fd3' 616 | | '\u1fd6'..'\u1fd7' 617 | | '\u1fe0'..'\u1fe7' 618 | | '\u1ff2'..'\u1ff4' 619 | | '\u1ff6'..'\u1ff7' 620 | | '\u210a'..'\u210e' 621 | | '\u210f'..'\u2113' 622 | | '\u212f'..'\u2139' 623 | | '\u213c'..'\u213d' 624 | | '\u2146'..'\u2149' 625 | | '\u214e'..'\u2184' 626 | | '\u2c30'..'\u2c5e' 627 | | '\u2c61'..'\u2c65' 628 | | '\u2c66'..'\u2c6c' 629 | | '\u2c71'..'\u2c73' 630 | | '\u2c74'..'\u2c76' 631 | | '\u2c77'..'\u2c7b' 632 | | '\u2c81'..'\u2ce3' 633 | | '\u2ce4'..'\u2cec' 634 | | '\u2cee'..'\u2cf3' 635 | | '\u2d00'..'\u2d25' 636 | | '\u2d27'..'\u2d2d' 637 | | '\ua641'..'\ua66d' 638 | | '\ua681'..'\ua69b' 639 | | '\ua723'..'\ua72f' 640 | | '\ua730'..'\ua731' 641 | | '\ua733'..'\ua771' 642 | | '\ua772'..'\ua778' 643 | | '\ua77a'..'\ua77c' 644 | | '\ua77f'..'\ua787' 645 | | '\ua78c'..'\ua78e' 646 | | '\ua791'..'\ua793' 647 | | '\ua794'..'\ua795' 648 | | '\ua797'..'\ua7a9' 649 | | '\ua7fa'..'\uab30' 650 | | '\uab31'..'\uab5a' 651 | | '\uab64'..'\uab65' 652 | | '\ufb00'..'\ufb06' 653 | | '\ufb13'..'\ufb17' 654 | | '\uff41'..'\uff5a' 655 | ; 656 | 657 | fragment UnicodeClassLT 658 | : '\u01c5'..'\u01cb' 659 | | '\u01f2'..'\u1f88' 660 | | '\u1f89'..'\u1f8f' 661 | | '\u1f98'..'\u1f9f' 662 | | '\u1fa8'..'\u1faf' 663 | | '\u1fbc'..'\u1fcc' 664 | | '\u1ffc'..'\u1ffc' 665 | ; 666 | 667 | fragment UnicodeClassLM 668 | : '\u02b0'..'\u02c1' 669 | | '\u02c6'..'\u02d1' 670 | | '\u02e0'..'\u02e4' 671 | | '\u02ec'..'\u02ee' 672 | | '\u0374'..'\u037a' 673 | | '\u0559'..'\u0640' 674 | | '\u06e5'..'\u06e6' 675 | | '\u07f4'..'\u07f5' 676 | | '\u07fa'..'\u081a' 677 | | '\u0824'..'\u0828' 678 | | '\u0971'..'\u0e46' 679 | | '\u0ec6'..'\u10fc' 680 | | '\u17d7'..'\u1843' 681 | | '\u1aa7'..'\u1c78' 682 | | '\u1c79'..'\u1c7d' 683 | | '\u1d2c'..'\u1d6a' 684 | | '\u1d78'..'\u1d9b' 685 | | '\u1d9c'..'\u1dbf' 686 | | '\u2071'..'\u207f' 687 | | '\u2090'..'\u209c' 688 | | '\u2c7c'..'\u2c7d' 689 | | '\u2d6f'..'\u2e2f' 690 | | '\u3005'..'\u3031' 691 | | '\u3032'..'\u3035' 692 | | '\u303b'..'\u309d' 693 | | '\u309e'..'\u30fc' 694 | | '\u30fd'..'\u30fe' 695 | | '\ua015'..'\ua4f8' 696 | | '\ua4f9'..'\ua4fd' 697 | | '\ua60c'..'\ua67f' 698 | | '\ua69c'..'\ua69d' 699 | | '\ua717'..'\ua71f' 700 | | '\ua770'..'\ua788' 701 | | '\ua7f8'..'\ua7f9' 702 | | '\ua9cf'..'\ua9e6' 703 | | '\uaa70'..'\uaadd' 704 | | '\uaaf3'..'\uaaf4' 705 | | '\uab5c'..'\uab5f' 706 | | '\uff70'..'\uff9e' 707 | | '\uff9f'..'\uff9f' 708 | ; 709 | 710 | fragment UnicodeClassLO 711 | : '\u00aa'..'\u00ba' 712 | | '\u01bb'..'\u01c0' 713 | | '\u01c1'..'\u01c3' 714 | | '\u0294'..'\u05d0' 715 | | '\u05d1'..'\u05ea' 716 | | '\u05f0'..'\u05f2' 717 | | '\u0620'..'\u063f' 718 | | '\u0641'..'\u064a' 719 | | '\u066e'..'\u066f' 720 | | '\u0671'..'\u06d3' 721 | | '\u06d5'..'\u06ee' 722 | | '\u06ef'..'\u06fa' 723 | | '\u06fb'..'\u06fc' 724 | | '\u06ff'..'\u0710' 725 | | '\u0712'..'\u072f' 726 | | '\u074d'..'\u07a5' 727 | | '\u07b1'..'\u07ca' 728 | | '\u07cb'..'\u07ea' 729 | | '\u0800'..'\u0815' 730 | | '\u0840'..'\u0858' 731 | | '\u08a0'..'\u08b2' 732 | | '\u0904'..'\u0939' 733 | | '\u093d'..'\u0950' 734 | | '\u0958'..'\u0961' 735 | | '\u0972'..'\u0980' 736 | | '\u0985'..'\u098c' 737 | | '\u098f'..'\u0990' 738 | | '\u0993'..'\u09a8' 739 | | '\u09aa'..'\u09b0' 740 | | '\u09b2'..'\u09b6' 741 | | '\u09b7'..'\u09b9' 742 | | '\u09bd'..'\u09ce' 743 | | '\u09dc'..'\u09dd' 744 | | '\u09df'..'\u09e1' 745 | | '\u09f0'..'\u09f1' 746 | | '\u0a05'..'\u0a0a' 747 | | '\u0a0f'..'\u0a10' 748 | | '\u0a13'..'\u0a28' 749 | | '\u0a2a'..'\u0a30' 750 | | '\u0a32'..'\u0a33' 751 | | '\u0a35'..'\u0a36' 752 | | '\u0a38'..'\u0a39' 753 | | '\u0a59'..'\u0a5c' 754 | | '\u0a5e'..'\u0a72' 755 | | '\u0a73'..'\u0a74' 756 | | '\u0a85'..'\u0a8d' 757 | | '\u0a8f'..'\u0a91' 758 | | '\u0a93'..'\u0aa8' 759 | | '\u0aaa'..'\u0ab0' 760 | | '\u0ab2'..'\u0ab3' 761 | | '\u0ab5'..'\u0ab9' 762 | | '\u0abd'..'\u0ad0' 763 | | '\u0ae0'..'\u0ae1' 764 | | '\u0b05'..'\u0b0c' 765 | | '\u0b0f'..'\u0b10' 766 | | '\u0b13'..'\u0b28' 767 | | '\u0b2a'..'\u0b30' 768 | | '\u0b32'..'\u0b33' 769 | | '\u0b35'..'\u0b39' 770 | | '\u0b3d'..'\u0b5c' 771 | | '\u0b5d'..'\u0b5f' 772 | | '\u0b60'..'\u0b61' 773 | | '\u0b71'..'\u0b83' 774 | | '\u0b85'..'\u0b8a' 775 | | '\u0b8e'..'\u0b90' 776 | | '\u0b92'..'\u0b95' 777 | | '\u0b99'..'\u0b9a' 778 | | '\u0b9c'..'\u0b9e' 779 | | '\u0b9f'..'\u0ba3' 780 | | '\u0ba4'..'\u0ba8' 781 | | '\u0ba9'..'\u0baa' 782 | | '\u0bae'..'\u0bb9' 783 | | '\u0bd0'..'\u0c05' 784 | | '\u0c06'..'\u0c0c' 785 | | '\u0c0e'..'\u0c10' 786 | | '\u0c12'..'\u0c28' 787 | | '\u0c2a'..'\u0c39' 788 | | '\u0c3d'..'\u0c58' 789 | | '\u0c59'..'\u0c60' 790 | | '\u0c61'..'\u0c85' 791 | | '\u0c86'..'\u0c8c' 792 | | '\u0c8e'..'\u0c90' 793 | | '\u0c92'..'\u0ca8' 794 | | '\u0caa'..'\u0cb3' 795 | | '\u0cb5'..'\u0cb9' 796 | | '\u0cbd'..'\u0cde' 797 | | '\u0ce0'..'\u0ce1' 798 | | '\u0cf1'..'\u0cf2' 799 | | '\u0d05'..'\u0d0c' 800 | | '\u0d0e'..'\u0d10' 801 | | '\u0d12'..'\u0d3a' 802 | | '\u0d3d'..'\u0d4e' 803 | | '\u0d60'..'\u0d61' 804 | | '\u0d7a'..'\u0d7f' 805 | | '\u0d85'..'\u0d96' 806 | | '\u0d9a'..'\u0db1' 807 | | '\u0db3'..'\u0dbb' 808 | | '\u0dbd'..'\u0dc0' 809 | | '\u0dc1'..'\u0dc6' 810 | | '\u0e01'..'\u0e30' 811 | | '\u0e32'..'\u0e33' 812 | | '\u0e40'..'\u0e45' 813 | | '\u0e81'..'\u0e82' 814 | | '\u0e84'..'\u0e87' 815 | | '\u0e88'..'\u0e8a' 816 | | '\u0e8d'..'\u0e94' 817 | | '\u0e95'..'\u0e97' 818 | | '\u0e99'..'\u0e9f' 819 | | '\u0ea1'..'\u0ea3' 820 | | '\u0ea5'..'\u0ea7' 821 | | '\u0eaa'..'\u0eab' 822 | | '\u0ead'..'\u0eb0' 823 | | '\u0eb2'..'\u0eb3' 824 | | '\u0ebd'..'\u0ec0' 825 | | '\u0ec1'..'\u0ec4' 826 | | '\u0edc'..'\u0edf' 827 | | '\u0f00'..'\u0f40' 828 | | '\u0f41'..'\u0f47' 829 | | '\u0f49'..'\u0f6c' 830 | | '\u0f88'..'\u0f8c' 831 | | '\u1000'..'\u102a' 832 | | '\u103f'..'\u1050' 833 | | '\u1051'..'\u1055' 834 | | '\u105a'..'\u105d' 835 | | '\u1061'..'\u1065' 836 | | '\u1066'..'\u106e' 837 | | '\u106f'..'\u1070' 838 | | '\u1075'..'\u1081' 839 | | '\u108e'..'\u10d0' 840 | | '\u10d1'..'\u10fa' 841 | | '\u10fd'..'\u1248' 842 | | '\u124a'..'\u124d' 843 | | '\u1250'..'\u1256' 844 | | '\u1258'..'\u125a' 845 | | '\u125b'..'\u125d' 846 | | '\u1260'..'\u1288' 847 | | '\u128a'..'\u128d' 848 | | '\u1290'..'\u12b0' 849 | | '\u12b2'..'\u12b5' 850 | | '\u12b8'..'\u12be' 851 | | '\u12c0'..'\u12c2' 852 | | '\u12c3'..'\u12c5' 853 | | '\u12c8'..'\u12d6' 854 | | '\u12d8'..'\u1310' 855 | | '\u1312'..'\u1315' 856 | | '\u1318'..'\u135a' 857 | | '\u1380'..'\u138f' 858 | | '\u13a0'..'\u13f4' 859 | | '\u1401'..'\u166c' 860 | | '\u166f'..'\u167f' 861 | | '\u1681'..'\u169a' 862 | | '\u16a0'..'\u16ea' 863 | | '\u16f1'..'\u16f8' 864 | | '\u1700'..'\u170c' 865 | | '\u170e'..'\u1711' 866 | | '\u1720'..'\u1731' 867 | | '\u1740'..'\u1751' 868 | | '\u1760'..'\u176c' 869 | | '\u176e'..'\u1770' 870 | | '\u1780'..'\u17b3' 871 | | '\u17dc'..'\u1820' 872 | | '\u1821'..'\u1842' 873 | | '\u1844'..'\u1877' 874 | | '\u1880'..'\u18a8' 875 | | '\u18aa'..'\u18b0' 876 | | '\u18b1'..'\u18f5' 877 | | '\u1900'..'\u191e' 878 | | '\u1950'..'\u196d' 879 | | '\u1970'..'\u1974' 880 | | '\u1980'..'\u19ab' 881 | | '\u19c1'..'\u19c7' 882 | | '\u1a00'..'\u1a16' 883 | | '\u1a20'..'\u1a54' 884 | | '\u1b05'..'\u1b33' 885 | | '\u1b45'..'\u1b4b' 886 | | '\u1b83'..'\u1ba0' 887 | | '\u1bae'..'\u1baf' 888 | | '\u1bba'..'\u1be5' 889 | | '\u1c00'..'\u1c23' 890 | | '\u1c4d'..'\u1c4f' 891 | | '\u1c5a'..'\u1c77' 892 | | '\u1ce9'..'\u1cec' 893 | | '\u1cee'..'\u1cf1' 894 | | '\u1cf5'..'\u1cf6' 895 | | '\u2135'..'\u2138' 896 | | '\u2d30'..'\u2d67' 897 | | '\u2d80'..'\u2d96' 898 | | '\u2da0'..'\u2da6' 899 | | '\u2da8'..'\u2dae' 900 | | '\u2db0'..'\u2db6' 901 | | '\u2db8'..'\u2dbe' 902 | | '\u2dc0'..'\u2dc6' 903 | | '\u2dc8'..'\u2dce' 904 | | '\u2dd0'..'\u2dd6' 905 | | '\u2dd8'..'\u2dde' 906 | | '\u3006'..'\u303c' 907 | | '\u3041'..'\u3096' 908 | | '\u309f'..'\u30a1' 909 | | '\u30a2'..'\u30fa' 910 | | '\u30ff'..'\u3105' 911 | | '\u3106'..'\u312d' 912 | | '\u3131'..'\u318e' 913 | | '\u31a0'..'\u31ba' 914 | | '\u31f0'..'\u31ff' 915 | | '\u3400'..'\u4db5' 916 | | '\u4e00'..'\u9fcc' 917 | | '\ua000'..'\ua014' 918 | | '\ua016'..'\ua48c' 919 | | '\ua4d0'..'\ua4f7' 920 | | '\ua500'..'\ua60b' 921 | | '\ua610'..'\ua61f' 922 | | '\ua62a'..'\ua62b' 923 | | '\ua66e'..'\ua6a0' 924 | | '\ua6a1'..'\ua6e5' 925 | | '\ua7f7'..'\ua7fb' 926 | | '\ua7fc'..'\ua801' 927 | | '\ua803'..'\ua805' 928 | | '\ua807'..'\ua80a' 929 | | '\ua80c'..'\ua822' 930 | | '\ua840'..'\ua873' 931 | | '\ua882'..'\ua8b3' 932 | | '\ua8f2'..'\ua8f7' 933 | | '\ua8fb'..'\ua90a' 934 | | '\ua90b'..'\ua925' 935 | | '\ua930'..'\ua946' 936 | | '\ua960'..'\ua97c' 937 | | '\ua984'..'\ua9b2' 938 | | '\ua9e0'..'\ua9e4' 939 | | '\ua9e7'..'\ua9ef' 940 | | '\ua9fa'..'\ua9fe' 941 | | '\uaa00'..'\uaa28' 942 | | '\uaa40'..'\uaa42' 943 | | '\uaa44'..'\uaa4b' 944 | | '\uaa60'..'\uaa6f' 945 | | '\uaa71'..'\uaa76' 946 | | '\uaa7a'..'\uaa7e' 947 | | '\uaa7f'..'\uaaaf' 948 | | '\uaab1'..'\uaab5' 949 | | '\uaab6'..'\uaab9' 950 | | '\uaaba'..'\uaabd' 951 | | '\uaac0'..'\uaac2' 952 | | '\uaadb'..'\uaadc' 953 | | '\uaae0'..'\uaaea' 954 | | '\uaaf2'..'\uab01' 955 | | '\uab02'..'\uab06' 956 | | '\uab09'..'\uab0e' 957 | | '\uab11'..'\uab16' 958 | | '\uab20'..'\uab26' 959 | | '\uab28'..'\uab2e' 960 | | '\uabc0'..'\uabe2' 961 | | '\uac00'..'\ud7a3' 962 | | '\ud7b0'..'\ud7c6' 963 | | '\ud7cb'..'\ud7fb' 964 | | '\uf900'..'\ufa6d' 965 | | '\ufa70'..'\ufad9' 966 | | '\ufb1d'..'\ufb1f' 967 | | '\ufb20'..'\ufb28' 968 | | '\ufb2a'..'\ufb36' 969 | | '\ufb38'..'\ufb3c' 970 | | '\ufb3e'..'\ufb40' 971 | | '\ufb41'..'\ufb43' 972 | | '\ufb44'..'\ufb46' 973 | | '\ufb47'..'\ufbb1' 974 | | '\ufbd3'..'\ufd3d' 975 | | '\ufd50'..'\ufd8f' 976 | | '\ufd92'..'\ufdc7' 977 | | '\ufdf0'..'\ufdfb' 978 | | '\ufe70'..'\ufe74' 979 | | '\ufe76'..'\ufefc' 980 | | '\uff66'..'\uff6f' 981 | | '\uff71'..'\uff9d' 982 | | '\uffa0'..'\uffbe' 983 | | '\uffc2'..'\uffc7' 984 | | '\uffca'..'\uffcf' 985 | | '\uffd2'..'\uffd7' 986 | | '\uffda'..'\uffdc' 987 | ; 988 | 989 | fragment UnicodeClassNL 990 | : '\u16EE' // RUNIC ARLAUG SYMBOL 991 | | '\u16EF' // RUNIC TVIMADUR SYMBOL 992 | | '\u16F0' // RUNIC BELGTHOR SYMBOL 993 | | '\u2160' // ROMAN NUMERAL ONE 994 | | '\u2161' // ROMAN NUMERAL TWO 995 | | '\u2162' // ROMAN NUMERAL THREE 996 | | '\u2163' // ROMAN NUMERAL FOUR 997 | | '\u2164' // ROMAN NUMERAL FIVE 998 | | '\u2165' // ROMAN NUMERAL SIX 999 | | '\u2166' // ROMAN NUMERAL SEVEN 1000 | | '\u2167' // ROMAN NUMERAL EIGHT 1001 | | '\u2168' // ROMAN NUMERAL NINE 1002 | | '\u2169' // ROMAN NUMERAL TEN 1003 | | '\u216A' // ROMAN NUMERAL ELEVEN 1004 | | '\u216B' // ROMAN NUMERAL TWELVE 1005 | | '\u216C' // ROMAN NUMERAL FIFTY 1006 | | '\u216D' // ROMAN NUMERAL ONE HUNDRED 1007 | | '\u216E' // ROMAN NUMERAL FIVE HUNDRED 1008 | | '\u216F' // ROMAN NUMERAL ONE THOUSAND 1009 | ; 1010 | 1011 | fragment UnicodeClassMN 1012 | : '\u0300' // COMBINING GRAVE ACCENT 1013 | | '\u0301' // COMBINING ACUTE ACCENT 1014 | | '\u0302' // COMBINING CIRCUMFLEX ACCENT 1015 | | '\u0303' // COMBINING TILDE 1016 | | '\u0304' // COMBINING MACRON 1017 | | '\u0305' // COMBINING OVERLINE 1018 | | '\u0306' // COMBINING BREVE 1019 | | '\u0307' // COMBINING DOT ABOVE 1020 | | '\u0308' // COMBINING DIAERESIS 1021 | | '\u0309' // COMBINING HOOK ABOVE 1022 | | '\u030A' // COMBINING RING ABOVE 1023 | | '\u030B' // COMBINING DOUBLE ACUTE ACCENT 1024 | | '\u030C' // COMBINING CARON 1025 | | '\u030D' // COMBINING VERTICAL LINE ABOVE 1026 | | '\u030E' // COMBINING DOUBLE VERTICAL LINE ABOVE 1027 | | '\u030F' // COMBINING DOUBLE GRAVE ACCENT 1028 | | '\u0310' // COMBINING CANDRABINDU 1029 | ; 1030 | 1031 | fragment UnicodeClassMC 1032 | : '\u0903' // DEVANAGARI SIGN VISARGA 1033 | | '\u093E' // DEVANAGARI VOWEL SIGN AA 1034 | | '\u093F' // DEVANAGARI VOWEL SIGN I 1035 | | '\u0940' // DEVANAGARI VOWEL SIGN II 1036 | | '\u0949' // DEVANAGARI VOWEL SIGN CANDRA O 1037 | | '\u094A' // DEVANAGARI VOWEL SIGN SHORT O 1038 | | '\u094B' // DEVANAGARI VOWEL SIGN O 1039 | | '\u094C' // DEVANAGARI VOWEL SIGN AU 1040 | ; 1041 | 1042 | fragment UnicodeClassCF 1043 | : '\u00AD' // SOFT HYPHEN 1044 | | '\u0600' // ARABIC NUMBER SIGN 1045 | | '\u0601' // ARABIC SIGN SANAH 1046 | | '\u0602' // ARABIC FOOTNOTE MARKER 1047 | | '\u0603' // ARABIC SIGN SAFHA 1048 | | '\u06DD' // ARABIC END OF AYAH 1049 | ; 1050 | 1051 | fragment UnicodeClassPC 1052 | : '\u005F' // LOW LINE 1053 | | '\u203F' // UNDERTIE 1054 | | '\u2040' // CHARACTER TIE 1055 | | '\u2054' // INVERTED UNDERTIE 1056 | | '\uFE33' // PRESENTATION FORM FOR VERTICAL LOW LINE 1057 | | '\uFE34' // PRESENTATION FORM FOR VERTICAL WAVY LOW LINE 1058 | | '\uFE4D' // DASHED LOW LINE 1059 | | '\uFE4E' // CENTRELINE LOW LINE 1060 | | '\uFE4F' // WAVY LOW LINE 1061 | | '\uFF3F' // FULLWIDTH LOW LINE 1062 | ; 1063 | 1064 | fragment UnicodeClassND 1065 | : '\u0030'..'\u0039' 1066 | | '\u0660'..'\u0669' 1067 | | '\u06f0'..'\u06f9' 1068 | | '\u07c0'..'\u07c9' 1069 | | '\u0966'..'\u096f' 1070 | | '\u09e6'..'\u09ef' 1071 | | '\u0a66'..'\u0a6f' 1072 | | '\u0ae6'..'\u0aef' 1073 | | '\u0b66'..'\u0b6f' 1074 | | '\u0be6'..'\u0bef' 1075 | | '\u0c66'..'\u0c6f' 1076 | | '\u0ce6'..'\u0cef' 1077 | | '\u0d66'..'\u0d6f' 1078 | | '\u0de6'..'\u0def' 1079 | | '\u0e50'..'\u0e59' 1080 | | '\u0ed0'..'\u0ed9' 1081 | | '\u0f20'..'\u0f29' 1082 | | '\u1040'..'\u1049' 1083 | | '\u1090'..'\u1099' 1084 | | '\u17e0'..'\u17e9' 1085 | | '\u1810'..'\u1819' 1086 | | '\u1946'..'\u194f' 1087 | | '\u19d0'..'\u19d9' 1088 | | '\u1a80'..'\u1a89' 1089 | | '\u1a90'..'\u1a99' 1090 | | '\u1b50'..'\u1b59' 1091 | | '\u1bb0'..'\u1bb9' 1092 | | '\u1c40'..'\u1c49' 1093 | | '\u1c50'..'\u1c59' 1094 | | '\ua620'..'\ua629' 1095 | | '\ua8d0'..'\ua8d9' 1096 | | '\ua900'..'\ua909' 1097 | | '\ua9d0'..'\ua9d9' 1098 | | '\ua9f0'..'\ua9f9' 1099 | | '\uaa50'..'\uaa59' 1100 | | '\uabf0'..'\uabf9' 1101 | | '\uff10'..'\uff19' 1102 | ; 1103 | --------------------------------------------------------------------------------