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

@ -1,132 +0,0 @@
package better_parser
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.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import prolog.ast.logic.Clause
import prolog.ast.logic.Fact
import prolog.ast.logic.Rule
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 {
private lateinit var parser: Grammar<List<Clause>>
@BeforeEach
fun setup() {
parser = SimpleSourceParser() as Grammar<List<Clause>>
}
@ParameterizedTest
@ValueSource(strings = [
"john.",
"mary.",
"jimmy.",
"male(john).",
"male(jimmy).",
"female(mary).",
"not(not(true)).",
"not(a, not(b, c), d, not(not(a)))."
])
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'")
}
@ParameterizedTest
@ValueSource(strings = [
"john. mary.",
"likes(john, mary). likes(mary, john).",
"belgium. capital(belgium, brussels).",
"plus(1, 2, 3). plus(3, 4, 7).",
])
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")
}
@Test
fun `simplest rule`() {
val input = "a :- b."
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())
}
@ParameterizedTest
@ValueSource(strings = [
"parent(X, Y) :- father(X, Y).",
"parent(X, Y) :- mother(X, Y)."
])
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")
}
@Test
fun `parse rule with very verbose checks`() {
val input = "parent(X, Y) :- father(X, Y)."
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
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")
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'")
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'")
}
@Test
fun `parse rule with conjunction`() {
val input = "father(X, Y) :- parent(X, Y), male(X)."
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
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")
}
@Test
fun `parse rule with nested conjunction`() {
val input = "guest(X, Y) :- invited(Y, X), has_time(X), not(sick(Y))."
val result = parser.parseToEnd(input)
assertEquals(1, result.size, "Expected 1 rule")
val rule = result[0] as Rule
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'")
}
}