gpt4 book ai didi

parsing - Antlr4:如何在语法中隐藏和使用 token

转载 作者:行者123 更新时间:2023-12-02 16:27:55 26 4
gpt4 key购买 nike

我正在解析一种定义两种类型语句的脚本语言;控制语句和非控制语句。非控制语句始终以 ';' 结尾,而控制语句可能以 ';'EOL ('\n') 结尾。语法的一部分如下所示:

script
: statement* EOF
;

statement
: control_statement
| no_control_statement
;

control_statement
: if_then_control_statement
;

if_then_control_statement
: IF expression THEN end_control_statment
( statement ) *
( ELSEIF expression THEN end_control_statment ( statement )* )*
( ELSE end_control_statment ( statement )* )?
END IF end_control_statment
;

no_control_statement
: sleep_statement
;

sleep_statement
: SLEEP expression END_STATEMENT
;

end_control_statment
: END_STATEMENT
| EOL
;

END_STATEMENT
: ';'
;

ANY_SPACE
: ( LINE_SPACE | EOL ) -> channel(HIDDEN)
;

EOL
: [\n\r]+
;

LINE_SPACE
: [ \t]+
;

在脚本语言的所有其他方面,我从不关心 EOL,因此我使用普通的词法分析器规则来隐藏空格。

这在所有情况下都可以正常工作,但在我需要使用 EOL 来查找控制语句终止的情况下,但使用上面的语法,所有 EOL被隐藏并且不在控制语句规则中使用。

有没有办法改变我的语法,以便我可以跳过所有EOL,但终止部分控制语句所需的语法?

最佳答案

找到一种方法来处理这个问题。

这个想法是将 EOL 转移到一个隐藏 channel 中,并将我不想在另一个隐藏 channel 中看到的其他内容(例如空格和注释)转移到其中。然后,当 EOL 应该出现时,我使用一些代码来回溯 token 并检查以前的 token channel (因为它们已经被消耗)。如果我在遇到普通 channel 的东西之前在 EOL channel 上找到了东西,那就没问题。

看起来像这样:

更改了词法分析器规则:

@lexer::members {
public static int EOL_CHANNEL = 1;
public static int OTHER_CHANNEL = 2;
}

...

EOL
: '\r'? '\n' -> channel(EOL_CHANNEL)
;

LINE_SPACE
: [ \t]+ -> channel(OTHER_CHANNEL)
;

我还将所有其他隐藏 channel (评论)转移到OTHER_CHANNEL。然后我更改了规则end_control_statment:

end_control_statment
: END_STATEMENT
| { isEOLPrevious() }?
;

并添加

@parser::members {
public static int EOL_CHANNEL = 1;
public static int OTHER_CHANNEL = 2;

boolean isEOLPrevious()
{
int idx = getCurrentToken().getTokenIndex();
int ch;

do
{
ch = getTokenStream().get(--idx).getChannel();
}
while (ch == OTHER_CHANNEL);

// Channel 1 is only carrying EOL, no need to check token itself
return (ch == EOL_CHANNEL);
}
}

可以坚持使用普通的隐藏 channel ,但回溯时需要同时跟踪 channel 和 token ,因此这可能会更容易一些......

希望这可以帮助其他人处理此类问题......

关于parsing - Antlr4:如何在语法中隐藏和使用 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41667217/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com