making Yaml and BFS of QNDTree work

This commit is contained in:
minjaesong
2018-12-09 01:52:57 +09:00
parent 11f7fa5c9a
commit 59c6876849
4 changed files with 153 additions and 27 deletions

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum
import java.util.ArrayList
import java.util.*
import kotlin.collections.ArrayList
class QNDTreeNode<T>(var data: T? = null, var parent: QNDTreeNode<T>? = null) {
var children = ArrayList<QNDTreeNode<T>>()
@@ -18,11 +19,54 @@ class QNDTreeNode<T>(var data: T? = null, var parent: QNDTreeNode<T>? = null) {
action(node, depth)
}
/**
* (QNDTreeNode, Int) is Node-depth pair, starting from zero.
*/
fun traversePreorder(action: (QNDTreeNode<T>, Int) -> Unit) {
this.traverse1(this, action)
}
/**
* (QNDTreeNode, Int) is Node-depth pair, starting from zero.
*/
fun traversePostorder(action: (QNDTreeNode<T>, Int) -> Unit) {
this.traverse2(this, action)
}
/**
* (QNDTreeNode, Int) is Node-depth pair, starting from zero.
*/
fun traverseLevelorder(action: (QNDTreeNode<T>, Int) -> Unit) {
val q = ArrayList<Pair<QNDTreeNode<T>, Int>>() // node, depth
q.add(this to 0)
while (q.isNotEmpty()) {
val node = q.removeAt(0)
action(node.first, node.second)
node.first.children.forEach {
q.add(it to node.second + 1)
}
}
}
/**
* Retrieves data in the node in a specific depth (level).
* Probably only useful for level = 1
*/
fun getLevelData(level: Int): List<T?> {
val list = ArrayList<T?>()
traversePreorder { node, i ->
if (i == level) {
list.add(node.data)
}
}
return list
}
override fun toString() = data.toString()
fun print() {
TODO()
}
}

View File

@@ -44,6 +44,7 @@ import java.util.*
* - All lines are indented with one space
* - All entries are preceded by '- ' (dash and a space)
* - All propery are separated by ' : ' (space colon space)
* - A line that does not start with '- ' are simply ignored, so you can freely make empty lines and/or comments.
*
* Any deviation to the above rule will cause a parse failure, because it's simple and dumb as that.
*
@@ -55,39 +56,41 @@ inline class Yaml(val text: String) {
val SEPARATOR = Regex(" : ")
}
fun parse(): QNDTreeNode<String> {
var currentIndentLevel = -1
val root = QNDTreeNode<String>()
var currentNode = root
val nodesStack = Stack<QNDTreeNode<String>>()
val validLineStartRe = Regex(""" *\- """)
nodesStack.push(currentNode)
text.split('\n') .forEach {
val indentLevel = it.countSpaces()
val it = it.trimIndent()
if (it.startsWith("- ")) {
val nodeName = it.drop(2)
if (validLineStartRe.containsMatchIn(it)) { // take partial match; do the task if the text's line is valid
val indentLevel = it.countSpaces()
val it = it.trimIndent()
if (it.startsWith("- ")) { // just double check if indent-trimmed line looks valid
val nodeName = it.drop(2)
if (indentLevel == currentIndentLevel) {
val sibling = QNDTreeNode(nodeName, currentNode.parent)
currentNode.parent!!.children.add(sibling)
currentNode = sibling
}
else if (indentLevel > currentIndentLevel) {
val childNode = QNDTreeNode(nodeName, currentNode)
currentNode.children.add(childNode)
nodesStack.push(currentNode)
currentNode = childNode
currentIndentLevel = indentLevel
}
else {
repeat(currentIndentLevel - indentLevel) { currentNode = nodesStack.pop() }
currentIndentLevel = indentLevel
val sibling = QNDTreeNode(nodeName, currentNode.parent)
currentNode.parent!!.children.add(sibling)
currentNode = sibling
if (indentLevel == currentIndentLevel) {
val sibling = QNDTreeNode(nodeName, currentNode.parent)
currentNode.parent!!.children.add(sibling)
currentNode = sibling
}
else if (indentLevel > currentIndentLevel) {
val childNode = QNDTreeNode(nodeName, currentNode)
currentNode.children.add(childNode)
nodesStack.push(currentNode)
currentNode = childNode
currentIndentLevel = indentLevel
}
else {
repeat(currentIndentLevel - indentLevel) { currentNode = nodesStack.pop() }
currentIndentLevel = indentLevel
val sibling = QNDTreeNode(nodeName, currentNode.parent)
currentNode.parent!!.children.add(sibling)
currentNode = sibling
}
}
}
}

View File

@@ -0,0 +1,78 @@
package net.torvald.terrarum.tests
import net.torvald.terrarum.Yaml
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
/**
* Created by minjaesong on 2018-12-08.
*/
class QNDTreeTest {
val treeStr = """
- File
- New : Ctrl-N
- Open : Ctrl-O
- Open Recent
- yaml_example.yaml
- Yaml.kt
- Close : Ctrl-W
- Settings
- Line Separators
- CRLF
- CR
- LF
- Edit
- Undo : Ctrl-Z
- Redo : Shift-Ctrl-Z
- Cut : Ctrl-X
- Copy : Ctrl-C
- Paste : Ctrl-V
- Find
- Find : Ctrl-F
- Replace : Shift-Ctrl-F
- Convert Indents
- To Spaces
- Set Project Indentation
- To Tabs
- Refactor
- Refactor This
- Rename : Shift-Ctrl-R
- Extract
- Variable
- Property
- Function
"""
operator fun invoke() {
val treeYaml = Yaml(treeStr)
val tree = treeYaml.parse()
println("\nTest traversePreorder()\n")
tree.traversePreorder { qndTreeNode, i ->
print("-".repeat(i))
print(" ")
println("$qndTreeNode <- ${qndTreeNode.parent}")
}
println("\nTest traversePostOrder()\n")
tree.traversePostorder { qndTreeNode, i ->
print("-".repeat(i))
print(" ")
println("$qndTreeNode <- ${qndTreeNode.parent}")
}
println("\nTest traverseLevelOrder()\n")
tree.traverseLevelorder { qndTreeNode, i ->
print("-".repeat(i))
print(" ")
println("$qndTreeNode <- ${qndTreeNode.parent}")
}
println("\nLevel 1 nodes:\n")
println(tree.getLevelData(1))
}
}
fun main(args: Array<String>) {
QNDTreeTest().invoke()
}

View File

@@ -11,9 +11,10 @@ import net.torvald.terrarum.Yaml
override var posX: Int,
override var posY: Int,
override var width: Int,
val tree: Yaml
val treeRepresentation: Yaml
) : UIItem(parent) {
override val height: Int
get() = TODO("not implemented")
val tree = treeRepresentation.parse()
override val height = -1
}*/