This commit is contained in:
Kagura 2024-06-16 10:17:06 +08:00
parent 74999d06b1
commit 978699086c
2 changed files with 104 additions and 99 deletions

View file

@ -1,11 +1,8 @@
import java.util.*
import kotlin.collections.ArrayDeque
class AnalyzeTable { class AnalyzeTable {
var V_n = mutableListOf<String>() var V_n = mutableListOf<String>()
var V_t = mutableListOf<String>("#") var V_t = mutableListOf<String>("#")
public var table = mutableMapOf<String, Int>() // k = E,i; v = 1 var table = mutableMapOf<String, Int>() // k = E,i; v = 1
var items = mutableListOf<String>() // 文法 var items = mutableListOf<String>() // 文法
var first = mutableMapOf<String, MutableList<String>>() // First(E) var first = mutableMapOf<String, MutableList<String>>() // First(E)
@ -15,7 +12,8 @@ class AnalyzeTable {
val NULL = "ε" val NULL = "ε"
} }
constructor() : this (""" constructor() : this(
"""
E -> TE' E -> TE'
E' -> +TE'|ε E' -> +TE'|ε
T -> FT' T -> FT'
@ -25,13 +23,13 @@ class AnalyzeTable {
"E" "E"
) )
constructor(lang: String,_s: String){ constructor(lang: String, _s: String) {
start = _s start = _s
// 先拆分 // 先拆分
lang.split("\n").forEach{ s -> lang.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)
} }
@ -46,14 +44,14 @@ class AnalyzeTable {
// 然后获取那些是终止符 // 然后获取那些是终止符
items.forEach { item -> items.forEach { item ->
var line = item.split("->")[1] var line = item.split("->")[1]
V_n.sortBy { - it.length } // 先把长的去掉 V_n.sortBy { -it.length } // 先把长的去掉
V_n.forEach { V_n.forEach {
if (line.contains(it)){ if (line.contains(it)) {
line = line.replace(it, ",") line = line.replace(it, ",")
} }
} }
line.split(",").forEach { line.split(",").forEach {
if (it.isNotBlank() && !V_t.contains(it) && it != NULL){ if (it.isNotBlank() && !V_t.contains(it) && it != NULL) {
V_t.add(it) V_t.add(it)
} }
} }
@ -63,24 +61,24 @@ class AnalyzeTable {
getTable() getTable()
} }
fun getTable(){ fun getTable() {
items.forEach {item -> items.forEach { item ->
val vn = item.split("->")[0] val vn = item.split("->")[0]
val right = item.split("->")[1] val right = item.split("->")[1]
val firsts = getFirst(right,vn) val firsts = getFirst(right, vn)
firsts.forEach { firsts.forEach {
if (it!= NULL) { if (it != NULL) {
table["$vn,$it"] = items.indexOf(item) table["$vn,$it"] = items.indexOf(item)
} }
} }
if (NULL in firsts){ if (NULL in firsts) {
val follows = getFollow(vn) val follows = getFollow(vn)
follows.forEach { follows.forEach {
if (it == NULL){ if (it == NULL) {
table["$vn,#"] = items.indexOf(item) table["$vn,#"] = items.indexOf(item)
}else{ } else {
table["$vn,$it"] = items.indexOf(item) table["$vn,$it"] = items.indexOf(item)
} }
} }
@ -88,44 +86,44 @@ class AnalyzeTable {
} }
} }
private fun getFirst(string: String,vn: String) : MutableList<String>{ private fun getFirst(string: String, vn: String): MutableList<String> {
val firsts = mutableListOf<String>() val firsts = mutableListOf<String>()
// 以NULL开头 // 以NULL开头
if (string == NULL){ if (string == NULL) {
firsts.add(NULL) firsts.add(NULL)
return firsts return firsts
} }
// 以终结符开头 // 以终结符开头
V_t.forEach { V_t.forEach {
if (string.startsWith(it)){ if (string.startsWith(it)) {
if (first[vn]!=null){ if (first[vn] != null) {
first[vn]!!.add(it) first[vn]!!.add(it)
}else { } else {
first[vn] = mutableListOf(it) first[vn] = mutableListOf(it)
} }
if (!firsts.contains(it)){ if (!firsts.contains(it)) {
firsts.add(it) firsts.add(it)
} }
} }
} }
if (firsts.size != 0){ if (firsts.size != 0) {
return firsts return firsts
} }
// 以非终结符开头 // 以非终结符开头
val parsedString = splitToVn(string) val parsedString = splitToVn(string)
for (item in parsedString){ // 拆过的按顺序的Vt for (item in parsedString) { // 拆过的按顺序的Vt
if (item in V_t){ if (item in V_t) {
firsts.add(item) firsts.add(item)
break break
}else{ } else {
val newFirst = mutableListOf<String>() val newFirst = mutableListOf<String>()
for (line in items){ for (line in items) {
if (line.split("->")[0] == item){ if (line.split("->")[0] == item) {
val newLine = line.split("->")[1] val newLine = line.split("->")[1]
val nextFirst = getFirst(newLine,item) // 求 item的follow val nextFirst = getFirst(newLine, item) // 求 item的follow
nextFirst.forEach { nextFirst.forEach {
if (it !in newFirst){ if (it !in newFirst) {
newFirst.add(it) newFirst.add(it)
} }
} }
@ -133,12 +131,12 @@ class AnalyzeTable {
} }
// 加入 firsts // 加入 firsts
newFirst.forEach { newFirst.forEach {
if (it !in firsts && it != NULL){ if (it !in firsts && it != NULL) {
firsts.add(it) firsts.add(it)
} }
} }
// 可能为空的话继续 // 可能为空的话继续
if (NULL !in newFirst){ if (NULL !in newFirst) {
return firsts return firsts
} }
} }
@ -147,39 +145,40 @@ class AnalyzeTable {
return firsts return firsts
} }
private fun getFollow(vn: String) : MutableList<String>{ private fun getFollow(vn: String): MutableList<String> {
val follows = mutableListOf<String>() val follows = mutableListOf<String>()
if (vn == start){ if (vn == start) {
follows.add(NULL) // 处理开始符号 follows.add(NULL) // 处理开始符号
} }
items.forEach { item -> items.forEach { item ->
val l = item.split("->")[0] val l = item.split("->")[0]
val r = item.split("->")[1] val r = item.split("->")[1]
if (vn in splitToVn(r,false) && vn != l){ if (vn in splitToVn(r, false) && vn != l) {
when (val split = r.split(vn)[1]){ when (val split = r.split(vn)[1]) {
"" -> { "" -> {
val upFollow = getFollow(l) val upFollow = getFollow(l)
if (upFollow == follows){ if (upFollow == follows) {
return follows return follows
}else { } else {
upFollow.forEach { upFollow.forEach {
if (it !in follows){ if (it !in follows) {
follows.add(it) follows.add(it)
} }
} }
} }
} }
else -> { else -> {
val upFirst = getFirst(split,l) val upFirst = getFirst(split, l)
upFirst.forEach { upFirst.forEach {
if (it!= NULL){ if (it != NULL) {
follows.add(it) follows.add(it)
} }
} }
if (NULL in upFirst){ if (NULL in upFirst) {
val upFollow = getFollow(l) val upFollow = getFollow(l)
upFollow.forEach { upFollow.forEach {
if (it !in follows){ if (it !in follows) {
follows.add(it) follows.add(it)
} }
} }
@ -192,9 +191,9 @@ class AnalyzeTable {
return follows return follows
} }
private fun splitToVn(string : String, stopAfterFirstVt: Boolean = false) : MutableList<String>{ private fun splitToVn(string: String, stopAfterFirstVt: Boolean = false): MutableList<String> {
val parsedString = mutableListOf<String>() val parsedString = mutableListOf<String>()
if (string == NULL){ if (string == NULL) {
return parsedString return parsedString
} }
var copy = string var copy = string
@ -203,22 +202,22 @@ class AnalyzeTable {
val backup = copy val backup = copy
V_t.forEach { V_t.forEach {
if (copy.startsWith(it)){ if (copy.startsWith(it)) {
parsedString.add(it) parsedString.add(it)
if (!stopAfterFirstVt){ if (!stopAfterFirstVt) {
copy = copy.substring(it.length) copy = copy.substring(it.length)
}else{ } else {
no_vt_now = false no_vt_now = false
} }
} }
} }
var startVn = "" var startVn = ""
for (it in V_n) { for (it in V_n) {
if (copy == it){ if (copy == it) {
parsedString.add(it) parsedString.add(it)
copy = "" copy = ""
break break
}else if (copy.startsWith(it)){ } else if (copy.startsWith(it)) {
startVn = it startVn = it
parsedString.add(it) parsedString.add(it)
break break
@ -227,49 +226,55 @@ class AnalyzeTable {
copy = copy.substring(startVn.length) copy = copy.substring(startVn.length)
if (backup == copy){ if (backup == copy) {
throw RuntimeException(""" throw RuntimeException(
"""
出现了未知符号${copy[0]} 出现了未知符号${copy[0]}
at: $copy at: $copy
^---------This ^---------This
""".trimIndent()) """.trimIndent()
)
} }
} }
return parsedString return parsedString
} }
public fun analyze(input: String,transform: (String) -> String) : List<String> { fun analyze(input: String, transform: (String) -> String): List<String> {
val analyzeDeque = ArrayDeque<String>() val analyzeDeque = ArrayDeque<String>()
analyzeDeque.addLast("#") analyzeDeque.addLast("#")
analyzeDeque.addLast(start) analyzeDeque.addLast(start)
val inputDeque = ArrayDeque<String>() val inputDeque = ArrayDeque<String>()
inputDeque.addLast("#")
val result = mutableListOf<String>() val result = mutableListOf<String>()
splitToVn(transform(input),false).forEach { splitToVn(transform(input), false).forEach {
inputDeque.addLast(it) inputDeque.addFirst(it)
} }
inputDeque.addFirst("#")
while (true) { while (true) {
// 在这个时候保存栈 // 在这个时候保存栈
result.add( result.add(
"${result.size+1}: " "${result.size + 1}: "
.padEnd(4) .padEnd(4)
+ +
"${analyzeDeque "${
analyzeDeque
.toString() .toString()
.replace("[","") .replace("[", "")
.replace("]","") .replace("]", "")
.replace(",","") .replace(",", "")
.replace(" ","") .replace(" ", "")
.padEnd(10)}\t" + .padEnd(10)
"${inputDeque.reversed() }\t" +
"${
inputDeque.reversed()
.toString() .toString()
.replace("[","") .replace("[", "")
.replace("]","") .replace("]", "")
.replace(",","") .replace(",", "")
.replace(" ","") .replace(" ", "")
.padStart(6)}\t" .padStart(6)
}\t"
) )
// 栈顶一样删除 // 栈顶一样删除
@ -277,7 +282,7 @@ class AnalyzeTable {
analyzeDeque.removeLast() analyzeDeque.removeLast()
inputDeque.removeLast() inputDeque.removeLast()
if (analyzeDeque.isEmpty() && inputDeque.isEmpty()){ if (analyzeDeque.isEmpty() && inputDeque.isEmpty()) {
result[result.size - 1] = "${result[result.size - 1]}成功" result[result.size - 1] = "${result[result.size - 1]}成功"
return result return result
} }

View file

@ -15,7 +15,7 @@ fun main() {
}.forEach { }.forEach {
println(it) println(it)
} }
println("分析过程:(106-80(*95)") println("分析过程:(106-80(*95) ")
analyzeTable.analyze("(106-80(*95)"){ analyzeTable.analyze("(106-80(*95)"){
it.replace("\\d+".toRegex(),"i") it.replace("\\d+".toRegex(),"i")
}.forEach { }.forEach {