Antlr4 如何共享不同令牌的值-输入不匹配';命令1';预期函数名为“2”-

Antlr4 如何共享不同令牌的值-输入不匹配';命令1';预期函数名为“2”-,antlr4,Antlr4,我的语法如下(简化以显示问题): 解析以下字符串可以很好地工作: TYPE1 ("abc") { COMMAND1(0) } TYPE2 ("abc") { COMMAND2(0) } 但是,解析以下字符串会导致错误 TYPE2 ("abc") { COMMAND1(0) } 我得到“不匹配的输入'COMMAND1'应为FUNCTIONNAME2” 我如何才能让这个场景工作?也就是说,两个代码块可以包含相同的函数名?基本问题是lexer将始终将“COMMAND1”分配给令牌函数名1,因为该规

我的语法如下(简化以显示问题):

解析以下字符串可以很好地工作:

TYPE1 ("abc") { COMMAND1(0) }
TYPE2 ("abc") { COMMAND2(0) }
但是,解析以下字符串会导致错误

TYPE2 ("abc") { COMMAND1(0) }
我得到“不匹配的输入'COMMAND1'应为FUNCTIONNAME2”


我如何才能让这个场景工作?也就是说,两个代码块可以包含相同的函数名?

基本问题是lexer将始终将“COMMAND1”分配给令牌函数名1,因为该规则首先出现,并且与规则函数名2相关的所有其他词法要求是相等的。您可以合并FUNCTIONNAME1/2规则,但这会导致语法的第二个问题

如前所述,语法试图在语法上完全相同的“Type1”和“Type2”语句之间进行语义区分。更好的做法是使用语法进行句法分析,并推迟对树行走的语义分析。分离关注点将使两者更容易

block
    : ( cmd OPAR STRING CPAR statement_block )+
    ;

statement_block
    : OBRACE function+ CBRACE
    ;

function
    : FUNCTIONNAME OPAR (parameter (',' parameter)*)? CPAR     
    ;

cmd : 'TYPE1' | 'TYPE2' ;
FUNCTIONNAME : 'COMMAND1' | 'COMMAND2' ;
block
    : ( cmd OPAR STRING CPAR statement_block )+
    ;

statement_block
    : OBRACE function+ CBRACE
    ;

function
    : FUNCTIONNAME OPAR (parameter (',' parameter)*)? CPAR     
    ;

cmd : 'TYPE1' | 'TYPE2' ;
FUNCTIONNAME : 'COMMAND1' | 'COMMAND2' ;