合肥工业大学编译原理实验LR(1)文法分析完整Scala实现代码(Java完成GUI封装)与测试数据

本文介绍了合肥工业大学编译原理实验中LR(1)文法分析的Scala实现,包括无GUI和含GUI版本的代码详细说明,其中GUI部分基于Java封装。还提供了测试数据和运行截图,代码可在GitHub找到。
摘要由CSDN通过智能技术生成

       

Table of Contents

        测试数据:

        代码:

        无GUI代码(Scala):

        含GUI代码:

        LR_1_try_GUI类(Scala):

        FileUtil类(Java):

         Analyse类(Java):

        运行截图:


        Java的GUI参考了“菊花侠”的手笔,Scala全部都是本人手写。

        github地址:LR(1)

        测试数据:

E->E+T
E->T
T->T*F
T->F
F->(E)
F->i

        代码:

        无GUI代码(Scala):

import scala.collection.immutable.Stack
import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, Map}
import scala.util.matching.Regex




object LR_1 {
	private final var allCharacters = new String()
	private final var relations = new ArrayBuffer[ (String, String, String) ]()
	private final var VN = new String()
	private final var VT = new String()
	private final var rowLength = 0
	private final var columnLength = 0
	private final val itemGroup = Map[ ArrayBuffer[ (String, String, String) ], Int ]()
	private final var LL1_G = new ArrayBuffer[ (String, String) ]()
	//private val allCandidateLetters = "αΑβΒγΓδΔεΕζΖηΗθΘιΙκΚλΛμΜνΝξΞοΟπΠρΡσΣτΤυΥφΦχΧψΨωΩ" + "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"
	private val allCandidateLetters = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩABCDEFGHIJKLMNOPQRSTUVWXYZ"
	private final var usedCharacters = ""
	// private val LL1_G = ArrayBuffer( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"),
	//    ("S", "ε"), ("F", "(E)"), ("F", "i") )//, ("Y", "*FS|/FS"), ("Y", "+TG|-TG"), ("Y", "x"), ("Y", "M"), ("M", "i"), ("M", "ε") )
	//  test data 1:
	//  ( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"),
	//       ("S", "ε"), ("F", "(E)"), ("F", "i"), ("Y", "S"), ("Y", "Gx"), ("Y", "x"), ("Y", "M"), ("M", "i"), ("M", "ε") )
	//  test data 2:
	//         ( ("D", "*FD"), ("D", "ε"), ("T", "FD"), ("E", "TC"), ("F", "(E)"), ("F", "i"), ("C", "+TC"), ("C", "ε") )
	//  test data 3:
	//         ( ("E", "E+T|T"), ("T", "T*F|T"), ("F", "(E)|i") )
	//  stand test data:
	//         ( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"), ("S", "ε"), ("F", "(E)"), ("F", "i") )

	def main(args: Array[String]): Unit = {

		//test parseFile
		val result = parseFile("/home/hadoop001/Documents/code/Scala/LR(1)/testData/test.data")
		println( "the original language rules:" )
		for( rs <- result ) {
			println( rs._1 + "->" + rs._2 )
		}
		initiate("/home/hadoop001/Documents/code/Scala/LR(1)/testData/test.data")
		utility()
		println("**************")
		analyse("i+i*i#")

	}

	/*
	* Function name: utility
	* Function description: 辅助输出函数
	* Input parameters: 无
	* Return value: 无
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Mon Oct 28 2019 +0800
	* Editor: 来自高山
	* Edited Date: Mon Oct 28 2019 +0800
	 */
	def utility(): Unit = {
		println( "after expanding the language rules:" )
		displayRelations()

		println("**************")
		//test FIRST
		println("FIRST:")
		val testFIRST = FIRST()
		for( ex <- testFIRST ) {
			println( "FIRST(" + ex._1 + ") = {" + ex._2.mkString(",") + "}" )
		}
		println("**************")

		var cnt4 = 0
		for( ex <- itemGroup.toList.sortBy(_._2) ) {
			println( cnt4 + ":\nI" + ex._2 + ":" )
			for (tx <- ex._1 ) {
				println( tx._1 + "->" + tx._2 + ", " + tx._3 )
			}
			println("^^^^^^^^^^^^^^^^^^^^^^^^")
			cnt4 += 1
		}

		println("**************")
		val test_createMatrix = createMatrix
		for ( i <- 0 to test_createMatrix.length - 1 ) {
			for ( j <- 0 to test_createMatrix(i).length - 1 ) {
				print( test_createMatrix(i)(j) + " " )
			}
			println()
		}
	}

