ANTLR Grouping Variables Attributes

Tag: antlr , antlr3 , abstract-syntax-tree Author: helloxfx Date: 2014-04-22

This question is an "adaptation" of this one: ANTLR Group expressions and save Variables

Now, I want to support the possibility of attribute more than one value to the variables. For example:

(name = Paul AND age = 16) OR country IN (china, japan);

or even : (name = Paul AND age = 16) OR country IN (china, japan) AND country NOT IN (russia);

In this cases, I don't know if it makes more sense have something like:

              |
              =
              |
   |----------|-------|
country     china   japan

Or something like:

              |
            country
              |
          IN / NOT IN
              |
          |-------|
        china   japan

My problem at this moment is to distinguish (expr) from (id_list) (see Grammar File). Maybe I should start by separate the cases in which the equality operation uses a '=' from those where 'IN' or 'NOT IN' are used?

HOW CAN I DIFFERENTIATE IF WHAT IS BETWEEN BRACKETS IS A RULE (EXPRESSION), OR A LIST OF ATTRIBUTES?

So, here is my Grammar File that returns the error


Decision can match input such as "'(' ID ')'" using multiple alternatives: 2, 4
As a result, alternative(s) 4 were disabled for that input

query
    :   expr ';' EOF
    ->  expr
    ;

expr
    :   logical_expr
    ;

logical_expr
    :   equality_expr (logical_op^ equality_expr)*
    ;

equality_expr
    :   atom (equality_op^ atom)*
    ;

atom
    :   ID
    |   id_list
    |   Int
    |   '(' expr ')'    ->  expr
    ;

id_list
    :   '(' ID (',' ID)* ')' 
    ->  ID+
    ;

equality_op
    :   '='
    |   'IN'
    |   'NOT IN'
    ;

logical_op
    :   'AND'
    |   'OR'
    ;

Number
    :   Int ('.' Digit*)?
    ;

ID
    :   ('a'..'z' | 'A'..'Z' | '_' | '.' | Digit)* 
    ;

String
@after {
    setText(getText().substring(1, getText().length()-1).replaceAll("\\\\(.)", "$1"));
    }
    :  '"'  (~('"' | '\\')  | '\\' ('\\' | '"'))* '"' 
    |  '\'' (~('\'' | '\\') | '\\' ('\\' | '\''))* '\''
    ;

Comment
    :  '//' ~('\r' | '\n')* {skip();}
    |  '/*' .* '*/'         {skip();}
    ;

Space
    :  (' ' | '\t' | '\r' | '\n' | '\u000C') {skip();}
    ;

fragment Int
    :  '1'..'9' Digit*
    |  '0'
    ;

fragment Digit 
    :  '0'..'9'
    ;

indexes
    :  ('[' expr ']')+ -> ^(INDEXES expr+)
    ;