package alice.tuprolog; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.junit.Ignore; import org.junit.Test; public class ParserTestCase { @Test public void readingTerms() throws InvalidTermException { Parser p = new Parser("hello."); Struct result = new Struct("hello"); assertEquals(result, p.nextTerm(true)); } @Test public void readingEOF() throws InvalidTermException { Parser p = new Parser(""); assertNull(p.nextTerm(false)); } @Test public void unaryPlusOperator() { Parser p = new Parser("n(+100).\n"); // SICStus Prolog interprets "n(+100)" as "n(100)" // GNU Prolog interprets "n(+100)" as "n(+(100))" // The ISO Standard says + is not a unary operator try { assertNotNull(p.nextTerm(true)); fail(); } catch (InvalidTermException e) {} } @Test public void unaryMinusOperator() throws InvalidTermException { Parser p = new Parser("n(-100).\n"); // TODO Check the interpretation by other engines // SICStus Prolog interprets "n(+100)" as "n(100)" // GNU Prolog interprets "n(+100)" as "n(+(100))" // What does the ISO Standard say about that? Struct result = new Struct("n", new Int(-100)); result.resolveTerm(); assertEquals(result, p.nextTerm(true)); } @Test public void binaryMinusOperator() throws InvalidTermException { String s = "abs(3-11)"; Parser p = new Parser(s); Struct result = new Struct("abs", new Struct("-", new Int(3), new Int(11))); assertEquals(result, p.nextTerm(false)); } @Test public void listWithTail() throws InvalidTermException { Parser p = new Parser("[p|Y]"); Struct result = new Struct(new Struct("p"), new Var("Y")); result.resolveTerm(); assertEquals(result, p.nextTerm(false)); } @Test public void braces() throws InvalidTermException { String s = "{a,b,[3,{4,c},5],{a,b}}"; Parser parser = new Parser(s); assertEquals(s, parser.nextTerm(false).toString()); } @Test public void univOperator() throws InvalidTermException { Parser p = new Parser("p =.. q."); Struct result = new Struct("=..", new Struct("p"), new Struct("q")); assertEquals(result, p.nextTerm(true)); } @Test public void dotOperator() throws InvalidTermException { String s = "class('java.lang.Integer').'MAX_VALUE'"; DefaultOperatorManager om = new DefaultOperatorManager(); om.opNew(".", "xfx", 600); Parser p = new Parser(om, s); Struct result = new Struct(".", new Struct("class", new Struct("java.lang.Integer")), new Struct("MAX_VALUE")); assertEquals(result, p.nextTerm(false)); } @Test public void bracketedOperatorAsTerm() throws InvalidTermException { String s = "u (b1) b2 (b3)"; DefaultOperatorManager om = new DefaultOperatorManager(); om.opNew("u", "fx", 200); om.opNew("b1", "yfx", 400); om.opNew("b2", "yfx", 500); om.opNew("b3", "yfx", 300); Parser p = new Parser(om, s); Struct result = new Struct("b2", new Struct("u", new Struct("b1")), new Struct("b3")); assertEquals(result, p.nextTerm(false)); } @Test public void bracketedOperatorAsTerm2() throws InvalidTermException { String s = "(u) b1 (b2) b3 a"; DefaultOperatorManager om = new DefaultOperatorManager(); om.opNew("u", "fx", 200); om.opNew("b1", "yfx", 400); om.opNew("b2", "yfx", 500); om.opNew("b3", "yfx", 300); Parser p = new Parser(om, s); Struct result = new Struct("b1", new Struct("u"), new Struct("b3", new Struct("b2"), new Struct("a"))); assertEquals(result, p.nextTerm(false)); } @Test public void integerBinaryRepresentation() throws InvalidTermException { String n = "0b101101"; Parser p = new Parser(n); alice.tuprolog.Number result = new Int(45); assertEquals(result, p.nextTerm(false)); String invalid = "0b101201"; try { new Parser(invalid).nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void integerOctalRepresentation() throws InvalidTermException { String n = "0o77351"; Parser p = new Parser(n); alice.tuprolog.Number result = new Int(32489); assertEquals(result, p.nextTerm(false)); String invalid = "0o78351"; try { new Parser(invalid).nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void integerHexadecimalRepresentation() throws InvalidTermException { String n = "0xDECAF"; Parser p = new Parser(n); alice.tuprolog.Number result = new Int(912559); assertEquals(result, p.nextTerm(false)); String invalid = "0xG"; try { new Parser(invalid).nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void emptyDCGAction() throws InvalidTermException { String s = "{}"; Parser p = new Parser(s); Struct result = new Struct("{}"); assertEquals(result, p.nextTerm(false)); } @Test public void singleDCGAction() throws InvalidTermException { String s = "{hello}"; Parser p = new Parser(s); Struct result = new Struct("{}", new Struct("hello")); assertEquals(result, p.nextTerm(false)); } @Test public void multipleDCGAction() throws InvalidTermException { String s = "{a, b, c}"; Parser p = new Parser(s); Struct result = new Struct("{}", new Struct(",", new Struct("a"), new Struct(",", new Struct("b"), new Struct("c")))); assertEquals(result, p.nextTerm(false)); } @Ignore("This is an error both in 2.0.1 and in 2.1... don't know why, though.") @Test public void dcgActionWithOperators() throws Exception { String input = "{A =.. B, hotel, 2}"; Struct result = new Struct("{}", new Struct(",", new Struct("=..", new Var("A"), new Var("B")), new Struct(",", new Struct("hotel"), new Int(2)))); result.resolveTerm(); Parser p = new Parser(input); assertEquals(result, p.nextTerm(false)); } @Test public void missingDCGActionElement() { String s = "{1, 2, , 4}"; Parser p = new Parser(s); try { p.nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void dcgActionCommaAsAnotherSymbol() { String s = "{1 @ 2 @ 4}"; Parser p = new Parser(s); try { p.nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void uncompleteDCGAction() { String s = "{1, 2,}"; Parser p = new Parser(s); try { p.nextTerm(false); fail(); } catch (InvalidTermException expected) {} s = "{1, 2"; p = new Parser(s); try { p.nextTerm(false); fail(); } catch (InvalidTermException expected) {} } @Test public void multilineComments() throws InvalidTermException { String theory = "t1." + "\n" + "/*" + "\n" + "t2" + "\n" + "*/" + "\n" + "t3." + "\n"; Parser p = new Parser(theory); assertEquals(new Struct("t1"), p.nextTerm(true)); assertEquals(new Struct("t3"), p.nextTerm(true)); } @Test public void singleQuotedTermWithInvalidLineBreaks() { String s = "out('"+ "can_do(X).\n"+ "can_do(Y).\n"+ "')."; Parser p = new Parser(s); try { p.nextTerm(true); fail(); } catch (InvalidTermException expected) {} } // TODO More tests on Parser // Character code for Integer representation // :-op(500, yfx, v). 3v2 NOT CORRECT, 3 v 2 CORRECT // 3+2 CORRECT, 3 + 2 CORRECT // +(2, 3) is now acceptable // what about f(+) }