Antlr4:如何将当前令牌的值传递给词法分析器的谓词?
Antlr4: How to pass current token's value to lexer's predicate?
有没有办法为词法分析器的谓词提供当前标记的值?例如,在我的 lexer grammar FlowLexer
中,我动态加载令牌:
在解析之前,我动态加载了令牌:
var lexer = new FlowLexer(new AntlrInputStream(flowContent)) {
TokenExists = tokenValue => tokensDictionary.ContainsKey(tokenValue)
};
然后在 parsing/lexing 期间调用 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
,其中一个有不同的规则)。
可以使用特殊语法访问 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);
Text
是 C# lexer 的 属性。
有没有办法为词法分析器的谓词提供当前标记的值?例如,在我的 lexer grammar FlowLexer
中,我动态加载令牌:
在解析之前,我动态加载了令牌:
var lexer = new FlowLexer(new AntlrInputStream(flowContent)) {
TokenExists = tokenValue => tokensDictionary.ContainsKey(tokenValue)
};
然后在 parsing/lexing 期间调用 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
,其中一个有不同的规则)。
可以使用特殊语法访问 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);
Text
是 C# lexer 的 属性。