	/*
	* Function name: analyse
	* Function description: 对指定的字符串进行LR(1)分析
	* Input parameters: -String(输入的指定字符串)
	* Return value: -Boolean(分析成功则返回true,否则false)
	* Exception: 未处理(有出错提示)
	* Author: 来自高山
	* Created date: Mon Oct 28 2019 +0800
	* Editor: 来自高山
	* Edited Date: Mon Oct 28 2019 +0800
	 */
	def analyse( expression: String ): Boolean = {
		val statusStack = new mutable.Stack[String]()
		val characterStack = new mutable.Stack[String]()
		val analyseTable = createMatrix()
//		val analyseTable = ArrayBuffer(ArrayBuffer(null, "+", "*", "(", ")", "i", "#", "E", "T", "F", "A"),
//										ArrayBuffer("0", null, null, "S4", null, "S5", null, "1", "2", "3", null),
//										ArrayBuffer("1", "S6", null, null, null, null, "acc", null, null, null, null),
//										ArrayBuffer("2", "r2", "S7", null, null, null, "r2", null, null, null, null),
//										ArrayBuffer("3", "r4", "r4", null, null, null, "r4", null, null, null, null),
//										ArrayBuffer("4", null, null, "S4", null, "S11", null, "8", "9", "10", null),
//										ArrayBuffer("5", "r6", "r6", null, null, null, "r6", null, null, null, null),
//										ArrayBuffer("6", null, null, "S4", null, "S5", null, null, "12", "13", null),
//										ArrayBuffer("7", null, null, "S4", null, "S5", null, null, null, "14", null),
//										ArrayBuffer("8", "S15", null, null, "S16", null, null, null, null, null, null),
//										ArrayBuffer("9", "r2", "S17", null, "r2", null, null, null, null, null, null),
//										ArrayBuffer("10", "r4", "r4", null, "r4", null, null, null, null, null, null),
//										ArrayBuffer("11", "r6", "r6", null, "r6", null, null, null, null, null, null),
//										ArrayBuffer("12", "r1", "S18", null, null, null, "r1", null, null, null, null),
//										ArrayBuffer("13", "r4", "r4", null, null, null, "r4",null, null, null, null),
//										ArrayBuffer("14", "r3", "r3", null, null, null, "r3", null, null, null, null),
//										ArrayBuffer("15", null, null, "S4", null, "S11", null, null, "19", "20", null),
//										ArrayBuffer("16", "r5", "r5", null, null, null, "r5", null, null, null, null),
//										ArrayBuffer("17", null, null, "S4", null, "S11", null, null, null, "21", null),
//										ArrayBuffer("18", null, null, "S4", null, "S5", null, null, null, "14", null),
//										ArrayBuffer("19", "r1", "S17", null, "r1", null, null, null, null, null, null),
//										ArrayBuffer("20", "r4", "r4", null, "r4", null, null, null, null, null, null),
//										ArrayBuffer("21", "r3", "r3", null, "r3", null, null, null, null, null, null)
//		)
		var expr = expression
		var flag = false
		var repeat = true
		statusStack.push("0")
		characterStack.push("#")
		var tot = 0
		case class characterToColumn(a: String) {
			var ans = -1
			for( j <- 1 to (columnLength - 1) ) {
				if( analyseTable(0)(j) == a ) {
					ans = j
				}
			}
			//ans
		}
		while ( repeat == true ) {
			//  s = statusTop
			val statusTop = statusStack.top
			val a = expr(0)

			val aColumn = characterToColumn(a.toString).ans
			var sRow = statusTop.toInt
			if(sRow == 0 ) sRow += 1 else sRow += 1

			if( analyseTable(sRow)(aColumn)(0) == 'S' ) {
				val newStatus = analyseTable(sRow)(aColumn).drop(1)
				statusStack.push(newStatus)
				characterStack.push(a.toString)
				expr = expr.drop(1)

				println( tot + "状态栈: [" + displayStack(statusStack.reverse).mkString(",") + "],符号栈:[" +
						displayStack(characterStack.reverse) + "],剩余字符串:" + expr + ",动作:ACTION[" +
						statusTop + ", " + a + "]," + "状态 " + aColumn + " 与符号 " + a + " 分别入栈")
				tot += 1
			}
			else if( analyseTable(sRow)(aColumn)(0) == 'r' ) {
				val exprLineNO =  analyseTable(sRow)(aColumn).drop(1).toInt
				val currentRelation = relations(exprLineNO)

				var popLength = 0
				if( currentRelation._3 != "א" ) {
					popLength = currentRelation._2.length + currentRelation._3.length
				}
				else {
					popLength = currentRelation._2.length
				}
				var cnt = popLength
				val  tmpCharacter = characterStack.reverse.toString.replace("Stack(", "").replace(")", "").replace(",", "").replace(" ", "") //.substring() //.substring(characterStack.length - popLength - 1, characterStack.length - 1 )
				val reduceCharacter = tmpCharacter.drop(tmpCharacter.length - popLength)
				while ( cnt >= 1 ) {
					statusStack.pop()
					characterStack.pop()
					cnt -= 1
				}
				// s' = characterTop
				val statusTop2 = statusStack.top.toInt

				var sRow2 = -1
				if( statusTop2 == 0 ) sRow2 = statusTop2 + 1 else sRow2 = statusTop2 + 1

				val A = currentRelation._1
				characterStack.push(A)
				val tmp = analyseTable(sRow2)( characterToColumn(A).ans )
				statusStack.push(tmp)

				println( tot + "状态栈: [" + displayStack(statusStack.reverse).mkString(",") + "],符号栈:[" +
						displayStack(characterStack.reverse) + "],剩余字符串:" + expr + ",动作:GOTO[" +
						statusTop2 + ", " + A + "]" + ",用产生式 " + A + "->" + reduceCharacter + " 进行规约")
				tot += 1
			}
			else if( analyseTable(sRow)(aColumn) == "acc" ) {
				println("succeed")
				flag = true
				repeat = false
			}
			else {
				println("error")
				println( "error in, sRow = " + sRow + ", aColumn = " + aColumn + ", analyseTable(" + sRow + ")(" + aColumn + ") = " + analyseTable(sRow)(aColumn) )
				flag = true
				repeat = false
			}
			//cnt += 1
		}
		if(flag) true else false
	}

