词法分析程序设计+说明语句的词法分析器+基于预测分析方法的表达式语法分析器

编译原理课设代码,仅供参考,请勿直接复制粘贴。。。

词法分析程序设计:

对源程序 begin x := 9 ; if x > 0 then x := 2 * x + 1 / 3 ; end #
经词法分析后输出如下序列:
(1,begin)(10,’x’) (18,:=) (11,9) (26 , ; ) (2,if)……

GetSyn.kt


package task1

class GetSyn {
    /***
     * 求出对应单词符号的种别码 syn
     */
    fun getSyn(word: String): Int {
        val syn: Int
        when (word) {
            "begin" -> syn = 1
            "if" -> syn = 2
            "then" -> syn = 3
            "while" -> syn = 4
            "do" -> syn = 5
            "end" -> syn = 6
            "ID" -> syn = 10
            "NUM" -> syn = 11
            "+" -> syn = 13
            "-" -> syn = 14
            "*" -> syn = 15
            "/" -> syn = 16
            ":" -> syn = 17
            ":=" -> syn = 18
            "<" -> syn = 20
            "<>" -> syn = 21
            "<=" -> syn = 22
            ">" -> syn = 23
            ">=" -> syn = 24
            "=" -> syn = 25
            ";" -> syn = 26
            "(" -> syn = 27
            ")" -> syn = 28
            "#" -> syn = 29
            else -> syn = -1
        }
        return syn
    }
}

GetTokenType.kt

package task1

import java.util.HashMap

import java.util.ArrayList
import java.util.regex.Pattern


class GetTokenType {

    private var g: GetSyn = GetSyn()

    /**
     * 将按间隔符分好的list进行判断,判断是否是合法的子串
     */
    fun getTokenAndSyn(list: Array<String?>): List<Map<*, *>> {
        var syn: Int //需要输出返回的关键字,种别码
        var word: String? //第一个首字符的类型
        val mList: MutableList<Map<*, *>> = ArrayList() //mlist用于返回整个List判断完成后的含有的字符和种别码
        for (i in list.indices) {
            val map: MutableMap<String, String?> = HashMap() //m用于保存最后返回的已经判别成功的字和种别码
            word = list[i] //word:需要进行处理判断的字
            //判断word是不是空的串,滤去
            if (word === "" || word == null || word.trim { it <= ' ' } === "")
                continue
            syn = g.getSyn(word)
            if (syn == -1) {
                syn = if (isID(word)) 10
                else if (isNum(word)) 11
                else {
                    println(word + " 不是合法的单词,所在的位置在:第" + (i + 1) + "个单词")
                    continue
                }
            }
            map["keyword"] = word
            map["syn"] = syn.toString()
            //println(syn.toString())
            mList.add(map)
        }
        return mList
    }


    /**
     * 正则判断是否是合法单词 letter(letter|digit)*
     */
    private fun isID(word: String): Boolean {
        val reg = "^[a-zA-Z][a-zA-Z0-9]*$"
        return Pattern.compile(reg).matcher(word).matches()
    }

    /**
     * 正则判断是否是合法数字 digitdigit*
     */
    private fun isNum(word: String): Boolean {
        val reg = "^[0-9]*$"
        return Pattern.compile(reg).matcher(word).matches()
    }


}

Main.kt

package task1

import java.io.BufferedReader
import java.io.FileReader
import java.util.ArrayList


fun main() {
    val tokenType = GetTokenType()
    val strList = readTestFile("D:\\IDEA\\KotlinSpace\\Compiler\\src\\main\\kotlin\\task1\\test.txt") //测试数据路径
    for (i in strList.indices) {
        //println("进行第" + (i + 1) + "行的判断:")
        val list:Array<String?> = strList[i].split(" ".toRegex()).toTypedArray() // 按空格分割单词
        val mList: List<Map<*, *>> = tokenType.getTokenAndSyn(list)
        for (m0 in mList) {
            val keyword = m0["keyword"] as String?
            val sortNum = m0["syn"] as String?
            println("($sortNum,$keyword)")
        }
    }
}


/**
 * 读取一个文件的内容,分行将所有的内容保存到一个list集合中
 */
fun readTestFile(filename: String): List<String> {
    val list: MutableList<String> = ArrayList()
    val fread = FileReader(filename)
    val bf = BufferedReader(fread)
    var strLine = bf.readLine()
    while (strLine != null) {
        println(strLine)
        list.add(strLine)
        strLine = bf.readLine()
    }
    bf.close()
    fread.close()
    return list
}

说明语句的词法分析器

输入如下正确的常量说明串:
const count=10,sum=81.5,char1=‘f’,max=169,str1=“h542…4S!AAsj”,char2=‘@’,str2=“aa!+h”;
输出:
count(integer,10)
sum(float,81.5)
char1(char, ‘f’)
max(integer,169)
str1(string,“h
54 2…4S!AAsj”)
char2(char, ‘@’)
str2(string,“aa!+h”)

Main.kt

package task3

import java.util.regex.Pattern


