├── LICENSE ├── README.md ├── doc └── plugin_architecture.png ├── examples ├── .gitignore ├── .mps │ ├── .name │ ├── encodings.xml │ ├── migration.xml │ ├── misc.xml │ ├── modules.xml │ ├── vcs.xml │ └── version.xml ├── languages │ ├── CSharp │ │ ├── CSharp.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ ├── models │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ │ └── sandbox │ │ │ ├── CSharp.sandbox.msd │ │ │ └── models │ │ │ └── CSharp │ │ │ └── sandbox.mps │ ├── JSON.adjusted │ │ ├── JSON.adjusted.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ ├── models │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ │ └── sandbox │ │ │ ├── JSON.adjusted.sandbox.msd │ │ │ └── models │ │ │ └── JSON │ │ │ └── adjusted │ │ │ └── sandbox.mps │ ├── JSON │ │ ├── JSON.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ ├── models │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ │ └── sandbox │ │ │ ├── JSON.sandbox.msd │ │ │ └── models │ │ │ └── JSON │ │ │ └── sandbox.mps │ ├── JavaScript.adjusted │ │ ├── JavaScript.adjusted.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ └── models │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ ├── JavaScript │ │ ├── JavaScript.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ ├── models │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ │ └── sandbox │ │ │ ├── JavaScript.sandbox.msd │ │ │ └── models │ │ │ └── JavaScript │ │ │ └── sandbox.mps │ ├── SimpleXML.adjusted │ │ ├── SimpleXML.adjusted.mpl │ │ ├── generator │ │ │ └── template │ │ │ │ └── main@generator.mps │ │ ├── models │ │ │ ├── actions.mps │ │ │ ├── behavior.mps │ │ │ ├── constraints.mps │ │ │ ├── editor.mps │ │ │ ├── intentions.mps │ │ │ ├── refactorings.mps │ │ │ ├── structure.mps │ │ │ ├── textGen.mps │ │ │ └── typesystem.mps │ │ └── sandbox │ │ │ ├── SimpleXML.adjusted.sandbox.msd │ │ │ └── models │ │ │ └── SimpleXML │ │ │ └── adjusted │ │ │ └── sandbox.mps │ └── SimpleXML │ │ ├── SimpleXML.mpl │ │ ├── generator │ │ └── template │ │ │ └── main@generator.mps │ │ ├── models │ │ ├── behavior.mps │ │ ├── constraints.mps │ │ ├── editor.mps │ │ ├── structure.mps │ │ ├── textGen.mps │ │ └── typesystem.mps │ │ └── sandbox │ │ ├── SimpleXML.sandbox.msd │ │ └── models │ │ └── SimpleXML │ │ └── sandbox.mps └── solutions │ └── JavaScript.adjusted.sandbox │ ├── JavaScript.adjusted.sandbox.msd │ └── models │ └── sandbox.mps ├── grammars ├── ANTLRv4 │ ├── ANTLRv4Lexer.g4 │ ├── ANTLRv4Parser.g4 │ ├── LexBasic.g4 │ └── LexUnicode.g4 ├── CSharp │ ├── CSharpLexer.g4 │ └── CSharpParser.g4 ├── ECMAScript.g4 ├── JSON.g4 ├── SimpleXML.g4 └── XML.g4 ├── out └── premun.mps.ingrid.2019_1.zip └── plugin ├── idea ├── .gitignore ├── .idea │ ├── .name │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── libraries │ │ ├── R_User_Library.xml │ │ ├── library.xml │ │ ├── org_antlr.xml │ │ └── org_jetbrains_mps.xml │ ├── misc.xml │ ├── modules.xml │ └── qaplug_profiles.xml ├── importer │ ├── importer.iml │ └── src │ │ └── premun │ │ └── mps │ │ └── ingrid │ │ └── importer │ │ ├── GrammarImporter.java │ │ ├── ImportForm.form │ │ ├── ImportForm.java │ │ ├── ImportInfo.java │ │ ├── NamingService.java │ │ ├── exceptions │ │ └── IngridException.java │ │ └── steps │ │ ├── AliasFinder.java │ │ ├── ConceptImporter.java │ │ ├── ConceptLinker.java │ │ ├── EditorBuilder.java │ │ ├── ImportStep.java │ │ ├── RegexTransformer.java │ │ └── TextGenBuilder.java ├── ingrid_sources.iml ├── model │ ├── model.iml │ └── src │ │ └── premun │ │ └── mps │ │ └── ingrid │ │ └── model │ │ ├── Alternative.java │ │ ├── BlockAltRule.java │ │ ├── BlockEndRule.java │ │ ├── BlockStartRule.java │ │ ├── FlatLexerRule.java │ │ ├── GrammarInfo.java │ │ ├── LexerRule.java │ │ ├── LiteralRule.java │ │ ├── ParserRule.java │ │ ├── QuantifierRule.java │ │ ├── Quantity.java │ │ ├── RegexRule.java │ │ ├── Rule.java │ │ └── RuleReference.java ├── parser │ ├── parser.iml │ └── src │ │ └── premun │ │ └── mps │ │ └── ingrid │ │ └── parser │ │ ├── CollectionErrorListener.java │ │ ├── GrammarParser.java │ │ ├── GrammarResolver.java │ │ ├── GrammarWalker.java │ │ ├── ParserResult.java │ │ ├── antlr │ │ ├── ANTLRv4Lexer.java │ │ ├── ANTLRv4Parser.java │ │ ├── ANTLRv4ParserBaseListener.java │ │ ├── ANTLRv4ParserListener.java │ │ └── LexerAdaptor.java │ │ ├── exception │ │ ├── IngridParserException.java │ │ └── UnresolvableRuleException.java │ │ └── model │ │ ├── UnresolvedLexerRule.java │ │ ├── UnresolvedParserRule.java │ │ └── UnresolvedRule.java └── parser_tests │ ├── parser_tests.iml │ ├── res │ ├── MySQLLexer.g4 │ ├── MySQLParser.g4 │ └── SimpleXML.g4 │ └── src │ └── premun │ └── mps │ └── ingrid │ └── parser │ ├── AdvancedFeaturesTest.java │ ├── GrammarParserTest.java │ └── RegexBuilderTest.java ├── lib └── antlr4-4.7.2-complete.jar └── mps ├── .gitignore ├── .mps ├── .name ├── encodings.xml ├── migration.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── version.xml ├── Ingrid.build ├── Ingrid.build.msd └── models │ └── Ingrid │ └── build.mps ├── build.xml ├── importer ├── models │ └── dummy.mps └── premun.mps.ingrid.importer.msd ├── library ├── models │ └── premun │ │ └── mps │ │ └── ingrid │ │ └── library.mps └── premun.mps.ingrid.library.msd ├── model ├── models │ └── dummy.mps └── premun.mps.ingrid.model.msd ├── org.antlr └── org.antlr.msd ├── parser ├── models │ └── dummy.mps └── premun.mps.ingrid.parser.msd └── plugin ├── models └── premun │ └── mps │ └── ingrid │ └── plugin │ └── plugin.mps └── premun.mps.ingrid.plugin.msd /doc/plugin_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/premun/ingrid/80f18c36d6496003f8ecd9a3ce23ea9b5cb38c70/doc/plugin_architecture.png -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | .mps/workspace.xml 2 | 3 | classes_gen 4 | source_gen 5 | source_gen.caches 6 | 7 | junitvmwatcher*.properties 8 | 9 | *.class -------------------------------------------------------------------------------- /examples/.mps/.name: -------------------------------------------------------------------------------- 1 | Examples -------------------------------------------------------------------------------- /examples/.mps/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/.mps/migration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/.mps/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /examples/.mps/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/.mps/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/.mps/version.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /examples/languages/CSharp/CSharp.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /examples/languages/CSharp/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/languages/CSharp/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/CSharp/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/CSharp/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/CSharp/sandbox/CSharp.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/JSON.adjusted.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 9283473d-1390-4574-be8a-cc6a2aa4b500(SimpleXML) 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/sandbox/JSON.adjusted.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/JSON.adjusted/sandbox/models/JSON/adjusted/sandbox.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /examples/languages/JSON/JSON.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /examples/languages/JSON/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/JSON/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/JSON/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/JSON/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/JSON/sandbox/JSON.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/JSON/sandbox/models/JSON/sandbox.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/languages/JavaScript.adjusted/JavaScript.adjusted.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | c72da2b9-7cce-4447-8389-f407dc1158b7(jetbrains.mps.lang.structure) 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /examples/languages/JavaScript.adjusted/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/JavaScript.adjusted/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/languages/JavaScript.adjusted/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/languages/JavaScript.adjusted/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/sandbox/JavaScript.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/JavaScript/sandbox/models/JavaScript/sandbox.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/SimpleXML.adjusted.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/actions.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/intentions.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/refactorings.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/sandbox/SimpleXML.adjusted.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML.adjusted/sandbox/models/SimpleXML/adjusted/sandbox.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/SimpleXML.mpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/generator/template/main@generator.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/models/behavior.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/models/constraints.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/models/typesystem.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/sandbox/SimpleXML.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/languages/SimpleXML/sandbox/models/SimpleXML/sandbox.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/solutions/JavaScript.adjusted.sandbox/JavaScript.adjusted.sandbox.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /grammars/ANTLRv4/LexBasic.g4: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2014-2015 Gerald Rosenberg 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * A generally reusable set of fragments for import in to Lexer grammars. 32 | * 33 | * Modified 2015.06.16 gbr - 34 | * -- generalized for inclusion into the ANTLRv4 grammar distribution 35 | * 36 | */ 37 | 38 | lexer grammar LexBasic; 39 | 40 | import LexUnicode; // Formal set of Unicode ranges 41 | 42 | 43 | // ====================================================== 44 | // Lexer fragments 45 | // 46 | 47 | 48 | // ----------------------------------- 49 | // Whitespace & Comments 50 | 51 | fragment Ws : Hws | Vws ; 52 | fragment Hws : [ \t] ; 53 | fragment Vws : [\r\n\f] ; 54 | 55 | fragment DocComment : '/**' .*? ('*/' | EOF) ; 56 | fragment BlockComment : '/*' .*? ('*/' | EOF) ; 57 | 58 | fragment LineComment : '//' ~[\r\n]* ; 59 | fragment LineCommentExt : '//' ~'\n'* ( '\n' Hws* '//' ~'\n'* )* ; 60 | 61 | 62 | // ----------------------------------- 63 | // Escapes 64 | 65 | // Any kind of escaped character that we can embed within ANTLR literal strings. 66 | fragment EscSeq 67 | : Esc 68 | ( [btnfr"'\\] // The standard escaped character set such as tab, newline, etc. 69 | | UnicodeEsc // A Unicode escape sequence 70 | | . // Invalid escape character 71 | | EOF // Incomplete at EOF 72 | ) 73 | ; 74 | 75 | fragment EscAny 76 | : Esc . 77 | ; 78 | 79 | fragment UnicodeEsc 80 | : 'u' (HexDigit (HexDigit (HexDigit HexDigit?)?)?)? 81 | ; 82 | 83 | fragment OctalEscape 84 | : OctalDigit 85 | | OctalDigit OctalDigit 86 | | [0-3] OctalDigit OctalDigit 87 | ; 88 | 89 | 90 | // ----------------------------------- 91 | // Numerals 92 | 93 | fragment HexNumeral 94 | : '0' [xX] HexDigits 95 | ; 96 | 97 | fragment OctalNumeral 98 | : '0' '_' OctalDigits 99 | ; 100 | 101 | fragment DecimalNumeral 102 | : '0' 103 | | [1-9] DecDigit* 104 | ; 105 | 106 | fragment BinaryNumeral 107 | : '0' [bB] BinaryDigits 108 | ; 109 | 110 | 111 | // ----------------------------------- 112 | // Digits 113 | 114 | fragment HexDigits : HexDigit+ ; 115 | fragment DecDigits : DecDigit+ ; 116 | fragment OctalDigits : OctalDigit+ ; 117 | fragment BinaryDigits : BinaryDigit+ ; 118 | 119 | fragment HexDigit : [0-9a-fA-F] ; 120 | fragment DecDigit : [0-9] ; 121 | fragment OctalDigit : [0-7] ; 122 | fragment BinaryDigit : [01] ; 123 | 124 | 125 | // ----------------------------------- 126 | // Literals 127 | 128 | fragment BoolLiteral : True | False ; 129 | 130 | fragment CharLiteral : SQuote ( EscSeq | ~['\r\n\\] ) SQuote ; 131 | fragment SQuoteLiteral : SQuote ( EscSeq | ~['\r\n\\] )* SQuote ; 132 | fragment DQuoteLiteral : DQuote ( EscSeq | ~["\r\n\\] )* DQuote ; 133 | fragment USQuoteLiteral : SQuote ( EscSeq | ~['\r\n\\] )* ; 134 | 135 | fragment DecimalFloatingPointLiteral 136 | : DecDigits Dot DecDigits? ExponentPart? FloatTypeSuffix? 137 | | Dot DecDigits ExponentPart? FloatTypeSuffix? 138 | | DecDigits ExponentPart FloatTypeSuffix? 139 | | DecDigits FloatTypeSuffix 140 | ; 141 | 142 | fragment ExponentPart 143 | : [eE] [+-]? DecDigits 144 | ; 145 | 146 | fragment FloatTypeSuffix 147 | : [fFdD] 148 | ; 149 | 150 | fragment HexadecimalFloatingPointLiteral 151 | : HexSignificand BinaryExponent FloatTypeSuffix? 152 | ; 153 | 154 | fragment HexSignificand 155 | : HexNumeral Dot? 156 | | '0' [xX] HexDigits? Dot HexDigits 157 | ; 158 | 159 | fragment BinaryExponent 160 | : [pP] [+-]? DecDigits 161 | ; 162 | 163 | 164 | // ----------------------------------- 165 | // Character ranges 166 | 167 | fragment NameChar 168 | : NameStartChar 169 | | '0'..'9' 170 | | Underscore 171 | | '\u00B7' 172 | | '\u0300'..'\u036F' 173 | | '\u203F'..'\u2040' 174 | ; 175 | 176 | fragment NameStartChar 177 | : 'A'..'Z' 178 | | 'a'..'z' 179 | | '\u00C0'..'\u00D6' 180 | | '\u00D8'..'\u00F6' 181 | | '\u00F8'..'\u02FF' 182 | | '\u0370'..'\u037D' 183 | | '\u037F'..'\u1FFF' 184 | | '\u200C'..'\u200D' 185 | | '\u2070'..'\u218F' 186 | | '\u2C00'..'\u2FEF' 187 | | '\u3001'..'\uD7FF' 188 | | '\uF900'..'\uFDCF' 189 | | '\uFDF0'..'\uFFFD' 190 | ; // ignores | ['\u10000-'\uEFFFF] ; 191 | 192 | 193 | fragment JavaLetter 194 | : [a-zA-Z$_] // "java letters" below 0xFF 195 | | JavaUnicodeChars 196 | ; 197 | 198 | fragment JavaLetterOrDigit 199 | : [a-zA-Z0-9$_] // "java letters or digits" below 0xFF 200 | | JavaUnicodeChars 201 | ; 202 | 203 | // covers all characters above 0xFF which are not a surrogate 204 | // and UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 205 | fragment JavaUnicodeChars 206 | : ~[\u0000-\u00FF\uD800-\uDBFF] {Character.isJavaIdentifierPart(_input.LA(-1))}? 207 | | [\uD800-\uDBFF] [\uDC00-\uDFFF] {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? 208 | ; 209 | 210 | 211 | // ----------------------------------- 212 | // Types 213 | 214 | fragment Boolean : 'boolean' ; 215 | fragment Byte : 'byte' ; 216 | fragment Short : 'short' ; 217 | fragment Int : 'int' ; 218 | fragment Long : 'long' ; 219 | fragment Char : 'char' ; 220 | fragment Float : 'float' ; 221 | fragment Double : 'double' ; 222 | 223 | fragment True : 'true' ; 224 | fragment False : 'false' ; 225 | 226 | 227 | // ----------------------------------- 228 | // Symbols 229 | 230 | fragment Esc : '\\' ; 231 | fragment Colon : ':' ; 232 | fragment DColon : '::' ; 233 | fragment SQuote : '\'' ; 234 | fragment DQuote : '"' ; 235 | fragment BQuote : '`' ; 236 | fragment LParen : '(' ; 237 | fragment RParen : ')' ; 238 | fragment LBrace : '{' ; 239 | fragment RBrace : '}' ; 240 | fragment LBrack : '[' ; 241 | fragment RBrack : ']' ; 242 | fragment RArrow : '->' ; 243 | fragment Lt : '<' ; 244 | fragment Gt : '>' ; 245 | fragment Lte : '<=' ; 246 | fragment Gte : '>=' ; 247 | fragment Equal : '=' ; 248 | fragment NotEqual : '!=' ; 249 | fragment Question : '?' ; 250 | fragment Bang : '!' ; 251 | fragment Star : '*' ; 252 | fragment Slash : '/' ; 253 | fragment Percent : '%' ; 254 | fragment Caret : '^' ; 255 | fragment Plus : '+' ; 256 | fragment Minus : '-' ; 257 | fragment PlusAssign : '+=' ; 258 | fragment MinusAssign : '-=' ; 259 | fragment MulAssign : '*=' ; 260 | fragment DivAssign : '/=' ; 261 | fragment AndAssign : '&=' ; 262 | fragment OrAssign : '|=' ; 263 | fragment XOrAssign : '^=' ; 264 | fragment ModAssign : '%=' ; 265 | fragment LShiftAssign : '<<=' ; 266 | fragment RShiftAssign : '>>=' ; 267 | fragment URShiftAssign : '>>>='; 268 | fragment Underscore : '_' ; 269 | fragment Pipe : '|' ; 270 | fragment Amp : '&' ; 271 | fragment And : '&&' ; 272 | fragment Or : '||' ; 273 | fragment Inc : '++' ; 274 | fragment Dec : '--' ; 275 | fragment LShift : '<<' ; 276 | fragment RShift : '>>' ; 277 | fragment Dollar : '$' ; 278 | fragment Comma : ',' ; 279 | fragment Semi : ';' ; 280 | fragment Dot : '.' ; 281 | fragment Range : '..' ; 282 | fragment Ellipsis : '...' ; 283 | fragment At : '@' ; 284 | fragment Pound : '#' ; 285 | fragment Tilde : '~' ; 286 | -------------------------------------------------------------------------------- /grammars/JSON.g4: -------------------------------------------------------------------------------- 1 | grammar JSON; 2 | 3 | json 4 | : object 5 | | array 6 | ; 7 | 8 | object 9 | : '{' pair (',' pair)* '}' 10 | | '{' '}' 11 | ; 12 | 13 | pair 14 | : '"' STRING '":' value 15 | ; 16 | 17 | array 18 | : '[' value (',' value)* ']' 19 | | '[' ']' 20 | ; 21 | 22 | value 23 | : '"' STRING '"' 24 | | NUMBER 25 | | object 26 | | array 27 | | 'true' 28 | | 'false' 29 | | 'null' 30 | ; 31 | 32 | 33 | STRING 34 | : (ESC | ~["\\])* 35 | ; 36 | 37 | fragment ESC 38 | : '\\' (["\\/bfnrt] | UNICODE) 39 | ; 40 | 41 | fragment UNICODE 42 | : 'u' HEX HEX HEX HEX 43 | ; 44 | 45 | fragment HEX 46 | : [0-9a-fA-F] 47 | ; 48 | 49 | NUMBER 50 | : '-'? INT '.' [0-9] + EXP? | '-'? INT EXP | '-'? INT 51 | ; 52 | 53 | fragment INT 54 | : '0' | [1-9] [0-9]* 55 | ; 56 | 57 | // no leading zeros 58 | fragment EXP 59 | : [Ee] [+-]? INT 60 | ; 61 | 62 | // \- since - means "range" inside [...] 63 | WS 64 | : [ \t\n\r] + -> skip 65 | ; -------------------------------------------------------------------------------- /grammars/SimpleXML.g4: -------------------------------------------------------------------------------- 1 | grammar SimpleXML; 2 | 3 | document : prolog? comment? element 4 | ; 5 | 6 | prolog : ''; 7 | 8 | comment : '' 9 | ; 10 | 11 | element : '<' Name attribute* '>' content* '' 12 | | '<' Name attribute* '/>' 13 | ; 14 | 15 | attribute : Name '="' TEXT '"' 16 | ; 17 | 18 | content : TEXT 19 | | element 20 | | comment 21 | | CDATA 22 | ; 23 | 24 | Name : NameStartChar NameChar* 25 | ; 26 | 27 | fragment 28 | DIGIT : [0-9] 29 | ; 30 | 31 | fragment 32 | NameChar : NameStartChar 33 | | '-' 34 | | '_' 35 | | '.' 36 | | DIGIT 37 | ; 38 | 39 | fragment 40 | NameStartChar 41 | : [:a-zA-Z] 42 | ; 43 | 44 | TEXT : ~[<"]* 45 | ; 46 | 47 | CDATA : '' 48 | ; 49 | -------------------------------------------------------------------------------- /grammars/XML.g4: -------------------------------------------------------------------------------- 1 | /** XML parser derived from ANTLR v4 ref guide book example */ 2 | grammar XMLParser; 3 | 4 | // options { tokenVocab=XMLLexer; } 5 | 6 | document : prolog? misc* element misc*; 7 | 8 | prolog : XMLDeclOpen attribute* SPECIAL_CLOSE ; 9 | 10 | content : chardata? 11 | ((element | reference | CDATA | PI | COMMENT) chardata?)* ; 12 | 13 | element : '<' Name attribute* '>' content '<' '/' Name '>' 14 | | '<' Name attribute* '/>' 15 | ; 16 | 17 | reference : EntityRef | CharRef ; 18 | 19 | attribute : Name '=' STRING ; // Our STRING is AttValue in spec 20 | 21 | /** ``All text that is not markup constitutes the character data of 22 | * the document.'' 23 | */ 24 | chardata : TEXT | SEA_WS ; 25 | 26 | misc : COMMENT | PI | SEA_WS ; 27 | 28 | 29 | 30 | // LEXER 31 | 32 | 33 | // Default "mode": Everything OUTSIDE of a tag 34 | COMMENT : '' ; 35 | CDATA : '' ; 36 | /** Scarf all DTD stuff, Entity Declarations like , 37 | * and Notation Declarations 38 | */ 39 | DTD : '' -> skip ; 40 | EntityRef : '&' Name ';' ; 41 | CharRef : '&#' DIGIT+ ';' 42 | | '&#x' HEXDIGIT+ ';' 43 | ; 44 | SEA_WS : (' '|'\t'|'\r'? '\n')+ ; 45 | 46 | OPEN : '<' -> pushMode(INSIDE) ; 47 | XMLDeclOpen : ' pushMode(INSIDE) ; 48 | SPECIAL_OPEN: ' more, pushMode(PROC_INSTR) ; 49 | 50 | TEXT : ~[<&]+ ; // match any 16 bit char other than < and & 51 | 52 | // ----------------- Everything INSIDE of a tag --------------------- 53 | mode INSIDE; 54 | 55 | CLOSE : '>' -> popMode ; 56 | SPECIAL_CLOSE: '?>' -> popMode ; // close 57 | SLASH_CLOSE : '/>' -> popMode ; 58 | SLASH : '/' ; 59 | EQUALS : '=' ; 60 | STRING : '"' ~[<"]* '"' 61 | | '\'' ~[<']* '\'' 62 | ; 63 | Name : NameStartChar NameChar* ; 64 | S : [ \t\r\n] -> skip ; 65 | 66 | fragment 67 | HEXDIGIT : [a-fA-F0-9] ; 68 | 69 | fragment 70 | DIGIT : [0-9] ; 71 | 72 | fragment 73 | NameChar : NameStartChar 74 | | '-' | '_' | '.' | DIGIT 75 | | '\u00B7' 76 | | '\u0300'..'\u036F' 77 | | '\u203F'..'\u2040' 78 | ; 79 | 80 | fragment 81 | NameStartChar 82 | : [:a-zA-Z] 83 | | '\u2070'..'\u218F' 84 | | '\u2C00'..'\u2FEF' 85 | | '\u3001'..'\uD7FF' 86 | | '\uF900'..'\uFDCF' 87 | | '\uFDF0'..'\uFFFD' 88 | ; 89 | 90 | // ----------------- Handle --------------------- 91 | mode PROC_INSTR; 92 | 93 | PI : '?>' -> popMode ; // close 94 | IGNORE : . -> more ; -------------------------------------------------------------------------------- /out/premun.mps.ingrid.2019_1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/premun/ingrid/80f18c36d6496003f8ecd9a3ce23ea9b5cb38c70/out/premun.mps.ingrid.2019_1.zip -------------------------------------------------------------------------------- /plugin/idea/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/java,intellij,linux 3 | 4 | ### Java ### 5 | *.class 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | 16 | ### Intellij ### 17 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 18 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 19 | 20 | # User-specific stuff: 21 | .idea/workspace.xml 22 | .idea/tasks.xml 23 | .idea/dictionaries 24 | .idea/vcs.xml 25 | .idea/jsLibraryMappings.xml 26 | 27 | # Sensitive or high-churn files: 28 | .idea/dataSources.ids 29 | .idea/dataSources.xml 30 | .idea/dataSources.local.xml 31 | .idea/sqlDataSources.xml 32 | .idea/dynamic.xml 33 | .idea/uiDesigner.xml 34 | 35 | # Gradle: 36 | .idea/gradle.xml 37 | 38 | # Mongo Explorer plugin: 39 | .idea/mongoSettings.xml 40 | 41 | ## File-based project format: 42 | *.iws 43 | 44 | ## Plugin-specific files: 45 | 46 | # IntelliJ 47 | /out/ 48 | 49 | # mpeltonen/sbt-idea plugin 50 | .idea_modules/ 51 | 52 | # JIRA plugin 53 | atlassian-ide-plugin.xml 54 | 55 | # Crashlytics plugin (for Android Studio and IntelliJ) 56 | com_crashlytics_export_strings.xml 57 | crashlytics.properties 58 | crashlytics-build.properties 59 | fabric.properties 60 | 61 | 62 | ### Linux ### 63 | *~ 64 | 65 | # temporary files which can be created if a process still has a handle open of a deleted file 66 | .fuse_hidden* 67 | 68 | # KDE directory preferences 69 | .directory 70 | 71 | # Linux trash folder which might appear on any partition or disk 72 | .Trash-* 73 | -------------------------------------------------------------------------------- /plugin/idea/.idea/.name: -------------------------------------------------------------------------------- 1 | Ingrid IDEA sources -------------------------------------------------------------------------------- /plugin/idea/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /plugin/idea/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /plugin/idea/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /plugin/idea/.idea/libraries/R_User_Library.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /plugin/idea/.idea/libraries/library.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/idea/.idea/libraries/org_antlr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /plugin/idea/.idea/libraries/org_jetbrains_mps.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /plugin/idea/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 75 | -------------------------------------------------------------------------------- /plugin/idea/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/idea/importer/importer.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/GrammarImporter.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer; 2 | 3 | import jetbrains.mps.lang.smodel.generator.smodelAdapter.*; 4 | import org.jetbrains.mps.openapi.model.*; 5 | import premun.mps.ingrid.importer.steps.*; 6 | import premun.mps.ingrid.model.*; 7 | import premun.mps.ingrid.parser.*; 8 | 9 | import java.io.*; 10 | 11 | public class GrammarImporter { 12 | private SModel editorModel; 13 | private SModel structureModel; 14 | private SModel textGenModel; 15 | 16 | private GrammarInfo grammar; 17 | private ImportInfo importInfo; 18 | 19 | public GrammarImporter(SModel structureModel, SModel editorModel, SModel textGenModel) { 20 | this.editorModel = editorModel; 21 | this.structureModel = structureModel; 22 | this.textGenModel = textGenModel; 23 | } 24 | 25 | /** 26 | * Prepares the target language for import (clears it away). 27 | */ 28 | private void initializeLanguage() { 29 | // Delete all nodes 30 | SModelOperations 31 | .nodes(this.structureModel, null) 32 | .stream() 33 | .forEach(SNodeOperations::deleteNode); 34 | 35 | SModelOperations 36 | .nodes(this.editorModel, null) 37 | .stream() 38 | .forEach(SNodeOperations::deleteNode); 39 | 40 | SModelOperations 41 | .nodes(this.textGenModel, null) 42 | .stream() 43 | .forEach(SNodeOperations::deleteNode); 44 | } 45 | 46 | /** 47 | * Main method of the import process. 48 | * 49 | * @param files List of ANTLR grammar files to be imported. 50 | */ 51 | public void importGrammars(File[] files) { 52 | initializeLanguage(); 53 | 54 | GrammarParser parser = new GrammarParser(); 55 | 56 | for (File f : files) { 57 | parser.parseFile(f.getPath()); 58 | } 59 | 60 | this.grammar = parser.resolveGrammar(); 61 | this.importInfo = new ImportInfo(this.grammar.rootRule.name); 62 | 63 | ImportStep[] steps = new ImportStep[] { 64 | new RegexTransformer(), 65 | new ConceptImporter(), 66 | new ConceptLinker(), 67 | new AliasFinder(), 68 | new EditorBuilder(), 69 | new TextGenBuilder() 70 | }; 71 | 72 | this.executeSteps(steps); 73 | } 74 | 75 | public ImportInfo getImportInfo() { 76 | return this.importInfo; 77 | } 78 | 79 | private void executeSteps(ImportStep[] steps) { 80 | // Initialize steps with data 81 | for (ImportStep step : steps) { 82 | step.Initialize(this.grammar, this.structureModel, this.editorModel, this.textGenModel, this.importInfo); 83 | } 84 | 85 | // Execute steps 86 | for (ImportStep step : steps) { 87 | step.Execute(); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/ImportInfo.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer; 2 | 3 | /** 4 | * Data object containing grammar statistics. 5 | */ 6 | public class ImportInfo { 7 | public int rules; 8 | 9 | public int tokens; 10 | 11 | public int interfaces; 12 | 13 | public String rootRuleName; 14 | 15 | public ImportInfo(String rootRuleName) { 16 | this.rootRuleName = rootRuleName; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/NamingService.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | 5 | import java.security.*; 6 | 7 | public class NamingService { 8 | private SModel structureModel; 9 | private static SecureRandom rnd = new SecureRandom(); 10 | 11 | public NamingService(SModel structureModel) { 12 | this.structureModel = structureModel; 13 | } 14 | 15 | public String generateName(String suggested) { 16 | boolean duplicit = false; 17 | 18 | for (SNode node : this.structureModel.getRootNodes()) { 19 | if (suggested.equals(node.getName())) { 20 | duplicit = true; 21 | break; 22 | } 23 | } 24 | 25 | if (duplicit) { 26 | return generateName(suggested + "_" + generateSuffix(4)); 27 | } 28 | 29 | suggested = capitalize(suggested); 30 | 31 | return suggested; 32 | } 33 | 34 | public static String capitalize(String s) { 35 | return Character.toUpperCase(s.charAt(0)) + s.substring(1); 36 | } 37 | 38 | private String generateSuffix(int length) { 39 | final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 40 | 41 | StringBuilder sb = new StringBuilder(length); 42 | for (int i = 0; i < length; i++) { 43 | sb.append(chars.charAt(rnd.nextInt(chars.length()))); 44 | } 45 | 46 | return sb.toString(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/exceptions/IngridException.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.exceptions; 2 | 3 | public class IngridException extends RuntimeException { 4 | public IngridException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/AliasFinder.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | import premun.mps.ingrid.library.*; 5 | import premun.mps.ingrid.model.*; 6 | 7 | /** 8 | * Step tries to build an alias for each concept out of literals contained inside. 9 | */ 10 | public class AliasFinder extends ImportStep { 11 | @Override 12 | public void Execute() { 13 | this.grammar.rules 14 | .values() 15 | .stream() 16 | .filter(r -> r instanceof ParserRule) 17 | .map(r -> (ParserRule) r) 18 | .forEach(this::findAlias); 19 | } 20 | 21 | /** 22 | * Tries to build an alias out of literals inside of the given rule. 23 | * 24 | * @param rule Rule for which we are building the alias. 25 | */ 26 | private void findAlias(ParserRule rule) { 27 | for (int i = 0; i < rule.alternatives.size(); i++) { 28 | Alternative alternative = rule.alternatives.get(i); 29 | SNode concept = alternative.node; 30 | 31 | StringBuilder alias = new StringBuilder(); 32 | 33 | // Try to find a literals inside 34 | alternative.elements 35 | .stream() 36 | .filter(r -> r.rule instanceof LiteralRule) 37 | .map(r -> (LiteralRule) r.rule) 38 | .forEach(r -> alias.append(alias.length() == 0 ? "" : " ").append(r.value)); 39 | 40 | if (alias.length() == 0) { 41 | // If only one rule reference is inside, try to use that 42 | if(alternative.elements.size() == 1 && alternative.elements.get(0).rule != null) { 43 | alias 44 | .append(this.capitalize(alternative.elements.get(0).rule.name)); 45 | 46 | if (!rule.name.contains("_block_")) { 47 | alias 48 | .append(" ") 49 | .append(rule.name.toLowerCase()); 50 | } 51 | } 52 | } 53 | 54 | if(alias.length() == 0) { 55 | // Try to use ID 56 | if (alternative.comment != null && !alternative.comment.isEmpty()) { 57 | alias.append(alternative.comment); 58 | } 59 | } 60 | 61 | if(alias.length() == 0) { 62 | alias.append(concept.getName()); 63 | } 64 | 65 | String newAlias = alias.toString(); 66 | NodeHelper.setProperty(concept, Property.Alias, newAlias); 67 | alternative.alias = newAlias; 68 | } 69 | } 70 | 71 | private String capitalize(String s) { 72 | return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/ConceptImporter.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | import premun.mps.ingrid.importer.*; 5 | import premun.mps.ingrid.model.*; 6 | 7 | import java.util.*; 8 | 9 | /** 10 | * Import step that creates concepts and interface concepts for grammar rules. 11 | * (constraint data concepts for lexer rules are created in the linking step) 12 | */ 13 | public class ConceptImporter extends ImportStep { 14 | 15 | @Override 16 | public void Execute() { 17 | // Creates interfaces for parser rules and concepts for alternatives 18 | // Constraint data types for Lexer rules are created later, during node linking, 19 | // so that only those, that are really referenced (e.g. not fragments), are created. 20 | this.grammar.rules 21 | .values() 22 | .stream() 23 | .filter(r -> r instanceof ParserRule) 24 | .map(r -> (ParserRule) r) 25 | .forEach(this::importRule); 26 | } 27 | 28 | /** 29 | * Imports parser rule as an interface or a concept (not their children or editors). 30 | * 31 | * For split rules, all alternatives are imported as empty concepts. 32 | * Example: 33 | * element: '<' Name '>' Content '' 34 | * | '<' Name '/>' 35 | * ; 36 | * 37 | * There will be created one interface and two concepts for this rule that will implements this concept. 38 | * They will be named element (interface) and element_1 and element_2 (concepts). 39 | * 40 | * @param rule Rule to be imported. 41 | */ 42 | private void importRule(ParserRule rule) { 43 | if (this.isInterfaceNeeded(rule)) { 44 | rule.name = NamingService.capitalize(rule.name); 45 | 46 | // Generate interface name 47 | String interfaceName = this.namingService.generateName("I" + rule.name); 48 | 49 | // We will create an interface and a child for each alternative that will inherit this interface 50 | SNode iface = this.nodeFactory.createInterface(interfaceName, "Interfaces"); 51 | this.structureModel.addRootNode(iface); 52 | rule.node = iface; 53 | 54 | ++this.grammarInfo.interfaces; 55 | 56 | // For each alternative, there will be a concept 57 | for (int i = 0; i < rule.alternatives.size(); ++i) { 58 | Alternative alternative = rule.alternatives.get(i); 59 | String name = this.namingService.generateName(rule.name + "_" + (i + 1)); 60 | String description = alternative.comment != null ? alternative.comment : rule.name; 61 | 62 | // Concrete element, we can create a concept 63 | SNode concept = this.nodeFactory.createConcept(name, name, description, "Rules." + rule.name, rule.equals(this.grammar.rootRule)); 64 | alternative.node = concept; 65 | 66 | this.structureModel.addRootNode(concept); 67 | 68 | ++this.grammarInfo.rules; 69 | } 70 | } else { 71 | // Generate unique name 72 | rule.name = this.namingService.generateName(rule.name); 73 | 74 | // We will create plain old concept 75 | Alternative alternative = rule.alternatives.get(0); 76 | String description = alternative.comment != null ? alternative.comment : rule.name; 77 | 78 | // Not a rule that splits into more rules - we create it directly 79 | SNode concept = this.nodeFactory.createConcept(rule.name, rule.name, description, "Rules." + rule.name, rule.equals(this.grammar.rootRule)); 80 | this.structureModel.addRootNode(concept); 81 | rule.node = concept; 82 | alternative.node = concept; 83 | 84 | ++this.grammarInfo.rules; 85 | } 86 | } 87 | 88 | /** 89 | * Detects, whether we need to create an interface for a rule. 90 | * 91 | * 1) When has more alternatives - then we need it to 92 | * 2) Or, when there could a shortcut lead through this concept. Then we need it, so that all end nodes can inherit it. 93 | * Example situation: 94 | * a : a1 95 | * | a2 96 | * | a3 97 | * ; 98 | * 99 | * a2 : b1 100 | * ; 101 | * 102 | * b1 : C1 103 | * | C2 104 | * ; 105 | * 106 | * Then, even when a2 is simple, we need an IA2 interface, so that nodes B1_1 and B1_2 can inherit it. 107 | * 108 | * @param rule Rule, to be verified 109 | * @return True, when we need to create an interface for this node. 110 | */ 111 | private boolean isInterfaceNeeded(ParserRule rule) { 112 | // Case 1) 113 | if (rule.alternatives.size() > 1) { 114 | return true; 115 | } 116 | 117 | // Case 2) 118 | List elements = rule.alternatives.get(0).elements; 119 | if (elements.size() == 1) { 120 | RuleReference element = elements.get(0); 121 | 122 | if (element.quantity == Quantity.EXACTLY_ONE && element.rule instanceof ParserRule) { 123 | return true; 124 | } 125 | } 126 | 127 | return false; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/ConceptLinker.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | import premun.mps.ingrid.library.*; 5 | import premun.mps.ingrid.model.*; 6 | 7 | import java.util.*; 8 | 9 | /** 10 | * Import step that links concepts together by creating properties and children. 11 | */ 12 | public class ConceptLinker extends ImportStep { 13 | 14 | private Shortcuts shortcuts = new Shortcuts(); 15 | 16 | @Override 17 | public void Execute() { 18 | this.grammar.rules 19 | .values() 20 | .stream() 21 | .filter(r -> r instanceof ParserRule) 22 | .map(r -> (ParserRule) r) 23 | .forEach(this::createConceptFields); 24 | 25 | addInterfacesToEndNodes(); 26 | } 27 | 28 | /** 29 | * Imports rule's alternatives (children and properties linking to different concepts). 30 | * 31 | * @param rule Rule to be imported. 32 | */ 33 | private void createConceptFields(ParserRule rule) { 34 | // For each alternative.. 35 | for (int altIndex = 0; altIndex < rule.alternatives.size(); altIndex++) { 36 | Alternative alternative = rule.alternatives.get(altIndex); 37 | 38 | // Concept representing current alternative 39 | SNode parent = alternative.node; 40 | 41 | int childIndex = 0; 42 | int propertyIndex = 0; 43 | 44 | // For each element of that alternative.. 45 | for (RuleReference childRef : alternative.elements) { 46 | if (childRef.rule instanceof LiteralRule) { 47 | // Literal rule will only appear in editor 48 | } else if (childRef.rule instanceof RegexRule) { 49 | // Create concept for token, if referenced for the first time 50 | RegexRule regexRule = ((RegexRule) childRef.rule); 51 | if (regexRule.node == null) { 52 | regexRule.name = this.namingService.generateName(regexRule.name); 53 | SNode node = this.nodeFactory.createConstraintDataType(regexRule.name, regexRule.regexp, "Tokens"); 54 | this.structureModel.addRootNode(node); 55 | regexRule.node = node; 56 | 57 | ++this.grammarInfo.tokens; 58 | } 59 | 60 | // Find regex type and create property for it 61 | String linkName = regexRule.name + "_" + (++propertyIndex); 62 | SNode tokenRule = regexRule.node; 63 | childRef.nodeReference = NodeHelper.addPropertyToNode(parent, linkName, tokenRule); 64 | } else if (childRef.rule instanceof ParserRule) { 65 | // Find referenced interface / concept 66 | ParserRule child = (ParserRule) childRef.rule; 67 | SNode childConcept = child.node; 68 | childRef.nodeReference = NodeHelper.addChildToNode(parent, childConcept, child.name + "_" + (++childIndex), childRef.quantity); 69 | } 70 | } 71 | } 72 | } 73 | 74 | /** 75 | * Finds all paths from interfaces to end nodes and link interfaces there. 76 | */ 77 | private void addInterfacesToEndNodes() { 78 | this.grammar.rules 79 | .values() 80 | .stream() 81 | .filter(r -> r instanceof ParserRule) 82 | .map(r -> (ParserRule) r) 83 | .forEach(this::findEndNodes); 84 | 85 | for (ParserRule key : this.shortcuts.keySet()) { 86 | for (Shortcut shortcut : this.shortcuts.get(key)) { 87 | // Last node is the target node, nodes before represent interfaces bound to parser rules 88 | SNode endNode = shortcut.path.get(shortcut.path.size() - 1); 89 | 90 | for (int i = 0; i < shortcut.path.size() - 1; i++) { 91 | NodeHelper.linkInterfaceToConcept(endNode, shortcut.path.get(i)); 92 | } 93 | } 94 | } 95 | } 96 | 97 | /** 98 | * Finds a list of shortcuts for given rule and saves it into the shortcuts field. 99 | * 100 | * @param rule Rule 101 | */ 102 | private void findEndNodes(ParserRule rule) { 103 | List result = findEndNodes(rule, new ArrayList<>()); 104 | 105 | // Rules without shortcuts, are rules that all have paths of length 1 106 | // If one of them had length > 1, we need to create the menu because of that 107 | if (result.stream().allMatch(s -> s.path.size() == 1)) return; 108 | 109 | // Save all shortcuts for this rule 110 | this.shortcuts.put(rule, result); 111 | } 112 | 113 | /** 114 | * Finds a list of paths that lead from a rule to an end node 115 | * (a rule represented by a classic concept). 116 | * 117 | * Example: 118 | * s : a; 119 | * 120 | * a : c 121 | * | d 122 | * | 'xxx' 123 | * ; 124 | * 125 | * c : STRING; 126 | * d : DIGIT; 127 | * 128 | * STRING : .+; 129 | * DIGIT : [0-9]+; 130 | * 131 | * Then findEndNodes(s) will find 3 different paths: 132 | * 1) s -> STRING (s->a_1->c) 133 | * 2) s -> DIGIT (s->a_2->d) 134 | * 3) s -> 'xxx' (s->a_3) 135 | * 136 | * @param rule Rule for which we want to find shortcuts. 137 | * @param path Alternatives that lead to that end node. 138 | * @return List of shortcuts. 139 | */ 140 | private List findEndNodes(ParserRule rule, List path) { 141 | List result = new ArrayList<>(); 142 | 143 | // Interface - we need to find implementors 144 | for (Alternative alternative : rule.alternatives) { 145 | List elements = alternative.elements; 146 | 147 | // Each alternative needs it's own path 148 | List clonedPath = clonePath(path); 149 | 150 | if (elements.size() == 1 && elements.get(0).rule instanceof ParserRule && elements.get(0).quantity == Quantity.EXACTLY_ONE) { 151 | // A single parser rule reference (shortcut) 152 | ParserRule next = (ParserRule) elements.get(0).rule; 153 | 154 | // Add current rule to path 155 | clonedPath.add(rule.node); 156 | 157 | // Recursively find all end nodes 158 | result.addAll(this.findEndNodes(next, clonedPath)); 159 | } else { 160 | // More elements in an alternative -> not a shortcut but an end node 161 | clonedPath.add(rule.node); 162 | if (clonedPath.isEmpty() || clonedPath.get(clonedPath.size() - 1) != alternative.node){ 163 | clonedPath.add(alternative.node); 164 | } 165 | 166 | Shortcut shortcut = new Shortcut(clonedPath); 167 | result.add(shortcut); 168 | } 169 | } 170 | 171 | return result; 172 | } 173 | 174 | /** 175 | * Makes a shallow copy of a List. 176 | * 177 | * @param list List to be copied. 178 | * @return Input copy. 179 | */ 180 | private static List clonePath(List list) { 181 | List clone = new ArrayList<>(list.size()); 182 | clone.addAll(list); 183 | return clone; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/EditorBuilder.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | import premun.mps.ingrid.library.*; 5 | import premun.mps.ingrid.model.*; 6 | 7 | /** 8 | * Import step that creates projection editors for all concepts. 9 | */ 10 | public class EditorBuilder extends ImportStep { 11 | private EditorHelper editorHelper; 12 | 13 | @Override 14 | public void Execute() { 15 | this.editorHelper = new EditorHelper(); 16 | 17 | this.grammar.rules 18 | .values() 19 | .stream() 20 | .filter(r -> r instanceof ParserRule) 21 | .map(r -> (ParserRule) r) 22 | .forEach(this::buildEditor); 23 | } 24 | 25 | /** 26 | * Builds an editor for given rule. 27 | * 28 | * @param rule Rule for which the editor is built. 29 | */ 30 | private void buildEditor(ParserRule rule) { 31 | // Interface - we need to find implementors 32 | for (Alternative alternative : rule.alternatives) { 33 | SNode editor = this.editorHelper.createEditor(alternative); 34 | this.editorModel.addRootNode(editor); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/ImportStep.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | import premun.mps.ingrid.importer.*; 5 | import premun.mps.ingrid.importer.exceptions.*; 6 | import premun.mps.ingrid.library.*; 7 | import premun.mps.ingrid.model.*; 8 | 9 | /** 10 | * Abstract import step. 11 | */ 12 | public abstract class ImportStep { 13 | GrammarInfo grammar; 14 | ImportInfo grammarInfo; 15 | SModel structureModel; 16 | SModel editorModel; 17 | SModel textGenModel; 18 | NodeFactory nodeFactory; 19 | NamingService namingService; 20 | 21 | public void Initialize(GrammarInfo grammar, SModel structureModel, SModel editorModel, SModel textGenModel, ImportInfo grammarInfo) { 22 | this.grammar = grammar; 23 | this.structureModel = structureModel; 24 | this.editorModel = editorModel; 25 | this.textGenModel = textGenModel; 26 | this.grammarInfo = grammarInfo; 27 | 28 | this.namingService = new NamingService(structureModel); 29 | this.nodeFactory = new NodeFactory(structureModel); 30 | } 31 | 32 | public abstract void Execute(); 33 | 34 | /** 35 | * Finds a concept by it's name. 36 | * 37 | * @param name Concept to be matched. 38 | * @return Concept node belonging to given rule. 39 | */ 40 | final SNode findConceptByName(String name) throws IngridException { 41 | for (SNode node : this.structureModel.getRootNodes()) { 42 | if (name.equals(node.getName())) { 43 | return node; 44 | } 45 | } 46 | 47 | throw new IngridException("Concept " + name + " not found!"); 48 | } 49 | 50 | /** 51 | * Finds a concept that was created for given rule. 52 | * 53 | * @param rule Rule to be matched. 54 | * @return Concept node belonging to given rule. 55 | */ 56 | final SNode findConceptByRule(Rule rule) throws IngridException { 57 | for (SNode node : this.structureModel.getRootNodes()) { 58 | if (rule.name.equals(node.getName()) || (rule.name + "_1").equals(node.getName())) { 59 | return node; 60 | } 61 | } 62 | 63 | throw new IngridException("Concept for rule " + rule.name + " not found!"); 64 | } 65 | 66 | /** 67 | * Finds a concept representing given alternative. 68 | * 69 | * @param rule Rule whose alternative we are resolving. 70 | * @param index Index of the alternative. 71 | * @return Concept node belonging to given alternative. 72 | * @throws IngridException 73 | */ 74 | protected final SNode findConceptByAlternative(ParserRule rule, int index) throws IngridException { 75 | if (rule.alternatives.size() == 1) { 76 | return this.findConceptByRule(rule); 77 | } else { 78 | return this.findConceptByName(rule.name + "_" + (index + 1)); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/RegexTransformer.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import premun.mps.ingrid.model.*; 4 | 5 | /** 6 | * Import step that closes the gap between ANTLRv4 regexes and MPS's format (Java). 7 | * https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#lexer-rule-elements 8 | */ 9 | public class RegexTransformer extends ImportStep { 10 | @Override 11 | public void Execute() { 12 | this.grammar.rules 13 | .values() 14 | .stream() 15 | .filter(r -> r instanceof RegexRule) 16 | .map(r -> (RegexRule) r) 17 | .forEach(this::transformRegex); 18 | } 19 | 20 | /** 21 | * Transforms a regex into a form that is valid inside MPS. 22 | * 23 | * @param rule Constraint data type's rule. 24 | */ 25 | private void transformRegex(RegexRule rule) { 26 | // Regex is stored as a string inside the constraint data type, 27 | // so slashes need to be doubly-escaped.. 28 | rule.regexp = rule.regexp 29 | .replaceAll("\\\\", "\\\\\\\\") 30 | 31 | // All-except-from has different notation 32 | .replaceAll("~\\[", "[^") 33 | .replaceAll("~ \\[", "[^"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugin/idea/importer/src/premun/mps/ingrid/importer/steps/TextGenBuilder.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.importer.steps; 2 | 3 | import premun.mps.ingrid.library.*; 4 | import premun.mps.ingrid.model.*; 5 | 6 | import java.util.*; 7 | import java.util.regex.*; 8 | 9 | /** 10 | * Step tries to generate TextGen aspects for all alternatives (concepts). 11 | */ 12 | public class TextGenBuilder extends ImportStep { 13 | @Override 14 | public void Execute() { 15 | this.grammar.rules 16 | .values() 17 | .stream() 18 | .filter(r -> r instanceof ParserRule) 19 | .map(r -> (ParserRule) r) 20 | .forEach(this::buildTextGen); 21 | } 22 | 23 | private void buildTextGen(ParserRule rule) { 24 | for (Alternative alternative : rule.alternatives) { 25 | TextGenHelper textGen = new TextGenHelper(alternative.node); 26 | 27 | // Go one by one element and create append statements for them 28 | List elements = alternative.elements; 29 | for (int i = 0; i < elements.size(); i++) { 30 | RuleReference element = elements.get(i); 31 | 32 | if (element.rule instanceof LiteralRule) { 33 | // Add constant content, no space needed 34 | textGen.appendString(((LiteralRule) element.rule).value); 35 | } else { 36 | // Will there be a space in front of us? 37 | boolean prependSpace = false; 38 | if(i > 0) { 39 | // Are we neighbours with literal token? 40 | Rule prevRule = elements.get(i - 1).rule; 41 | if(prevRule instanceof LiteralRule) { 42 | // We will only put space when tokens like "function" or "return" are present 43 | // We check, whether the last character is alphabetic 44 | // Turns out it works nice in a lot of cases, since user usually inserts alphanumeric content 45 | prependSpace = Pattern.matches(".*[a-zA-Z_]$", ((LiteralRule) prevRule).value); 46 | } else { 47 | prependSpace = true; 48 | } 49 | } 50 | 51 | if (element.rule instanceof RegexRule) { 52 | // Add property value 53 | textGen.appendProperty(element, prependSpace); 54 | } else if (element.rule instanceof ParserRule) { 55 | // Add child value 56 | textGen.appendChild(element, prependSpace); 57 | } 58 | } 59 | } 60 | 61 | // Root rule needs some extra information about output format 62 | if (rule == this.grammar.rootRule) { 63 | textGen.setupAsRootConcept(rule.name, ""); 64 | } 65 | 66 | this.textGenModel.addRootNode(textGen.getTextGen()); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /plugin/idea/ingrid_sources.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/idea/model/model.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/Alternative.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | 5 | import java.util.*; 6 | 7 | public class Alternative { 8 | public List elements = new ArrayList<>(); 9 | 10 | public String comment; 11 | 12 | public SNode node = null; 13 | 14 | public String alias = null; 15 | } 16 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/BlockAltRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public class BlockAltRule extends Rule { 4 | public BlockAltRule() { 5 | super("|"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/BlockEndRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public class BlockEndRule extends Rule { 4 | public BlockEndRule() { 5 | super(")"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/BlockStartRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public class BlockStartRule extends Rule { 4 | public BlockStartRule() { 5 | super("("); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/FlatLexerRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public abstract class FlatLexerRule extends Rule { 4 | public FlatLexerRule(String name) { 5 | super(name); 6 | } 7 | 8 | public abstract String getContent(); 9 | } 10 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/GrammarInfo.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import java.util.*; 4 | 5 | public class GrammarInfo { 6 | public String name; 7 | public Map rules = new HashMap<>(); 8 | public Rule rootRule = null; 9 | 10 | public GrammarInfo(String name) { 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | StringBuilder sb = new StringBuilder(); 17 | 18 | sb 19 | .append("grammar ") 20 | .append(this.name) 21 | .append(";") 22 | .append(System.lineSeparator()); 23 | 24 | for (Rule rule : this.rules.values()) { 25 | sb 26 | .append(rule.toString()) 27 | .append(System.lineSeparator()) 28 | .append(System.lineSeparator()); 29 | } 30 | 31 | return sb.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/LexerRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import java.util.*; 4 | 5 | public class LexerRule extends Rule { 6 | public List> alternatives = new ArrayList<>(); 7 | 8 | public LexerRule(String name) { 9 | super(name); 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | StringBuilder sb = new StringBuilder(); 15 | 16 | sb 17 | .append(this.name) 18 | .append(System.lineSeparator()); 19 | 20 | for (List alternatives : this.alternatives) { 21 | sb.append("\t\t| "); 22 | 23 | for (Rule rule : alternatives) { 24 | if (rule instanceof LiteralRule) { 25 | sb.append(((LiteralRule) rule).value); 26 | } else if (rule instanceof RegexRule) { 27 | sb.append(((RegexRule) rule).regexp); 28 | } else { 29 | sb.append(rule.name); 30 | } 31 | 32 | sb.append(" "); 33 | } 34 | 35 | sb.append(System.lineSeparator()); 36 | } 37 | 38 | return sb.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/LiteralRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public class LiteralRule extends FlatLexerRule { 4 | public String value; 5 | 6 | public LiteralRule(String name, String value) { 7 | super(name); 8 | // Strip apostrophes 'foo' -> foo 9 | if (value.startsWith("'")) { 10 | this.value = value.substring(1, value.length() - 1); 11 | } else { 12 | this.value = value; 13 | } 14 | } 15 | 16 | public LiteralRule(String value) { 17 | this(java.util.UUID.randomUUID().toString(), value); 18 | } 19 | 20 | @Override 21 | public String getContent() { 22 | return value; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return this.name 28 | + ":\t" 29 | + this.value 30 | + System.lineSeparator() 31 | + "\t\t;" 32 | + System.lineSeparator(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/ParserRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | 5 | import java.util.*; 6 | 7 | public class ParserRule extends Rule { 8 | public List alternatives = new ArrayList<>(); 9 | 10 | public SNode node = null; 11 | 12 | public ParserRule(String name) { 13 | super(name); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | StringBuilder sb = new StringBuilder(); 19 | 20 | sb 21 | .append(this.name) 22 | .append(System.lineSeparator()); 23 | 24 | for (Alternative alternative : this.alternatives) { 25 | sb.append("\t\t| "); 26 | 27 | for (RuleReference ref : alternative.elements) { 28 | if (ref.rule instanceof FlatLexerRule) { 29 | sb 30 | .append(((FlatLexerRule) ref.rule).getContent()) 31 | .append(ref.quantity.toString()); 32 | } else { 33 | sb 34 | .append(ref.rule.name) 35 | .append(ref.quantity.toString()); 36 | } 37 | 38 | sb.append(" "); 39 | } 40 | 41 | sb.append(System.lineSeparator()); 42 | } 43 | 44 | return sb.toString(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/QuantifierRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public class QuantifierRule extends Rule { 4 | public Quantity quantity; 5 | 6 | public QuantifierRule(Quantity quantity) { 7 | super(quantity.toString()); 8 | this.quantity = quantity; 9 | } 10 | 11 | public QuantifierRule(String quantity) { 12 | this(Quantity.FromString(quantity)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/Quantity.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public enum Quantity { 4 | EXACTLY_ONE, 5 | MAX_ONE, 6 | AT_LEAST_ONE, 7 | ANY; 8 | 9 | public String getCardinality() { 10 | switch (this) { 11 | case EXACTLY_ONE: 12 | return "1"; 13 | 14 | case ANY: 15 | return "0..n"; 16 | 17 | case AT_LEAST_ONE: 18 | return "1..n"; 19 | 20 | case MAX_ONE: 21 | return "0..1"; 22 | 23 | default: 24 | throw new IllegalArgumentException(); 25 | } 26 | } 27 | 28 | public static Quantity FromString(String quantifier) { 29 | switch (quantifier) { 30 | case "?": 31 | case "??": // non-greedy (https://github.com/antlr/antlr4/blob/master/doc/wildcard.md) 32 | return MAX_ONE; 33 | 34 | case "*": 35 | case "*?": // non-greedy (https://github.com/antlr/antlr4/blob/master/doc/wildcard.md) 36 | return ANY; 37 | 38 | case "+": 39 | case "+?": // non-greedy (https://github.com/antlr/antlr4/blob/master/doc/wildcard.md) 40 | return AT_LEAST_ONE; 41 | 42 | default: 43 | throw new IllegalArgumentException("Unknown quantification character '" + quantifier + "'"); 44 | } 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | switch (this) { 50 | case EXACTLY_ONE: 51 | return ""; 52 | 53 | case ANY: 54 | return "*"; 55 | 56 | case AT_LEAST_ONE: 57 | return "+"; 58 | 59 | case MAX_ONE: 60 | return "?"; 61 | 62 | default: 63 | throw new IllegalArgumentException(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/RegexRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | 5 | public class RegexRule extends FlatLexerRule { 6 | public String regexp; 7 | 8 | public SNode node = null; 9 | 10 | public RegexRule(String name, String regexp) { 11 | super(name); 12 | this.regexp = regexp; 13 | } 14 | 15 | public RegexRule(String regexp) { 16 | this(java.util.UUID.randomUUID().toString(), regexp); 17 | } 18 | 19 | @Override 20 | public String getContent() { 21 | return regexp; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return this.name 27 | + ":\t" 28 | + this.regexp 29 | + System.lineSeparator() 30 | + "\t\t;" 31 | + System.lineSeparator(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/Rule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | public abstract class Rule { 4 | public String name; 5 | 6 | public Rule(String name) { 7 | this.name = name; 8 | } 9 | 10 | @Override 11 | public String toString() { 12 | return this.name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugin/idea/model/src/premun/mps/ingrid/model/RuleReference.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.model; 2 | 3 | import org.jetbrains.mps.openapi.model.*; 4 | 5 | /** 6 | * Class wrapper used inside rule alternatives. Represents a single alternative element. 7 | */ 8 | public class RuleReference { 9 | /** 10 | * Referenced rule 11 | */ 12 | public Rule rule; 13 | 14 | /** 15 | * Cardinality of the element 16 | */ 17 | public Quantity quantity = Quantity.EXACTLY_ONE; 18 | 19 | /** 20 | * Holds the MPS reference - either a PropertyDeclaration or a LinkDeclaration node. 21 | * This is not the target (referenced) concept, but the reference itself! 22 | */ 23 | public SNode nodeReference = null; 24 | 25 | public RuleReference(Rule rule) { 26 | this.rule = rule; 27 | } 28 | 29 | public RuleReference(Rule rule, Quantity quantity) { 30 | this.rule = rule; 31 | this.quantity = quantity; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return this.rule.toString() + this.quantity.toString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /plugin/idea/parser/parser.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/CollectionErrorListener.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import org.antlr.v4.runtime.*; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * Class collects all errors, that the ANTLR parser detected. 9 | */ 10 | class CollectionErrorListener extends BaseErrorListener { 11 | private final List errors = new ArrayList<>(); 12 | 13 | public List getErrors() { 14 | return errors; 15 | } 16 | 17 | @Override 18 | public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { 19 | this.errors.add(msg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/GrammarParser.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import org.antlr.v4.runtime.*; 4 | import org.antlr.v4.runtime.tree.*; 5 | import premun.mps.ingrid.model.*; 6 | import premun.mps.ingrid.parser.antlr.*; 7 | import premun.mps.ingrid.parser.exception.*; 8 | 9 | import java.io.*; 10 | import java.util.*; 11 | 12 | public class GrammarParser { 13 | private ParserResult data = new ParserResult(); 14 | 15 | public void parseFile(String fileName) { 16 | File file = new File(fileName); 17 | 18 | FileInputStream fis; 19 | try { 20 | fis = new FileInputStream(file); 21 | } catch (FileNotFoundException e) { 22 | throw new IngridParserException("File '" + fileName + "' not found"); 23 | } 24 | 25 | byte[] data = new byte[(int) file.length()]; 26 | 27 | try { 28 | fis.read(data); 29 | fis.close(); 30 | } catch (IOException e) { 31 | e.printStackTrace(); 32 | throw new IngridParserException("Error while reading the file: " + e.getMessage()); 33 | } 34 | 35 | parseString(new String(data)); 36 | } 37 | 38 | public void parseString(String grammar) { 39 | ANTLRv4Lexer lexer = new ANTLRv4Lexer(new ANTLRInputStream(grammar)); 40 | 41 | // Get a list of matched tokens 42 | CommonTokenStream tokens = new CommonTokenStream(lexer); 43 | 44 | // Pass the tokens to the parser 45 | ANTLRv4Parser parser = new ANTLRv4Parser(tokens); 46 | 47 | CollectionErrorListener errorListener = new CollectionErrorListener(); 48 | parser.addErrorListener(errorListener); 49 | 50 | // Walk it and attach our listener 51 | ParseTreeWalker walker = new ParseTreeWalker(); 52 | GrammarWalker listener = new GrammarWalker(); 53 | walker.walk(listener, parser.grammarSpec()); 54 | 55 | List errors = errorListener.getErrors(); 56 | if (errors.size() != 0) { 57 | throw new IngridParserException("Couldn't parse the grammar file:\n" + String.join("\n", errors)); 58 | } 59 | 60 | ParserResult parseResult = listener.getParseResult(); 61 | 62 | // Merge results with previous results 63 | if (parseResult.grammarName != null) { 64 | this.data.grammarName = parseResult.grammarName; 65 | } 66 | 67 | if (parseResult.rootRule != null) { 68 | this.data.rootRule = parseResult.rootRule; 69 | } 70 | 71 | for (Map.Entry entry : parseResult.rules.entrySet()) { 72 | this.data.rules.put(entry.getKey(), entry.getValue()); 73 | } 74 | } 75 | 76 | public GrammarInfo resolveGrammar() { 77 | return GrammarResolver.generateGrammar(this.data); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/ParserResult.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import premun.mps.ingrid.model.*; 4 | 5 | import java.util.*; 6 | 7 | class ParserResult { 8 | public String grammarName; 9 | public Map rules; 10 | public String rootRule; 11 | 12 | public ParserResult() { 13 | this.rules = new HashMap<>(); 14 | } 15 | 16 | public ParserResult(String grammarName, Map rules, String rootRule) { 17 | this.grammarName = grammarName; 18 | this.rules = rules; 19 | this.rootRule = rootRule; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/antlr/LexerAdaptor.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.antlr; 2 | 3 | import org.antlr.v4.runtime.*; 4 | import org.antlr.v4.runtime.misc.*; 5 | 6 | abstract class LexerAdaptor extends Lexer { 7 | 8 | /** 9 | * Track whether we are inside of a rule and whether it is lexical parser. _currentRuleType==Token.INVALID_TYPE 10 | * means that we are outside of a rule. At the first sign of a rule name reference and _currentRuleType==invalid, we 11 | * can assume that we are starting a parser rule. Similarly, seeing a token reference when not already in rule means 12 | * starting a token rule. The terminating ';' of a rule, flips this back to invalid type. 13 | * 14 | * This is not perfect logic but works. For example, "grammar T;" means that we start and stop a lexical rule for 15 | * the "T;". Dangerous but works. 16 | * 17 | * The whole point of this state information is to distinguish between [..arg actions..] and [charsets]. Char sets 18 | * can only occur in lexical rules and arg actions cannot occur. 19 | */ 20 | private int _currentRuleType = Token.INVALID_TYPE; 21 | 22 | public LexerAdaptor(CharStream input) { 23 | super(input); 24 | } 25 | 26 | public int getCurrentRuleType() { 27 | return _currentRuleType; 28 | } 29 | 30 | public void setCurrentRuleType(int ruleType) { 31 | this._currentRuleType = ruleType; 32 | } 33 | 34 | void handleBeginArgument() { 35 | if (inLexerRule()) { 36 | pushMode(ANTLRv4Lexer.LexerCharSet); 37 | more(); 38 | } else { 39 | pushMode(ANTLRv4Lexer.Argument); 40 | } 41 | } 42 | 43 | void handleEndArgument() { 44 | popMode(); 45 | if (_modeStack.size() > 0) { 46 | setType(ANTLRv4Lexer.ARGUMENT_CONTENT); 47 | } 48 | } 49 | 50 | void handleEndAction() { 51 | popMode(); 52 | if (_modeStack.size() > 0) { 53 | setType(ANTLRv4Lexer.ACTION_CONTENT); 54 | } 55 | } 56 | 57 | @Override 58 | public Token emit() { 59 | if (_type == ANTLRv4Lexer.ID) { 60 | String firstChar = _input.getText(Interval.of(_tokenStartCharIndex, _tokenStartCharIndex)); 61 | if (Character.isUpperCase(firstChar.charAt(0))) { 62 | _type = ANTLRv4Lexer.TOKEN_REF; 63 | } else { 64 | _type = ANTLRv4Lexer.RULE_REF; 65 | } 66 | 67 | if (_currentRuleType == Token.INVALID_TYPE) { // if outside of rule def 68 | _currentRuleType = _type; // set to inside lexer or parser rule 69 | } 70 | } else if (_type == ANTLRv4Lexer.SEMI) { // exit rule def 71 | _currentRuleType = Token.INVALID_TYPE; 72 | } 73 | 74 | return super.emit(); 75 | } 76 | 77 | private boolean inLexerRule() { 78 | return _currentRuleType == ANTLRv4Lexer.TOKEN_REF; 79 | } 80 | 81 | @SuppressWarnings("unused") 82 | private boolean inParserRule() { // not used, but added for clarity 83 | return _currentRuleType == ANTLRv4Lexer.RULE_REF; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/exception/IngridParserException.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.exception; 2 | 3 | public class IngridParserException extends RuntimeException { 4 | public IngridParserException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/exception/UnresolvableRuleException.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.exception; 2 | 3 | public class UnresolvableRuleException extends IngridParserException { 4 | public UnresolvableRuleException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/model/UnresolvedLexerRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.model; 2 | 3 | /** 4 | * Class represents a placeholder that is placed inside a grammar tree 5 | * during the first walk, before the grammar rules are fully resolved. 6 | */ 7 | public class UnresolvedLexerRule extends UnresolvedRule { 8 | public UnresolvedLexerRule(String name) { 9 | super(name); 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "[Unresolved lexer rule " + this.name + "]"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/model/UnresolvedParserRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.model; 2 | 3 | /** 4 | * Class represents a placeholder that is placed inside a grammar tree 5 | * during the first walk, before the grammar rules are fully resolved. 6 | */ 7 | public class UnresolvedParserRule extends UnresolvedRule { 8 | public UnresolvedParserRule(String name) { 9 | super(name); 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "[Unresolved parser rule " + this.name + "]"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/idea/parser/src/premun/mps/ingrid/parser/model/UnresolvedRule.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser.model; 2 | 3 | import premun.mps.ingrid.model.*; 4 | 5 | public abstract class UnresolvedRule extends Rule { 6 | public UnresolvedRule(String name) { 7 | super(name); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /plugin/idea/parser_tests/parser_tests.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /plugin/idea/parser_tests/res/MySQLLexer.g4: -------------------------------------------------------------------------------- 1 | lexer grammar MySQLLexer; 2 | 3 | SELECT : 'select' ; 4 | 5 | FROM : 'from' ; 6 | 7 | ASTERISK : '*' ; 8 | 9 | TableName: '`' [A-Za-z0-9\.]+ '`' ; 10 | -------------------------------------------------------------------------------- /plugin/idea/parser_tests/res/MySQLParser.g4: -------------------------------------------------------------------------------- 1 | parser grammar MySQLParser; 2 | 3 | select_clause : SELECT ASTERISK FROM TableName ; -------------------------------------------------------------------------------- /plugin/idea/parser_tests/res/SimpleXML.g4: -------------------------------------------------------------------------------- 1 | grammar SimpleXML; 2 | 3 | document : comment? element EOF 4 | ; 5 | 6 | comment : '/*' Content '*/' 7 | ; 8 | 9 | element : LT Name '>' ( Content | element )* '' # FullElement 10 | | '<' Name '/>' # SelfclosingElement 11 | ; 12 | 13 | Content : [a-zA-Z0-9 ]+ 14 | ; 15 | 16 | Name : NameStartChar NameChar* 17 | ; 18 | 19 | fragment 20 | DIGIT : [0-9] 21 | | '0'..'9' 22 | ; 23 | 24 | fragment 25 | NameChar : NameStartChar 26 | | ('-'? | ('_' | '.')+)* 27 | | DIGIT 28 | ; 29 | 30 | fragment 31 | NameStartChar 32 | : [:a-zA-Z] 33 | ; 34 | 35 | LT : '<' 36 | ; 37 | 38 | actionRule : {_input.LT(1).getText().equals("set")}? Name LT 39 | ; 40 | 41 | S : [ \t\r\n] -> skip 42 | ; -------------------------------------------------------------------------------- /plugin/idea/parser_tests/src/premun/mps/ingrid/parser/AdvancedFeaturesTest.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import org.junit.*; 4 | import premun.mps.ingrid.model.*; 5 | 6 | import java.util.*; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | import static org.junit.Assert.assertNotNull; 10 | import static org.junit.Assert.assertTrue; 11 | 12 | public class AdvancedFeaturesTest { 13 | @Test 14 | public void LabeledElementTest() { 15 | GrammarParser parser = new GrammarParser(); 16 | parser.parseString( 17 | "grammar foo; " + 18 | "int_result : left_operand=int_result op=(MUL | DIV | MOD) right_operand=int_result\n" + 19 | " | INT\n" + 20 | " ;\n" + 21 | 22 | "MUL : '*';\n" + 23 | "DIV : '/';\n" + 24 | "MOD : '%';\n" + 25 | 26 | "INT : '-'? [0-9]+;\n" 27 | ); 28 | 29 | GrammarInfo grammar = parser.resolveGrammar(); 30 | ParserRule rule = (ParserRule) grammar.rules.get("int_result"); 31 | 32 | assertNotNull(rule); 33 | assertEquals(2, rule.alternatives.size()); 34 | 35 | 36 | List elements = rule.alternatives.get(0).elements; 37 | assertEquals(3, elements.size()); 38 | assertEquals(grammar.rules.get("int_result"), elements.get(0).rule); 39 | assertTrue(elements.get(1).rule instanceof ParserRule); 40 | assertTrue(elements.get(1).rule.name.contains("block_")); 41 | assertEquals(grammar.rules.get("int_result"), elements.get(2).rule); 42 | } 43 | 44 | @Test 45 | public void ActionTest() { 46 | GrammarParser parser = new GrammarParser(); 47 | parser.parseString( 48 | "grammar foo; " + 49 | "actionRule : {_input.LT(1).getText().equals(\"set\")}? 'foo' 'bar'\n" + 50 | " ;\n" + 51 | 52 | "S : [ \\t\\r\\n] -> skip\n" + 53 | " ;" 54 | ); 55 | 56 | GrammarInfo grammar = parser.resolveGrammar(); 57 | 58 | ParserRule actionRule = (ParserRule) grammar.rules.get("actionRule"); 59 | RegexRule s = (RegexRule) grammar.rules.get("S"); 60 | 61 | assertNotNull(actionRule); 62 | assertNotNull(s); 63 | 64 | assertEquals(2, actionRule.alternatives.get(0).elements.size()); 65 | assertEquals("[ \\t\\r\\n]", s.regexp); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /plugin/idea/parser_tests/src/premun/mps/ingrid/parser/GrammarParserTest.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import org.junit.*; 4 | import premun.mps.ingrid.model.*; 5 | import premun.mps.ingrid.model.Rule; 6 | import premun.mps.ingrid.parser.exception.*; 7 | 8 | import java.util.*; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | public class GrammarParserTest { 13 | @Test 14 | public void testFullGrammar() throws Exception { 15 | String filePath = getClass().getResource("/SimpleXML.g4").getPath(); 16 | 17 | GrammarParser parser = new GrammarParser(); 18 | parser.parseFile(filePath); 19 | GrammarInfo grammar = parser.resolveGrammar(); 20 | 21 | assertNotNull(grammar); 22 | assertEquals("SimpleXML", grammar.name); 23 | 24 | String[] parserRules = {"document", "comment", "element"}; 25 | // All present 26 | assertTrue(Arrays.stream(parserRules).allMatch(r -> grammar.rules.containsKey(r))); 27 | // All resolved 28 | assertTrue(Arrays.stream(parserRules).allMatch(r -> grammar.rules.get(r) instanceof ParserRule)); 29 | 30 | String[] lexerRules = {"Content", "Name", "NameChar", "LT"}; 31 | // All present 32 | assertTrue(Arrays.stream(lexerRules).allMatch(r -> grammar.rules.containsKey(r))); 33 | // All resolved 34 | assertTrue(Arrays.stream(lexerRules).allMatch(r -> grammar.rules.get(r) instanceof FlatLexerRule)); 35 | 36 | // Random specific tests: 37 | 38 | assertEquals("document", grammar.rootRule.name); 39 | assertTrue(grammar.rootRule instanceof ParserRule); 40 | 41 | ParserRule document = (ParserRule) grammar.rootRule; 42 | 43 | // document: comment? element 44 | Alternative alternative = document.alternatives.get(0); 45 | assertEquals(2, alternative.elements.size()); 46 | assertEquals(Quantity.MAX_ONE, alternative.elements.get(0).quantity); 47 | assertEquals(Quantity.EXACTLY_ONE, alternative.elements.get(1).quantity); 48 | assertTrue(alternative.elements.get(1).rule instanceof ParserRule); 49 | 50 | ParserRule element = (ParserRule) alternative.elements.get(1).rule; 51 | assertEquals("element", element.name); 52 | assertEquals(2, element.alternatives.size()); 53 | assertEquals("FullElement", element.alternatives.get(0).comment); 54 | assertEquals("SelfclosingElement", element.alternatives.get(1).comment); 55 | 56 | assertTrue(grammar.rules.get("LT") instanceof LiteralRule); 57 | assertTrue(grammar.rules.get("Content") instanceof RegexRule); 58 | 59 | // Test the rule block that was inside first alternative 60 | RuleReference block = ((ParserRule) grammar.rules.get("element")).alternatives.get(0).elements.get(3); 61 | assertEquals(Quantity.ANY, block.quantity); 62 | 63 | ParserRule blockRule = (ParserRule) block.rule; 64 | 65 | Rule contentAlternative = blockRule.alternatives.get(0).elements.get(0).rule; 66 | assertEquals(grammar.rules.get("Content").getClass(), contentAlternative.getClass()); 67 | assertTrue(grammar.rules.get("Content") == contentAlternative); 68 | 69 | Rule elementAlternative = blockRule.alternatives.get(1).elements.get(0).rule; 70 | assertEquals(grammar.rules.get("element").getClass(), elementAlternative.getClass()); 71 | assertTrue(grammar.rules.get("element") == elementAlternative); 72 | 73 | RegexRule nameRule = (RegexRule) grammar.rules.get("Name"); 74 | assertEquals("[:a-zA-Z](([:a-zA-Z]|(((\\-)?|(_|\\.)+)*)|(([0-9]|[0-9]))))*", nameRule.regexp); 75 | 76 | assertEquals(2, ((ParserRule) grammar.rules.get("actionRule")).alternatives.get(0).elements.size()); 77 | assertEquals("[ \\t\\r\\n]", ((RegexRule) grammar.rules.get("S")).regexp); 78 | } 79 | 80 | @Test 81 | public void testMultipleFiles() throws Exception { 82 | String filePath1 = getClass().getResource("/MySQLLexer.g4").getPath(); 83 | String filePath2 = getClass().getResource("/MySQLParser.g4").getPath(); 84 | 85 | GrammarParser parser = new GrammarParser(); 86 | parser.parseFile(filePath1); 87 | parser.parseFile(filePath2); 88 | GrammarInfo grammar = parser.resolveGrammar(); 89 | 90 | assertEquals(5, grammar.rules.size()); 91 | assertNotNull(grammar.rules.get("select_clause")); 92 | 93 | assertNotNull(grammar.rules.get("SELECT")); 94 | assertNotNull(grammar.rules.get("ASTERISK")); 95 | assertNotNull(grammar.rules.get("FROM")); 96 | assertNotNull(grammar.rules.get("TableName")); 97 | } 98 | 99 | @Test 100 | public void testMultipleFilesReverseOrder() throws Exception { 101 | String filePath1 = getClass().getResource("/MySQLLexer.g4").getPath(); 102 | String filePath2 = getClass().getResource("/MySQLParser.g4").getPath(); 103 | 104 | GrammarParser parser = new GrammarParser(); 105 | parser.parseFile(filePath2); 106 | parser.parseFile(filePath1); 107 | GrammarInfo grammar = parser.resolveGrammar(); 108 | 109 | assertEquals(5, grammar.rules.size()); 110 | assertNotNull(grammar.rules.get("select_clause")); 111 | 112 | assertNotNull(grammar.rules.get("SELECT")); 113 | assertNotNull(grammar.rules.get("ASTERISK")); 114 | assertNotNull(grammar.rules.get("FROM")); 115 | assertNotNull(grammar.rules.get("TableName")); 116 | } 117 | 118 | @Test(expected = IngridParserException.class) 119 | public void testInvalidFile1() throws Exception { 120 | GrammarParser parser = new GrammarParser(); 121 | parser.parseString("ff"); 122 | } 123 | 124 | @Test(expected = IngridParserException.class) 125 | public void testInvalidFile2() throws Exception { 126 | GrammarParser parser = new GrammarParser(); 127 | parser.parseString( 128 | "grammar foo; " + 129 | "Name : NameStartChar NameChar*\n"); 130 | } 131 | 132 | @Test(expected = IngridParserException.class) 133 | public void testNotexistentFile() throws Exception { 134 | GrammarParser parser = new GrammarParser(); 135 | parser.parseFile("foo"); 136 | } 137 | } -------------------------------------------------------------------------------- /plugin/idea/parser_tests/src/premun/mps/ingrid/parser/RegexBuilderTest.java: -------------------------------------------------------------------------------- 1 | package premun.mps.ingrid.parser; 2 | 3 | import org.junit.*; 4 | import premun.mps.ingrid.model.*; 5 | import premun.mps.ingrid.parser.exception.*; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | public class RegexBuilderTest { 10 | @Test 11 | public void FlattenRulesTest() { 12 | GrammarParser parser = new GrammarParser(); 13 | parser.parseString( 14 | "grammar foo; " + 15 | "Name : NameStartChar NameChar*\n" + 16 | " ;\n" + 17 | "fragment\n" + 18 | "DIGIT : '0'..'9'\n" + 19 | " ;\n" + 20 | "fragment\n" + 21 | "NameChar : NameStartChar\n" + 22 | " | '-' | '_' | '.'\n" + 23 | " | DIGIT\n" + 24 | " ;\n" + 25 | "fragment\n" + 26 | "NameStartChar\n" + 27 | " : [:a-zA-Z]\n" + 28 | " ;"); 29 | 30 | GrammarInfo grammarInfo = parser.resolveGrammar(); 31 | 32 | RegexRule rule = (RegexRule) grammarInfo.rules.get("Name"); 33 | assertNotNull(rule); 34 | assertEquals("[:a-zA-Z](([:a-zA-Z]|\\-|_|\\.|[0-9]))*", rule.regexp); 35 | } 36 | 37 | @Test 38 | public void SpecialCharEscapeTest() { 39 | GrammarParser parser = new GrammarParser(); 40 | parser.parseString( 41 | "grammar foo; " + 42 | "Tag: '.jpg' [0-9]+ '\\\\';"); 43 | GrammarInfo grammarInfo = parser.resolveGrammar(); 44 | 45 | RegexRule rule = (RegexRule) grammarInfo.rules.get("Tag"); 46 | assertNotNull(rule); 47 | assertEquals("\\.jpg([0-9])+\\\\\\\\", rule.regexp); 48 | } 49 | 50 | @Test(expected = IngridParserException.class) 51 | public void CyclicRuleTest() { 52 | GrammarParser parser = new GrammarParser(); 53 | parser.parseString( 54 | "grammar foo; " + 55 | "Foo\n" + 56 | " : Foo '_'\n" + 57 | " | '.'\n" + 58 | ";"); 59 | parser.resolveGrammar(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /plugin/lib/antlr4-4.7.2-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/premun/ingrid/80f18c36d6496003f8ecd9a3ce23ea9b5cb38c70/plugin/lib/antlr4-4.7.2-complete.jar -------------------------------------------------------------------------------- /plugin/mps/.gitignore: -------------------------------------------------------------------------------- 1 | .mps/workspace.xml 2 | 3 | classes_gen 4 | source_gen 5 | source_gen.caches 6 | 7 | junitvmwatcher*.properties 8 | 9 | *.class 10 | /build/ 11 | -------------------------------------------------------------------------------- /plugin/mps/.mps/.name: -------------------------------------------------------------------------------- 1 | Ingrid -------------------------------------------------------------------------------- /plugin/mps/.mps/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /plugin/mps/.mps/migration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /plugin/mps/.mps/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /plugin/mps/.mps/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /plugin/mps/.mps/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/mps/.mps/version.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /plugin/mps/Ingrid.build/Ingrid.build.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 422c2909-59d6-41a9-b318-40e6256b250f(jetbrains.mps.ide.build) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /plugin/mps/importer/models/dummy.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/mps/importer/premun.mps.ingrid.importer.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | a34e01c8-8c6f-48c5-a512-bb294cca062e(premun.mps.ingrid.model) 16 | 9450b346-4f8d-4243-9894-05b73fc17e09(premun.mps.ingrid.library) 17 | 66288791-e621-45d1-bebf-408d2568bbe6(premun.mps.ingrid.parser) 18 | 8865b7a8-5271-43d3-884c-6fd1d9cfdd34(MPS.OpenAPI) 19 | 7866978e-a0f0-4cc7-81bc-4d213d9375e1(jetbrains.mps.lang.smodel) 20 | 4db458f1-215f-424c-8756-4cc4b0227697(org.antlr) 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /plugin/mps/library/premun.mps.ingrid.library.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | a34e01c8-8c6f-48c5-a512-bb294cca062e(premun.mps.ingrid.model) 11 | b83431fe-5c8f-40bc-8a36-65e25f4dd253(jetbrains.mps.lang.textGen) 12 | 18bc6592-03a6-4e29-a83a-7ff23bde13ba(jetbrains.mps.lang.editor) 13 | c72da2b9-7cce-4447-8389-f407dc1158b7(jetbrains.mps.lang.structure) 14 | 8865b7a8-5271-43d3-884c-6fd1d9cfdd34(MPS.OpenAPI) 15 | 7866978e-a0f0-4cc7-81bc-4d213d9375e1(jetbrains.mps.lang.smodel) 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /plugin/mps/model/models/dummy.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/mps/model/premun.mps.ingrid.model.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 4db458f1-215f-424c-8756-4cc4b0227697(org.antlr) 16 | 8865b7a8-5271-43d3-884c-6fd1d9cfdd34(MPS.OpenAPI) 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /plugin/mps/org.antlr/org.antlr.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /plugin/mps/parser/models/dummy.mps: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/mps/parser/premun.mps.ingrid.parser.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | a34e01c8-8c6f-48c5-a512-bb294cca062e(premun.mps.ingrid.model) 16 | 4db458f1-215f-424c-8756-4cc4b0227697(org.antlr) 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /plugin/mps/plugin/premun.mps.ingrid.plugin.msd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 6ed54515-acc8-4d1e-a16c-9fd6cfe951ea(MPS.Core) 11 | 742f6602-5a2f-4313-aa6e-ae1cd4ffdc61(MPS.Platform) 12 | 8865b7a8-5271-43d3-884c-6fd1d9cfdd34(MPS.OpenAPI) 13 | 498d89d2-c2e9-11e2-ad49-6cf049e62fe5(MPS.IDEA) 14 | f0276ed1-44e5-4463-9cfe-cf15618e4974(premun.mps.ingrid.importer) 15 | 6354ebe7-c22a-4a0f-ac54-50b52ab9b065(JDK) 16 | 019b622b-0aef-4dd3-86d0-4eef01f3f6bb(jetbrains.mps.ide) 17 | 9450b346-4f8d-4243-9894-05b73fc17e09(premun.mps.ingrid.library) 18 | a34e01c8-8c6f-48c5-a512-bb294cca062e(premun.mps.ingrid.model) 19 | 66288791-e621-45d1-bebf-408d2568bbe6(premun.mps.ingrid.parser) 20 | 4db458f1-215f-424c-8756-4cc4b0227697(org.antlr) 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | --------------------------------------------------------------------------------