	/*
	* Function name: createMatrix
	* Function description: 构造ACTION与GOTO分析表
	* Input parameters: 无
	* Return value: -Array[ Array[String] ](分析表矩阵元素构成的二维数组)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Mon Oct 28 2019 +0800
	* Editor: 来自高山
	* Edited Date: Mon Oct 28 2019 +0800
	 */
	def createMatrix(): Array[ Array[String] ] = {
		val result = initiateMatrix()
		val localVT = VT
		val localVN = VN

		case class getColumn( ch: String ) {
			val matrix = initiateMatrix()
			var ans = -1
			for( j <- 0 to (columnLength - 1) ) {
				if( matrix(0)(j) == ch ) {
					ans = j
				}
			}
		}


		for( ex <- itemGroup ) {
			for( tx <- ex._1 ) {
				val pointPosition = tx._2.indexOf("·")
				//· 不在最右边
				//若项目[A->α·aβ] ∈ Ik,且GO(Ik, a) = Ij,a为终结符,则置ACTION[k, a]为“sj”
				if (pointPosition < tx._2.length - 1) {
					val a = tx._2( pointPosition + 1 )
					if( localVT.contains(a) == true && findItemOrder(ex._1, a.toString) != -1 ) {
						val j = findItemOrder(ex._1, a.toString)
						var tmpRow = -1
						tmpRow = ex._2 + 1
						result(tmpRow)( getColumn(a.toString).ans ) = "S" + j.toString
					}
				}
				if (pointPosition == tx._2.length - 1 ) {
					val a = tx._3
					var tmpRow = -1
					tmpRow = ex._2 + 1
					result(tmpRow)(getColumn(a).ans) = "r" + ( findRelationOrder( (tx._1,
							tx._2.replace("·", "") ) ) )
				}
				if( tx._1 == relations(0)._1 && tx._2 == relations(0)._2 + "·" && tx._3 == "#" ) {
					var tmpRow = -1
					tmpRow = ex._2 + 1
					result(tmpRow)( getColumn("#").ans ) = "acc"
				}
			}
			for( ch <- localVN ) {
				if( findItemOrder(ex._1, ch.toString) != -1 ) {
					val gotoNumber = findItemOrder(ex._1, ch.toString)
					var tmpRow = -1
					tmpRow = ex._2 + 1
					//A = ch
					result(tmpRow)( getColumn(ch.toString).ans ) = gotoNumber.toString
				}
			}
		}
		result
	}