fun main() {
    val str = "const count=10,sum=81.5,char1='f',max=169,str1=\"h*54 2..4S!AAsj\",char2='@',str2=\"aa!+h\",12sum=1,char3='asd',min=003;"
    // val str = readLine().toString()
    println("The input string is:\n $str")
    val const = str.substring(0..4)
    if (const != "const" || str[str.lastIndex] != ';') { //保留字const错误,或者结尾不是分号
        println("It is not a constant declaration statement!")
        println("Please input a string again!")
    } else {
        val map = devide(str.substring(6..str.length - 2))
        var num = 0
        var string = 0
        var char = 0
        var float = 0
        for ((key, value) in map) {
            //println(key+" "+value)
            var flag = false // 判断是否出错,true没错,false出错
            when (value) {
                "error1" -> println(key + "(Wrong! It is not a identifier!)")
                "error2" -> println(key + "(Wrong! There are  more than one char in ''.)")
                "error3" -> println(key + "(Wrong! The integer can’t be started with '0'.)")
                else -> flag = true
            }
            if (flag) {
                if (isNum(value)) {
                    println(key + "(integer," + value + ")")
                    num++
                } else if (isFloat(value)) {
                    println(key + "(float," + value + ")")
                    float++
                } else if (isChar(value)) {
                    println(key + "(char," + value + ")")
                    char++
                } else {
                    println(key + "(string," + value + ")")
                    string++
                }
            }
        }
        println("int num = $num; char num = $char; string num = $string; float num = $float")
    }
}

/**
 * 分割字符串
 */
fun devide(str: String): MutableMap<String, String> {
    val map: MutableMap<String, String> = mutableMapOf()
    val list = str.split(',') // 按逗号分割赋值式
    for (l in list) {
        val tmp = l.split('=') // 按等号分割变量名和赋值
        val key = tmp[0]
        val value = tmp[1]
        if (!isLegal(key))  // 变量名不规范错误
            map[key] = "error1"
        else if (value.contains('\'') && value.length > 3)  // 字符多于一个错误
            map[key] = "error2"
        else if (isNum(value) && !isLegalNum(value)) // 数字开始为 0 错误
            map[key] = "error3"
        else map[key] = value
    }
    return map
}


/**
 * 正则判断是否是字符
 */

fun isChar(word: String): Boolean {
    return word.contains('\'') && word.length == 3
}

/**
 * 正则判断变量名是否符合规范
 */
fun isLegal(word: String): Boolean {
    val reg = "^[a-zA-Z_][a-zA-Z0-9_]*$"
    return Pattern.compile(reg).matcher(word).matches()
}

/**
 * 正则判断是否是合法数字
 */
fun isLegalNum(word: String): Boolean {
    val reg = "^[1-9][0-9]*$"
    return Pattern.compile(reg).matcher(word).matches()
}

/**
 * 正则判断是否是数字
 */
fun isNum(word: String): Boolean {
    val reg = "^[0-9]*$"
    return Pattern.compile(reg).matcher(word).matches()
}

/**
 * 正则判断是否是浮点数
 */
fun isFloat(word: String): Boolean {
    val reg = "^[0-9.]*$"
    return Pattern.compile(reg).matcher(word).matches()
}

基于预测分析方法的表达式语法分析器

从键盘输入串: m+m * m#;
输出: 用预测分析法分析符号串m+m * m#的过程

StepStackStringRule
1#Sm+m*m#S->AT
2#TAm+m*m#A->BU
3#TUBm+m*m#B->m
4#TUmm+m*m#M匹配
5#TU+m*m#U->$
6#T+m*m#T->+AT
7#TA++m*m#+匹配
8#TAm*m#A->BU
9#TUBm*m#B->m
10#TUmm*m#M匹配
11#TU*m#U->*BU
12#TUB**m#*匹配
13#TUBm#B->m
14#TUmm#M匹配
15#TU#U->$
16#T#T->$
17##接受

Main.kt

package task4

fun main() {
    val grammar = listOf( // 文法G的 LL(1)分析表
        arrayListOf("m", "S", "AT"), // S->AT, m
        arrayListOf("(", "S", "AT"), // S->AT, (
        arrayListOf("m", "A", "BU"), // A->BU, m
        arrayListOf("(", "A", "BU"), // A->BU, (
        arrayListOf("+", "T", "+AT"), // T->+AT, +
        arrayListOf(")", "T", "$"), // T->$, )
        arrayListOf("#", "T", "$"), // T->$, #
        arrayListOf("*", "U", "*BU"), // U->*BU, *
        arrayListOf("+", "U", "$"), // U->$, +
        arrayListOf(")", "U", "$"), // U->$, )
        arrayListOf("#", "U", "$"), // U->$, #
        arrayListOf("(", "B", "(S)"), // B->(S), (
        arrayListOf("m", "B", "m")// B->m, m
    )
    val str = mutableListOf("m", "+", "m", "*", "m", "#") // m+m*m#
    var cnt = 1
    val stack = mutableListOf("#", "S") // 分析栈
    while (stack.size!=1) {
        print(cnt.toString() + " " + stack + " " + str + " ")
        if (stack[stack.lastIndex] == str[0]) { // 栈顶字符和输入字符一样,规约
            println(stack[stack.lastIndex] + "匹配")
            //栈和输入串同时弹出规约字符
            stack.removeAt(stack.lastIndex)
            str.removeAt(0)
        } else {
            var flag = false // 判断是否可以移进,否则报错
            for (list in grammar) { //
                if (stack[stack.lastIndex] == list[1] && str[0] == list[0]) { // 从预测分析表找出对应的表达式
                    println(list[1] + "->" + list[2])
                    flag = true
                    stack.removeAt(stack.lastIndex)
                    if (list[2] != "$") { //如果移进不为空,倒序放入分析栈
                        val rev = list[2].reversed()
                        for (character in rev)
                            stack.add(character.toString())
                    }
                    break
                }
            }
            if (!flag) {
                println("错误,无法继续运行")
                break
            }
        }
        cnt++
    }
    println(cnt.toString() + " " + stack + " " + str + " 接受")

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值