antlr — ошибка строки комментария

#antlr #antlrworks

#antlr #antlrworks

Вопрос:

Я использую Antlr 3 под ANTLRWorks 1.4.3, и у меня возникли проблемы с написанием грамматики для игнорирования строк комментариев.

Это грамматика, которая показывает проблему:

 grammar Ex2;
@header {
    import java.util.HashMap;
}
@members {
    HashMap memory = new HashMap();
}
prog: stat  ;

stat
    : expr NEWLINE {System.out.println($expr.value);}
    | ID '=' expr NEWLINE
        { memory.put($ID.text, new Integer($expr.value)); }
    | NEWLINE
    ;

expr returns [int value]
    : e=term {$value = $e.value;}
    ( ' ' e=term {$value  = $e.value;}
    | '-' e=term {$value -= $e.value;}
    )*
    ;

term returns [int value]
    : e=fact {$value = $e.value; }
    ( '*' e=fact {$value *= $e.value;}
    | '/' e=fact {$value /= $e.value;}
    | '^' e=fact {
                    for(int i = 0; i < $e.value; i  )
                        $value *= $value;   
                 }  
    )*;

fact returns [int value]
    : INT {$value = Integer.parseInt($INT.text);}
    | ID
    {
        Integer v = (Integer)memory.get($ID.text);
        if ( v!=null ) $value = v.intValue();
        else System.err.println("undefined variable " $ID.text);
    }
    | '(' expr ')' {$value = $expr.value;}
    ;

COMMENT
    : '--' ~('/r' | '/n')* {skip();}
    ;   
ID 
    : ('a'..'z'|'A'..'Z')  
    ;
INT 
    : '0'..'9'  
    ;
NEWLINE
    :'r'? 'n' 
    ;
WS 
    : (' '|'t')  {skip();} 
    ;
 

Я получаю эту ошибку

 error(204): /../Ex2.g:46:16: duplicate token type '/n' when collapsing subrule into set 
 

Я хотел бы упомянуть, что почти каждый тип грамматики, который я пытаюсь отладить, используя правило КОММЕНТАРИЕВ для лексера, приводит к одной и той же ошибке.

Пожалуйста, помогите и заранее благодарим вас.

Ответ №1:

Это не:

 COMMENT
    : '--' ~('/r' | '/n')* {skip();}
    ; 
 

но:

 COMMENT
    : '--' ~('r' | 'n')* {skip();}
    ; 
 

Проблема в том, что /n это два символа, а оператор отрицания работает только с наборами отдельных символов. Вы не можете отрицать две подстроки '/r' и '/n' , но вы можете отрицать набор из двух (одиночных) символов 'r' и 'n' .