	/*
	* Function name: findRelationOrder
	* Function description: 获取产生式的位于文法的第几行,从0开始
	* Input parameters: -(String, String)(給定的产生式)
	* Return value: -Int(給定的产生式在給定文法中的行数)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Mon Oct 28 2019 +0800
	* Editor: 来自高山
	* Edited Date: Mon Oct 28 2019 +0800
	 */
	def findRelationOrder( expression: (String, String) ): Int ={
		var ans = -1
		var cnt = 0
		val localRelations = relations
		for( ex <- localRelations ) {
			var expr = ""
			if( ex._3 != "א" ) {
				expr = ex._1 + ex._2 + ex._3
			}
			else {
				expr = ex._1 + ex._2
			}
			if( expr.equals(expression._1 + expression._2) ) {
				ans = cnt
			}
			cnt += 1
		}
		ans
	}

	/*
	* Function name: findItemOrder
	* Function description: 获取特定项目对于指定字符在项目集族中的编号,从0开始
	* Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), -String(給定字符)
	* Return value: -Int(給定的项目对于指定字符在项目集族中的编号)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Mon Oct 28 2019 +0800
	* Editor: 来自高山
	* Edited Date: Mon Oct 28 2019 +0800
	 */
	def findItemOrder( item: ArrayBuffer[ (String, String, String) ], a: String ): Int = {
		var ans = -1
		val givenItem = go( item, a).sorted
		val localItemGroup = itemGroup
		for( ex <- localItemGroup ) {
			if( ex._1.sorted.equals(givenItem) ) {
				ans = ex._2
			}
		}
		ans
	}

	/*
	* Function name: initiateMatrix
	* Function description: 初始化分析表,即ACTION表与GOTO表
	* Input parameters: 无
	* Return value: -Array[ Array[ String] ](已完成初始的分析表)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Sun Oct 27 2019 +0800
	* Editor: 来自高山
	* Edited Date: Sun Oct 27 2019 +0800
	 */
	def initiateMatrix(): Array[ Array[ String] ] = {
		val localVN = VN
		val localVT = VT
		val tableRowLength = rowLength
		val tableColumnLength = columnLength
		val result = Array.ofDim[String](tableRowLength, tableColumnLength)
		for( j <- 1 to localVT.length ) {
			result(0)(j) = localVT(j - 1).toString
		}
		for( j <- localVT.length + 1 to tableColumnLength - 1 ) {
			result(0)(j) = localVN(j - localVT.length - 1).toString
		}
		for( i <- 1 to ( tableRowLength - 1 ) ) {
			result(i)(0) = (i - 1).toString
		}
		for( i <- 0 to (tableRowLength - 1) ) {
			for( j <- 0 to (tableColumnLength - 1) ) {
				if( result.isEmpty != false ) {
					result(i)(j) = null
				}
			}
		}

		result
	}

