Add remove left recusive

This commit is contained in:
Kagura 2024-06-19 21:03:45 +08:00
parent ab2f19e027
commit 3ee6675e72

View file

@ -13,25 +13,40 @@ class AnalyzeTable {
constructor() : this( constructor() : this(
""" """
E ::= TE' E->E+T|T
E' -> +TE'|ε T->T*F|F
T -> FT' F->(E)|i
T' ::= *FT'|ε
F -> (E)|i
""".trimIndent() """.trimIndent()
) )
constructor(lang: String, _s: String? = null) { constructor(lang: String, _s: String? = null) {
start = _s ?: lang.trim()[0].toString() start = _s ?: lang.trim()[0].toString()
val lang = if ("::=" in lang) { // 换成一个符号方便 val newLang = if ("::=" in lang) { // 换成一个符号方便
lang.replace("::=", "->") lang.replace("::=", "->")
} else { } else {
lang lang
} }
// 检查并消除左递归
var noLeftRecLang = ""
for (line in newLang.split("\n")) {
val l = line.split("->")[0]
val r = line.split("->")[1]
if (r.startsWith(l)){
val rec = r.split("|", limit = 2)[0].substring(l.length)
val rest = r.split("|", limit = 2)[1]
noLeftRecLang += "$l->$rest$l'\n" +
"$l'->$rec$l'|$NULL\n"
}else{
noLeftRecLang += line
}
}
// 先拆分 // 先拆分
lang.split("\n").forEach { s -> noLeftRecLang.split("\n").forEach { s ->
val vn = s.split("->")[0].trim() val vn = s.split("->")[0].trim()
if (vn.isNotEmpty() && !V_n.contains(vn)) { if (vn.isNotEmpty() && !V_n.contains(vn)) {
V_n.add(vn) V_n.add(vn)