Skip to content

Commit

Permalink
Adding interface for Lushu, implementing context storage structures
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitor-Git15 committed Dec 10, 2023
1 parent 965ce4b commit 1b48752
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 186 deletions.
1 change: 1 addition & 0 deletions Lushu/src/main/kotlin/lushu/ContextGrammar/GeneratorApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fun main(args: Array<String>) {
println(
"options:\nHTML = 0\nC = 1\n"
)

return
}
}
4 changes: 2 additions & 2 deletions Lushu/src/main/kotlin/lushu/ContextGrammar/Grammar/Grammar.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package lushu.ContextGrammar.Grammar

import lushu.ContextGrammar.MapGrammar.MapGrammar
import lushu.ContextGrammar.MapGrammar.Grammar
import java.io.File
import java.io.FileReader

class Grammar(
private val contextAnalyzer: ContextAnalyzer = ContextAnalyzer(),
private val mapGrammar: MapGrammar = MapGrammar()
private val mapGrammar: Grammar = Grammar()
) {
fun consume(words: MutableList<String>): String {
val consumedWords = contextAnalyzer.parsing(words)
Expand Down
8 changes: 4 additions & 4 deletions Lushu/src/main/kotlin/lushu/ContextGrammar/Grammar/Rules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Rules(private val root: GrammarNode = GrammarNode()) {
inputTokens: MutableList<String>,
mutableTokens: MutableList<String>,
index: Int,
current: GrammarNode?
current: GrammarNode?,
): Pair<Int, GrammarNode?> {
when {
// don't match
Expand Down Expand Up @@ -147,7 +147,7 @@ class Rules(private val root: GrammarNode = GrammarNode()) {
inputTokens: MutableList<String>,
mutableTokens: MutableList<String>,
index: Int,
current: GrammarNode?
current: GrammarNode?,
): Int {
when {
current == null -> return noMatchFound
Expand All @@ -172,7 +172,7 @@ class Rules(private val root: GrammarNode = GrammarNode()) {
inputTokens,
mutableTokens,
index,
current
current,
)

if ((nextNode != null) && (nextNode.isSensitive())) {
Expand Down Expand Up @@ -274,7 +274,7 @@ class Rules(private val root: GrammarNode = GrammarNode()) {
dsl.isSensitive(),
dsl.isStar(),
dsl.isNonMergeable(),
endOfContext
endOfContext,
)

dsl.setIsCase(nextCases)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
package lushu.ContextGrammar.MapGrammar

import lushu.Merger.Lattice.Node.MergeableToken
import lushu.Merger.Lattice.Node.*
import lushu.Merger.Lattice.Node.MergerS
import lushu.Merger.Lattice.Node.Node
import lushu.Merger.Lattice.Node.NonMergeableToken
import lushu.Merger.Lattice.Node.Token
import org.slf4j.LoggerFactory
import java.io.File
import java.io.FileReader

class MapGrammar() {
private val logger = LoggerFactory.getLogger(this::class.java)
import lushu.Merger.Merger.Merger

class ContextMap(
val dsl: DSL = DSL(),
val merger: Merger,
) {
data class PivotData(
val openingRef: Token,
val func: String
val func: String,
)

private val dsl: DSL = DSL()
private val merger = MergerS.merger()

// openingMap contains the first tags of contexts. For instance, in '<c>
// BEGIN <*>bla</*> END </c>', BEGIN is an opening token.
private val openingMap: MutableMap<Token, Int> = mutableMapOf()
Expand All @@ -30,48 +23,10 @@ class MapGrammar() {

// pivotMap stores the string we are searching for. For instance, in '<c> BEGIN
// <*>bla</*> END </c>', 'bla' is a pivot token.
private val pivotMap: MutableMap<Token, PivotData> = mutableMapOf()

// TODO: remove once we support customizable actions from the user side
// -aholmquist 2023-11-03
private var maxBlocks: Int = 0

// TODO: remove maxBlocks once we support customizable actions from the user
// side -aholmquist 2023-11-02
fun getMaxBlocks(): Int = maxBlocks

fun consume(file: File) = FileReader(file).use { reader ->
reader.forEachLine {
consume(it)
}
}

fun consume(input: String) = streamString(input)

fun addContext(contextInput: String?) {
if (contextInput.isNullOrBlank()) {
return
}
val contexts = extractContext(contextInput)
contexts.forEach { insertContext(it) }
logger.debug("Maps after adding context:\n$openingMap\n$closingMap\n$pivotMap")
}

private fun streamString(input: String) =
blankRegex.findAll(input).forEach { matchResult -> match(matchResult.value) }

private fun string2list(string: String): List<String> {
val woNewline = string.split(newlineDelim).joinToString(spaceDelim)
return woNewline.split(spaceDelim)
}
private val pivotMap: MutableMap<Token, ContextMap.PivotData> = mutableMapOf()

private fun toToken(word: String): Token {
val isMergeable = dsl.isMergeable(word)
val woTags = dsl.removeAllTags(word)
if (isMergeable) {
return MergeableToken(woTags)
}
return NonMergeableToken(woTags)
private inline fun <reified V> insert(map: MutableMap<Token, V>, key: Token, value: V) {
map[key] = value
}

private inline fun <reified V> inMap(map: MutableMap<Token, V>, token: Token): Token? {
Expand Down Expand Up @@ -102,7 +57,7 @@ class MapGrammar() {
this.openingMap[token] = oldValue + value
}

private fun match(word: String) {
fun match(word: String) {
val wordTokens = merger.tokensFromString(word)

val openingFound = inMap(openingMap, wordTokens)
Expand All @@ -122,58 +77,32 @@ class MapGrammar() {
if (pivot.component1().match(wordTokens)) {
val openingReference = pivot.component2().openingRef
val value = openingMap[openingReference]
if (value != null && value > 1) {
maxBlocks++
if (value != null && value >= 1) {
}
}
}
}

private fun extractContext(input: String): List<String> {
val matcher = contextRegex.findAll(input)
val substrings = matcher.map { it.groupValues[1] }.toList()
return substrings
}

private fun getLambdaFunction(input: String): String {
val regex = Regex(".*<a (\\w+)>.+</a>.*")
val matchResult = regex.find(input)

val res = matchResult?.groups?.get(1)?.value
if (res.isNullOrBlank()) {
return "println"
}
return res
}

private inline fun <reified V> insert(map: MutableMap<Token, V>, key: Token, value: V) {
map[key] = value
}

private inline fun <reified V> insert(map: MutableMap<Token, V>, key: String, value: V) {
insert(map, toToken(key), value)
}

private fun insertPivot(pivots: List<String>, openingToken: Token) {
pivots.forEach { pivot ->
val func = getLambdaFunction(pivot)
val func = dsl.getLambdaFunction(pivot)
insert(pivotMap, pivot, PivotData(openingToken, func))
}
}

private inline fun <reified V> findEquivalent(map: MutableMap<Token, V>, token: Token): Pair<Token, Boolean> {
map.forEach { element ->
if (element.key == token) {
return Pair(element.key, true)
}
}
return Pair(token, false)
private fun string2list(string: String): List<String> {
val woNewline = string.split(Grammar.newlineDelim).joinToString(Grammar.spaceDelim)
return woNewline.split(Grammar.spaceDelim)
}

private fun insertContext(context: String) {
private fun insert(context: String) {
val contextTokens = string2list(context)

if (contextTokens.size < minElems) {
if (contextTokens.size < Grammar.minElems) {
println("Warning: Insufficient number of elements provided.")
return
}
Expand All @@ -182,19 +111,41 @@ class MapGrammar() {
val res = findEquivalent(openingMap, token)
val openingToken = res.first
if (!res.second) {
insert(openingMap, openingToken, noOccurrences)
insert(openingMap, openingToken, Grammar.noOccurrences)
}
insert(closingMap, contextTokens.last(), openingToken)
insertPivot(contextTokens.subList(1, contextTokens.size - 1), openingToken)
}

fun insertContext(context: String) {
val contexts = dsl.extractContext(context)
contexts.forEach { insert(it) }
}

private inline fun <reified V> findEquivalent(map: MutableMap<Token, V>, token: Token): Pair<Token, Boolean> {
map.forEach { element ->
if (element.key == token) {
return Pair(element.key, true)
}
}
return Pair(token, false)
}

private fun toToken(word: String): Token {
val isMergeable = dsl.isMergeable(word)
val woTags = dsl.removeAllTags(word)
if (isMergeable) {
return MergeableToken(woTags)
}
return NonMergeableToken(woTags)
}

companion object {
val minElems = 3
val noOccurrences = 0
val spaceDelim = " "
val newlineDelim = "\n"

val contextRegex = Regex("""<c>(.*?)</c>""")
val blankRegex = Regex("""\S+""")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package lushu.ContextGrammar.MapGrammar

import lushu.ContextGrammar.Grammar.Rules
import lushu.Merger.Lattice.Node.GrammarNode
import lushu.Merger.Merger.Merger

class ContextTree(
val dsl: DSL = DSL(),
val merger: Merger,
) {
private val root: GrammarNode = GrammarNode()

private fun string2list(string: String): List<String> {
val woNewline = string.split(Grammar.newlineDelim).joinToString(Grammar.spaceDelim)
return woNewline.split(Grammar.spaceDelim)
}

private fun insert(context: MutableList<String>, current: GrammarNode? = root) {
if (context.isNullOrEmpty()) {
return
}

val firstWord = 0
val word = context[firstWord]

val func = dsl.getLambdaFunction(word)
val mergeable = dsl.isMergeable(word)
val kleene = dsl.isStarCase(word)

val wordWoTags = dsl.removeAllTags(word)

// true if it's the last word in the context
val endOfContext: Boolean = (context.size == 1)

val updatedCurrent = current?.findOrAddChild(
wordWoTags,
kleene,
mergeable,
func,
endOfContext,
)

context.removeAt(firstWord)

if (nextCases[Rules.starCase]) {
addContextRule(context, current)
} else {
addContextRule(context, updatedCurrent)
}
}

fun insertContext(context: String) {
val contexts = dsl.extractContext(context)
val contextTokens = string2list(context)
insert(contextTokens.toMutableList())
}
}
40 changes: 36 additions & 4 deletions Lushu/src/main/kotlin/lushu/ContextGrammar/MapGrammar/DSL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ enum class Tags(val tagName: String) {
CONTEXT("c"),
LATTICE("l"),
KLEENE("*"),
ACTION("a")
ACTION("a"),
}

class DSL(
val tags: List<String> = Tags.values().map { it.tagName }.map { "<$it>" }
val tags: List<String> = Tags.values().map { it.tagName }.map { "<$it>" },
) {
fun isMergeable(string: String): Boolean {
return string.contains("<l>") || string.contains("</l>")
return string.contains(Tags.LATTICE.tagName) || string.contains(Tags.LATTICE.tagName)
}

fun isStarCase(string: String): Boolean {
return string.contains(Tags.KLEENE.tagName) || string.contains(Tags.KLEENE.tagName)
}

private fun opening2CloserTag(openingTag: String): String {
Expand All @@ -27,7 +31,35 @@ class DSL(
return tags.map { opening2CloserTag(it) }.toList()
}

fun removeActionTag(word: String): String {
val regex = Regex("""<a=[^>]+>|</a>""")
return word.replace(regex, "")
}

fun removeAllTags(word: String): String {
return removeTags(removeTags(word, tags.toList()), openingTags2ClosingTags(tags))
val wordWT = removeTags(removeTags(word, tags.toList()), openingTags2ClosingTags(tags))
return removeActionTag(wordWT)
}

fun extractContext(input: String): List<String> {
val matcher = Grammar.contextRegex.findAll(input)
val substrings = matcher.map { it.groupValues[1] }.toList()
return substrings
}

fun getLambdaFunction(input: String): String {
val matchResult = actionRegex.find(input)

val res = matchResult?.groups?.get(1)?.value
if (res.isNullOrBlank()) {
return withoutAction
}
return res
}

companion object {
val withoutAction = ""
val actionRegex = Regex(".*<a=(\\w+)>.+</a>.*")
val contextRegex = Regex("""<c>(.*?)</c>""")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package lushu.ContextGrammar.MapGrammar

class DefaultFunctions {

private fun print() {
}

private fun count() {
}

private fun save() {
}
}
Loading

0 comments on commit 1b48752

Please sign in to comment.