使用ANTLR语法来识别不同的函数(函数可能具有相同的起始项,但在中间有关键字)



我刚刚遇到了一些令人头疼的事情..

尝试将语句拆分为不同的函数,就像我有一个示例语句

start
 n turnTo 's'.
 n terminate.
end

两个语句都以"n"开头,目前我正在写

statement 
    :
    (turnTo_statment|terminate_statment)*
    ;
turnTo_statment
    :
    variable 'turnTo' ''' value ''' '.'
    ;
terminate_statment
    :
    variable 'terminate' '.'
    ;

但是当词法分析器运行时,它无法确定哪个是哪个,因为两个子状态都以相同的事物"n"开头,编译器有其他选择来使用这些规则。 如果下一个字符串与编译器使用的第一个规则不匹配,那么它将自动抛出一个不匹配的错误。

如果我遇到"x turnTo y",我如何识别并告诉 ANTLR 然后使用规则turnTo_statment,如果我遇到"x 终止",则使用规则 terminate_statment..

即 antlr 中是否有任何功能

执行此操作..
statement 
    :
    ((if statement contain_keywords 'turnTO') -> turnTo_statment
    |
    (if statement contain_keywords 'terminate') ->terminate_statment)*
    ;

谢谢。。

首先,不要在解析器规则中使用"文字"。如果没有在ANTLR方面的丰富经验,这会给您带来麻烦。创建真实的词法分析器规则:

TURNTO: 'turnTo';

现在,您可能需要通读ANTLR wiki上的教程并研究可下载的示例,并确保理解它们。写好的语法似乎很容易,因为语法语言学习起来微不足道,但实际上它需要相当多的知识。首先要意识到的是,词法分析器不了解解析器 - 它只是标记输入流并将这些标记传递给解析器 - 因此词法分析器模式不能模棱两可 - 解析器规则可以处理潜在的差异。

ANTLR 可能可以处理你的语法而不将其转换为 LL(1),因为 ANTLR 可以处理 LL(k),并且通常在没有你帮助的情况下计算出 k 是什么。这是你的全部语法吗?但是,无论如何最好还是留下因素:

statement: var ( TURNTO {etc} | TERMINATE DOT )

你的语法不是LL(1)语法(因为,正如你所注意到的,first(turnTo_statment) = first(terminate_statment))。但是, 你可以通过左分解将其转换为 LL(1) 语法:

statement -> var_stmt statement
var_stmt -> variable turnto_stmt | variable terminate_stmt
turnto_stmt -> "turnTo" value
terminate_stmt -> "terminate."

我对ANTLR了解不多,但这是处理此类冲突的传统方式。

相关内容

  • 没有找到相关文章

最新更新