如何使用Javaparser解析for循环?

时间:2017-12-30 13:34:26

标签: java loops parsing javaparser

我需要使用javaparserfor-loop的不正确形式解析为正确的形式。我的循环有5个参数:

  1. 循环索引(i);
  2. 索引的初始值。它可以是其他值(例如,k)或int值(10);
  3. 循环不变量(3)的值;
  4. 不变量的条件(>,<,> =或< =);
  5. 操作,在每次循环运行后执行( - 或+将更改为i--或i ++)。
  6. enter image description here

    我创建了两个班级。第一个是不正确的循环,第二个是正确的循环(解析后)。我首先决定编写这两个类来检查在解析之前和之后应该如何查看代码然后编写用于解析的代码。但我不确定它是一个好的开始,我代表我的for-loop校正。 澄清:我想将Class.java中的代码解析为ClassAltered.java。

    第一个有不正确循环的类:

    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");
    }
    }
    

    具有正确循环的第二个类:

    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");
        }
     }
    

2 个答案:

答案 0 :(得分:1)

这是可能的,但远高于平均水平。

您无法使用“normal”javaparser执行此操作,因为javaparser解析Java语法而FOR(i, 10, 3, >, -);不是Java语法。所以“普通”javaparser将无法解析此问题。

您需要做的是创建自己的javaparser分叉/版本并修改java.jj语法以包含“不正确”语句。检查this fragment查看正常ForStatement的内容:

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);
  }
}

这并不太难,你可能只能通过类比来做到这一点,你不需要太多的JavaCC知识。

接下来,当语法完成后,你将获得一个javaparser,它将能够解析“不正确”的for循环。结果将是包含IncorrectForStmt之类的AST(您需要实现此类)。

在测试中,您需要解析源代码,然后分析生成的AST以找到IncorrectForStmt。要验证您是否需要检查IncorrectForStmt的子节点。

答案 1 :(得分:1)

[我是JavaParser的维护者]你可以使用正则表达式搜索/替换,完全避免使用JavaParser。不是很好,但如果语法很简单,它大部分时间都可以工作。