'ANTLR how to discriminate two similar comments

In Antlr, if i have a rule for example:

> someRule : COMM TYPE arg EQUAL COMMENT_TEXT;

where:

  • 'COMM' : is '|'
  • 'TYPE' : is ('C'|'I'|'U')
  • 'arg' : can be 'number,number'(1,0) or only a number (1)
  • EQUALS : '='
  • COMMENT_TEXT : String

it would accept :

-   | C10,1 = comment
-   | U10 = comment

In my grammar this rule is a DEFINITION.

When even one of these "token" is missing, I would like a generic comment:

|C1 comment   -> Generic Comment (EQUAL is missing)
|1 = comment  -> Generic comment ('type' is missing)
|C = Comment  -> Generic comment ('arg' is missing)
|comment      ....

Grammar:

currLine : commentType | .....; 

commentType: COMM (defComm | genComm); 

defComm: TYPE arg EQUAL COMMENT_TEXT #defcom;

how can i say that everything else is genComm?

genComm: ....

EDIT:

One possible solution can be:

genComment:
     : TYPE arg? EQUAL? COMMENT_TEXT?
     | arg EQUAL? COMMENT_TEXT?
     | EQUAL COMMENT_TEXT?
     | COMMENT_TEXT 
     ; 

My Parser grammar:

parser grammar ParserComments;

options {
      tokenVocab = LexerComments;
  }

prog : (line? EOL)+;   
line : comment; 

comment: SINGLE_COMMENT (defComm | genericComment); 

defComm: TYPE arg EQUAL COMMENT_TEXT;

arg : (argument1) (VIRGOLA argument2)?;  
  
argument1    : numbers ;  
argument2    : numbers ;  
numbers      : NUMBER+ ;  
 
genericComment
 : TYPE arg? EQUAL? COMMENT_TEXT?
 | arg EQUAL? COMMENT_TEXT?
 | EQUAL COMMENT_TEXT?
 | COMMENT_TEXT 
 ; 

// ------ general  ------ 
ignored : . ;  

My Lexer grammar:

lexer grammar LexerComments;

SINGLE_COMMENT : '|' -> pushMode(COMMENT); 
NUMBER : [0-9];  
VIRGOLA : ',';
WS  : [ \t] -> skip ;   
EOL : [\r\n]+;  
 
// ------------ Everything INSIDE a COMMENT ------------ 
mode COMMENT;
    COMMENT_NUMBER  : NUMBER -> type(NUMBER);
    COMMENT_VIRGOLA : VIRGOLA -> type(VIRGOLA);
    
    TYPE : 'I'| 'U'| 'Q';
     
    EQUAL : '=';
    
    COMMENT_TEXT: ('a'..'z' | 'A'..'Z')+;
     
    WS_1        : [ \t] -> skip ;   
    COMMENT_EOL : EOL -> type(EOL);

but parsing:

  • | Q1,0 = text

I get a full context and ambiguity error in BaseErrorListener.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source