Я использую ANTLR4
для анализа некоторого «упрощенного» исходного кода C-стиля. Моя грамматика выглядит следующим образом:Соответствие до конца функции
grammar Language;
script: (include)* (functionDefinition)* EOF;
include: '#include' Blank FilePath Semicolon;
functionName: FileName;
functionDefinition: functionName '(' parameters ')' '{' functionBody '}';
functionBody: .*?; // This needs fixing
parameter: FileName;
parameters: parameter (',' Blank parameter)*;
FileName: AlphaCharacter WordCharacter*;
FilePath: FileName ChildFilePath*;
ChildFilePath: PathSlash FileName;
PathSlash: ForwardSlash | BackwardSlash;
ForwardSlash: '/';
BackwardSlash: '\\';
AlphaCharacter: [a-zA-Z];
WordCharacter: [a-zA-Z_0-9];
Blank: ' ';
Whitespace: (' ' | '\t' | '\r' | '\n');
Semicolon: ';';
SkipWhitespaces: Whitespace+ -> skip;
Учитывая следующий ввод текста:
#include testWz/fdrf675tr\a56s;
#include testWz/fdrftr\s;
func1(param, par)
{
if(true)
{
whatever();
}
}
func2()
{
}
Я реализовал следующий посетитель, чтобы видеть, что происходит:
public class ListenerPrinter extends LanguageBaseListener
{
@Override
public void enterInclude(LanguageParser.IncludeContext context)
{
System.out.println("[INCLUDE] " + context.FilePath().getText());
}
@Override
public void enterFunctionDefinition(LanguageParser.FunctionDefinitionContext definition)
{
LanguageParser.ParametersContext parameters = definition.parameters();
System.out.println("[FUNCTION DEFINITION] " + definition.getText());
System.out.println("[PARAMETERS] " + parameters.getText());
System.out.println("[BODY] " + definition.functionBody().getText());
}
}
Я хотел бы, чтобы правильно определить конечно, функциональные тела, не разбивая их на свои компоненты, так как это намного больше. До сих пор следующий вывод производится:
[INCLUDE] testWz/fdrf675tr\a56s
[INCLUDE] testWz/fdrftr\s
[FUNCTION DEFINITION] func1(param, par){if(true){whatever();}}func2(){}
[PARAMETERS] param, par
[BODY] if(true){whatever();}}func2(){
Тело функции слишком длинный и включает в себя определение следующей функции, а также. Одна из идей заключалась бы в обнаружении следующей закрывающей скобки + количества открытых скобок, найденных между ними, но я не уверен, как это сделать с помощью грамматических правил.
Предоставляет ли ваша «упрощенная» C возможность содержать вложенные {...}? Вы подразумеваете, что фраза * обнаруживает ... количество открытых скобок, найденных между *. Если это так, простое регулярное выражение не может подобрать тело функции, поскольку регулярные выражения не могут совпадать с произвольными скобками. Если нет, ваш упрощенный C нереалистичен, и непонятно, что вы узнаете, выполняя это упражнение на нереалистичном языке, и вы сможете использовать его где-то еще. –
@IraBaxter: Это не нереалистичный язык, поскольку он существует как скриптовый движок. Кроме того, я не уверен, что вы имеете в виду с вложенными {...}, поскольку существуют обычные циклы 'if' и' while', но нет функции, вложенной в другую функцию, которая была бы довольно необычной в любом случае – BullyWiiPlaza
. Вам разрешено иметь вложенные { ...}? например, если c {... если d {} ...}? Это очень распространено. Язык, который их не позволяет, очень необычен. –