0

I need using javaparser to parse uncorrect form of the for-loop to the correct form. My loop has 5 arguments:

  1. index of the loop (i);
  2. initial value of the index. It can be other value (for example, k) or int value (10);
  3. value of the loop invariant (3);
  4. condition of the invariant (>, <, >= or <=);
  5. operation, performed after each loop run (- or + will be changed to i-- or i++).

enter image description here

I've created two classes. The first one is with the uncorrect loop and the second one is with the correct loop (after parsing). I decided at first to write this two classes to check how should look the code before and after the parsing and then writing the code for parsing. But I'm not sure that it's a good start and I represented my for-loop correctry. Clarify: I want to parse the code from Class.java to the ClassAltered.java.

The first class with uncorrect loop:

public class Class {
public static void main(String[] args) {
    test1();
    test2();
}

public static void test1() {
    FOR(i, 10, 3, >, -);
    System.out.println("FOR(i, 10, 3, >, -) test passed");
}

public static void test2() {
    FOR(j, 0, 10, <=, +);
    System.out.println("FOR(j, 0, 10, <=, +) test passed");
}
}

The second class with the correct loop:

public class ClassAltered {
    public static void main(String[] args) {
        test1();
        test2();
    }

    public static void test1() {
        for(int i=10; i > 3; i--);
        System.out.println("FOR(i, 10, 3, >, -) test passed");
    }

    public static void test2() {
        for(int j=0; j<= 10; j++);
        System.out.println("FOR(j, 0, 10, <=, +) test passed");
    }
 }
Viola
  • 487
  • 1
  • 10
  • 33
  • To clarify, are you trying to parse suddenly code into java? – MartinByers Dec 30 '17 at 13:51
  • I want to parse the code from Class.java to the ClassAltered.java. But at first I want to write this two classes correctly. – Viola Dec 30 '17 at 13:53
  • The first thing I will say is: never call a class "Class", for two reasons, first of does not describe what it does/represents, second there is already a java.lang.Class so can cause confusion. – MartinByers Dec 30 '17 at 14:10
  • Currently neither of them look like they will compile. Just to clarify, ultimately you are trying to convert the sudo code to java then execute it using javaparser, and these intermediate classes are just to help you understand/implement a solution. It's that correct? – MartinByers Dec 30 '17 at 14:13
  • I need to parse uncorrect for-loop to the correct for-loop, like on the picture above, so I create the Class.java with the uncorrect loop and ClassAltered.java with the correct loop. Then I should create a main method which will parse the first class to the second. If I will remove the second class it should appear again and will be look like I want (with the correct for-loop). – Viola Dec 30 '17 at 15:10

2 Answers2

1

This is possible but well above average task.

You can't do this with "normal" javaparser because javaparser parses Java syntax and FOR(i, 10, 3, >, -); is not Java syntax. So "normal" javaparser will not be able to parse this.

What you will need to do is to create your own fork/version of javaparser and modify the java.jj grammar to include your "incorrect for" statement. Check this fragment for what a normal ForStatement looks like:

Statement ForStatement():
{
    VariableDeclarationExpr varExpr = null;
    Expression expr = null;
    NodeList<Expression> init = emptyList();
    NodeList<Expression> update = emptyList();
    Statement body;
    JavaToken begin;
}
{
  "for" {begin=token();} "("

  (
      LOOKAHEAD(VariableDeclarationExpression() ":")
      varExpr = VariableDeclarationExpression() ":" expr = Expression()
    |
     [ init = ForInit() ] ";" [ expr = Expression() ] ";" [ update = ForUpdate() ]
  )

  ")" body = Statement()

  {
    if (varExpr != null) {
        return new ForeachStmt(range(begin, token()),varExpr, expr, body);
    }
    return new ForStmt(range(begin, token()),init, expr, update, body);
  }
}

It's not too difficult, you will probably able to do this just by analogy, you won't need much of JavaCC knowledge.

Next, when the grammar is done you'll get a javaparser which will be able to parse "incorrect" for-loops. The result will be an AST containing something like IncorrectForStmt (you'll need to implement this class).

In the test you'll need to parse the source code and then analyze the resulting AST to locate IncorrectForStmt. To verify you'll need to check the sub-nodes of IncorrectForStmt.

lexicore
  • 42,748
  • 17
  • 132
  • 221
  • thank you for the answer, but I'm sure that it can be done without creating the own grammar. – Viola Dec 30 '17 at 14:28
  • [I am a contributor to JavaParser] Lexicore is right, the correct way to do this is to fork JavaParser. We are thinking on how to make JavaParser extensible more easily but currently this is the only way to do it. That said I wonder why some clearly non Java code ended up being mixed with Java code. I guess it was generated by some tool, so I would try to solve the problem BEFORE you get weird non Java code in Java. Sure you can also do some hack looking for "FOR" in uppercase but you would get something brittle. – Federico Tomassetti Dec 31 '17 at 10:53
  • @Viola I am pretty sure it cannot be done without creating your own grammar. JavaParser is JavaCC-based so this pretty much forces you into grammars. – lexicore Dec 31 '17 at 15:06
1

[I am the maintainer of JavaParser] You could use a search/replace with regular expressions, avoiding JavaParser alltogether. Not pretty, but if the syntax is simple it will work most of the time.

Danny
  • 161
  • 1
  • 6