如何分享不同令牌的值 - 不匹配的输入' COMMAND1'期待FUNCTIONNAME2" -

时间:2015-01-16 23:33:20

标签: antlr4

我的语法看起来像这样(简化显示问题):

parse
    : block EOF
    ;

block
    : TYPE1 OPAR STRING CPAR type1_statement_block      
    | TYPE2 OPAR STRING CPAR type2_statement_block          
    ;

type1_statement_block
    : OBRACE function1+ CBRACE                  
    ;

function1
    : FUNCTIONNAME1 OPAR (parameter (',' parameter)*)? CPAR     
    ;

FUNCTIONNAME1 : 'COMMAND1';

type2_statement_block
    : OBRACE function2+ CBRACE                  
    ;

function2
    : FUNCTIONNAME2 OPAR (parameter (',' parameter)*)? CPAR     
    ;

FUNCTIONNAME2 : 'COMMAND1' | 'COMMAND2'

parameter
    : INT                               
    ;

OPAR : '(';
CPAR : ')';
OBRACE : '{';
CBRACE : '}';
TYPE1 : 'TYPE1';
TYPE2 : 'TYPE2';

INT
     : [0-9]+
     ;

STRING
 : '"' (~["\r\n] | '""')* '"'
 ;

SPACE
 : [ \t\r\n] -> skip
 ;

ErrChar
  : .
  ;

解析以下字符串可以正常工作:

TYPE1 ("abc") { COMMAND1(0) }
TYPE2 ("abc") { COMMAND2(0) }

但解析以下字符串会导致错误

TYPE2 ("abc") { COMMAND1(0) }

我得到"不匹配的输入' COMMAND1'期待FUNCTIONNAME2"

如何让这种情况发挥作用?即两个代码块都可以包含相同的函数名吗?

1 个答案:

答案 0 :(得分:0)

基本问题是词法分析器将始终指定“COMMAND1'到令牌FUNCTIONNAME1,因为该规则首先出现,而相对于规则FUNCTIONNAME2的所有其他词法要求都相等。您可以合并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' ;