2015-08-19 4 views
0

Я пытаюсь разобрать тело конкретного метода, используя приведенную здесь грамматику Java Grammar. Я немного изменил грамматику, изменив правило начала разбора (например, compilationUnit), чтобы включить в качестве альтернативы класс classBodyDeclaration.antlr4 для разбора метода body

Однако при попытке проанализировать тело метода, например, показанное ниже, оно не дает мне дерева синтаксического разбора.

public static String[] getCNs(X509Certificate cert) { 

LinkedList<String> cnList = new LinkedList<String>(); 
String subjectPrincipal = cert.getSubjectX500Principal().toString(); 
StringTokenizer st = new StringTokenizer(subjectPrincipal, ","); 
while(st.hasMoreTokens()) { 
    String tok = st.nextToken().trim(); 
    if (tok.length() > 3) { 
     if (tok.substring(0, 3).equalsIgnoreCase("CN=")) { 
      cnList.add(tok.substring(3)); 
     } 
    } 
} 

if(!cnList.isEmpty()) { 
    String[] cns = new String[cnList.size()]; 
    cnList.toArray(cns); 
    return cns; 
} else { 
    return null; 
}} 

Я использую функцию parseMethodBody, показанную ниже для синтаксического анализа;

private ParseTree parseMethodBody(String programString, TestErrorListener testErrListener) throws IOException{ 

     CharStream inputCharStream = new ANTLRInputStream(new StringReader(programString)); 
     TokenSource tokenSource = new JavaLexer(inputCharStream); 
     TokenStream inputTokenStream = new CommonTokenStream(tokenSource); 
     JavaParser parser = new JavaParser(inputTokenStream); 

     parser.addErrorListener(testErrListener); 
     tree = parser.compilationUnit(); 
     return tree; 

} 

Я могу разобрать некоторые другие тела методов. Для меня неожиданностью является то, что если я удалю LinkedList<String> cnList = new LinkedList<String>(); и , если условие внизу от метода выше, синтаксический анализ успешно завершен. Какие-нибудь намеки, что здесь может быть неправильным? Это проблема с сгенерированными файлами JavaLexer/JavaParser, отсутствие поддержки в грамматике для некоторых конструкций (не уверен в этом, так как грамматика поддерживает Java7) .... Дополнительная информация: ANTLRErrorListener, прикрепленный к синтаксическому анализатору, вызывает сообщение AttemptingFullContext() как фальшивый флаг.

+0

Я не уверен, что понимаю. Вы передаете программу с кодом за пределами тела метода и попросите ANTLR проанализировать внутреннюю часть тела метода? –

+0

Я хотел разобрать внутри тела метода java. Я использую грамматику, используемую для разбора java-файла. Я сделал простую модификацию грамматики, добавив ** classBodyDeclaration ** в качестве альтернативного стартового правила, считая, что сгенерированный парсер сможет анализировать полные файлы классов java, а также тела java-методов. – user1577269

ответ

0

я отлажен грамматика немного, изменяя исходное правило синтаксического анализа (т.е. compilationUnit) также включает в себя classBodyDeclaration в качестве альтернативы.

Это нарушает основную логику грамматики, которая объясняет нечетность когда и если генерируется дерево синтаксического анализа.

Правило верхнего уровня, которое будет соответствовать только данному методу, правильно, classBodyDeclaration. Используйте это как правило для начала (без изменения грамматики).

tree = parser.classBodyDeclaration(); 
+0

правило ** parse ** выражения Declaration ** не будет соответствовать объявлению метода, потому что альтернативы управляют им (должен быть класс, enum .... для соответствия этому правилу). Однако меня интересует только совмещение тела метода и разбор внутренней части тела. Вот почему я сделал ** classBodyDeclaration ** одним из стартовых альтернативных правил. – user1577269

+0

Похоже, что метод был завернут в блок, но это просто форматирование SO. Ответ исправлен. Если это не сработает, вы можете попробовать использовать Java8-грамматику - возможно, она более эффективна при работе с генериками. – GRosenberg

+0

FWIW, оба работают для меня. – GRosenberg

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