Pārlūkot izejas kodu

Differentiate all kinds of blocks

Robin Maisch 4 gadi atpakaļ
vecāks
revīzija
4ec51ace7f

+ 2 - 0
jplag.frontend.kotlin/README.md

@@ -7,6 +7,8 @@ It is based on the [Kotlin ANTLR4 grammar](https://github.com/antlr/grammars-v4/
 
 The underlying grammar definition does not specify which version of Kotlin it is built on, but the presence of the `inline` keyword and the lack of support for trailing commas in argument lists indicate that it complies with Kotlin 1.3, released in late 2018.
 
+The grammar in this repo contains a fix and some modifications to allow for easier token generation, see the comment in the [KotlinParser](src/main/antlr4/de/jplag/kotlin/grammar/KotlinParser.g4).
+
 If there are any major updates or fixes to the grammar<a href="#footnote-1"><sup>1</sup></a>, they should surely be applied to this module as well. 
 
 

+ 5 - 0
jplag.frontend.kotlin/src/main/antlr4/de/jplag/kotlin/grammar/KotlinLexer.g4

@@ -10,6 +10,11 @@
  * https://github.com/JetBrains/kotlin/tree/master/compiler/testData/psi
  */
 
+/*
+ * Source: https://github.com/antlr/grammars-v4
+ * Licenced under the Apache 2.0.
+ */
+
 lexer grammar KotlinLexer;
 
 import UnicodeClasses;

+ 30 - 10
jplag.frontend.kotlin/src/main/antlr4/de/jplag/kotlin/grammar/KotlinParser.g4

@@ -11,9 +11,13 @@
  */
 
 /*
- Source: https://github.com/antlr/grammars-v4
- Modified at line 194: Add "NL*" twice. - Robin Maisch
- Licenced under the Apache 2.0.
+ * Source: https://github.com/antlr/grammars-v4
+ * Licenced under the Apache 2.0.
+ *
+ * Modifications:
+ * 'propertyDeclaration' rule: Add "NL*" twice (suspected fault in orginial).
+ * 'block' rule: Introduced specific types of blocks for each occurrence, namely 'tryBody', 'catchBody', 'finallyBody'.
+ * - Robin Maisch
 */
 
 parser grammar KotlinParser;
@@ -118,7 +122,11 @@ classMemberDeclaration
     ;
 
 anonymousInitializer
-    : INIT NL* block
+    : INIT NL* initBlock
+    ;
+
+initBlock
+    : block
     ;
 
 secondaryConstructor
@@ -205,7 +213,7 @@ variableDeclaration
 
 getter
     : modifierList? GETTER
-    | modifierList? GETTER NL* LPAREN RPAREN (NL* COLON NL* type)? NL* (block | ASSIGNMENT NL* expression)
+    | modifierList? GETTER NL* LPAREN RPAREN (NL* COLON NL* type)? NL* functionBody
     ;
 
 setter
@@ -531,15 +539,27 @@ typeTest
     ;
 
 tryExpression
-    : TRY NL* block (NL* catchBlock)* (NL* finallyBlock)?
+    : TRY NL* tryBody (NL* catchStatement)* (NL* finallyStatement)?
+    ;
+
+tryBody
+    : block
     ;
 
-catchBlock
-    : CATCH NL* LPAREN annotations* simpleIdentifier COLON userType RPAREN NL* block
+catchStatement
+    : CATCH NL* LPAREN annotations* simpleIdentifier COLON userType RPAREN NL* catchBody
     ;
 
-finallyBlock
-    : FINALLY NL* block
+catchBody
+    : block
+    ;
+
+finallyStatement
+    : FINALLY NL* finallyBody
+    ;
+
+finallyBody
+    : block
     ;
 
 loopExpression

+ 60 - 24
jplag.frontend.kotlin/src/main/java/de/jplag/kotlin/KotlinListener.java

@@ -51,7 +51,7 @@ public class KotlinListener extends KotlinParserBaseListener {
 
     @Override
     public void enterClassDeclaration(KotlinParser.ClassDeclarationContext context) {
-        transformToken(CLASS_DECLARATION, context.getStart(), context.getStop());
+        transformToken(CLASS_DECLARATION, context.getStart());
         super.enterClassDeclaration(context);
     }
 
@@ -63,7 +63,7 @@ public class KotlinListener extends KotlinParserBaseListener {
 
     @Override
     public void enterCompanionObject(KotlinParser.CompanionObjectContext context) {
-        transformToken(COMPANION_DECLARATION, context.getStart(), context.getStop());
+        transformToken(COMPANION_DECLARATION, context.getStart());
         super.enterCompanionObject(context);
     }
 
@@ -123,7 +123,7 @@ public class KotlinListener extends KotlinParserBaseListener {
 
     @Override
     public void enterPropertyDeclaration(KotlinParser.PropertyDeclarationContext context) {
-        transformToken(PROPERTY_DECLARATION, context.getStart(), context.getStop());
+        transformToken(PROPERTY_DECLARATION, context.getStart());
         super.enterPropertyDeclaration(context);
     }
 
@@ -133,6 +133,18 @@ public class KotlinListener extends KotlinParserBaseListener {
         super.enterAnonymousInitializer(context);
     }
 
+    @Override
+    public void enterInitBlock(KotlinParser.InitBlockContext context) {
+        transformToken(INITIALIZER_BODY_START, context.getStart());
+        super.enterInitBlock(context);
+    }
+
+    @Override
+    public void exitInitBlock(KotlinParser.InitBlockContext context) {
+        transformToken(INITIALIZER_BODY_END, context.getStop());
+        super.exitInitBlock(context);
+    }
+
     @Override
     public void enterFunctionDeclaration(KotlinParser.FunctionDeclarationContext context) {
         transformToken(FUNCTION, context.getStart());
@@ -181,18 +193,6 @@ public class KotlinListener extends KotlinParserBaseListener {
         super.exitFunctionLiteral(context);
     }
 
-    @Override
-    public void enterBlock(KotlinParser.BlockContext context) {
-        transformToken(BLOCK_BEGIN, context.getStart());
-        super.enterBlock(context);
-    }
-
-    @Override
-    public void exitBlock(KotlinParser.BlockContext context) {
-        transformToken(BLOCK_END, context.getStop());
-        super.exitBlock(context);
-    }
-
     @Override
     public void enterForExpression(KotlinParser.ForExpressionContext context) {
         transformToken(FOR_EXPRESSION_BEGIN, context.getStart());
@@ -243,26 +243,56 @@ public class KotlinListener extends KotlinParserBaseListener {
 
     @Override
     public void enterTryExpression(KotlinParser.TryExpressionContext context) {
-        transformToken(TRY_EXPRESSION_START, context.getStart());
+        transformToken(TRY_EXPRESSION, context.getStart());
         super.enterTryExpression(context);
     }
 
     @Override
-    public void exitTryExpression(KotlinParser.TryExpressionContext context) {
-        transformToken(TRY_EXPRESSION_END, context.getStop());
-        super.exitTryExpression(context);
+    public void enterTryBody(KotlinParser.TryBodyContext ctx) {
+        transformToken(TRY_BODY_START, ctx.getStart());
+        super.enterTryBody(ctx);
+    }
+
+    @Override
+    public void exitTryBody(KotlinParser.TryBodyContext ctx) {
+        transformToken(TRY_BODY_END, ctx.getStop());
+        super.exitTryBody(ctx);
     }
 
     @Override
-    public void enterCatchBlock(KotlinParser.CatchBlockContext context) {
+    public void enterCatchStatement(KotlinParser.CatchStatementContext context) {
         transformToken(CATCH, context.getStart());
-        super.enterCatchBlock(context);
+        super.enterCatchStatement(context);
     }
 
     @Override
-    public void enterFinallyBlock(KotlinParser.FinallyBlockContext context) {
+    public void enterCatchBody(KotlinParser.CatchBodyContext context) {
+        transformToken(CATCH_BODY_START, context.getStart());
+        super.enterCatchBody(context);
+    }
+
+    @Override
+    public void exitCatchBody(KotlinParser.CatchBodyContext context) {
+        transformToken(CATCH_BODY_END, context.getStop());
+        super.exitCatchBody(context);
+    }
+
+    @Override
+    public void enterFinallyStatement(KotlinParser.FinallyStatementContext context) {
         transformToken(FINALLY, context.getStart());
-        super.enterFinallyBlock(context);
+        super.enterFinallyStatement(context);
+    }
+
+    @Override
+    public void enterFinallyBody(KotlinParser.FinallyBodyContext context) {
+        transformToken(FINALLY_BODY_START, context.getStart());
+        super.enterFinallyBody(context);
+    }
+
+    @Override
+    public void exitFinallyBody(KotlinParser.FinallyBodyContext context) {
+        transformToken(FINALLY_BODY_END, context.getStop());
+        super.exitFinallyBody(context);
     }
 
     @Override
@@ -285,10 +315,16 @@ public class KotlinListener extends KotlinParserBaseListener {
 
     @Override
     public void enterControlStructureBody(KotlinParser.ControlStructureBodyContext context) {
-        transformToken(DO, context.getStart(), context.getStop());
+        transformToken(CONTROL_STRUCTURE_BODY_START, context.getStart());
         super.enterControlStructureBody(context);
     }
 
+    @Override
+    public void exitControlStructureBody(KotlinParser.ControlStructureBodyContext context) {
+        transformToken(CONTROL_STRUCTURE_BODY_END, context.getStop());
+        super.exitControlStructureBody(context);
+    }
+
     @Override
     public void enterVariableDeclaration(KotlinParser.VariableDeclarationContext context) {
         transformToken(VARIABLE_DECLARATION, context.getStart());

+ 11 - 5
jplag.frontend.kotlin/src/main/java/de/jplag/kotlin/KotlinToken.java

@@ -28,6 +28,8 @@ public class KotlinToken extends Token {
             case ENUM_CLASS_BODY_END -> "}ENUM";
             case PROPERTY_DECLARATION -> "PROPERTY";
             case INITIALIZER -> "INIT";
+            case INITIALIZER_BODY_START -> "INIT{";
+            case INITIALIZER_BODY_END -> "}INIT";
             case FUNCTION -> "FUN";
             case GETTER -> "GET";
             case SETTER -> "SET";
@@ -36,8 +38,6 @@ public class KotlinToken extends Token {
             case FUNCTION_BODY_END -> "}FUN";
             case FUNCTION_LITERAL_BEGIN -> "FUNC_LIT{";
             case FUNCTION_LITERAL_END -> "}FUNC_LIT";
-            case BLOCK_BEGIN -> "{";
-            case BLOCK_END -> "}";
             case FOR_EXPRESSION_BEGIN -> "FOR";
             case FOR_EXPRESSION_END -> "}FOR";
             case IF_EXPRESSION_START -> "IF";
@@ -46,14 +46,20 @@ public class KotlinToken extends Token {
             case WHILE_EXPRESSION_END -> "}WHILE";
             case DO_WHILE_EXPRESSION_START -> "DO";
             case DO_WHILE_EXPRESSION_END -> "}DO-WHILE";
-            case TRY_EXPRESSION_START -> "TRY";
-            case TRY_EXPRESSION_END -> "}TRY";
+            case TRY_EXPRESSION -> "TRY";
+            case TRY_BODY_START -> "TRY{";
+            case TRY_BODY_END -> "}TRY";
             case CATCH -> "CATCH";
+            case CATCH_BODY_START -> "CATCH{";
+            case CATCH_BODY_END -> "}CATCH";
             case FINALLY -> "FINALLY";
+            case FINALLY_BODY_START -> "FINALLY{";
+            case FINALLY_BODY_END -> "}FINALLY";
             case WHEN_EXPRESSION_START -> "WHEN";
             case WHEN_EXPRESSION_END -> "}WHEN";
             case WHEN_CONDITION -> "COND";
-            case DO -> "{";
+            case CONTROL_STRUCTURE_BODY_START -> "THEN{";
+            case CONTROL_STRUCTURE_BODY_END -> "}THEN";
             case VARIABLE_DECLARATION -> "VARDECL";
             case ENUM_ENTRY -> "ENUM_ENTRY";
             case FUNCTION_INVOCATION -> "INVOC";

+ 38 - 33
jplag.frontend.kotlin/src/main/java/de/jplag/kotlin/KotlinTokenConstants.java

@@ -22,20 +22,19 @@ public interface KotlinTokenConstants extends TokenConstants {
     int PROPERTY_DECLARATION = 13;
 
     int INITIALIZER = 14;
+    int INITIALIZER_BODY_START = 15;
+    int INITIALIZER_BODY_END = 16;
 
-    int FUNCTION = 15;
+    int FUNCTION = 17;
 
-    int GETTER = 16;
-    int SETTER = 17;
-    int FUNCTION_PARAMETER = 18;
-    int FUNCTION_BODY_BEGIN = 19;
-    int FUNCTION_BODY_END = 20;
+    int GETTER = 18;
+    int SETTER = 19;
+    int FUNCTION_PARAMETER = 20;
+    int FUNCTION_BODY_BEGIN = 21;
+    int FUNCTION_BODY_END = 22;
 
-    int FUNCTION_LITERAL_BEGIN = 21;
-    int FUNCTION_LITERAL_END = 22;
-
-    int BLOCK_BEGIN = 23;
-    int BLOCK_END = 24;
+    int FUNCTION_LITERAL_BEGIN = 23;
+    int FUNCTION_LITERAL_END = 24;
 
     int FOR_EXPRESSION_BEGIN = 25;
     int FOR_EXPRESSION_END = 26;
@@ -49,26 +48,32 @@ public interface KotlinTokenConstants extends TokenConstants {
     int DO_WHILE_EXPRESSION_START = 31;
     int DO_WHILE_EXPRESSION_END = 32;
 
-    int TRY_EXPRESSION_START = 33;
-    int TRY_EXPRESSION_END = 34;
-    int CATCH = 35;
-    int FINALLY = 36;
-    int WHEN_EXPRESSION_START = 37;
-    int WHEN_EXPRESSION_END = 38;
-    int WHEN_CONDITION = 39;
-
-    int DO = 40;
-
-    int VARIABLE_DECLARATION = 41;
-    int ENUM_ENTRY = 42;
-    int FUNCTION_INVOCATION = 43;
-    int CREATE_OBJECT = 44;
-    int ASSIGNMENT = 45;
-
-    int THROW = 46;
-    int RETURN = 47;
-    int CONTINUE = 48;
-    int BREAK = 49;
-
-    int NUMBER_DIFF_TOKENS = 50;
+    int TRY_EXPRESSION = 33;
+    int TRY_BODY_START = 34;
+    int TRY_BODY_END = 35;
+    int CATCH = 36;
+    int CATCH_BODY_START = 37;
+    int CATCH_BODY_END = 38;
+    int FINALLY = 39;
+    int FINALLY_BODY_START = 40;
+    int FINALLY_BODY_END = 41;
+    int WHEN_EXPRESSION_START = 42;
+    int WHEN_EXPRESSION_END = 43;
+    int WHEN_CONDITION = 44;
+
+    int CONTROL_STRUCTURE_BODY_START = 45;
+    int CONTROL_STRUCTURE_BODY_END = 46;
+
+    int VARIABLE_DECLARATION = 47;
+    int ENUM_ENTRY = 48;
+    int FUNCTION_INVOCATION = 49;
+    int CREATE_OBJECT = 50;
+    int ASSIGNMENT = 51;
+
+    int THROW = 52;
+    int RETURN = 53;
+    int CONTINUE = 54;
+    int BREAK = 55;
+
+    int NUMBER_DIFF_TOKENS = 56;
 }