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

运行结果

相关推荐
小金子同志1 小时前
发现 Kotlin MultiPlatform 的一点小变化
kotlin
androidwork2 小时前
嵌套滚动交互处理总结
android·java·kotlin
橙子199110165 小时前
Kotlin 中的 Object
android·开发语言·kotlin
江梦寻15 小时前
软件工程教学评价
开发语言·后端·macos·架构·github·软件工程
吕永强18 小时前
大话软工笔记—需求分析概述
项目管理·软件工程
醉雨清风18 小时前
组件化场景下动态库与静态库依赖分析
编译原理
岸芷漫步20 小时前
Kotlin中协程的关键函数分析
kotlin
张较瘦_1 天前
[论文阅读] 人工智能+软件工程(软件测试) | 当大语言模型遇上APP测试:SCENGEN如何让手机应用更靠谱
论文阅读·人工智能·软件工程
程序员鱼皮1 天前
刚刚 B站又血崩了?!我来告诉你真正原因
计算机·互联网·编程经验·事故
纳于大麓1 天前
Kotlin基础语法五
android·开发语言·kotlin