stuck making simple grammar for filter language I have tried and get close but keep getting stuck. Input language is like this
('aaa' eq '42') and ('bbb' gt 'zzz') or (....) and (....)

ie a set of clauses of the form left op right joined by 'and' or 'or'. THere can be 1 or more clauses
This seemed simple to me but I am sure I have started getting too complicated
grammar filter;

options {
    language=CSharp2;
      output=AST;
}

 tokens {
  ROOT;

  }
  OPEN_PAREN
    :   '(';
  CLOSE_PAREN
    :   ')';
  SINGLE_QUOTE
    :   '\'' ;
  AND   :   'and';
  OR    :   'or';
  GT    :   'gt';
  GE    :   'ge';
  EQ    :   'eq';
  LT    :   'lt';
  LE    :   'le';

fragment
ID   : ('a'..'z' | 'A'..'Z'  )+;
STRING  :   SINGLE_QUOTE ID SINGLE_QUOTE;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = Hidden; } ;

//public root   :    filter -> ^(ROOT filter);

public filter
    : clause^
    | lc=clause join rc=clause ->^(join $lc $rc)
    ;

left    :    STRING;
right   :   STRING; 
clause
    : OPEN_PAREN left  op   right CLOSE_PAREN //-> ^(op left right)
    ;

join    : AND 
    | OR
    ;

op  : GT|GE|LT|LE|EQ;

when I run this in C# I get 'more than one node as root'
Also I am not sure how I can do the N joins