Skip to content

Commit a8072a9

Browse files
committed
Demo for Stack Language. Added support for epsilon edges in Input Graph
1 parent e19a767 commit a8072a9

File tree

5 files changed

+142
-15
lines changed

5 files changed

+142
-15
lines changed

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

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package org.srcgll
33
import org.srcgll.grammar.combinator.Grammar
44
import org.srcgll.grammar.combinator.regexp.*
55
import org.srcgll.grammar.symbol.Terminal
6+
import org.srcgll.grammar.writeRSMToDOT
67
import org.srcgll.input.Edge
78
import org.srcgll.input.ILabel
89
import org.srcgll.input.IGraph
910
import org.srcgll.sppf.node.SPPFNode
1011

1112
/**
1213
* Define Class for a^n b^n Language CF-Grammar
13-
* @param TerminalType = String
1414
*/
1515
class AnBn : Grammar()
1616
{
@@ -26,17 +26,51 @@ class AnBn : Grammar()
2626
}
2727
}
2828

29+
/**
30+
* Define Class for Stack Language CF-Grammar
31+
*/
32+
class Stack : Grammar()
33+
{
34+
// Nonterminals
35+
var S by NT()
36+
37+
init {
38+
// Production rules. 'or' is Alternative, '*' is Concatenation
39+
S = 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") or
52+
S * S
53+
54+
// Set Starting Nonterminal
55+
setStart(S)
56+
}
57+
}
58+
2959
/**
3060
* Realisation of ILabel interface which represents label on Input Graph edges
31-
* @param TerminalType = String
3261
*/
3362
class SimpleInputLabel
3463
(
35-
label : String
64+
label : String?
3665
)
3766
: ILabel
3867
{
39-
override val terminal : Terminal<String> = Terminal(label)
68+
// null terminal represents epsilon edge in Graph
69+
override val terminal : Terminal<String>? =
70+
when (label) {
71+
null -> null
72+
else -> Terminal(label)
73+
}
4074

4175
override fun equals(other : Any?) : Boolean
4276
{
@@ -50,7 +84,6 @@ class SimpleInputLabel
5084
/**
5185
* Simple Realisation of IGraph interface as Directed Graph
5286
* @param VertexType = Int
53-
* @param TerminalType = String
5487
* @param LabelType = SimpleInputLabel
5588
*/
5689
class SimpleGraph : IGraph<Int, SimpleInputLabel>
@@ -106,12 +139,9 @@ class SimpleGraph : IGraph<Int, SimpleInputLabel>
106139
}
107140
}
108141

