编译原理实验-自上而下语法分析-2 预测分析法

用预测分析法(表驱动)分析文法 G 的正确句子和错误句子

不如直接给一个例子,根据例子了解预测分析法的分析过程

产生式和它的SELECT集

对应的预测分析表

分析过程

代码实现

好久没写Kotlin了,正好复习Kotlin语法

  • Main.kt

    kotlin 复制代码
    fun main() {
        (
                mutableMapOf(
                    "E" infer symStr("T", "E'") select symStr("(", "id"),
                    "E'" infer symStr("+", "T", "E'") select symStr("+"),
                    "E'" infer symStr("ε") select symStr("#", ")"),
                    "T" infer symStr("F", "T'") select symStr("(", "id"),
                    "T'" infer symStr("*", "F", "T'") select symStr("*"),
                    "T'" infer symStr("ε") select symStr("+", "#", ")"),
                    "F" infer symStr("(", "E", ")") select symStr("("),
                    "F" infer symStr("id") select symStr("id"),
                )
                        fuck mkGrammar("E".also { print("开始符$it\n待分析串") })
                ).analyze(symStr("id", "+", "id", "*", "id", "#").also(::println))
            { symbolStr, grammar, stack ->
                val mutableSymbolStr = symbolStr.toMutableList()
                println("序号" + "\t".repeat(2) + "符号栈" + "\t".repeat(6) + "输入串" + "\t".repeat(6) + "所用产生式")
                stack.repeatWhile({ it.isNotEmpty() }) { _, index ->
                    val peek = stack.peek()
                    val currentSymbol = mutableSymbolStr[0]
                    var findProduct: Product? = null
    
                    println(
                        "$index" + "\t".repeat(2)  + "$stack" + "\t".repeat(8 - stack.size) + "$mutableSymbolStr" + "\t".repeat(8 - mutableSymbolStr.size) +
                                when {
                                    peek != currentSymbol -> {
                                        // 如果不可以匹配,则找表达式
                                        findProduct = grammar.findProduct(peek, currentSymbol)
                                        findProduct
                                    }
    
                                    else -> {
                                        // 如果可以匹配,则栈和串同时去掉一位
                                        mutableSymbolStr.removeAt(0)
                                        ""$currentSymbol"匹配"
                                    }
                                }
                    )
    
                    stack.pop()
                    findProduct?.apply {
                        right.takeIf { right[0] != "ε" }?.let {
                            it.reversed().forEach { sym ->
                                stack.push(sym)
                            }
                        }
                    }
    
                }
    
            }
    }
  • SimonGrammar.kt

    kotlin 复制代码
    import java.util.*
    
    typealias Symbol = String // 符号
    typealias SymbolStr = List<String> // 符号串
    
    fun symStr(vararg elements: Symbol) = elements.asList() // 快速将多个符号组成符号串
    
    data class Product(val left: Symbol, val right: SymbolStr) {
        override fun toString(): String {
            return "$left->$right"
        }
    } // 产生式
    
    infix fun Symbol.infer(right: SymbolStr) = Product(this, right) // 生成一个产生式
    
    data class SimonGrammar(val startSymbol: Symbol) {
        val selectMap: MutableMap<Product, SymbolStr> = mutableMapOf()
    }
    
    fun mkGrammar(startSymbol: String) = SimonGrammar(startSymbol)
    
    infix fun <R> Product.select(that: R): Pair<Product, R> {
        return Pair(this, that)
    }
    
    infix fun MutableMap<Product, SymbolStr>.fuck(target: SimonGrammar): SimonGrammar {
        target.selectMap.putAll(this)
        return target
    }
    
    fun SimonGrammar.analyze(symbolStr: SymbolStr, block: (SymbolStr, SimonGrammar, Stack<Symbol>) -> Unit) {
        val stack = Stack<Symbol>()
        stack.push("#") // 结束符入栈
        stack.push(this.startSymbol)  // 开始符入栈
        block.invoke(symbolStr, this, stack)
    }
    
    fun <T> Stack<T>.repeatWhile(condition: (Stack<T>) -> Boolean, action: (Stack<T>, index: Int) -> Unit) {
        var index = 0
        while (condition.invoke(this)) {
            action.invoke(this, ++index)
        }
    }
    
    fun SimonGrammar.findProduct(left: Symbol, target: Symbol): Product? {
        // 如果values中包含了target,那就判断该values对应的产生式的左部是不是你要的
        return this.selectMap.filter {
            it.value.contains(target) && it.key.left == left
        }.map {
            it.key
        }.firstOrNull()
    }

运行结果

相关推荐
沿着路走到底2 小时前
面向对象程序设计
软件工程
Dola_Zou9 小时前
CodeMeter 8.20&AxProtector 11.50版本更新
安全·软件工程·软件加密
滴水成冰-1 天前
Kotlin-Flow学习笔记
笔记·学习·kotlin
_Shirley2 天前
android.view.InflateException: Binary XML file line #7: Error inflating class
android·xml·java·ide·kotlin·android studio
ChinaDragonDreamer2 天前
Kotlin:1.9.0 的新特性
android·开发语言·kotlin
⠀One0ne2 天前
软件设计原则(Java实现/给出正例反例)
java·软件工程
茜茜西西CeCe3 天前
软件工程知识点总结(7):软件项目管理
软件工程·甘特图·软件项目管理·wbs·gantt
帅次3 天前
重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估支持浏览器在线编程的系统架构设计
性能优化·重构·软件工程·软件构建·个人开发·代码规范·规格说明书
辉哥的编程道路3 天前
基于OpenSSL的密码管理系统-应用密码学课程报告
计算机·密码学·同等学力申硕
长安er3 天前
编译原理/软件工程核心概念-问题理解
java·开发语言·软件工程·编译·指针·敏捷开发·瀑布模型