匹配到功能结束

时间:2016-10-15 03:51:26

标签: java parsing antlr antlr4

我正在使用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(){

函数体太长,也包含下一个函数的定义。一个想法是检测下一个结束括号+中间打开括号的数量,但我不知道如何单独使用语法规则。

1 个答案:

答案 0 :(得分:-1)

functionBody是一个匹配所有规则。非贪婪修饰符在这里没有帮助,因为规则本身没有终止令牌。因此,请尝试删除它,而是将通配符匹配放入functionDefinition规则:

functionDefinition: functionName '(' parameters ')' '{' .*? '}';

或者将花括号移动到functionBody规则:

functionDefinition: functionName '(' parameters ')' functionBody;
functionBody: OpenCurly .*? CloseCurly;

注意:我按意图使用了花括号的词法规则。建议在自己的规则中定义所有词法分析器令牌,而不是在解析器规则中隐式定义(避免像多个定义那样麻烦,自动分配令牌名称等)。

更新

我不知道所需的解决方案应该支持由花括号分隔的嵌套块(整个问题可能需要一些抛光,这就是为什么有3次近距离投票)。解决方案的一般原则是您定义一个或多个明确定义花括号对的规则,以便只有在打开和关闭括号平衡时才匹配规则。你可以这样做:

functionBody: OpenCurly .*? (functionBody .*?)? CloseCurly;

即。递归地将functionBody定义为包含自身。