Question

If I have my input message:

name IS (Jon, Ted) IS NOT (Peter);

I want this AST:

      name
       |
    |-----|
   IS   IS NOT
    |     |
    |    Peter
 |----|
Jon  Ted

But I'm receiving:

                name
                  |
        |-----------------|
       IS              IS NOT
        |                 |
        |                 |
   |----|-----|      |----|-----|
  Jon  Ted  Peter   Jon  Ted  Peter 

My Grammar file has:

...

expression
    |   NAME 'IS' OParen Identifier (Comma Identifier)* CParen 'IS NOT' OParen 
Identifier (Comma Identifier)* CParen
    ->  ^(NAME ^('IS' ^(Identifier)*) ^('IS NOT' ^(Identifier)*))
    ;

...

NAME
    :   'name'
    ;

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

How can I differentiate what "belongs" to the 'IS' and what to belongs to the 'IS NOT' ?

Was it helpful?

Solution

Something like this should do it:

expression
 : NAME IS left=id_list IS NOT right=id_list -> ^(NAME ^(IS $left) ^(NOT $right))
 ;

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

IS : 'IS';
NOT : 'NOT'; // not a single token that is 'IS NOT'

ID
 : ('a'..'z' | 'A'..'Z' | '_' | '.' | Digit)+ 
   // Not `(...)*`: it should always match a single char!
 ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top