我正在使用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(){
函数体太长,也包含下一个函数的定义。一个想法是检测下一个结束括号+中间打开括号的数量,但我不知道如何单独使用语法规则。
答案 0 :(得分:-1)
functionBody是一个匹配所有规则。非贪婪修饰符在这里没有帮助,因为规则本身没有终止令牌。因此,请尝试删除它,而是将通配符匹配放入functionDefinition
规则:
functionDefinition: functionName '(' parameters ')' '{' .*? '}';
或者将花括号移动到functionBody
规则:
functionDefinition: functionName '(' parameters ')' functionBody;
functionBody: OpenCurly .*? CloseCurly;
注意:我按意图使用了花括号的词法规则。建议在自己的规则中定义所有词法分析器令牌,而不是在解析器规则中隐式定义(避免像多个定义那样麻烦,自动分配令牌名称等)。
我不知道所需的解决方案应该支持由花括号分隔的嵌套块(整个问题可能需要一些抛光,这就是为什么有3次近距离投票)。解决方案的一般原则是您定义一个或多个明确定义花括号对的规则,以便只有在打开和关闭括号平衡时才匹配规则。你可以这样做:
functionBody: OpenCurly .*? (functionBody .*?)? CloseCurly;
即。递归地将functionBody
定义为包含自身。