Skip to content

Commit 7316694

Browse files
committed
Refactor GLL algorithm
1 parent 6b0462a commit 7316694

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+524
-2577
lines changed

benchmarks/src/main/kotlin/org/ucfs/Java8ParserRecovery.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
package org.ucfs
44

5-
import org.ucfs.JavaToken
65
import org.ucfs.descriptors.Descriptor
76
import org.ucfs.input.IInputGraph
87
import org.ucfs.input.ILabel
@@ -8649,8 +8648,8 @@ public class Java8ParserRecovery<VertexType, LabelType : ILabel> :
86498648
}
86508649
}
86518650

8652-
override fun parse(descriptor: Descriptor<VertexType>) {
8653-
super.parse(descriptor)
8651+
override fun handleDescriptor(descriptor: Descriptor<VertexType>) {
8652+
super.handleDescriptor(descriptor)
86548653
org.ucfs.intersection.RecoveryIntersection.handleRecoveryEdges(this, descriptor)
86558654
}
86568655

generator/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ repositories {
99
dependencies {
1010
implementation(project(":solver"))
1111
implementation("com.squareup:kotlinpoet:1.16.0")
12+
testImplementation(kotlin("test"))
1213
}
1314

1415
tasks.test {
Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +0,0 @@
1-
package org.ucfs.ast
2-
3-
import org.ucfs.GeneratorException
4-
import org.ucfs.rsm.symbol.Nonterminal
5-
import org.ucfs.sppf.node.*
6-
7-
class AstExtractor(val pkg: String) {
8-
val nonterminalToClass = HashMap<Nonterminal, Class<*>>()
9-
10-
/**
11-
* need to handle "many" in rules (many can make cycles in sppf)
12-
*/
13-
val used = HashSet<PackedSppfNode<*>>()
14-
fun extract(sppf: ISppfNode?): Node {
15-
val root = Node(null, 0)
16-
extract(sppf, root, null)
17-
return root.children.firstOrNull() ?: root
18-
}
19-
20-
private fun getOffset(left: Node?, parent: Node): Int {
21-
return if (left == null) {
22-
parent.offset
23-
} else {
24-
left.offset + left.length
25-
}
26-
}
27-
28-
/**
29-
* return rightest node of subtree
30-
*/
31-
private fun extract(sppf: ISppfNode?, parent: Node, left: Node?): Node? {
32-
when (sppf) {
33-
is PackedSppfNode<*> -> {
34-
val newLeft = extract(sppf.leftSppfNode, parent, left)
35-
return extract(sppf.rightSppfNode, parent, newLeft)
36-
}
37-
38-
is IntermediateSppfNode<*> -> {
39-
return extract(sppf.children.firstOrNull(), parent, left)
40-
}
41-
42-
is SymbolSppfNode<*> -> {
43-
val nodeClass = getNodeClass(sppf.symbol)
44-
val ctor = nodeClass.getConstructor(Node::class.java, Int::class.java)
45-
46-
val node: Node = ctor.newInstance(parent, getOffset(left, parent)) as Node
47-
node.isRecovered = sppf.weight > 0
48-
node.left = left
49-
parent.children.add(node)
50-
51-
val packedNode: PackedSppfNode<*> = sppf.children.first { pn -> !used.contains(pn) }
52-
used.add(packedNode)
53-
54-
extract(packedNode, node, null)
55-
parent.length += node.length
56-
return node
57-
}
58-
59-
is TerminalSppfNode<*> -> {
60-
val node = TerminalNode(parent, getOffset(left, parent), sppf.terminal, left)
61-
node.isRecovered = sppf.weight > 0
62-
parent.children.add(node)
63-
parent.length += sppf.terminal.toString().length
64-
return node
65-
}
66-
67-
null -> return null
68-
else -> throw GeneratorException("Unknown sppf node type : $sppf")
69-
}
70-
}
71-
72-
private fun getNodeClass(nt: Nonterminal): Class<*> {
73-
return nonterminalToClass.getOrPut(nt)
74-
{ Class.forName("$pkg.${NodeClassesGenerator.getClassName(nt)}") }
75-
}
76-
}
Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +0,0 @@
1-
package org.ucfs.examples
2-
3-
import org.ucfs.ast.AstExtractor
4-
import org.ucfs.ast.DotWriter
5-
import org.ucfs.ast.NodeClassesGenerator
6-
import org.ucfs.examples.dyck.DyckGrammar
7-
import org.ucfs.examples.golang.SimpleGolang
8-
import org.ucfs.grammar.combinator.Grammar
9-
import org.ucfs.input.LinearInput
10-
import org.ucfs.parser.Gll
11-
import org.ucfs.rsm.writeRsmToDot
12-
import org.ucfs.sppf.writeSppfToDot
13-
import java.nio.file.Path
14-
15-
16-
object Examples {
17-
fun generateAst(grammar: Grammar, pkg: String, input: String, name: String) {
18-
val grammarClass = grammar::class.java
19-
NodeClassesGenerator(grammarClass).generate(Path.of("generator", "src", "main", "kotlin"), pkg)
20-
val gll = Gll.gll(grammar.rsm, LinearInput.buildFromString(input))
21-
val sppf = gll.parse().first
22-
writeSppfToDot(sppf!!, Path.of("${name}.dot").toString(), "${grammarClass.simpleName} SPPF for $input")
23-
val ast = AstExtractor(pkg).extract(sppf)
24-
val label = "${grammarClass.simpleName} AST for $input"
25-
DotWriter().writeToFile(
26-
ast,
27-
name,
28-
label,
29-
false
30-
)
31-
DotWriter().writeToFile(
32-
ast,
33-
"$name with siblings",
34-
label,
35-
true
36-
)
37-
38-
}
39-
}
40-
41-
42-
fun main() {
43-
writeRsmToDot(DyckGrammar().rsm, "rsm.dot")
44-
Examples.generateAst(SimpleGolang(), "org.ucfs.examples.golang", "r 1 + 1 ;", "simple golang")
45-
Examples.generateAst(SimpleGolang(), "org.ucfs.examples.golang", "r 1 + 1 ; 1 ; r 1 ;", "simple golang")
46-
Examples.generateAst(DyckGrammar(), "org.ucfs.examples.dyck", "[ ( ) ] ", "1_dyck")
47-
Examples.generateAst(DyckGrammar(), "org.ucfs.examples.dyck", "[ ( ) ] { }", "2_dyck")
48-
Examples.generateAst(DyckGrammar(), "org.ucfs.examples.dyck", "[ ] { } [ ( ) ]", "3_dyck")
49-
Examples.generateAst(DyckGrammar(), "org.ucfs.examples.dyck", " [ { } ( ) ] ", "3_dyck")
50-
Examples.generateAst(DyckGrammar(), "org.ucfs.examples.dyck", "[ ] { { } ( ) } [ ( ) ]", "3_dyck")
51-
}

0 commit comments

Comments
 (0)