	/*
	* Function name: getItemGroup
	* Function description: 对于输入的文法,建立初始化的项目集
	* Input parameters: 无
	* Return value: -Unit
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Wed Oct 23 2019 +0800
	* Editor: 来自高山
	* Edited Date: Sun Oct 27 2019 +0800
	 */
	def getItemGroup(): Unit = {
		val ldx = ( relations(0)._1, "·" + relations(0)._2, "#" )
		val I0 = getClosure( ArrayBuffer(ldx) )
		val wholeCharacters = allCharacters
		var tot = 0
//		var cnt = 0
		itemGroup(I0) = tot
		var appendFlag = true
		while (appendFlag == true) {
			var originalAns = Map[ ArrayBuffer[ (String, String, String) ], Int ]()
			originalAns = itemGroup.clone()
			//为什么用I作为遍历变量不行?!
			for(item <- itemGroup.keys) {
				for (ch <- wholeCharacters) {
					val newItem = go(item, ch.toString).sorted
					if (newItem.isEmpty == false && itemGroup.contains(newItem) == false) {
						tot += 1
						itemGroup(newItem) = tot
					}
				}
			}
			if( originalAns.equals(itemGroup) == true ) {
				appendFlag = false
//				println( cnt + ", all same" )
//				cnt += 1
			}
			else {
				originalAns.clear()
				originalAns = itemGroup.clone()
//				println( cnt + ", changed" )
//				cnt += 1
			}
		}
	}

	/*
	* Function name: getItems
	* Function description: 返回文法的初始项目集I0
	* Input parameters: 无
	* Return value: -ArrayBuffer[String](文法的项目集,第一个元素是文法产生式左边符号,第二个是对应的右边字符串所生成的项目)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Wed Oct 23 2019 +0800
	* Editor: 来自高山
	* Edited Date: Sar Oct 26 2019 +0800
	 */
	def getItems(): ArrayBuffer[ (String, String, String) ] = {
		val result = new ArrayBuffer[ (String, String, String) ]()
		val localRelations = relations
		//initiate
		for (ex <- localRelations) {
			if (ex._3 != "א") {
				result += ((ex._1, "·" + ex._2, "#"))
				result += ((ex._1, "·" + ex._3, "#"))
			}
			else {
				result += ((ex._1, "·" + ex._2, "#"))
			}
		}
		result
	}

	/*
	* Function name: go
	* Function description: 求給定项目对于特定字符的下一状态
	* Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), String(特定字符)
	* Return value: -ArrayBuffer[ (String, String, String) ](給定项目对于特定字符的下一状态)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Sat Oct 26 2019 +0800
	* Editor: 来自高山
	* Edited Date: Sat Oct 26 2019 +0800
	 */
	def go( I: ArrayBuffer[ (String, String, String) ], X: String ): ArrayBuffer[ (String, String, String) ] = {
		//GO(I, X) = CLOSURE(J)
		//J = {任何形如[A->αX·β, a]的项目|[A->α·Xβ, a]∈I}
		val ans = new ArrayBuffer[ (String, String, String) ]()
		val items = new ArrayBuffer[ (String, String, String) ]()

		for( ex <- I ) {
			val pointPosition = ex._2.indexOf("·")
			//· 不在最右边
			if (pointPosition < ex._2.length - 1) {
				val A = ex._1
				val possibleX = ex._2( pointPosition + 1)
				//  αXβ
				val noPointExpressionPart2 = ex._2.replace("·", "")
				if( X == possibleX.toString ) {
					//  αX·β
					val newPart2 = noPointExpressionPart2.substring(0, pointPosition + 1) + "·" +
							noPointExpressionPart2.substring(pointPosition + 1, noPointExpressionPart2.length)
					val a = ex._3
					items += ( (A, newPart2, a) )
				}
			}
		}
		ans.appendAll( getClosure(items) )
		ans
	}

	/*
	* Function name: getClosure
	* Function description: 求給定项目集的闭包
	* Input parameters: -ArrayBuffer[ (String, String, String) ](給定的项目集)
	* Return value: -ArrayBuffer[ (String, String, String) ](給定项目集的闭包)
	* Exception: 未处理
	* Author: 来自高山
	* Created date: Sat Oct 26 2019 +0800
	* Editor: 来自高山
	* Edited Date: Sun Oct 27 2019 +0800
	 */
	def getClosure( items: ArrayBuffer[ (String, String, String) ] ): ArrayBuffer[ (String, String, String) ] = {
		val result = new ArrayBuffer[ (String
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值