grammar test; test : table_ref; table_ref : table_ref_simple ((CROSS_JOIN table_ref) | qualified_join)* ; table_ref_simple : (qualified_name | LPAREN (table_ref | select_stmt) RPAREN) (AS? ID (LPAREN column_name_list RPAREN)?)? ; qualified_join : NATURAL JOIN table_ref | (INNER | (LEFT | RIGHT | FULL) OUTER?)? JOIN table_ref join_spec ; join_spec : ON search_condition | USING LPAREN column_name_list RPAREN ; column_name_list : ID (',' ID)* ; qualified_name : ID ('.' ID)* ; search_condition : ; select_stmt : ; LPAREN : '('; RPAREN : ')'; AS : 'as'; NATURAL : 'natural'; INNER : 'inner'; LEFT : 'left'; RIGHT : 'right'; FULL : 'full'; OUTER : 'outer'; UNION : 'union'; JOIN : 'join'; ON : 'on'; USING : 'using'; CROSS_JOIN : 'cross' ' '+ 'join' ; ID : (SINGLE_LATIN_LETTER | INT) (SINGLE_LATIN_LETTER | INT | '_')* ; fragment SINGLE_LATIN_LETTER : 'a'..'z' | 'A'..'Z' ; fragment INT : '0'..'9'; WS : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} ;