2015-09-17 5 views
0

Я хочу извлечь все вызовы методов из java-кода. Я написал следующие два регулярных выражения, но они не могут извлечь все вызовы методов.Извлечение методов вызовы из java-кода

Reg1: Pattern.compile("([a-zA-Z][0-9_a-zA-Z]*\\([a-zA-Z0-9_\\s,\\[\\]\\(\\)\\.]+\\))");

Reg2: Pattern.compile("([a-zA-Z][0-9_a-zA-Z]*\\([\\s]*\\))")

Вход:

"{ 
    if ((war == null) && (config != null)) { 
    sb.append(&config=); 
    sb.append(URLEncoder.encode(config,getCharset())); 
    } 
    if ((war == null) && (localWar != null)) { 
    sb.append(&war=); 
    sb.append(URLEncoder.encode(localWar,getCharset())); 
    } 
    if (update) { 
    sb.append(&update=true); 
    } 
    if (tag != null) { 
     sb.append(&tag=); 
     sb.append(URLEncoder.encode(tag,getCharset())); 
    } 
    }" 

выход:

getCharset getCharset getCharset append append append 

Я не смог извлечь "encode".

Есть ли у кого-нибудь идеи, как я должен добавить к регулярному выражению?

+5

Это (в соответствии с хорошо известными принципами теории языка) невозможно сделать с помощью регулярных выражений, в основном потому, что каждый вызов может содержать вызовы который может содержать вызовы, которые ... – laune

+0

Пожалуйста, предложите мне альтернативу. – Sangeeta

+2

Возможно, этот пост любой помощи http://stackoverflow.com/questions/2206065/java-parse-java-source-code-extract-methods – Mariano

ответ

6

Для выполнения этой задачи вам понадобится код Java Code Parser. Вот пример, который использует Java Parser:

public class MethodCallPrinter 
{ 
    public static void main(String[] args) throws Exception 
    { 
     FileInputStream in = new FileInputStream("MethodCallPrinter.java"); 

     CompilationUnit cu; 
     try 
     { 
      cu = JavaParser.parse(in); 
     } 
     finally 
     { 
      in.close(); 
     } 
     new MethodVisitor().visit(cu, null); 
    } 

    private static class MethodVisitor extends VoidVisitorAdapter 
    { 
     @Override 
     public void visit(MethodCallExpr methodCall, Object arg) 
     { 
      System.out.print("Method call: " + methodCall.getName() + "\n"); 
      List<Expression> args = methodCall.getArgs(); 
      if (args != null) 
       handleExpressions(args); 
     } 

     private void handleExpressions(List<Expression> expressions) 
     { 
      for (Expression expr : expressions) 
      { 
       if (expr instanceof MethodCallExpr) 
        visit((MethodCallExpr) expr, null); 
       else if (expr instanceof BinaryExpr) 
       { 
        BinaryExpr binExpr = (BinaryExpr)expr; 
        handleExpressions(Arrays.asList(binExpr.getLeft(), binExpr.getRight())); 
       } 
      } 
     } 
    } 
} 

Выход:

Method call: parse 
Method call: close 
Method call: visit 
Method call: print 
Method call: getName 
Method call: getArgs 
Method call: handleExpressions 
Method call: visit 
Method call: handleExpressions 
Method call: asList 
Method call: getLeft 
Method call: getRight 
+0

Основная трудность заключается в обработке рекурсий в предложениях. Вы можете добавить это к своему ответу, например, другому посетителю для выражений. – laune

+0

@laune Что значит «рекурсии в предложениях»? – splash

+1

Грамматика Java определяет, как должны быть построены «предложения» языка. В определении «вызов метода» через несколько NT между ними снова появляется «вызов метода»: рекурсия. - Поэтому должна быть итерация 'for (Expression e: methodCall.getArgs()) {...}' и т. Д. – laune

Смежные вопросы