CypherParser { public Expr parse(CharSequence input) { functionsRef.set(functions); return Parsers.or(functions, IDENTIFIER).parse(input); }  Expr parse(CharSequence input);  }
@Test public void parsesIdentifier() throws Exception { assertThat(parser.parse("joe")).isEqualTo(new Identifier("joe")); assertThat(parser.parse("joe67_")).isEqualTo(new Identifier("joe67_")); }
@Test(expected = ParserException.class) public void rejectsIdentifierStartingWithANumber() throws Exception { parser.parse("67joe"); }
@Test public void parsesFunctionCall() throws Exception { assertThat(parser.parse("foo()")).isEqualTo(new Function(new Identifier("foo"))); assertThat(parser.parse("foo(bar)")).isEqualTo(new Function(new Identifier("foo"), new Identifier("bar"))); assertThat(parser.parse("foo(bar,baz,qix)")).isEqualTo(new Function(new Identifier("foo"), new Identifier("bar"), new Identifier("baz"), new Identifier("qix"))); assertThat(parser.parse("foo(bar,baz(qix))")).isEqualTo(new Function(new Identifier("foo"), new Identifier("bar"), new Function(new Identifier("baz"), new Identifier("qix")))); }