编译原理课设代码,仅供参考,请勿直接复制粘贴。。。
词法分析程序设计:
对源程序 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,“h54 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#的过程
Step | Stack | String | Rule |
---|---|---|---|
1 | #S | m+m*m# | S->AT |
2 | #TA | m+m*m# | A->BU |
3 | #TUB | m+m*m# | B->m |
4 | #TUm | m+m*m# | M匹配 |
5 | #TU | +m*m# | U->$ |
6 | #T | +m*m# | T->+AT |
7 | #TA+ | +m*m# | +匹配 |
8 | #TA | m*m# | A->BU |
9 | #TUB | m*m# | B->m |
10 | #TUm | m*m# | M匹配 |
11 | #TU | *m# | U->*BU |
12 | #TUB* | *m# | *匹配 |
13 | #TUB | m# | B->m |
14 | #TUm | m# | 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 + " 接受")
}