Skip to content

Commit

Permalink
refactor: Use object for StringParser
Browse files Browse the repository at this point in the history
  • Loading branch information
kennarddh committed Mar 19, 2024
1 parent 4172fc4 commit b430da1
Showing 1 changed file with 55 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,71 @@ open class StringParserToken
data object SkipToken : StringParserToken()
data class StringToken(val value: String) : StringParserToken()

class StringParser {
companion object {
private val escapedCharactersMap = mapOf('n' to "\n", '\"' to "\"", '\\' to "\\", '*' to "*")

fun parse(input: String): Iterator<StringParserToken> =
iterator {
var isEscaping = false
var isInQuote = false

val output = buildString {
for (char in input) {
if (isEscaping) {
if (escapedCharactersMap.contains(char)) {
append(escapedCharactersMap[char])

isEscaping = false

continue
} else {
throw InvalidEscapedCharacterException("$char is not a valid character to be escaped")
}
}
object StringParser {
private val escapedCharactersMap = mapOf('n' to "\n", '\"' to "\"", '\\' to "\\", '*' to "*")

fun parse(input: String): Iterator<StringParserToken> =
iterator {
var isEscaping = false
var isInQuote = false

val output = buildString {
for (char in input) {
if (isEscaping) {
if (escapedCharactersMap.contains(char)) {
append(escapedCharactersMap[char])

isEscaping = false

when (char) {
'\\' -> isEscaping = true
'"' -> isInQuote = !isInQuote
'*' -> {
if (!isInQuote && isEmpty())
yield(SkipToken)
else
append(char)
}

' ' -> {
if (!isInQuote) {
if (isNotEmpty()) {
yield(StringToken(toString()))
clear()
}
} else
append(char)
}

else -> append(char)
continue
} else {
throw InvalidEscapedCharacterException("$char is not a valid character to be escaped")
}
}
}

if (isEscaping) {
throw InvalidEscapedCharacterException("No character provided after escape character")
} else if (isInQuote) {
throw UnterminatedStringException("Double quoted string $output is not terminated")
} else if (output.isNotBlank()) {
yield(StringToken(output.toString()))
when (char) {
'\\' -> isEscaping = true
'"' -> isInQuote = !isInQuote
'*' -> {
if (!isInQuote && isEmpty())
yield(SkipToken)
else
append(char)
}

' ' -> {
if (!isInQuote) {
if (isNotEmpty()) {
yield(StringToken(toString()))
clear()
}
} else
append(char)
}

else -> append(char)
}
}
}

fun parseToArray(input: String): Array<StringParserToken> {
val parsed = parse(input)
if (isEscaping) {
throw InvalidEscapedCharacterException("No character provided after escape character")
} else if (isInQuote) {
throw UnterminatedStringException("Double quoted string $output is not terminated")
} else if (output.isNotBlank()) {
yield(StringToken(output.toString()))
}
}

val output: MutableList<StringParserToken> = mutableListOf()
fun parseToArray(input: String): Array<StringParserToken> {
val parsed = parse(input)

parsed.forEach {
output.add(it)
}
val output: MutableList<StringParserToken> = mutableListOf()

return output.toTypedArray()
parsed.forEach {
output.add(it)
}

return output.toTypedArray()
}
}

0 comments on commit b430da1

Please sign in to comment.