2016-02-10 3 views
0

Я хочу получить все определения функций отдельно от файла исходного кода. В конечном счете, я хочу просто получить все имена функций. Исходные файлы имеют следующий вид:Соответствие (основные) Объявление функций

#include bla 

first_function_name() 
{ 
} 

second_function_name(first_parameter, second_parameter) 
{ 
    i = 0; 
} 

Обратите внимание, что нет никаких модификаторов доступа и типов возврата, это НЕ для разбора языка программирования Java.

Я хочу реализовать решение через regular expression. До сих пор мне удалось сопоставить определения функций, однако у меня возникла проблема, что регулярное выражение не только соответствует одной функции, но и тем, которые потом появляются. В принципе, это не заканчивается в закрывающей скобке. Я попытался использовать символ $, но он также не заканчивает регулярное выражение.

Регулярные выражения настоящее время я использую выглядеть следующим образом:

private static final String FUNCTION_NAME_MATCHER = "[a-zA-Z]\\w*"; 
private static final String FUNCTION_MATCHER = "(?s)" + FUNCTION_NAME_MATCHER + "[(].*[)].*[\\{]([^\\}]*)?[\\}]"; 

Как остановить его от согласования следующей функции (ы), а? Он должен соответствовать дважды для вышеупомянутых функций, но вместо этого он только один раз (оба определения функций сразу).

Способ получения списка согласованных определений функций выглядит следующим образом:

public List<String> getMatches() 
{ 
    List<String> matchedResults = new ArrayList<>(); 
    Matcher matcher = Pattern.compile(FUNCTION_MATCHER).matcher(sourceFile); 

    while (matcher.find()) 
    { 
     String functionDefinition = matcher.group(); 
     String functionName = functionDefinition.split(FUNCTION_NAME_MATCHER)[0]; 
     matchedResults.add(functionName); 
    } 

    return matchedResults; 
} 
+1

У вас есть грамматика для языка? Затем вы можете использовать что-то вроде [Компилятор компилятора Java] (https://javacc.java.net/). –

+0

@AndyTurner: Не совсем, но это основной язык сценариев, ничего необычного. Он основан на C – BullyWiiPlaza

ответ

1

Попробуйте

private static final String FUNCTION_NAME_MATCHER = "([a-zA-Z]\\w*)"; 
private static final String FUNCTION_MATCHER = "(?s)" + FUNCTION_NAME_MATCHER + "\\([^)]*\\)\\s*\\{[^}]*\\}"; 

public static List<String> getMatches() 
{ 
    List<String> matchedResults = new ArrayList<>(); 
    Matcher matcher = Pattern.compile(FUNCTION_MATCHER).matcher(sourceFile); 

    while (matcher.find()) 
    { 
     matchedResults.add(matcher.group(1)); 
    } 

    return matchedResults; 
} 
1

* жаден, он будет выбирать все возможные совпадения символов, которые можно найти. Прямо сейчас часть [(].*[)] потребляет все, начиная с первого (, в первой функции вплоть до последних ) в второй. Вы хотите сделать это неохотно, где он будет потреблять только персонажа, если это необходимо. Делайте это, изменив все .* на .*?

Кроме того, вы, вероятно, хотите, чтобы соответствовать только пробелы между декларацией и тела функции, так что вы должны заменить [)].*[\\{] с [)]\\s*[\\{]

Если вы заключите FUNCTION_NAME_MATCHER и аргументы с ( и ) он будет захвачен в группу захвата, чтобы вы могли его извлечь.

1

Во-первых, вы хотите, чтобы соответствовать все функции, чтобы избежать функции согласования вызывает & дубликаты:

[^\s]*\(([^}]*)\)\{([^}]*)} 

Затем вы хотите разделить это, чтобы получить имя:

String matchedName = matchedFunction.split("(")[0] 

И вот ты! Все сделано и пыль!

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