编译原理实验-自上而下语法分析-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()
    }

运行结果

相关推荐
DsirNg19 小时前
把 AI 放进一次合并请求:一个批量归档功能的交付闭环
软件工程·测试·代码审查·开发效率·pull request·ai辅助编程·需求拆解
_瑞20 小时前
读懂 iOS 的线程调用栈
ios·编译原理·汇编语言
Android打工仔1 天前
Kotlin 协程源码解析(五):BaseContinuationImpl.resumeWith() —— Continuation 链是如何被展开的?
android·kotlin
Android-Flutter1 天前
android Glide 源码流程分析
android·kotlin
Android-Flutter1 天前
android Glide 使用详解
android·kotlin
树欲静而风不止861 天前
制造企业研发数字化|APQP+QMS 一体化
软件工程
小陈的进阶之路1 天前
Claude Code辅助测试:API测试与pytest自动化
android·开发语言·kotlin
老郑聊AI业财智造2 天前
Transformer 技术架构与源码分析
人工智能·python·深度学习·语言模型·架构·transformer·软件工程
alexhilton2 天前
规范驱动开发:让AI生成符合预期的KMP代码
android·kotlin·android jetpack
Android-Flutter2 天前
android 性能优化 详解
android·kotlin