Skip to content

Commit

Permalink
Fix Term equals
Browse files Browse the repository at this point in the history
  • Loading branch information
bachish authored and gsvgit committed Nov 22, 2023
1 parent c520b75 commit 2b1e9ee
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 29 deletions.
3 changes: 3 additions & 0 deletions src/main/kotlin/org/srcgll/grammar/combinator/Grammar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ object GlobalState
{
private var value = 0
fun getNextInt() : Int = value++
fun resetCounter() {
value = 0
}
}

open class Grammar
Expand Down
19 changes: 12 additions & 7 deletions src/main/kotlin/org/srcgll/grammar/combinator/regexp/Term.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package org.srcgll.grammar.combinator.regexp

import org.srcgll.rsm.symbol.Terminal

open class Term <TerminalType>
(
value : TerminalType,
)
: DerivedSymbol
{
val terminal : Terminal<TerminalType> = Terminal(value)
open class Term<TerminalType>
(
value: TerminalType,
) : DerivedSymbol {
val terminal: Terminal<TerminalType> = Terminal(value)

override fun equals(other: Any?): Boolean {
if (other !is Term<*>) return false
return terminal == other.terminal
}

override fun hashCode(): Int = terminal.hashCode()
}
48 changes: 27 additions & 21 deletions src/main/kotlin/org/srcgll/rsm/RSMState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,37 @@ import org.srcgll.rsm.symbol.Nonterminal
import org.srcgll.rsm.symbol.Terminal

class RSMState
(
val id : Int,
val nonterminal : Nonterminal,
val isStart : Boolean = false,
val isFinal : Boolean = false,
)
{
val outgoingTerminalEdges : HashMap<Terminal<*>, HashSet<RSMState>> = HashMap()
val outgoingNonterminalEdges : HashMap<Nonterminal, HashSet<RSMState>> = HashMap()
val coveredTargetStates : HashSet<RSMState> = HashSet()
val errorRecoveryLabels : HashSet<Terminal<*>> = HashSet()
(
val id: Int,
val nonterminal: Nonterminal,
val isStart: Boolean = false,
val isFinal: Boolean = false,
) {
val outgoingTerminalEdges: HashMap<Terminal<*>, HashSet<RSMState>> = HashMap()
val outgoingNonterminalEdges: HashMap<Nonterminal, HashSet<RSMState>> = HashMap()
val coveredTargetStates: HashSet<RSMState> = HashSet()
val errorRecoveryLabels: HashSet<Terminal<*>> = HashSet()

override fun toString() =
"RSMState(id=$id, nonterminal=$nonterminal, isStart=$isStart, isFinal=$isFinal)"

override fun equals(other : Any?) : Boolean
{
if (this === other) return true
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is RSMState) return false
if (id != other.id) return false
if (id != other.id) return false

return true
}

val hashCode : Int = id
val hashCode: Int = id
override fun hashCode() = hashCode

fun addTerminalEdge(edge : RSMTerminalEdge)
{
fun addTerminalEdge(edge: RSMTerminalEdge) {
if (!coveredTargetStates.contains(edge.head)) {
errorRecoveryLabels.add(edge.terminal)
coveredTargetStates.add(edge.head)
}

if (outgoingTerminalEdges.containsKey(edge.terminal)) {
val targetStates = outgoingTerminalEdges.getValue(edge.terminal)

Expand All @@ -47,8 +44,7 @@ class RSMState
}
}

fun addNonterminalEdge(edge : RSMNonterminalEdge)
{
fun addNonterminalEdge(edge: RSMNonterminalEdge) {
if (outgoingNonterminalEdges.containsKey(edge.nonterminal)) {
val targetStates = outgoingNonterminalEdges.getValue(edge.nonterminal)

Expand All @@ -57,4 +53,14 @@ class RSMState
outgoingNonterminalEdges[edge.nonterminal] = hashSetOf(edge.head)
}
}

fun rsmEquals(other: RSMState): Boolean {
if (this != other) {
return false
}
if (outgoingTerminalEdges != other.outgoingTerminalEdges) {
return false
}
return outgoingNonterminalEdges == other.outgoingNonterminalEdges
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/org/srcgll/rsm/symbol/Nonterminal.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Nonterminal
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Nonterminal) return false
return value != other.value
return value == other.value
}

val hashCode: Int = value.hashCode()
Expand Down
41 changes: 41 additions & 0 deletions src/test/kotlin/rsm/api/TerminalsEqualsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package rsm.api

import org.junit.jupiter.api.Test
import org.srcgll.grammar.combinator.GlobalState
import org.srcgll.grammar.combinator.Grammar
import org.srcgll.grammar.combinator.regexp.NT
import org.srcgll.grammar.combinator.regexp.Term
import org.srcgll.grammar.combinator.regexp.or
import org.srcgll.grammar.combinator.regexp.times
import kotlin.test.assertTrue

class TerminalsEqualsTest {
class AStarTerms : Grammar() {
var S by NT()
val A = Term("a")

init {
setStart(S)
S = Term("a") or Term("a") * S or S * S
}
}

class AStar : Grammar() {
var S by NT()
val A = Term("a")

init {
setStart(S)
S = A or A * S or S * S
}
}

@Test
fun testRsm() {
GlobalState.resetCounter()
val expected = AStar().buildRsm()
GlobalState.resetCounter()
val actual = AStarTerms().buildRsm()
assertTrue { expected.rsmEquals(actual) }
}
}
47 changes: 47 additions & 0 deletions src/test/kotlin/rsm/builder/AStarTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package rsm.builder

import org.junit.jupiter.api.Test
import org.srcgll.grammar.combinator.GlobalState
import org.srcgll.grammar.combinator.Grammar
import org.srcgll.grammar.combinator.regexp.NT
import org.srcgll.grammar.combinator.regexp.Term
import org.srcgll.grammar.combinator.regexp.or
import org.srcgll.grammar.combinator.regexp.times
import org.srcgll.rsm.RSMNonterminalEdge
import org.srcgll.rsm.RSMState
import org.srcgll.rsm.RSMTerminalEdge
import org.srcgll.rsm.symbol.Nonterminal
import org.srcgll.rsm.symbol.Terminal
import kotlin.test.assertTrue

class AStarTest {
class AStar : Grammar() {
var S by NT()
val A = Term("a")

init {
setStart(S)
S = A or A * S or S * S
}
}

@Test
fun testRsm() {
val s = Nonterminal("S")
val a = Terminal("a")
val st0 = RSMState(0, s, isStart = true)
s.startState = st0
val st1 = RSMState(1, s, isFinal = true)
val st2 = RSMState(2, s)
val st3 = RSMState(3, s, isFinal = true)
st0.addTerminalEdge(RSMTerminalEdge(a, st1))
st1.addNonterminalEdge(RSMNonterminalEdge(s, st3))
st0.addNonterminalEdge(RSMNonterminalEdge(s, st2))
st2.addNonterminalEdge(RSMNonterminalEdge(s, st3))

GlobalState.resetCounter()
val actual = AStar().buildRsm()

assertTrue { st0.rsmEquals(actual) }
}
}

0 comments on commit 2b1e9ee

Please sign in to comment.