如何使Antlr4在规则完成时停止解析
我必须解析文件中有表达式的部分,如:如何使Antlr4在规则完成时停止解析,antlr4,Antlr4,我必须解析文件中有表达式的部分,如: garbage garbage garbage BEGIN <something> END garbage garbage... 它正确地解析了我的表达式,如果它是我文件中唯一的东西的话。遗憾的是,当我在文件中遇到BEGIN时尝试踢解析器时,解析器将正确地解析表达式,但随后将尝试在结束后获取其他标记 我已经阅读了ANTLR4书中的abiut Fyzy语法部分,但这不是我想要的,因为解析的结果基本上会影响文件的其余部分,解析的结果将产生一组替换,
garbage garbage garbage
BEGIN <something> END
garbage garbage...
它正确地解析了我的表达式,如果它是我文件中唯一的东西的话。遗憾的是,当我在文件中遇到BEGIN时尝试踢解析器时,解析器将正确地解析表达式,但随后将尝试在结束后获取其他标记
我已经阅读了ANTLR4书中的abiut Fyzy语法部分,但这不是我想要的,因为解析的结果基本上会影响文件的其余部分,解析的结果将产生一组替换,应用于下面的文本中
我要寻找的是一种告诉解析器在END关键字之后停止的方法。我已尝试覆盖TokenStream以在满足END时生成Token.EOF,并使用此修改的规则集:
rule : BEGIN expr EOF;
expr : ... ;
代码如下:
public Token LT(int k)
{
Token token = super.LT( k );
if ( token.getType() == MyParser.END )
{
token = new CommonToken(Token.EOF,"");
}
return token;
}
但在本例中,流已关闭,我无法再将其用于剩余文件…您可以在lexer中创建一种特殊模式,将垃圾作为单个垃圾令牌使用。在下面的示例代码中,我将GarbageMode作为独立模式,这要求您在创建lexer的新实例后显式调用lexer.setModeGarbageMode。另一种方法是将垃圾和垃圾模块开始规则置于默认模式,并将其余规则从默认模式移至新模式,例如MainMode
使上述lexer工作的关键是在创建垃圾令牌之前重写lexer.emit方法以重置输入流位置。这方面的一个示例在中提供,并带有相应的单元测试。在您的情况下,如果垃圾令牌的文本以BEGIN结尾,您只需从垃圾令牌中删除最后5个字符。应该可以,谢谢您的技巧,假设我可以标记inputStream,但在这里,我必须完成我的家庭作业。仅供参考,我使用了一个“模糊解析器”,它会吞下语法中没有的所有内容,但这意味着我必须读取文件两次。你的建议将为我节省一个阶段。如果有一个在条目规则完成后停止获取令牌的特性,那将是非常棒的。类似于解析结束时的伪令牌EOP之类的东西可能会有所帮助。wdyt?@EmmanuelLécharny如果你尝试的话,你最终会遇到的。事实上,我遇到了118:-我本应该得到一个异常,但实际上,lexer只是读取文件末尾的所有内容。。。这就是为什么我发布了这个问题。
public Token LT(int k)
{
Token token = super.LT( k );
if ( token.getType() == MyParser.END )
{
token = new CommonToken(Token.EOF,"");
}
return token;
}
BEGIN
: 'BEGIN'
;
END
: 'END' -> mode(GarbageMode)
;
mode GarbageMode;
GARBAGE
: .+? (BEGIN | EOF) -> mode(DEFAULT_MODE)
;
GarbageMode_BEGIN
: BEGIN -> type(BEGIN), mode(DEFAULT_MODE)
;