Skip to content

Commit 2b1e9ee

Browse files
bachishgsvgit
authored andcommitted
Fix Term equals
1 parent c520b75 commit 2b1e9ee

File tree

6 files changed

+131
-29
lines changed

6 files changed

+131
-29
lines changed

src/main/kotlin/org/srcgll/grammar/combinator/Grammar.kt

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ object GlobalState
88
{
99
private var value = 0
1010
fun getNextInt() : Int = value++
11+
fun resetCounter() {
12+
value = 0
13+
}
1114
}
1215

1316
open class Grammar

src/main/kotlin/org/srcgll/grammar/combinator/regexp/Term.kt

+12-7
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@ package org.srcgll.grammar.combinator.regexp
22

33
import org.srcgll.rsm.symbol.Terminal
44

5-
open class Term <TerminalType>
6-
(
7-
value : TerminalType,
8-
)
9-
: DerivedSymbol
10-
{
11-
val terminal : Terminal<TerminalType> = Terminal(value)
5+
open class Term<TerminalType>
6+
(
7+
value: TerminalType,
8+
) : DerivedSymbol {
9+
val terminal: Terminal<TerminalType> = Terminal(value)
10+
11+
override fun equals(other: Any?): Boolean {
12+
if (other !is Term<*>) return false
13+
return terminal == other.terminal
14+
}
15+
16+
override fun hashCode(): Int = terminal.hashCode()
1217
}

src/main/kotlin/org/srcgll/rsm/RSMState.kt

+27-21
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,37 @@ import org.srcgll.rsm.symbol.Nonterminal
44
import org.srcgll.rsm.symbol.Terminal
55

66
class RSMState
7-
(
8-
val id : Int,
9-
val nonterminal : Nonterminal,
10-
val isStart : Boolean = false,
11-
val isFinal : Boolean = false,
12-
)
13-
{
14-
val outgoingTerminalEdges : HashMap<Terminal<*>, HashSet<RSMState>> = HashMap()
15-
val outgoingNonterminalEdges : HashMap<Nonterminal, HashSet<RSMState>> = HashMap()
16-
val coveredTargetStates : HashSet<RSMState> = HashSet()
17-
val errorRecoveryLabels : HashSet<Terminal<*>> = HashSet()
7+
(
8+
val id: Int,
9+
val nonterminal: Nonterminal,
10+
val isStart: Boolean = false,
11+
val isFinal: Boolean = false,
12+
) {
13+
val outgoingTerminalEdges: HashMap<Terminal<*>, HashSet<RSMState>> = HashMap()
14+
val outgoingNonterminalEdges: HashMap<Nonterminal, HashSet<RSMState>> = HashMap()
15+
val coveredTargetStates: HashSet<RSMState> = HashSet()
16+
val errorRecoveryLabels: HashSet<Terminal<*>> = HashSet()
1817

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

22-
override fun equals(other : Any?) : Boolean
23-
{
24-
if (this === other) return true
21+
override fun equals(other: Any?): Boolean {
22+
if (this === other) return true
2523
if (other !is RSMState) return false
26-
if (id != other.id) return false
24+
if (id != other.id) return false
2725

2826
return true
2927
}
3028

31-
val hashCode : Int = id
29+
val hashCode: Int = id
3230
override fun hashCode() = hashCode
3331

34-
fun addTerminalEdge(edge : RSMTerminalEdge)
35-
{
32+
fun addTerminalEdge(edge: RSMTerminalEdge) {
3633
if (!coveredTargetStates.contains(edge.head)) {
3734
errorRecoveryLabels.add(edge.terminal)
3835
coveredTargetStates.add(edge.head)
3936
}
40-
37+
4138
if (outgoingTerminalEdges.containsKey(edge.terminal)) {
4239
val targetStates = outgoingTerminalEdges.getValue(edge.terminal)
4340

@@ -47,8 +44,7 @@ class RSMState
4744
}
4845
}
4946

50-
fun addNonterminalEdge(edge : RSMNonterminalEdge)
51-
{
47+
fun addNonterminalEdge(edge: RSMNonterminalEdge) {
5248
if (outgoingNonterminalEdges.containsKey(edge.nonterminal)) {
5349
val targetStates = outgoingNonterminalEdges.getValue(edge.nonterminal)
5450

@@ -57,4 +53,14 @@ class RSMState
5753
outgoingNonterminalEdges[edge.nonterminal] = hashSetOf(edge.head)
5854
}
5955
}
56+
57+
fun rsmEquals(other: RSMState): Boolean {
58+
if (this != other) {
59+
return false
60+
}
61+
if (outgoingTerminalEdges != other.outgoingTerminalEdges) {
62+
return false
63+
}
64+
return outgoingNonterminalEdges == other.outgoingNonterminalEdges
65+
}
6066
}

src/main/kotlin/org/srcgll/rsm/symbol/Nonterminal.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Nonterminal
1212
override fun equals(other: Any?): Boolean {
1313
if (this === other) return true
1414
if (other !is Nonterminal) return false
15-
return value != other.value
15+
return value == other.value
1616
}
1717

1818
val hashCode: Int = value.hashCode()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package rsm.api
2+
3+
import org.junit.jupiter.api.Test
4+
import org.srcgll.grammar.combinator.GlobalState
5+
import org.srcgll.grammar.combinator.Grammar
6+
import org.srcgll.grammar.combinator.regexp.NT
7+
import org.srcgll.grammar.combinator.regexp.Term
8+
import org.srcgll.grammar.combinator.regexp.or
9+
import org.srcgll.grammar.combinator.regexp.times
10+
import kotlin.test.assertTrue
11+
12+
class TerminalsEqualsTest {
13+
class AStarTerms : Grammar() {
14+
var S by NT()
15+
val A = Term("a")
16+
17+
init {
18+
setStart(S)
19+
S = Term("a") or Term("a") * S or S * S
20+
}
21+
}
22+
23+
class AStar : Grammar() {
24+
var S by NT()
25+
val A = Term("a")
26+
27+
init {
28+
setStart(S)
29+
S = A or A * S or S * S
30+
}
31+
}
32+
33+
@Test
34+
fun testRsm() {
35+
GlobalState.resetCounter()
36+
val expected = AStar().buildRsm()
37+
GlobalState.resetCounter()
38+
val actual = AStarTerms().buildRsm()
39+
assertTrue { expected.rsmEquals(actual) }
40+
}
41+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package rsm.builder
2+
3+
import org.junit.jupiter.api.Test
4+
import org.srcgll.grammar.combinator.GlobalState
5+
import org.srcgll.grammar.combinator.Grammar
6+
import org.srcgll.grammar.combinator.regexp.NT
7+
import org.srcgll.grammar.combinator.regexp.Term
8+
import org.srcgll.grammar.combinator.regexp.or
9+
import org.srcgll.grammar.combinator.regexp.times
10+
import org.srcgll.rsm.RSMNonterminalEdge
11+
import org.srcgll.rsm.RSMState
12+
import org.srcgll.rsm.RSMTerminalEdge
13+
import org.srcgll.rsm.symbol.Nonterminal
14+
import org.srcgll.rsm.symbol.Terminal
15+
import kotlin.test.assertTrue
16+
17+
class AStarTest {
18+
class AStar : Grammar() {
19+
var S by NT()
20+
val A = Term("a")
21+
22+
init {
23+
setStart(S)
24+
S = A or A * S or S * S
25+
}
26+
}
27+
28+
@Test
29+
fun testRsm() {
30+
val s = Nonterminal("S")
31+
val a = Terminal("a")
32+
val st0 = RSMState(0, s, isStart = true)
33+
s.startState = st0
34+
val st1 = RSMState(1, s, isFinal = true)
35+
val st2 = RSMState(2, s)
36+
val st3 = RSMState(3, s, isFinal = true)
37+
st0.addTerminalEdge(RSMTerminalEdge(a, st1))
38+
st1.addNonterminalEdge(RSMNonterminalEdge(s, st3))
39+
st0.addNonterminalEdge(RSMNonterminalEdge(s, st2))
40+
st2.addNonterminalEdge(RSMNonterminalEdge(s, st3))
41+
42+
GlobalState.resetCounter()
43+
val actual = AStar().buildRsm()
44+
45+
assertTrue { st0.rsmEquals(actual) }
46+
}
47+
}

0 commit comments

Comments
 (0)