Skip to content

Commit 453dd29

Browse files
committed
Incapsulated distance calculation in SPPF
1 parent 818bcaa commit 453dd29

File tree

3 files changed

+80
-75
lines changed

3 files changed

+80
-75
lines changed

src/main/kotlin/org/srcgll/Example.kt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@ class Stack : Grammar() {
3636
init {
3737
// Production rules. 'or' is Alternative, '*' is Concatenation
3838
S = Many(
39-
Term("<-()") * Term("->()") or Term("<-.") * Term("->.") or Term("use_a") * Term("def_a") or Term("use_A") * Term(
40-
"def_A"
41-
) or Term("use_B") * Term("def_B") or Term("use_x") * Term("def_x") or Term("<-()") * S * Term("->()") or Term(
42-
"<-."
43-
) * S * Term("->.") or Term("use_a") * S * Term("def_a") or Term("use_A") * S * Term("def_A") or Term("use_B") * S * Term(
44-
"def_B"
45-
) or Term("use_b") * S * Term("def_b") or Term("use_x") * S * Term("def_x")
39+
Term("<-()") * Term("->()") or
40+
Term("<-.") * Term("->.") or
41+
Term("use_a") * Term("def_a") or
42+
Term("use_A") * Term("def_A") or
43+
Term("use_B") * Term("def_B") or
44+
Term("use_x") * Term("def_x") or
45+
Term("<-()") * S * Term("->()") or
46+
Term("<-.") * S * Term("->.") or
47+
Term("use_a") * S * Term("def_a") or
48+
Term("use_A") * S * Term("def_A") or
49+
Term("use_B") * S * Term("def_B") or
50+
Term("use_b") * S * Term("def_b") or
51+
Term("use_x") * S * Term("def_x")
4652
)
4753

4854
// Set Starting Nonterminal
@@ -53,10 +59,9 @@ class Stack : Grammar() {
5359
/**
5460
* Realisation of ILabel interface which represents label on Input Graph edges
5561
*/
56-
class SimpleInputLabel
57-
(
62+
class SimpleInputLabel(
5863
label: String?,
59-
) : ILabel {
64+
): ILabel {
6065
// null terminal represents epsilon edge in Graph
6166
override val terminal: Terminal<String>? = when (label) {
6267
null -> null
@@ -76,7 +81,7 @@ class SimpleInputLabel
7681
* @param VertexType = Int
7782
* @param LabelType = SimpleInputLabel
7883
*/
79-
class SimpleGraph : IGraph<Int, SimpleInputLabel> {
84+
class SimpleGraph: IGraph<Int, SimpleInputLabel> {
8085
override val vertices: MutableMap<Int, Int> = HashMap()
8186
override val edges: MutableMap<Int, MutableList<Edge<Int, SimpleInputLabel>>> = HashMap()
8287

src/main/kotlin/org/srcgll/GLL.kt

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class GLL<VertexType, LabelType : ILabel>(
2626
private val createdGSSNodes: HashMap<GSSNode<VertexType>, GSSNode<VertexType>> = HashMap()
2727
private var parseResult: SPPFNode<VertexType>? = null
2828
private val reachabilityPairs: HashMap<Pair<VertexType, VertexType>, Int> = HashMap()
29-
private val minDistanceRecognisedBySymbol: HashMap<SymbolSPPFNode<VertexType>, Int> = HashMap()
3029

3130
fun parse(): Pair<SPPFNode<VertexType>?, HashMap<Pair<VertexType, VertexType>, Int>> {
3231
for (startVertex in input.getInputStartVertices()) {
@@ -84,68 +83,6 @@ class GLL<VertexType, LabelType : ILabel>(
8483
return Pair(parseResult, reachabilityPairs)
8584
}
8685

87-
private fun minDistance(root: ISPPFNode): Int {
88-
val cycle = HashSet<ISPPFNode>()
89-
val visited = HashSet<ISPPFNode>()
90-
val stack = ArrayDeque(listOf(root))
91-
var curSPPFNode: ISPPFNode
92-
var minDistance = 0
93-
94-
while (stack.isNotEmpty()) {
95-
curSPPFNode = stack.last()
96-
visited.add(curSPPFNode)
97-
98-
if (!cycle.contains(curSPPFNode)) {
99-
cycle.add(curSPPFNode)
100-
101-
when (curSPPFNode) {
102-
is TerminalSPPFNode<*> -> {
103-
minDistance++
104-
}
105-
106-
is PackedSPPFNode<*> -> {
107-
if (curSPPFNode.rightSPPFNode != null) stack.add(curSPPFNode.rightSPPFNode!!)
108-
if (curSPPFNode.leftSPPFNode != null) stack.add(curSPPFNode.leftSPPFNode!!)
109-
}
110-
111-
is ItemSPPFNode<*> -> {
112-
if (curSPPFNode.kids.isNotEmpty()) {
113-
curSPPFNode.kids.findLast {
114-
it.rightSPPFNode != curSPPFNode && it.leftSPPFNode != curSPPFNode && !visited.contains(
115-
it
116-
)
117-
}?.let { stack.add(it) }
118-
curSPPFNode.kids.forEach { visited.add(it) }
119-
}
120-
}
121-
122-
is SymbolSPPFNode<*> -> {
123-
if (minDistanceRecognisedBySymbol.containsKey(curSPPFNode)) {
124-
minDistance += minDistanceRecognisedBySymbol[curSPPFNode]!!
125-
} else {
126-
if (curSPPFNode.kids.isNotEmpty()) {
127-
curSPPFNode.kids.findLast {
128-
it.rightSPPFNode != curSPPFNode && it.leftSPPFNode != curSPPFNode && !visited.contains(
129-
it
130-
)
131-
}?.let { stack.add(it) }
132-
curSPPFNode.kids.forEach { visited.add(it) }
133-
}
134-
}
135-
}
136-
}
137-
}
138-
if (curSPPFNode == stack.last()) {
139-
stack.removeLast()
140-
cycle.remove(curSPPFNode)
141-
}
142-
}
143-
144-
minDistanceRecognisedBySymbol[root as SymbolSPPFNode<VertexType>] = minDistance
145-
146-
return minDistance
147-
}
148-
14986
private fun parse(curDescriptor: Descriptor<VertexType>) {
15087
val state = curDescriptor.rsmState
15188
val pos = curDescriptor.inputPosition
@@ -175,7 +112,7 @@ class GLL<VertexType, LabelType : ILabel>(
175112
}
176113

177114
val pair = Pair(leftExtent, rightExtent)
178-
val distance = minDistance(curSPPFNode)
115+
val distance = sppf.minDistance(curSPPFNode)
179116

180117
if (reachabilityPairs.containsKey(pair)) {
181118
reachabilityPairs[pair] = minOf(distance, reachabilityPairs[pair]!!)

src/main/kotlin/org/srcgll/sppf/SPPF.kt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,69 @@ import org.srcgll.sppf.node.*
88
class SPPF<VertexType> {
99
private val createdSPPFNodes: HashMap<SPPFNode<VertexType>, SPPFNode<VertexType>> = HashMap()
1010
private val createdTerminalNodes: HashMap<VertexType, HashSet<TerminalSPPFNode<VertexType>>> = HashMap()
11+
private val minDistanceRecognisedBySymbol: HashMap<SymbolSPPFNode<VertexType>, Int> = HashMap()
12+
13+
fun minDistance(root: ISPPFNode): Int {
14+
val cycle = HashSet<ISPPFNode>()
15+
val visited = HashSet<ISPPFNode>()
16+
val stack = ArrayDeque(listOf(root))
17+
var curSPPFNode: ISPPFNode
18+
var minDistance = 0
19+
20+
while (stack.isNotEmpty()) {
21+
curSPPFNode = stack.last()
22+
visited.add(curSPPFNode)
23+
24+
if (!cycle.contains(curSPPFNode)) {
25+
cycle.add(curSPPFNode)
26+
27+
when (curSPPFNode) {
28+
is TerminalSPPFNode<*> -> {
29+
minDistance++
30+
}
31+
32+
is PackedSPPFNode<*> -> {
33+
if (curSPPFNode.rightSPPFNode != null) stack.add(curSPPFNode.rightSPPFNode!!)
34+
if (curSPPFNode.leftSPPFNode != null) stack.add(curSPPFNode.leftSPPFNode!!)
35+
}
36+
37+
is ItemSPPFNode<*> -> {
38+
if (curSPPFNode.kids.isNotEmpty()) {
39+
curSPPFNode.kids.findLast {
40+
it.rightSPPFNode != curSPPFNode && it.leftSPPFNode != curSPPFNode && !visited.contains(
41+
it
42+
)
43+
}?.let { stack.add(it) }
44+
curSPPFNode.kids.forEach { visited.add(it) }
45+
}
46+
}
47+
48+
is SymbolSPPFNode<*> -> {
49+
if (minDistanceRecognisedBySymbol.containsKey(curSPPFNode)) {
50+
minDistance += minDistanceRecognisedBySymbol[curSPPFNode]!!
51+
} else {
52+
if (curSPPFNode.kids.isNotEmpty()) {
53+
curSPPFNode.kids.findLast {
54+
it.rightSPPFNode != curSPPFNode && it.leftSPPFNode != curSPPFNode && !visited.contains(
55+
it
56+
)
57+
}?.let { stack.add(it) }
58+
curSPPFNode.kids.forEach { visited.add(it) }
59+
}
60+
}
61+
}
62+
}
63+
}
64+
if (curSPPFNode == stack.last()) {
65+
stack.removeLast()
66+
cycle.remove(curSPPFNode)
67+
}
68+
}
69+
70+
minDistanceRecognisedBySymbol[root as SymbolSPPFNode<VertexType>] = minDistance
71+
72+
return minDistance
73+
}
1174

1275
fun removeNode(sppfNode: SPPFNode<VertexType>) {
1376
createdSPPFNodes.remove(sppfNode)

0 commit comments

Comments
 (0)