All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.unibo.tuprolog.parser.PrologParserTest.kt Maven / Gradle / Ivy

package it.unibo.tuprolog.parser

import it.unibo.tuprolog.parser.dynamic.DynamicLexer
import org.antlr.v4.runtime.BaseErrorListener
import org.antlr.v4.runtime.BufferedTokenStream
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.RecognitionException
import org.antlr.v4.runtime.Recognizer
import org.antlr.v4.runtime.Token
import org.antlr.v4.runtime.TokenStream
import org.junit.Assert
import org.junit.Test
import java.util.LinkedList
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class PrologParserTest {

    companion object {

        private fun lexerForString(input: String): PrologLexer {
            return PrologLexer(CharStreams.fromString(input))
        }

        private fun tokenStreamFromLexer(lexer: DynamicLexer): TokenStream {
            return BufferedTokenStream(lexer)
        }

        private fun tokenStreamToList(stream: TokenStream): List {
            val result = LinkedList()
            var i = 0
            stream.consume()
            do {
                result.add(stream[i++])
                stream.consume()
            } while (stream.LA(1) != TokenStream.EOF)
            result.add(stream[i])
            return result
        }

        private fun assertTokenIs(token: Token, type: Int, text: String) {
            Assert.assertEquals("'$text'", "'" + token.text + "'")
            Assert.assertEquals(
                PrologLexer.VOCABULARY.getSymbolicName(type),
                PrologLexer.VOCABULARY.getSymbolicName(token.type)
            )
        }

        private fun parseTerm(string: String): PrologParser.SingletonTermContext {
            val parser: PrologParser = this.createParser(string)
            parser.addErrorListener(
                object : BaseErrorListener() {
                    override fun syntaxError(
                        recognizer: Recognizer<*, *>,
                        offendingSymbol: Any,
                        line: Int,
                        charPositionInLine: Int,
                        msg: String,
                        e: RecognitionException
                    ) {
                        throw e
                    }
                }
            )
            return parser.singletonTerm()
        }

        private fun parseExpression(string: String): PrologParser.SingletonExpressionContext {
            val parser: PrologParser = createParser(string)
            parser.addErrorListener(
                object : BaseErrorListener() {
                    override fun syntaxError(
                        recognizer: Recognizer<*, *>,
                        offendingSymbol: Any,
                        line: Int,
                        charPositionInLine: Int,
                        msg: String,
                        e: RecognitionException
                    ) {
                        throw e
                    }
                }
            )
            return parser.singletonExpression()
        }

        private fun createParser(string: String): PrologParser {
            return PrologParser(
                tokenStreamFromLexer(
                    lexerForString(
                        string
                    )
                )
            )
        }
    }

    @Test
    fun testInteger() {
        val tc = parseTerm("1").term()
        assertTrue(tc.isNum && !tc.isExpr && !tc.isList && !tc.isStruct && !tc.isVar)
        val nc = tc.number()
        assertTrue(nc.isInt && !nc.isReal)
        val ic = nc.integer()
        assertEquals(ic.value.text.toInt(), 1)
    }

    @Test
    fun testReal() {
        val tc = parseTerm("1.1").term()
        assertTrue(tc.isNum && !tc.isExpr && !tc.isList && !tc.isStruct && !tc.isVar)
        val nc = tc.number()
        assertTrue(nc.isReal && !nc.isInt)
        val rc = nc.real()
        assertEquals(rc.value.text.toDouble(), 1.1)
    }

    @Test
    fun testAtom() {
        val tc = parseTerm("a").term()
        assertTrue(tc.isStruct && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isVar)
        val sc = tc.structure()
        assertTrue(
            sc.arity == sc.args.count() &&
                sc.arity == 0 &&
                !sc.isList &&
                !sc.isSet &&
                !sc.isTruth &&
                sc.functor.text == "a" &&
                sc.functor.type == PrologLexer.ATOM
        )
    }

    @Test
    fun testString() {
        sequenceOf("'a'", "\"a\"").forEach {
            val tc = parseTerm(it).term()
            assertTrue(tc.isStruct && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isVar)
            val s = tc.structure()
            assertTrue(
                s.arity == s.args.count() &&
                    s.arity == 0 && s.isString && !s.isSet && !s.isList && !s.isTruth &&
                    s.functor.text == "a" &&
                    (s.functor.type == PrologLexer.DQ_STRING || s.functor.type == PrologLexer.SQ_STRING)
            )
        }
    }

    @Test
    fun testTrue() {
        val tc = parseTerm("true").term()
        assertTrue(tc.isStruct && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isVar)
        val s = tc.structure()
        assertTrue(
            s.arity == s.args.count() &&
                s.isTruth && !s.isList && !s.isString &&
                s.functor.text == "true" &&
                s.functor.type == PrologLexer.BOOL
        )
    }

    @Test
    fun testFalse() {
        val tc = parseTerm("fail").term()
        assertTrue(tc.isStruct && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isVar)
        val s = tc.structure()
        assertTrue(
            s.arity == s.args.count() &&
                s.isTruth && !s.isList && !s.isString &&
                s.functor.text == "fail" &&
                s.functor.type == PrologLexer.BOOL
        )
    }

    @Test
    fun testEmptyList() {
        sequenceOf("[]", "[ ]", "[   ]").forEach {
            val tc = parseTerm(it).term()
            assertTrue(tc.isStruct && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isVar)
            val s = tc.structure()
            assertTrue(
                s.arity == s.args.count() &&
                    s.arity == 0 &&
                    s.isList && !s.isTruth && !s.isString &&
                    s.functor.type == PrologLexer.EMPTY_LIST
            )
        }
    }

    @Test
    fun testVar() {
        sequenceOf("A", "_A", "_1A", "A_").forEach {
            val tc = parseTerm(it).term()
            assertTrue(tc.isVar && !tc.isExpr && !tc.isList && !tc.isNum && !tc.isStruct)
            val v = tc.variable()
            assertTrue(
                !v.isAnonymous &&
                    v.value.text.contains("A") &&
                    v.value.type == PrologLexer.VARIABLE
            )
        }
    }

    @Test
    fun testSingletonList() {
        sequenceOf("[1]", "[1 ]", "[ 1]", "[ 1 ]").forEach {
            val tc = parseTerm(it).term()
            assertTrue(tc.isList && !tc.isExpr && !tc.isVar && !tc.isNum && !tc.isStruct)
            val l = tc.list()
            assertTrue(
                l.length == l.items.count() &&
                    l.length == 1 &&
                    !l.hasTail && l.tail == null
            )
            val expr = l.items[0]
            assertTrue(expr.isTerm && expr.left != null && expr.operators.count() == 0 && expr.right.count() == 0)
            val t = expr.left!!
            assertTrue(t.isNum && !t.isVar && !t.isList && !t.isStruct && !t.isExpr)
            val n = t.number()
            assertTrue(n.isInt && !n.isReal)
            val i = n.integer()
            assertEquals(i.value.text.toInt(), 1)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy