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

View file

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