Rework parsing structure

This commit is contained in:
Tibo De Peuter 2025-04-27 19:31:29 +02:00
parent a4ec29f084
commit b9f419a59d
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
17 changed files with 246 additions and 278 deletions

View file

@ -0,0 +1,36 @@
package parser
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertInstanceOf
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import prolog.ast.logic.Fact
import prolog.ast.terms.Atom
import prolog.logic.equivalent
import kotlin.test.assertTrue
class ScriptParserTests {
private lateinit var parser: ScriptParser
@BeforeEach
fun setup() {
parser = ScriptParser()
}
@Test
fun `parse single atom`() {
val input = """
a.
""".trimIndent()
val result = parser.parse(input)
val expected = Fact(Atom("a"))
assertEquals(1, result.size, "Should return one result")
assertInstanceOf(Fact::class.java, result[0], "Result should be a fact")
assertTrue(
equivalent(expected.head, result[0].head, emptyMap()),
"Expected fact 'a'"
)
}
}

View file

@ -1,8 +1,8 @@
package better_parser
package parser.grammars
import com.github.h0tk3y.betterParse.grammar.Grammar
import com.github.h0tk3y.betterParse.grammar.parseToEnd
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
@ -14,14 +14,13 @@ import prolog.ast.terms.CompoundTerm
import prolog.ast.terms.Structure
import prolog.ast.terms.Variable
import prolog.builtins.Conjunction
import prolog.builtins.Disjunction
class SimpleSourcePrologParserTests {
class LogicGrammarTests {
private lateinit var parser: Grammar<List<Clause>>
@BeforeEach
fun setup() {
parser = SimpleSourceParser() as Grammar<List<Clause>>
parser = LogicGrammar() as Grammar<List<Clause>>
}
@ParameterizedTest
@ -38,9 +37,9 @@ class SimpleSourcePrologParserTests {
fun `parse simple fact`(input: String) {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 fact")
assertTrue(result[0] is Fact, "Expected a fact")
assertEquals(input, "${result[0].toString()}.", "Expected fact to be '$input'")
Assertions.assertEquals(1, result.size, "Expected 1 fact")
Assertions.assertTrue(result[0] is Fact, "Expected a fact")
Assertions.assertEquals(input, "${result[0].toString()}.", "Expected fact to be '$input'")
}
@ParameterizedTest
@ -53,9 +52,9 @@ class SimpleSourcePrologParserTests {
fun `parse multiple facts`(input: String) {
val result = parser.parseToEnd(input)
assertEquals(2, result.size, "Expected 2 facts")
assertTrue(result[0] is Fact, "Expected a fact")
assertTrue(result[1] is Fact, "Expected a fact")
Assertions.assertEquals(2, result.size, "Expected 2 facts")
Assertions.assertTrue(result[0] is Fact, "Expected a fact")
Assertions.assertTrue(result[1] is Fact, "Expected a fact")
}
@Test
@ -64,9 +63,9 @@ class SimpleSourcePrologParserTests {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
assertTrue(result[0] is Rule, "Expected a rule")
assertEquals("a :- b", result[0].toString())
Assertions.assertEquals(1, result.size, "Expected 1 rule")
Assertions.assertTrue(result[0] is Rule, "Expected a rule")
Assertions.assertEquals("a :- b", result[0].toString())
}
@ParameterizedTest
@ -77,8 +76,8 @@ class SimpleSourcePrologParserTests {
fun `parse simple rule`(input: String) {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
assertTrue(result[0] is Rule, "Expected a rule")
Assertions.assertEquals(1, result.size, "Expected 1 rule")
Assertions.assertTrue(result[0] is Rule, "Expected a rule")
}
@Test
@ -87,22 +86,22 @@ class SimpleSourcePrologParserTests {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
assertTrue(result[0] is Rule, "Expected a rule")
Assertions.assertEquals(1, result.size, "Expected 1 rule")
Assertions.assertTrue(result[0] is Rule, "Expected a rule")
val rule = result[0] as Rule
assertTrue(rule.head is Structure, "Expected head to be a structure")
Assertions.assertTrue(rule.head is Structure, "Expected head to be a structure")
val head = rule.head as Structure
assertEquals("parent/2", head.functor, "Expected functor 'parent/2'")
assertEquals(Variable("X"), head.arguments[0], "Expected first argument 'X'")
assertEquals(Variable("Y"), head.arguments[1], "Expected second argument 'Y'")
Assertions.assertEquals("parent/2", head.functor, "Expected functor 'parent/2'")
Assertions.assertEquals(Variable("X"), head.arguments[0], "Expected first argument 'X'")
Assertions.assertEquals(Variable("Y"), head.arguments[1], "Expected second argument 'Y'")
assertTrue(rule.body is Structure, "Expected body to be a structure")
Assertions.assertTrue(rule.body is Structure, "Expected body to be a structure")
val body = rule.body as Structure
assertEquals("father/2", body.functor, "Expected functor 'father/2'")
assertEquals(Variable("X"), body.arguments[0], "Expected first argument 'X'")
assertEquals(Variable("Y"), body.arguments[1], "Expected second argument 'Y'")
Assertions.assertEquals("father/2", body.functor, "Expected functor 'father/2'")
Assertions.assertEquals(Variable("X"), body.arguments[0], "Expected first argument 'X'")
Assertions.assertEquals(Variable("Y"), body.arguments[1], "Expected second argument 'Y'")
}
@Test
@ -111,10 +110,10 @@ class SimpleSourcePrologParserTests {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
assertInstanceOf(Rule::class.java, result[0], "Expected a rule")
Assertions.assertEquals(1, result.size, "Expected 1 rule")
Assertions.assertInstanceOf(Rule::class.java, result[0], "Expected a rule")
val rule = result[0] as Rule
assertInstanceOf(Conjunction::class.java, rule.body, "Expected body to be a conjunction")
Assertions.assertInstanceOf(Conjunction::class.java, rule.body, "Expected body to be a conjunction")
}
@Test
@ -123,10 +122,10 @@ class SimpleSourcePrologParserTests {
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
Assertions.assertEquals(1, result.size, "Expected 1 rule")
val rule = result[0] as Rule
assertTrue(rule.body is Conjunction, "Expected body to be a conjunction")
Assertions.assertTrue(rule.body is Conjunction, "Expected body to be a conjunction")
val conjunction = rule.body as Conjunction
assertEquals("invited/2", (conjunction.left as CompoundTerm).functor, "Expected functor 'invited/2'")
Assertions.assertEquals("invited/2", (conjunction.left as CompoundTerm).functor, "Expected functor 'invited/2'")
}
}

View file

@ -1,9 +1,8 @@
package better_parser
package parser.grammars
import com.github.h0tk3y.betterParse.grammar.Grammar
import com.github.h0tk3y.betterParse.grammar.parseToEnd
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
@ -16,12 +15,12 @@ import prolog.ast.terms.Term
import prolog.ast.terms.Variable
import prolog.logic.equivalent
class SimplePrologPrologParserTests {
class TermsGrammarTests {
private lateinit var parser: Grammar<Term>
@BeforeEach
fun setup() {
parser = SimplePrologParser() as Grammar<Term>
parser = TermsGrammar() as Grammar<Term>
}
@ParameterizedTest
@ -29,7 +28,7 @@ class SimplePrologPrologParserTests {
fun `parse atom`(name: String) {
val result = parser.parseToEnd(name)
assertEquals(Atom(name), result, "Expected atom '$name'")
Assertions.assertEquals(Atom(name), result, "Expected atom '$name'")
}
@ParameterizedTest
@ -37,7 +36,7 @@ class SimplePrologPrologParserTests {
fun `parse variable`(name: String) {
val result = parser.parseToEnd(name)
assertEquals(Variable(name), result, "Expected atom '$name'")
Assertions.assertEquals(Variable(name), result, "Expected atom '$name'")
}
@Test
@ -46,7 +45,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Structure(Atom("f"), emptyList()), result, emptyMap()),
"Expected atom 'f'"
)
@ -58,7 +57,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Structure(Atom("f"), listOf(Atom("a"))), result, emptyMap()),
"Expected atom 'f(a)'"
)
@ -70,7 +69,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))), result, emptyMap()),
"Expected atom 'f(a, b)'"
)
@ -82,7 +81,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Structure(Atom("f"), listOf(Atom("a"), Variable("X"))), result, emptyMap()),
"Expected atom 'f(a, X)'"
)
@ -94,7 +93,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Atom("b"))))),
result,
@ -110,7 +109,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Variable("X"))))),
result,
@ -127,7 +126,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertEquals(Integer(number), result, "Expected integer '$number'")
Assertions.assertEquals(Integer(number), result, "Expected integer '$number'")
}
@Test
@ -136,7 +135,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Float(42.0f), result, emptyMap()),
"Expected float '42.0'"
)
@ -148,7 +147,7 @@ class SimplePrologPrologParserTests {
val result = parser.parseToEnd(input)
assertTrue(
Assertions.assertTrue(
equivalent(Float(-42.0f), result, emptyMap()),
"Expected float '-42.0'"
)

View file

@ -6,4 +6,7 @@ parent(mary, jimmy).
father(X, Y) :- parent(X, Y), male(X).
mother(X, Y) :- parent(X, Y), female(X).
kan_goed_koken(miriam).
:- write(hello),
nl.
:- write(hello2).