Antlr4:如何将当前令牌的值传递给lexer的谓词?

时间:2019-07-09 17:51:58

标签: c# antlr antlr4 antlr4cs

有没有一种方法可以为词法分析器的谓词提供当前令牌的值?例如,在我的lexer grammar FlowLexer中,我动态加载令牌:

在解析之前,我会动态加载令牌:

var lexer = new FlowLexer(new AntlrInputStream(flowContent)) {
    TokenExists = tokenValue => tokensDictionary.ContainsKey(tokenValue)
};

然后在解析/词法分析期间,TokenExists谓词称为:

@lexer::members{
    public Func<string,bool> TokenExists = null;
}

/* ... stuff ... */

TOK : [-_.0-9a-zA-Z]+ 
    {!TokenExists(/*WHAT GOES HERE?*/);}? 
    -> mode(IN_TOKEN);

/* ... stuff ... */

但是如何将令牌值传递给TokenExists谓词?

(这是尝试创建上下文感知的词法分析器:我有多个mode,并且其中有不同的规则)。

1 个答案:

答案 0 :(得分:1)

可以使用特殊语法在ANTLR4谓词和操作中访问令牌值。有关详细信息,请参见Actions and Attributes文档。

通常,您可以使用美元符号和令牌名称来访问已解析的令牌,例如

a: x = INT {$x.text == "0"}?;

或没有标签(且仅当该子规则在该解析器规则中仅存在一次时):

a: INT {$INT.text == "0"}?;

ANTLR4将此类伪代码转换为目标语言代码,以允许访问令牌属性(例如,在C ++中,它变为:INT->getText() == "0")。

但是,在词法分析器规则中,此special access ist not possible(ANTLR3支持它,但不支持ANTLR4)。不过,您仍然可以使用本机代码访问令牌的属性(实际上,它不是令牌,因为它尚不存在,但是可以在词法分析器规则完成后使用其值创建令牌)。但是,这通常不能移植到其他目标语言中(如果您没有多个解析器目标,这没关系)。

在词法分析器操作(包括谓词)中触发的代码在词法分析器的上下文中执行。规则结束后,此词法分析器保留从中创建新令牌的值。这样可以获取当前匹配的文本:

TOK : [-_.0-9a-zA-Z]+ {!TokenExists(Text);}? -> mode(IN_TOKEN);

TextC# lexer的属性。