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

运行结果

相关推荐
wuwu_q16 小时前
用通俗易懂 + Android 开发实战的方式讲解 Kotlin Flow 中的 filter 操作符
android·开发语言·kotlin
小哈里19 小时前
【软考架构】2025H2系统架构设计师考试复习.jpg(软件架构、软件工程、数据库、Web开发、高项)
数据库·架构·系统架构·软件工程·后端开发
HLJ洛神千羽19 小时前
软件工程综合实践3实验报告——校园二手交易平台系统(黑龙江大学)
软件工程·软件需求
雾江流1 天前
WPS国际版18.22 | 集Word,PDF,Sheet,PowerPoint于一体的多功能免费办公套件
pdf·word·软件工程·wps
Coffeeee1 天前
面试被问到Compose的副作用不会,只怪我没好好学
android·kotlin·android jetpack
张较瘦_2 天前
[论文阅读] AI + 软件工程 | 3340个Python ML项目实证:PyQu工具+61种代码变更,精准提升软件质量!
论文阅读·人工智能·软件工程
wuwu_q2 天前
用通俗易懂方式,详细讲讲 Kotlin Flow 中的 map 操作符
android·开发语言·kotlin
Halo_tjn2 天前
基于 Object 类及包装类的专项实验
java·开发语言·计算机
雾江流3 天前
MinimalWalls v1.9.8 | 提供高质量简约壁纸,支持一键下载、收藏和自动更换等功能,界面干净并支持深浅模式切换
软件工程
会跑的兔子3 天前
Android 16 Kotlin协程 第一部分
android·开发语言·kotlin