109-
fun main()
142+
fun createAnBnExampleGraph(startVertex : Int) : SimpleGraph
110143
{
111-
val rsmStartState = AnBn().buildRsm()
112-
val inputGraph = SimpleGraph()
113-
val startVertex = 0
114-
144+
val inputGraph = SimpleGraph()
115145
for (i in 0..3) inputGraph.addVertex(vertex = i)
116146

117147
inputGraph.addEdge(from = 0, to = 1, label = SimpleInputLabel("a"))
@@ -124,11 +154,80 @@ fun main()
124154
// calls to addVertex and addStartVertex
125155
inputGraph.addStartVertex(startVertex)
126156

157+
return inputGraph
158+
}
159+
160+
fun createStackExampleGraph(startVertex : Int) : SimpleGraph
161+
{
162+
val inputGraph = SimpleGraph()
163+
164+
inputGraph.addEdge(from = 0, to = 1, label = SimpleInputLabel("use_x"))
165+
inputGraph.addEdge(from = 1, to = 2, label = SimpleInputLabel("<-."))
166+
inputGraph.addEdge(from = 2, to = 3, label = SimpleInputLabel("<-()"))
167+
inputGraph.addEdge(from = 3, to = 33, label = SimpleInputLabel("use_B"))
168+
inputGraph.addEdge(from = 33, to = 32, label = SimpleInputLabel(null))
169+
inputGraph.addEdge(from = 4, to = 5, label = SimpleInputLabel("use_x"))
170+
inputGraph.addEdge(from = 5, to = 6, label = SimpleInputLabel("<-."))
171+
inputGraph.addEdge(from = 6, to = 32, label = SimpleInputLabel("use_B"))
172+
inputGraph.addEdge(from = 32, to = 31, label = SimpleInputLabel(null))
173+
inputGraph.addEdge(from = 13, to = 33, label = SimpleInputLabel("->."))
174+
inputGraph.addEdge(from = 14, to = 13, label = SimpleInputLabel("def_b"))
175+
inputGraph.addEdge(from = 31, to = 10, label = SimpleInputLabel("def_B"))
176+
inputGraph.addEdge(from = 10, to = 40, label = SimpleInputLabel("->."))
177+
inputGraph.addEdge(from = 10, to = 9, label = SimpleInputLabel("->()"))
178+
inputGraph.addEdge(from = 9, to = 41, label = SimpleInputLabel("->."))
179+
inputGraph.addEdge(from = 41, to = 40, label = SimpleInputLabel(null))
180+
inputGraph.addEdge(from = 41, to = 8, label = SimpleInputLabel("<-."))
181+
inputGraph.addEdge(from = 8, to = 7, label = SimpleInputLabel("<-()"))
182+
inputGraph.addEdge(from = 40, to = 7, label = SimpleInputLabel("<-."))
183+
inputGraph.addEdge(from = 7, to = 30, label = SimpleInputLabel("use_A"))
184+
inputGraph.addEdge(from = 30, to = 11, label = SimpleInputLabel("<-."))
185+
inputGraph.addEdge(from = 31, to = 30, label = SimpleInputLabel(null))
186+
inputGraph.addEdge(from = 11, to = 12, label = SimpleInputLabel("use_a"))
187+
inputGraph.addEdge(from = 12, to = 15, label = SimpleInputLabel(null))
188+
inputGraph.addEdge(from = 15, to = 16, label = SimpleInputLabel("def_a"))
189+
inputGraph.addEdge(from = 16, to = 22, label = SimpleInputLabel("->."))
190+
inputGraph.addEdge(from = 22, to = 17, label = SimpleInputLabel("def_A"))
191+
inputGraph.addEdge(from = 17, to = 18, label = SimpleInputLabel("->()"))
192+
inputGraph.addEdge(from = 17, to = 20, label = SimpleInputLabel("->."))
193+
inputGraph.addEdge(from = 18, to = 21, label = SimpleInputLabel("->."))
194+
inputGraph.addEdge(from = 21, to = 20, label = SimpleInputLabel(null))
195+
inputGraph.addEdge(from = 20, to = 19, label = SimpleInputLabel("def_x"))
196+
197+
for (kvp in inputGraph.edges) {
198+
inputGraph.addVertex(kvp.key)
199+
for (e in kvp.value) {
200+
inputGraph.addVertex(e.head)
201+
}
202+
}
203+
204+
inputGraph.addStartVertex(startVertex)
205+
206+
return inputGraph
207+
}
208+
209+
fun main() {
210+
val rsmAnBnStartState = AnBn().buildRsm()
211+
val rsmStackStartState = Stack().buildRsm()
212+
val startVertex = 0
213+
val inputGraphAnBn = createAnBnExampleGraph(startVertex)
214+
val inputGraphStack = createStackExampleGraph(startVertex)
215+
127216
// result = (root of SPPF, set of reachable vertices)
128-
val result : Pair<SPPFNode<Int>?, HashSet<Int>> = GLL<Int, SimpleInputLabel>(rsmStartState, inputGraph, recovery = RecoveryMode.OFF).parse()
217+
val resultAnBn : Pair<SPPFNode<Int>?, HashSet<Int>> =
218+
GLL(rsmAnBnStartState, inputGraphAnBn, recovery = RecoveryMode.OFF).parse()
219+
val resultStack : Pair<SPPFNode<Int>?, HashSet<Int>> =
220+
GLL(rsmStackStartState, inputGraphStack, recovery = RecoveryMode.OFF).parse()
221+
222+
println("AnBn Language Grammar")
223+
println("Reachable vertices from vertex $startVertex : ")
224+
for (reachable in resultAnBn.second) {
225+
println("Vertex: $reachable")
226+
}
129227

228+
println("\nStack Language Grammar")
130229
println("Reachable vertices from vertex $startVertex : ")
131-
for (reachable in result.second) {
230+
for (reachable in resultStack.second) {
132231
println("Vertex: $reachable")
133232
}
134233
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.srcgll
2+
3+
import org.srcgll.grammar.combinator.Grammar
4+
import org.srcgll.grammar.combinator.regexp.NT
5+
import org.srcgll.grammar.combinator.regexp.Term
6+
import org.srcgll.grammar.combinator.regexp.times

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ class GLL <VertexType, LabelType : ILabel>
9393
}
9494

9595
for (inputEdge in input.getEdges(pos)) {
96+
if (inputEdge.label.terminal == null) {
97+
val descriptor =
98+
Descriptor(
99+
state,
100+
gssNode,
101+
sppf.getNodeP(
102+
state,
103+
curSPPFNode,
104+
sppf.getOrCreateTerminalSPPFNode(
105+
terminal = null,
106+
pos,
107+
inputEdge.head,
108+
weight = 0
109+
)
110+
),
111+
inputEdge.head
112+
)
113+
stack.add(descriptor)
114+
continue
115+
}
96116
for (kvp in state.outgoingTerminalEdges) {
97117
if (inputEdge.label.terminal == kvp.key) {
98118
for (target in kvp.value) {
@@ -141,7 +161,9 @@ class GLL <VertexType, LabelType : ILabel>
141161

142162
if (currentEdges.isNotEmpty()) {
143163
for (currentEdge in currentEdges) {
144-
val currentTerminal = currentEdge.label.terminal
164+
if (currentEdge.label.terminal == null) continue
165+
166+
val currentTerminal = currentEdge.label.terminal!!
145167

146168
val coveredByCurrentTerminal : HashSet<RSMState> =
147169
if (state.outgoingTerminalEdges.containsKey(currentTerminal)) {

src/main/kotlin/org/srcgll/input/ILabel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.srcgll.grammar.symbol.Terminal
44

55
interface ILabel
66
{
7-
val terminal : Terminal<*>
7+
val terminal : Terminal<*>?
88

99
override fun equals(other : Any?) : Boolean
1010
}

src/main/kotlin/org/srcgll/input/LinearInputLabel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class LinearInputLabel
1111
override fun equals(other : Any?) : Boolean
1212
{
1313
if (this === other) return true
14-
if (other !is LinearInputLabel) return false
14+
if (other !is LinearInputLabel) return false
1515
if (this.terminal != other.terminal) return false
1616

1717
return true

0 commit comments

Comments
 (0)