测试数据:
1 E->E+T 2 E->T 3 T->T*F 4 T->F 5 F->(E) 6 F->i
代码:
无GUI代码(Scala):

1 import scala.collection.immutable.Stack 2 import scala.collection.mutable 3 import scala.collection.mutable.{ArrayBuffer, Map} 4 import scala.util.matching.Regex 5 6 7 8 9 object LR_1 { 10 private final var allCharacters = new String() 11 private final var relations = new ArrayBuffer[ (String, String, String) ]() 12 private final var VN = new String() 13 private final var VT = new String() 14 private final var rowLength = 0 15 private final var columnLength = 0 16 private final val itemGroup = Map[ ArrayBuffer[ (String, String, String) ], Int ]() 17 private final var LL1_G = new ArrayBuffer[ (String, String) ]() 18 //private val allCandidateLetters = "αΑβΒγΓδΔεΕζΖηΗθΘιΙκΚλΛμΜνΝξΞοΟπΠρΡσΣτΤυΥφΦχΧψΨωΩ" + "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ" 19 private val allCandidateLetters = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩABCDEFGHIJKLMNOPQRSTUVWXYZ" 20 private final var usedCharacters = "" 21 // private val LL1_G = ArrayBuffer( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"), 22 // ("S", "ε"), ("F", "(E)"), ("F", "i") )//, ("Y", "*FS|/FS"), ("Y", "+TG|-TG"), ("Y", "x"), ("Y", "M"), ("M", "i"), ("M", "ε") ) 23 // test data 1: 24 // ( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"), 25 // ("S", "ε"), ("F", "(E)"), ("F", "i"), ("Y", "S"), ("Y", "Gx"), ("Y", "x"), ("Y", "M"), ("M", "i"), ("M", "ε") ) 26 // test data 2: 27 // ( ("D", "*FD"), ("D", "ε"), ("T", "FD"), ("E", "TC"), ("F", "(E)"), ("F", "i"), ("C", "+TC"), ("C", "ε") ) 28 // test data 3: 29 // ( ("E", "E+T|T"), ("T", "T*F|T"), ("F", "(E)|i") ) 30 // stand test data: 31 // ( ("E", "TG"), ("G", "+TG|-TG"), ("G", "ε"), ("T", "FS"), ("S", "*FS|/FS"), ("S", "ε"), ("F", "(E)"), ("F", "i") ) 32 33 def main(args: Array[String]): Unit = { 34 35 //test parseFile 36 val result = parseFile("/home/hadoop001/Documents/code/Scala/LR(1)/testData/test.data") 37 println( "the original language rules:" ) 38 for( rs <- result ) { 39 println( rs._1 + "->" + rs._2 ) 40 } 41 initiate("/home/hadoop001/Documents/code/Scala/LR(1)/testData/test.data") 42 utility() 43 println("**************") 44 analyse("i+i*i#") 45 46 } 47 48 /* 49 * Function name: utility 50 * Function description: 辅助输出函数 51 * Input parameters: 无 52 * Return value: 无 53 * Exception: 未处理 54 * Author: 来自高山 55 * Created date: Mon Oct 28 2019 +0800 56 * Editor: 来自高山 57 * Edited Date: Mon Oct 28 2019 +0800 58 */ 59 def utility(): Unit = { 60 println( "after expanding the language rules:" ) 61 displayRelations() 62 63 println("**************") 64 //test FIRST 65 println("FIRST:") 66 val testFIRST = FIRST() 67 for( ex <- testFIRST ) { 68 println( "FIRST(" + ex._1 + ") = {" + ex._2.mkString(",") + "}" ) 69 } 70 println("**************") 71 72 var cnt4 = 0 73 for( ex <- itemGroup.toList.sortBy(_._2) ) { 74 println( cnt4 + ":\nI" + ex._2 + ":" ) 75 for (tx <- ex._1 ) { 76 println( tx._1 + "->" + tx._2 + ", " + tx._3 ) 77 } 78 println("^^^^^^^^^^^^^^^^^^^^^^^^") 79 cnt4 += 1 80 } 81 82 println("**************") 83 val test_createMatrix = createMatrix 84 for ( i <- 0 to test_createMatrix.length - 1 ) { 85 for ( j <- 0 to test_createMatrix(i).length - 1 ) { 86 print( test_createMatrix(i)(j) + " " ) 87 } 88 println() 89 } 90 } 91 92 /* 93 * Function name: analyse 94 * Function description: 对指定的字符串进行LR(1)分析 95 * Input parameters: -String(输入的指定字符串) 96 * Return value: -Boolean(分析成功则返回true,否则false) 97 * Exception: 未处理(有出错提示) 98 * Author: 来自高山 99 * Created date: Mon Oct 28 2019 +0800 100 * Editor: 来自高山 101 * Edited Date: Mon Oct 28 2019 +0800 102 */ 103 def analyse( expression: String ): Boolean = { 104 val statusStack = new mutable.Stack[String]() 105 val characterStack = new mutable.Stack[String]() 106 val analyseTable = createMatrix() 107 // val analyseTable = ArrayBuffer(ArrayBuffer(null, "+", "*", "(", ")", "i", "#", "E", "T", "F", "A"), 108 // ArrayBuffer("0", null, null, "S4", null, "S5", null, "1", "2", "3", null), 109 // ArrayBuffer("1", "S6", null, null, null, null, "acc", null, null, null, null), 110 // ArrayBuffer("2", "r2", "S7", null, null, null, "r2", null, null, null, null), 111 // ArrayBuffer("3", "r4", "r4", null, null, null, "r4", null, null, null, null), 112 // ArrayBuffer("4", null, null, "S4", null, "S11", null, "8", "9", "10", null), 113 // ArrayBuffer("5", "r6", "r6", null, null, null, "r6", null, null, null, null), 114 // ArrayBuffer("6", null, null, "S4", null, "S5", null, null, "12", "13", null), 115 // ArrayBuffer("7", null, null, "S4", null, "S5", null, null, null, "14", null), 116 // ArrayBuffer("8", "S15", null, null, "S16", null, null, null, null, null, null), 117 // ArrayBuffer("9", "r2", "S17", null, "r2", null, null, null, null, null, null), 118 // ArrayBuffer("10", "r4", "r4", null, "r4", null, null, null, null, null, null), 119 // ArrayBuffer("11", "r6", "r6", null, "r6", null, null, null, null, null, null), 120 // ArrayBuffer("12", "r1", "S18", null, null, null, "r1", null, null, null, null), 121 // ArrayBuffer("13", "r4", "r4", null, null, null, "r4",null, null, null, null), 122 // ArrayBuffer("14", "r3", "r3", null, null, null, "r3", null, null, null, null), 123 // ArrayBuffer("15", null, null, "S4", null, "S11", null, null, "19", "20", null), 124 // ArrayBuffer("16", "r5", "r5", null, null, null, "r5", null, null, null, null), 125 // ArrayBuffer("17", null, null, "S4", null, "S11", null, null, null, "21", null), 126 // ArrayBuffer("18", null, null, "S4", null, "S5", null, null, null, "14", null), 127 // ArrayBuffer("19", "r1", "S17", null, "r1", null, null, null, null, null, null), 128 // ArrayBuffer("20", "r4", "r4", null, "r4", null, null, null, null, null, null), 129 // ArrayBuffer("21", "r3", "r3", null, "r3", null, null, null, null, null, null) 130 // ) 131 var expr = expression 132 var flag = false 133 var repeat = true 134 statusStack.push("0") 135 characterStack.push("#") 136 var tot = 0 137 case class characterToColumn(a: String) { 138 var ans = -1 139 for( j <- 1 to (columnLength - 1) ) { 140 if( analyseTable(0)(j) == a ) { 141 ans = j 142 } 143 } 144 //ans 145 } 146 while ( repeat == true ) { 147 // s = statusTop 148 val statusTop = statusStack.top 149 val a = expr(0) 150 151 val aColumn = characterToColumn(a.toString).ans 152 var sRow = statusTop.toInt 153 if(sRow == 0 ) sRow += 1 else sRow += 1 154 155 if( analyseTable(sRow)(aColumn)(0) == 'S' ) { 156 val newStatus = analyseTable(sRow)(aColumn).drop(1) 157 statusStack.push(newStatus) 158 characterStack.push(a.toString) 159 expr = expr.drop(1) 160 161 println( tot + "状态栈: [" + displayStack(statusStack.reverse).mkString(",") + "],符号栈:[" + 162 displayStack(characterStack.reverse) + "],剩余字符串:" + expr + ",动作:ACTION[" + 163 statusTop + ", " + a + "]," + "状态 " + aColumn + " 与符号 " + a + " 分别入栈") 164 tot += 1 165 } 166 else if( analyseTable(sRow)(aColumn)(0) == 'r' ) { 167 val exprLineNO = analyseTable(sRow)(aColumn).drop(1).toInt 168 val currentRelation = relations(exprLineNO) 169 170 var popLength = 0 171 if( currentRelation._3 != "א" ) { 172 popLength = currentRelation._2.length + currentRelation._3.length 173 } 174 else { 175 popLength = currentRelation._2.length 176 } 177 var cnt = popLength 178 val tmpCharacter = characterStack.reverse.toString.replace("Stack(", "").replace(")", "").replace(",", "").replace(" ", "") //.substring() //.substring(characterStack.length - popLength - 1, characterStack.length - 1 ) 179 val reduceCharacter = tmpCharacter.drop(tmpCharacter.length - popLength) 180 while ( cnt >= 1 ) { 181 statusStack.pop() 182 characterStack.pop() 183 cnt -= 1 184 } 185 // s' = characterTop 186 val statusTop2 = statusStack.top.toInt 187 188 var sRow2 = -1 189 if( statusTop2 == 0 ) sRow2 = statusTop2 + 1 else sRow2 = statusTop2 + 1 190 191 val A = currentRelation._1 192 characterStack.push(A) 193 val tmp = analyseTable(sRow2)( characterToColumn(A).ans ) 194 statusStack.push(tmp) 195 196 println( tot + "状态栈: [" + displayStack(statusStack.reverse).mkString(",") + "],符号栈:[" + 197 displayStack(characterStack.reverse) + "],剩余字符串:" + expr + ",动作:GOTO[" + 198 statusTop2 + ", " + A + "]" + ",用产生式 " + A + "->" + reduceCharacter + " 进行规约") 199 tot += 1 200 } 201 else if( analyseTable(sRow)(aColumn) == "acc" ) { 202 println("succeed") 203 flag = true 204 repeat = false 205 } 206 else { 207 println("error") 208 println( "error in, sRow = " + sRow + ", aColumn = " + aColumn + ", analyseTable(" + sRow + ")(" + aColumn + ") = " + analyseTable(sRow)(aColumn) ) 209 flag = true 210 repeat = false 211 } 212 //cnt += 1 213 } 214 if(flag) true else false 215 } 216 217 /* 218 * Function name: createMatrix 219 * Function description: 构造ACTION与GOTO分析表 220 * Input parameters: 无 221 * Return value: -Array[ Array[String] ](分析表矩阵元素构成的二维数组) 222 * Exception: 未处理 223 * Author: 来自高山 224 * Created date: Mon Oct 28 2019 +0800 225 * Editor: 来自高山 226 * Edited Date: Mon Oct 28 2019 +0800 227 */ 228 def createMatrix(): Array[ Array[String] ] = { 229 val result = initiateMatrix() 230 val localVT = VT 231 val localVN = VN 232 233 case class getColumn( ch: String ) { 234 val matrix = initiateMatrix() 235 var ans = -1 236 for( j <- 0 to (columnLength - 1) ) { 237 if( matrix(0)(j) == ch ) { 238 ans = j 239 } 240 } 241 } 242 243 244 for( ex <- itemGroup ) { 245 for( tx <- ex._1 ) { 246 val pointPosition = tx._2.indexOf("·") 247 //· 不在最右边 248 //若项目[A->α·aβ] ∈ Ik,且GO(Ik, a) = Ij,a为终结符,则置ACTION[k, a]为“sj” 249 if (pointPosition < tx._2.length - 1) { 250 val a = tx._2( pointPosition + 1 ) 251 if( localVT.contains(a) == true && findItemOrder(ex._1, a.toString) != -1 ) { 252 val j = findItemOrder(ex._1, a.toString) 253 var tmpRow = -1 254 tmpRow = ex._2 + 1 255 result(tmpRow)( getColumn(a.toString).ans ) = "S" + j.toString 256 } 257 } 258 if (pointPosition == tx._2.length - 1 ) { 259 val a = tx._3 260 var tmpRow = -1 261 tmpRow = ex._2 + 1 262 result(tmpRow)(getColumn(a).ans) = "r" + ( findRelationOrder( (tx._1, 263 tx._2.replace("·", "") ) ) ) 264 } 265 if( tx._1 == relations(0)._1 && tx._2 == relations(0)._2 + "·" && tx._3 == "#" ) { 266 var tmpRow = -1 267 tmpRow = ex._2 + 1 268 result(tmpRow)( getColumn("#").ans ) = "acc" 269 } 270 } 271 for( ch <- localVN ) { 272 if( findItemOrder(ex._1, ch.toString) != -1 ) { 273 val gotoNumber = findItemOrder(ex._1, ch.toString) 274 var tmpRow = -1 275 tmpRow = ex._2 + 1 276 //A = ch 277 result(tmpRow)( getColumn(ch.toString).ans ) = gotoNumber.toString 278 } 279 } 280 } 281 result 282 } 283 284 /* 285 * Function name: findRelationOrder 286 * Function description: 获取产生式的位于文法的第几行,从0开始 287 * Input parameters: -(String, String)(給定的产生式) 288 * Return value: -Int(給定的产生式在給定文法中的行数) 289 * Exception: 未处理 290 * Author: 来自高山 291 * Created date: Mon Oct 28 2019 +0800 292 * Editor: 来自高山 293 * Edited Date: Mon Oct 28 2019 +0800 294 */ 295 def findRelationOrder( expression: (String, String) ): Int ={ 296 var ans = -1 297 var cnt = 0 298 val localRelations = relations 299 for( ex <- localRelations ) { 300 var expr = "" 301 if( ex._3 != "א" ) { 302 expr = ex._1 + ex._2 + ex._3 303 } 304 else { 305 expr = ex._1 + ex._2 306 } 307 if( expr.equals(expression._1 + expression._2) ) { 308 ans = cnt 309 } 310 cnt += 1 311 } 312 ans 313 } 314 315 /* 316 * Function name: findItemOrder 317 * Function description: 获取特定项目对于指定字符在项目集族中的编号,从0开始 318 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), -String(給定字符) 319 * Return value: -Int(給定的项目对于指定字符在项目集族中的编号) 320 * Exception: 未处理 321 * Author: 来自高山 322 * Created date: Mon Oct 28 2019 +0800 323 * Editor: 来自高山 324 * Edited Date: Mon Oct 28 2019 +0800 325 */ 326 def findItemOrder( item: ArrayBuffer[ (String, String, String) ], a: String ): Int = { 327 var ans = -1 328 val givenItem = go( item, a).sorted 329 val localItemGroup = itemGroup 330 for( ex <- localItemGroup ) { 331 if( ex._1.sorted.equals(givenItem) ) { 332 ans = ex._2 333 } 334 } 335 ans 336 } 337 338 /* 339 * Function name: initiateMatrix 340 * Function description: 初始化分析表,即ACTION表与GOTO表 341 * Input parameters: 无 342 * Return value: -Array[ Array[ String] ](已完成初始的分析表) 343 * Exception: 未处理 344 * Author: 来自高山 345 * Created date: Sun Oct 27 2019 +0800 346 * Editor: 来自高山 347 * Edited Date: Sun Oct 27 2019 +0800 348 */ 349 def initiateMatrix(): Array[ Array[ String] ] = { 350 val localVN = VN 351 val localVT = VT 352 val tableRowLength = rowLength 353 val tableColumnLength = columnLength 354 val result = Array.ofDim[String](tableRowLength, tableColumnLength) 355 for( j <- 1 to localVT.length ) { 356 result(0)(j) = localVT(j - 1).toString 357 } 358 for( j <- localVT.length + 1 to tableColumnLength - 1 ) { 359 result(0)(j) = localVN(j - localVT.length - 1).toString 360 } 361 for( i <- 1 to ( tableRowLength - 1 ) ) { 362 result(i)(0) = (i - 1).toString 363 } 364 for( i <- 0 to (tableRowLength - 1) ) { 365 for( j <- 0 to (tableColumnLength - 1) ) { 366 if( result.isEmpty != false ) { 367 result(i)(j) = null 368 } 369 } 370 } 371 372 result 373 } 374 375 /* 376 * Function name: getItemGroup 377 * Function description: 对于输入的文法,建立初始化的项目集 378 * Input parameters: 无 379 * Return value: -Unit 380 * Exception: 未处理 381 * Author: 来自高山 382 * Created date: Wed Oct 23 2019 +0800 383 * Editor: 来自高山 384 * Edited Date: Sun Oct 27 2019 +0800 385 */ 386 def getItemGroup(): Unit = { 387 val ldx = ( relations(0)._1, "·" + relations(0)._2, "#" ) 388 val I0 = getClosure( ArrayBuffer(ldx) ) 389 val wholeCharacters = allCharacters 390 var tot = 0 391 // var cnt = 0 392 itemGroup(I0) = tot 393 var appendFlag = true 394 while (appendFlag == true) { 395 var originalAns = Map[ ArrayBuffer[ (String, String, String) ], Int ]() 396 originalAns = itemGroup.clone() 397 //为什么用I作为遍历变量不行?! 398 for(item <- itemGroup.keys) { 399 for (ch <- wholeCharacters) { 400 val newItem = go(item, ch.toString).sorted 401 if (newItem.isEmpty == false && itemGroup.contains(newItem) == false) { 402 tot += 1 403 itemGroup(newItem) = tot 404 } 405 } 406 } 407 if( originalAns.equals(itemGroup) == true ) { 408 appendFlag = false 409 // println( cnt + ", all same" ) 410 // cnt += 1 411 } 412 else { 413 originalAns.clear() 414 originalAns = itemGroup.clone() 415 // println( cnt + ", changed" ) 416 // cnt += 1 417 } 418 } 419 } 420 421 /* 422 * Function name: getItems 423 * Function description: 返回文法的初始项目集I0 424 * Input parameters: 无 425 * Return value: -ArrayBuffer[String](文法的项目集,第一个元素是文法产生式左边符号,第二个是对应的右边字符串所生成的项目) 426 * Exception: 未处理 427 * Author: 来自高山 428 * Created date: Wed Oct 23 2019 +0800 429 * Editor: 来自高山 430 * Edited Date: Sar Oct 26 2019 +0800 431 */ 432 def getItems(): ArrayBuffer[ (String, String, String) ] = { 433 val result = new ArrayBuffer[ (String, String, String) ]() 434 val localRelations = relations 435 //initiate 436 for (ex <- localRelations) { 437 if (ex._3 != "א") { 438 result += ((ex._1, "·" + ex._2, "#")) 439 result += ((ex._1, "·" + ex._3, "#")) 440 } 441 else { 442 result += ((ex._1, "·" + ex._2, "#")) 443 } 444 } 445 result 446 } 447 448 /* 449 * Function name: go 450 * Function description: 求給定项目对于特定字符的下一状态 451 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), String(特定字符) 452 * Return value: -ArrayBuffer[ (String, String, String) ](給定项目对于特定字符的下一状态) 453 * Exception: 未处理 454 * Author: 来自高山 455 * Created date: Sat Oct 26 2019 +0800 456 * Editor: 来自高山 457 * Edited Date: Sat Oct 26 2019 +0800 458 */ 459 def go( I: ArrayBuffer[ (String, String, String) ], X: String ): ArrayBuffer[ (String, String, String) ] = { 460 //GO(I, X) = CLOSURE(J) 461 //J = {任何形如[A->αX·β, a]的项目|[A->α·Xβ, a]∈I} 462 val ans = new ArrayBuffer[ (String, String, String) ]() 463 val items = new ArrayBuffer[ (String, String, String) ]() 464 465 for( ex <- I ) { 466 val pointPosition = ex._2.indexOf("·") 467 //· 不在最右边 468 if (pointPosition < ex._2.length - 1) { 469 val A = ex._1 470 val possibleX = ex._2( pointPosition + 1) 471 // αXβ 472 val noPointExpressionPart2 = ex._2.replace("·", "") 473 if( X == possibleX.toString ) { 474 // αX·β 475 val newPart2 = noPointExpressionPart2.substring(0, pointPosition + 1) + "·" + 476 noPointExpressionPart2.substring(pointPosition + 1, noPointExpressionPart2.length) 477 val a = ex._3 478 items += ( (A, newPart2, a) ) 479 } 480 } 481 } 482 ans.appendAll( getClosure(items) ) 483 ans 484 } 485 486 /* 487 * Function name: getClosure 488 * Function description: 求給定项目集的闭包 489 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定的项目集) 490 * Return value: -ArrayBuffer[ (String, String, String) ](給定项目集的闭包) 491 * Exception: 未处理 492 * Author: 来自高山 493 * Created date: Sat Oct 26 2019 +0800 494 * Editor: 来自高山 495 * Edited Date: Sun Oct 27 2019 +0800 496 */ 497 def getClosure( items: ArrayBuffer[ (String, String, String) ] ): ArrayBuffer[ (String, String, String) ] = { 498 val result = new ArrayBuffer[ (String, String, String) ]() 499 result.appendAll(items) 500 val localFIRST = FIRST() 501 var addFlag = true 502 var cnt = 1 503 while (addFlag == true ) { 504 val originalResult = new ArrayBuffer[(String, String, String)]() 505 originalResult.appendAll(result) 506 for (ex <- result) { 507 508 val pointPosition = ex._2.indexOf("·") 509 //· 不在最右边 510 if (pointPosition < ex._2.length - 1) { 511 //B在 · 的右边 512 val B = ex._2(pointPosition + 1) 513 val a = ex._3 514 515 // case 1: β != Φ and a != # or 516 // case 2: β != Φ and a = # 517 if (pointPosition < ex._2.length - 2) { 518 val β = ex._2(pointPosition + 2) 519 // ξ 520 val rightExpressionsOfB = getRightExpressions(B.toString) 521 val FIRST_Of_βa = localFIRST(β.toString) 522 for (b <- FIRST_Of_βa) { 523 for (ksi <- rightExpressionsOfB) { 524 val tmp = ((B.toString, "·" + ksi, b.toString)) 525 526 if (result.contains(tmp) == false) { 527 result += tmp 528 } 529 } 530 } 531 } 532 // case 3: β = Φ and a equals any character 533 if (pointPosition == ex._2.length - 2) { 534 val rightExpressionsOfB = getRightExpressions(B.toString) 535 val FIRST_Of_βa = localFIRST(a.toString) 536 for (b <- FIRST_Of_βa) { 537 for (ksi <- rightExpressionsOfB) { 538 val tmp = ((B.toString, "·" + ksi, b.toString)) 539 if (result.contains(tmp) == false) { 540 result += tmp 541 } 542 } 543 } 544 } 545 } 546 } 547 if (result != originalResult) { 548 originalResult.remove(0, originalResult.length) 549 originalResult.appendAll(result) 550 cnt += 1 551 } 552 else { 553 addFlag = false 554 cnt += 1 555 } 556 } 557 result 558 } 559 560 /* 561 * Function name: getRightExpressions 562 * Function description: 获取給定非终结符所在产生式的右部,可能不止一个,因此返回值是String类型的ArrayBuffer数组 563 * Input parameters: -String(給定的非终结符) 564 * Return value: -ArrayBuffer[String](給定非终结符所在产生式的右部) 565 * Exception: 未处理 566 * Author: 来自高山 567 * Created date: Fri Oct 25 2019 +0800 568 * Editor: 来自高山 569 * Edited Date: Fri Oct 25 2019 +0800 570 */ 571 def getRightExpressions(ch: String): ArrayBuffer[String] = { 572 val result = new ArrayBuffer[String]() 573 val localRelations = relations 574 for( ex <- localRelations ) { 575 if( ex._1 == ch ) { 576 if( ex._3 != "א" ) { 577 result += ex._2 578 result += ex._3 579 } 580 else { 581 result += ex._2 582 } 583 } 584 } 585 result 586 } 587 588 def getSingleRelation( ch: String ): ArrayBuffer[ (String, String, String) ] = { 589 val result = new ArrayBuffer[ (String, String, String) ]() 590 val localRelations = relations 591 for( ex<- localRelations ) { 592 if(ex._1 == ch ) { 593 result += ex 594 } 595 } 596 result 597 } 598 599 /* 600 * Function name: splitString 601 * Function description: 从字符串的首字符的左边到尾字符的右边,依次插入点“·”;每插入一个点即将其作为元素加入待返回String类型的ArrayBuffer数组 602 * Input parameters: -String(待处理的String类型的字符串) 603 * Return value: -ArrayBuffer[String](输入字符串依次添加点“·”为元素的字符串数组) 604 * Exception: 未处理 605 * Author: 来自高山 606 * Created date: Wed Oct 23 2019 +0800 607 * Editor: 来自高山 608 * Edited Date: Wed Oct 23 2019 +0800 609 */ 610 def splitString( string: String ): ArrayBuffer[String] = { 611 val result = new ArrayBuffer[String]() 612 val stringLength = string.length 613 for( i <- 0 to stringLength ) { 614 result += string.substring(0, i) + "·" + string.substring(i, stringLength) 615 } 616 result 617 } 618 619 /* 620 * Function name: displayStack 621 * Function description: 输出栈的所有元素 622 * Input parameters: -mutable.Stack[String](待处理的String类型的栈) 623 * Return value: -String(栈所有元素组成的字符串) 624 * Exception: 未处理 625 * Author: 来自高山 626 * Created date: Mon Oct 21 2019 +0800 627 * Editor: 来自高山 628 * Edited Date: Mon Oct 21 2019 +0800 629 */ 630 def displayStack( stack: mutable.Stack[String] ): String = { 631 var result = "" 632 for( ex <- stack ) { 633 result += ex 634 } 635 result 636 } 637 638 /* 639 * Function name: initiate 640 * Function description: 初始化全局变量 641 * Input parameters: the absolute path of the language-rule source file 642 * Return value: 无 643 * Exception: 未处理 644 * Author: 来自高山 645 * Created date: Sat Oct 19 2019 +0800 646 * Editor: 来自高山 647 * Edited Date: Sun Oct 27 2019 +0800 648 */ 649 def initiate( filePath: String ): Unit = { 650 LL1_G = parseFile(filePath) 651 allCharacters = getWholeCharacters(LL1_G) 652 usedCharacters = allCharacters 653 relations = getRelation(LL1_G) 654 VN = getVN(allCharacters) 655 VT = getVT(allCharacters) 656 val leftCharacters = subString(allCandidateLetters, VN) 657 //relations += ( ( leftCharacters(0).toString, (relations(0)._1), "א" ) ) 658 relations.insert(0, ( leftCharacters(0).toString, (relations(0)._1), "א" ) ) 659 VN += leftCharacters(0).toString 660 usedCharacters += leftCharacters(0).toString 661 allCharacters += leftCharacters(0).toString 662 663 allCharacters += "#" 664 usedCharacters += "#" 665 VT += "#" 666 getItemGroup 667 columnLength = VN.length + VT.length + 1 668 rowLength = itemGroup.size + 1 669 } 670 671 /* 672 * Function name: subString 673 * Function description: 获取两输入字符串的差集(要求两者均非空) 674 * Input parameters: 无 675 * Return value: -String(两输入字符串的差集) 676 * Exception: 未处理 677 * Author: 来自高山 678 * Created date: Sat Oct 19 2019 +0800 679 * Editor: 来自高山 680 * Edited Date: Sat Oct 19 2019 +0800 681 */ 682 def subString( usedCharacters: String, localCandidateLetters: String ): String = { 683 require( usedCharacters.length != 0 && localCandidateLetters.length != 0 ) 684 var ans = "" 685 var A = usedCharacters 686 var B = localCandidateLetters 687 if( A.length < B.length ) { 688 val tmp = A 689 A = B 690 B = tmp 691 } 692 for( i <- 0 to (A.length - 1) ) { 693 var j = 0 694 while( j < B.length && B(j) != A(i) ) { 695 j += 1 696 } 697 if( j == B.length ) { 698 ans += A(i) 699 } 700 } 701 ans 702 } 703 704 /* 705 * Function name: displayRelations 706 * Function description: display all he language rules 707 * Input parameters: 无 708 * Return value: 无 709 * Exception: 未处理 710 * Author: 来自高山 711 * Created date: Sat Oct 19 2019 +0800 712 * Editor: 来自高山 713 * Edited Date: Sat Oct 19 2019 +0800 714 */ 715 def displayRelations(): Unit = { 716 for( ex <- relations ) { 717 if( ex._3 != "א" ) { 718 println( ex._1 + "->" + ex._2 + "|" + ex._3 ) 719 } 720 else { 721 println( ex._1 + "->" + ex._2 ) 722 } 723 } 724 } 725 726 /* 727 * Function name: parseFile 728 * Function description: 解析文本文件,保存在数组中 729 * Input parameters: 文本绝对路径 730 * Return value: -ArrayBuffer[ ( String, String ) ](String类型的元组ArrayBuffer数组) 731 * Exception: 未处理 732 * Author: 来自高山 733 * Created date: Fri Oct 18 2019 +0800 734 * Editor: 来自高山 735 * Edited Date: Fri Oct 18 2019 +0800 736 */ 737 def parseFile( filePath: String ): ArrayBuffer[ ( String, String ) ] = { 738 val result = new ArrayBuffer[ ( String, String ) ]( countLines( readFromTxtByLine(filePath) ) ) 739 val sourceFile = readFromTxtByLine(filePath) //filePath 740 for( line <- sourceFile ) { 741 val tmp = line.split( "->", 2 ) 742 result += ( ( tmp.head, tmp.last ) ) 743 } 744 result 745 } 746 747 /* 748 * Function name: countLines 749 * Function description: 计算文本行数,用于创建接收数组时开辟相应空间 750 * Input parameters: -Array[String](文本文件数据构成的数组) 751 * Return value: -Int(文本行数) 752 * Exception: 未处理 753 * Author: 来自高山 754 * Created date: Fri Oct 18 2019 +0800 755 * Editor: 来自高山 756 * Edited Date: Sat Oct 19 2019 +0800 757 */ 758 def countLines( sourceFile: Array[String] ): Int = { 759 var cnt = 0 760 for( line <- sourceFile ) { 761 cnt += 1 762 } 763 cnt 764 } 765 766 /* 767 * Function name: readFromTxtByLine 768 * Function description: 读取文本文件 769 * Input parameters: -String(文本文件绝对路径) 770 * Return value: -Array[String](文本文件构成的数组,每行数据占一个数组元素) 771 * Exception: -未处理 772 * Author: 来自高山 773 * Created date: Fri Oct 18 2019 +0800 774 * Editor: 来自高山 775 * Edited Date: Fri Oct 18 2019 +0800 776 */ 777 def readFromTxtByLine(filePath: String): Array[String] = { 778 import scala.io.Source 779 val source = Source.fromFile(filePath, "UTF-8") 780 //val lineIterator = source.getLines() 781 //lineIterator.foreach() 782 val lines = source.getLines().toArray 783 source.close() 784 //println(lines.size) 785 lines 786 } 787 788 /* 789 * Function name: getWholeCharacters 790 * Function description: 获取文法的除“|”之外的所有字符 791 * Input parameters: -ArrayBuffer[ (String, String) ](由文法左右两部分字符构成一个元组的数组,筛掉“|”) 792 * Return value: -String(文法的除“|”之外的所有字符) 793 * Exception: 未处理(有出错提示) 794 * Author: 来自高山 795 * Created date: Fri Oct 11 2019 +0800 796 * Editor: 来自高山 797 * Edited Date: Fri Oct 11 2019 +0800 798 */ 799 def getWholeCharacters( string: ArrayBuffer[ (String, String) ] ): String = { 800 var wholeCharacters = "" 801 for( expression <- string ) { 802 wholeCharacters += expression._1 + expression._2 803 } 804 val pattern = new Regex("\\|") 805 val result = pattern replaceAllIn( wholeCharacters, "" ) 806 if( result.isEmpty ) 807 "function getWholeCharacters failed" 808 else 809 result.distinct 810 } 811 /* 812 * Function name: getVN 813 * Function description: 获取文法的所有非终结符(non-terminal character),默认大写字母为非终结符,使用正则表达式匹配 814 * Input parameters: -String(函数getWholeCharacters传来的文法的所有字符) 815 * Return value: -String(文法的所有非终结符) 816 * Exception: 未处理(有出错提示) 817 * Author: 来自高山 818 * Created date: Fri Oct 11 2019 +0800 819 * Editor: 来自高山 820 * Edited Date: Fri Oct 11 2019 +0800 821 */ 822 def getVN( string: String ): String = { 823 //match big letter: 824 //^[A-Z]+$ 825 val pattern = new Regex("[A-Z]")//("^[A-Z]+$") 826 if( (pattern findAllIn string) != null ) 827 (pattern findAllIn string).mkString("") 828 else 829 "function getVN failed" 830 } 831 832 /* 833 * Function name: getVT 834 * Function description: 获取文法的所有非终结符(terminal character),默认大写字母外的字符为终结符,使用正则表达式匹配 835 * Input parameters: -String(函数getWholeCharacters传来的文法的所有字符) 836 * Return value: -String(文法的所有终结符) 837 * Exception: 未处理(有出错提示) 838 * Author: 来自高山 839 * Created date: Fri Oct 11 2019 +0800 840 * Editor: 来自高山 841 * Edited Date: Fri Oct 11 2019 +0800 842 */ 843 def getVT( string: String ): String = { 844 val pattern1 = new Regex("[A-Z]") 845 val pattern2 = new Regex("\\|") 846 val firstFilter = pattern1 replaceAllIn( string, "" ) 847 val result = pattern2 replaceAllIn( firstFilter, "" ) 848 if( result.isEmpty == false ) 849 result 850 else 851 return "function getVT failed" 852 } 853 /* 854 * Function name: getRelation 855 * Function description: 获取文法每一行对应的推导关系,若文法只推出了1项(即没有符号“|”),则返回元组的第三个用希伯来字母“א”示空 856 * Input parameters: -ArrayBuffer[ (String, String)(已经分割好的文法左右部分构成的数组) 857 * Return value: -ArrayBuffer[ (String, String, String) ](元组第一个元素为推导式左边符号,第二为右边第二个符号串,第三为右边(若有)第三个符号串) 858 * Exception: 未处理 859 * Author: 来自高山 860 * Created date: Fri Oct 11 2019 +0800 861 * Editor: 来自高山 862 * Edited Date: Fri Oct 11 2019 +0800 863 */ 864 def getRelation( string: ArrayBuffer[ (String, String) ] ): ArrayBuffer[ (String, String, String) ] = { 865 val relation = new ArrayBuffer[ (String, String, String) ]() 866 for( expression <- string ) { 867 if( expression._2.contains("|") == false ) { 868 relation += ( ( expression._1, expression._2, "א" ) ) 869 } 870 else { 871 val tmp = expression._2.split("\\|", 2 ) 872 relation += ( ( expression._1, tmp.head, tmp.last ) ) 873 } 874 } 875 relation 876 } 877 878 /* 879 * Function name: findFirst 880 * Function description: 获取指定字符的右边两个(可能是一个)导出字符串的首个非 ε 组成的字符串 881 * Input parameters: -String(指定字符) 882 * Return value: -String(指定字符的右边两个(可能是一个)导出字符串的首个非 ε 组成的字符串) 883 * Exception: 未处理 884 * Author: 来自高山 885 * Created date: Fri Oct 11 2019 +0800 886 * Editor: 来自高山 887 * Edited Date: Fri Oct 11 2019 +0800 888 */ 889 def findFirst( ch: String ): String = { 890 891 val localRelations = relations 892 var result = "" 893 for( ex <- localRelations ) { 894 if( ch == ex._1 ) { 895 if( ex._3 != "א" ) { 896 if( VT.contains( ex._2(0) ) && ex._2(0) != 'ε' ) { 897 result += ex._2(0).toString 898 } 899 if( VT.contains( ex._3(0) ) && ex._3(0) != 'ε' ) { 900 result += ex._3(0).toString 901 } 902 } 903 else { 904 if( VT.contains( ex._2(0) ) && ex._2(0) != 'ε' ) { 905 result += ex._2(0).toString 906 } 907 } 908 } 909 } 910 result 911 } 912 913 /* 914 * Function name: judgeOnlyOneVoidSuccession 915 * Function description: 判断指定字符是否可推出唯一的字符ε 916 * Input parameters: -String(指定字符串) 917 * Return value: -Boolean(存在则true,否则false) 918 * Exception: 未处理 919 * Author: 来自高山 920 * Created date: Fri Oct 11 2019 +0800 921 * Editor: 来自高山 922 * Edited Date: Fri Oct 11 2019 +0800 923 */ 924 def judgeOnlyOneVoidSuccession( ch: String ): Boolean = { 925 val localRelations = relations 926 var result = 1 927 for( ex <- localRelations ) { 928 if( ch == ex._1 ) { 929 if( ex._3 != "א" ) { 930 if( ( ex._2.length == 1 && ex._2(0) == 'ε' ) || (ex._3.length == 1 && ex._3(0) == 'ε') ) { 931 result = 1 932 } 933 else { 934 result = 0 935 } 936 } 937 else { 938 if( ( ex._2.length == 1 && ex._2(0) == 'ε' ) ) { 939 result = 1 940 } 941 else { 942 result = 0 943 } 944 } 945 } 946 } 947 if( result == 1 ) true else false 948 } 949 950 /* 951 * Function name: judgeCaseXY 952 * Function description: 判断构造FIRST集时可能的第3种情况的(1),即若X->Y...是一个产生式且Y∈VN(省略若干描述) 953 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 954 * Return value: -Boolean(满足则true,否则false) 955 * Exception: 未处理 956 * Author: 来自高山 957 * Created date: Sat Oct 12 2019 +0800 958 * Editor: 来自高山 959 * Edited Date: Sat Oct 12 2019 +0800 960 */ 961 def judgeCaseXY( ch: Char ): Boolean = { 962 val localVN = VN 963 val localRelations = relations 964 var result = 0 965 if( localVN.contains(ch) == true ) { 966 for( ex <- localRelations ) { 967 if( ex._1(0) == ch ) { 968 if( localVN.contains( ex._2(0) ) || localVN.contains( ex._3(0) ) ) { 969 result += 1 970 } 971 } 972 } 973 } 974 if( result > 0 ) 975 true 976 else 977 false 978 } 979 980 /* 981 * Function name: findCase_Y_In_XY 982 * Function description: 获取构造FIRST集时可能的第3种情况的(1),即若X->Y...是一个产生式且Y∈VN(省略若干描述)时的Y 983 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 984 * Return value: -String(Y构成的String字符串,无则为空) 985 * Exception: 未处理 986 * Author: 来自高山 987 * Created date: Sat Oct 12 2019 +0800 988 * Editor: 来自高山 989 * Edited Date: Sat Oct 12 2019 +0800 990 */ 991 def findCase_Y_In_XY( ch: Char ): String = { 992 val localVN = VN 993 val localRelations = relations 994 var result = "" 995 if( localVN.contains(ch) == true ) { 996 for( ex <- localRelations ) { 997 if( ex._1(0) == ch ) { 998 if( ex._3 != "א" ) { 999 if( localVN.contains( ex._2(0) ) == true ) { 1000 result += ex._2(0).toString 1001 } 1002 if( localVN.contains( ex._3(0) ) == true ) { 1003 result += ex._3(0).toString 1004 } 1005 } 1006 else { 1007 if( localVN.contains( ex._2(0) ) == true ) { 1008 result += ex._2(0).toString 1009 } 1010 } 1011 } 1012 } 1013 } 1014 result 1015 } 1016 1017 /* 1018 * Function name: findCase_Y_In_nY 1019 * Function description: 获取构造FIRST集时可能的第3种情况的(2)时的FIRST(Yi)中所有的非ε-元素(省略描述若干字) 1020 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 1021 * Return value: -String(FIRST(Yi)中所有的非ε-元素构成的String字符串,无则为空) 1022 * Exception: 未处理 1023 * Author: 来自高山 1024 * Created date: Sat Oct 12 2019 +0800 1025 * Editor: 来自高山 1026 * Edited Date: Sat Oct 12 2019 +0800 1027 */ 1028 def findCase_Y_In_nY( ch: Char ): String = { 1029 val localVN = VN 1030 val localRelations = relations 1031 var result = "" 1032 for( ex <- localRelations ) { 1033 if (ex._1 == ch.toString) { 1034 var tmp = "" 1035 1036 if (ex._3 != 'א') { 1037 var cnt = 0 1038 for (tx <- ex._2) { 1039 // add the element belongs to tmp 1040 if (localVN.contains(tx)) { 1041 tmp += tx.toString 1042 cnt += 1 1043 } 1044 // otherwise, reset tmp as empty string 1045 else { 1046 tmp = "" 1047 } 1048 } 1049 if (cnt == ex._2.length) { 1050 result += tmp 1051 } 1052 1053 // reset 1054 cnt = 0 1055 tmp = "" 1056 for (tx <- ex._3) { 1057 // add the element belongs to tmp 1058 if (localVN.contains(tx)) { 1059 tmp += tx.toString 1060 cnt += 1 1061 } 1062 // otherwise, reset result as empty string 1063 else { 1064 tmp = "" 1065 } 1066 } 1067 if (cnt == ex._3.length) { 1068 result += tmp 1069 } 1070 } 1071 else { 1072 tmp = "" 1073 var cnt = 0 1074 for (tx <- ex._2) { 1075 // add the element belongs to tmp 1076 if (localVN.contains(tx)) { 1077 tmp += tx.toString 1078 cnt += 1 1079 } 1080 // otherwise, reset tmp as empty string 1081 else { 1082 tmp = "" 1083 } 1084 } 1085 if (cnt == ex._2.length) { 1086 result += tmp 1087 } 1088 } 1089 } 1090 } 1091 result = result.distinct 1092 result 1093 } 1094 1095 /* 1096 * Function name: FIRST 1097 * Function description: 按照教材P78左下角的算法描述实现求解指定文法FIRST集;因用的是循环迭代求解,因此代码较长 1098 * Input parameters: -ArrayBuffer[ (String, String) ](产生式左右两部分分别构成元组的第1个和第2个元素) 1099 * Return value: -Map[ String, String ](Map的key是非终结符,value是其FIRST元素) 1100 * Exception: 未处理 1101 * Author: 来自高山 1102 * Created date: Mon Oct 14 2019 +0800 1103 * Editor: 来自高山 1104 * Edited Date: Sat Oct 19 2019 +0800 1105 */ 1106 def FIRST(): Map[ String, String ] = { 1107 val FIRST_Group = Map[ String, String ]() 1108 val wholeCharacters = allCharacters 1109 val localVT = VT 1110 val localVN = VN 1111 1112 for( character <- wholeCharacters ) { 1113 // case 1 1114 if( localVT.contains(character) ) { 1115 //if there exist the original key that equals the current one 1116 if( FIRST_Group.contains(character.toString) == true ) { 1117 val tmp = character.toString + FIRST_Group(character.toString) 1118 FIRST_Group(character.toString) = tmp.distinct 1119 } 1120 //otherwise 1121 else { 1122 FIRST_Group(character.toString) = character.toString 1123 } 1124 } 1125 1126 // case 2 1127 if( localVN.contains(character.toString) == true ) { 1128 // case 2.1 1129 val value = findFirst(character.toString) 1130 if ( value.length != 0 ) { 1131 if ( FIRST_Group.contains(character.toString) == true ) { 1132 for( ch <- value ) { 1133 val tmp = ch + FIRST_Group(character.toString) 1134 FIRST_Group(character.toString) = tmp.distinct 1135 } 1136 } 1137 else { 1138 FIRST_Group(character.toString) = value.toString 1139 } 1140 } 1141 1142 // case 2.2 1143 if( judgeOnlyOneVoidSuccession(character.toString) == true ) { 1144 if ( FIRST_Group.contains(character.toString) == true ) { 1145 val tmp = "ε" + FIRST_Group(character.toString) 1146 FIRST_Group(character.toString) = tmp.distinct 1147 } 1148 else { 1149 FIRST_Group(character.toString) = "ε" 1150 } 1151 } 1152 } 1153 1154 for( character <- wholeCharacters ) { 1155 // case 3 1156 // case 3.1 1157 if( judgeCaseXY(character) == true ) { 1158 val tmpReply = findCase_Y_In_XY(character) 1159 for( eachTmpReply <- tmpReply ) { 1160 if( FIRST_Group.contains(eachTmpReply.toString) == true ) { 1161 for (ex <- FIRST_Group(eachTmpReply.toString)) { 1162 if (ex != 'ε') { 1163 if (FIRST_Group.contains(character.toString) == true) { 1164 val tmp = ex.toString + FIRST_Group(character.toString) 1165 FIRST_Group(character.toString) = tmp.distinct 1166 } 1167 else { 1168 FIRST_Group(character.toString) = ex.toString 1169 } 1170 } 1171 } 1172 } 1173 } 1174 } 1175 1176 // case 3.2 1177 if( findCase_Y_In_nY(character).length > 0 ) { 1178 var flag = true 1179 val tmpReply = findCase_Y_In_nY(character) 1180 1181 for( ex <- tmpReply ) { 1182 if( localVN.contains(ex.toString) && FIRST_Group.contains(ex.toString) == true ) { 1183 if( FIRST_Group(ex.toString).contains("ε") == false ) { 1184 flag = false 1185 } 1186 } 1187 else { 1188 flag = false 1189 } 1190 if( flag == true ) { 1191 if (FIRST_Group.contains(character.toString) == true) { 1192 val tmp = FIRST_Group(ex.toString).replace( "ε", "" ) + FIRST_Group(character.toString) 1193 FIRST_Group(character.toString) = tmp.distinct 1194 } 1195 else { 1196 FIRST_Group(character.toString) = FIRST_Group(ex.toString).replace( "ε", "" ) 1197 } 1198 1199 } 1200 } 1201 } 1202 // case 3.3 1203 if( findCase_Y_In_nY(character).length > 0 ) { 1204 var flag = true 1205 val tmpReply = findCase_Y_In_nY(character) 1206 for( ex <- tmpReply ) { 1207 if( localVN.contains(ex.toString) && FIRST_Group.contains(ex.toString) == true ) { 1208 if( FIRST_Group(ex.toString).contains("ε") == false ) { 1209 flag = false 1210 } 1211 } 1212 else { 1213 flag = false 1214 } 1215 if( flag == true ) { 1216 1217 if (FIRST_Group.contains(character.toString) == true) { 1218 val tmp = "ε" + FIRST_Group(character.toString) 1219 FIRST_Group(character.toString) = tmp.distinct 1220 } 1221 else { 1222 FIRST_Group(character.toString) = "ε" 1223 } 1224 } 1225 } 1226 } 1227 } 1228 } 1229 FIRST_Group 1230 } 1231 1232 }
含GUI代码:
LR_1_try_GUI类(Scala):

1 import java.awt.{Color} 2 import java.awt.event.{ActionEvent, ActionListener} 3 4 import javax.swing.table.{AbstractTableModel} 5 import javax.swing.{JButton, JFileChooser, JFrame, JPanel, JScrollPane, JTable, JTextField, JTextPane} 6 import pojo.Analyse 7 8 import scala.collection.mutable 9 import scala.collection.mutable.{ArrayBuffer, Map} 10 import scala.util.matching.Regex 11 12 13 object LR_1_try_GUI { 14 private final var allCharacters = new String() 15 private final var relations = new ArrayBuffer[ (String, String, String) ]() 16 private final var VN = new String() 17 private final var VT = new String() 18 private final var rowLength = 0 19 private final var columnLength = 0 20 private final val itemGroup = Map[ ArrayBuffer[ (String, String, String) ], Int ]() 21 private final var LL1_G = new ArrayBuffer[ (String, String) ]() 22 private val allCandidateLetters = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩABCDEFGHIJKLMNOPQRSTUVWXYZ" 23 private final var usedCharacters = "" 24 25 val staticAnalyseList : ArrayBuffer[Analyse] = new ArrayBuffer[Analyse](); 26 var staticTestMatrix : Array[ Array[String] ] = new Array[Array[String]](0) 27 var staticStringBuilder : StringBuilder = new StringBuilder(); 28 var staticStringBuilder2 : StringBuilder = new StringBuilder(); 29 30 def main(args: Array[String]): Unit = { 31 GUI1 32 } 33 34 /* 35 * Function name: GUI1 36 * Function description: 实现图形化界面展示,开始界面 37 * Input parameters: 无 38 * Return value: 无 39 * Exception: 未处理 40 * Author: 来自高山 41 * Created date: Sun Oct 20 2019 +0800 42 * Editor: 来自高山 43 * Edited Date: Mon Oct 28 2019 +0800 44 */ 45 def GUI1(): Unit = { 46 val jFrame = new JFrame("LR(1)词法分析"); 47 val jPanel = new JPanel(); 48 jFrame.setBounds( 0, 10,1000,90); 49 50 val appendFileJButton2 = new JButton("开始分析"); 51 appendFileJButton2.setBounds( 100, 400,200,30); 52 appendFileJButton2.addActionListener(new ActionListener { 53 override def actionPerformed(e: ActionEvent): Unit = { 54 GUI2 55 jFrame.dispose() 56 } 57 }) 58 59 //添加文件按钮 60 val appendFileJButton = new JButton("添加文件"); 61 appendFileJButton.setBounds( 300, 400,200,30); 62 appendFileJButton.addActionListener(new ActionListener { 63 override def actionPerformed(e: ActionEvent): Unit = { 64 val fileChooser = new JFileChooser(); 65 fileChooser.showOpenDialog(jFrame); 66 val filePath = fileChooser.getSelectedFile.getAbsolutePath 67 initiate(filePath) 68 utility 69 } 70 }) 71 72 val appendFileJButton3 = new JButton("退出程序") 73 appendFileJButton3.setBounds(500, 400, 200, 30) 74 appendFileJButton3.addActionListener(new ActionListener { 75 override def actionPerformed(e: ActionEvent): Unit = { 76 jFrame.dispose() 77 } 78 }) 79 80 jPanel.add(appendFileJButton) 81 jPanel.add(appendFileJButton2) 82 jPanel.add(appendFileJButton3) 83 jPanel.setBackground(Color.gray) 84 jFrame.add(jPanel) 85 import java.awt.FlowLayout 86 jPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 200, 20)) 87 jFrame.setResizable(false); 88 jFrame.setVisible(true); 89 } 90 91 /* 92 * Function name: GUI2 93 * Function description: 实现图形化界面展示,分析界面 94 * Input parameters: 无 95 * Return value: 无 96 * Exception: 未处理 97 * Author: 菊花侠 98 * Created date: Sat Oct 19 2019 +0800 99 * Editor: 来自高山 100 * Edited Date: Mon Oct 28 2019 +0800 101 */ 102 def GUI2(): Unit = { 103 val jFrame = new JFrame("LR(1)词法分析"); 104 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) 105 jFrame.setResizable(false) 106 jFrame.setBounds(0,0,1000,1000); 107 jFrame.setLayout(null) 108 109 //输入行 110 val inputJPanel = new JPanel(); 111 inputJPanel.setBounds(0,0,1000,30); 112 inputJPanel.setLayout(null); 113 114 val inputJTextField = new JTextField(); 115 inputJTextField.setBounds(0,0,300,30); 116 val inputJButton = new JButton("确认"); 117 inputJButton.setBounds(320,0,60,30); 118 inputJPanel.add(inputJTextField) 119 inputJPanel.add(inputJButton) 120 jFrame.add(inputJPanel); 121 122 123 val displayFileJTextPane = new JTextPane(); 124 displayFileJTextPane.setEditable(false); 125 126 val displayFileJScrollPane = new JScrollPane(); 127 displayFileJScrollPane.setBounds(0,64,1000,300); 128 displayFileJScrollPane.setViewportView(displayFileJTextPane); 129 jFrame.add(displayFileJScrollPane) 130 131 val appendFileJButton = new JButton("显示初始文法") 132 appendFileJButton.setBounds(0, 32,120,30) 133 appendFileJButton.addActionListener(new ActionListener { 134 override def actionPerformed(e: ActionEvent): Unit = { 135 displayFileJTextPane.setText(staticStringBuilder2.toString()); 136 } 137 }) 138 139 val appendFileJButton2 = new JButton("返回") 140 appendFileJButton2.setBounds(220, 32, 120, 30) 141 appendFileJButton2.addActionListener(new ActionListener { 142 override def actionPerformed(e: ActionEvent): Unit = { 143 GUI1 144 jFrame.dispose() 145 } 146 }) 147 148 val appendFileJButton3 = new JButton("退出") 149 appendFileJButton3.setBounds(440, 32, 120, 30) 150 appendFileJButton3.addActionListener(new ActionListener { 151 override def actionPerformed(e: ActionEvent): Unit = { 152 jFrame.dispose() 153 } 154 }) 155 156 jFrame.add(appendFileJButton) 157 jFrame.add(appendFileJButton2) 158 jFrame.add(appendFileJButton3) 159 160 val dataMode1 = new AbstractTableModel() { 161 162 override def getColumnCount = 5 163 164 override 165 166 def getRowCount = staticAnalyseList.length 167 168 override 169 170 def getValueAt(row: Int, col: Int): String = { 171 val a = staticAnalyseList(row); 172 if(col == 0){ 173 return a.getStep(); 174 } 175 if(col == 1){ 176 return a.getAnalysisStack; 177 } 178 if(col == 2){ 179 return a.getRemainingString; 180 } 181 if(col == 3){ 182 return a.getProductionType; 183 } 184 if(col == 4){ 185 return a.getAction; 186 } 187 return new String(); 188 } 189 } 190 191 val table1JScrollPane = new JScrollPane(); 192 val table1JTable = new JTable(dataMode1); 193 194 195 196 table1JScrollPane.setBounds(0,370,690,300) 197 table1JScrollPane.setViewportView(table1JTable); 198 199 val table1JTextPaneScrollPan = new JScrollPane(); 200 table1JTextPaneScrollPan.setBounds(692,370,300,300); 201 202 203 val table1JTextPane = new JTextPane(); 204 table1JTextPane.setEditable(false); 205 table1JTextPaneScrollPan.setViewportView(table1JTextPane); 206 jFrame.add(table1JTextPaneScrollPan); 207 jFrame.add(table1JScrollPane); 208 209 val table2JTable = new JTable(); 210 table2JTable.setBounds(0,682,1000,300); 211 212 val table2JScrollPane = new JScrollPane(); 213 214 table2JScrollPane.setBounds(0,682,1000,300) 215 table2JScrollPane.setViewportView(table2JTable);//ryr 216 217 table2JScrollPane.add(table2JTable) 218 jFrame.add(table2JTable); 219 220 jFrame.setVisible(true); 221 222 inputJButton.addActionListener(new ActionListener { 223 override def actionPerformed(e: ActionEvent): Unit = { 224 staticAnalyseList.clear(); 225 staticTestMatrix = createMatrix(); 226 analyse( inputJTextField.getText() + "#" ); 227 val dataMode1 = new AbstractTableModel() { 228 229 override def getColumnCount = 5 230 231 override 232 233 def getRowCount = staticAnalyseList.length 234 235 override 236 237 def getValueAt(row: Int, col: Int): String = { 238 val a = staticAnalyseList(row); 239 if(col == 0){ 240 return a.getStep(); 241 } 242 if(col == 1){ 243 return a.getAnalysisStack; 244 } 245 if(col == 2){ 246 return a.getRemainingString; 247 } 248 if(col == 3){ 249 return a.getProductionType; 250 } 251 if(col == 4){ 252 return a.getAction; 253 } 254 return new String(); 255 } 256 257 } 258 table1JTable.setModel(dataMode1); 259 260 val dataMode2 = new AbstractTableModel() { 261 262 override def getColumnCount = columnLength 263 264 override 265 266 def getRowCount = rowLength 267 268 override 269 270 def getValueAt(row: Int, col: Int) = staticTestMatrix(row)(col) 271 } 272 table2JTable.setModel(dataMode2); 273 table1JTextPane.setText(staticStringBuilder.toString()) 274 } 275 }) 276 } 277 278 /* 279 * Function name: utility 280 * Function description: 辅助输出函数 281 * Input parameters: 无 282 * Return value: 无 283 * Exception: 未处理 284 * Author: 来自高山 285 * Created date: Mon Oct 28 2019 +0800 286 * Editor: 来自高山 287 * Edited Date: Mon Oct 28 2019 +0800 288 */ 289 def utility(): Unit = { 290 291 staticStringBuilder.append( "after expanding the language rules:" + "\r\n" ) 292 displayRelations() 293 staticStringBuilder.append( "**************" + "\r\n" ) 294 staticStringBuilder.append( "FIRST:" + "\r\n" ) 295 val testFIRST = FIRST() 296 for( ex <- testFIRST ) { 297 staticStringBuilder.append( "FIRST(" + ex._1 + ") = {" + ex._2.mkString(",") + "}" + "\r\n" ) 298 } 299 staticStringBuilder.append( "**************" + "\r\n" ) 300 //test getItemGroup 301 var cnt4 = 0 302 for( ex <- itemGroup.toList.sortBy(_._2) ) { 303 staticStringBuilder.append( "I" + ex._2 + ":" + "\r\n" ) 304 for (tx <- ex._1 ) { 305 306 staticStringBuilder.append( tx._1 + "->" + tx._2 + ", " + tx._3 + "\r\n" ) 307 } 308 staticStringBuilder.append( "^^^^^^^^^^^^^^^^^^^^^^^^" + "\r\n" ) 309 cnt4 += 1 310 } 311 staticStringBuilder.append( "**************" + "\r\n" ) 312 val test_createMatrix = createMatrix 313 staticTestMatrix = test_createMatrix 314 for ( i <- 0 to test_createMatrix.length - 1 ) { 315 for ( j <- 0 to test_createMatrix(i).length - 1 ) { 316 print( test_createMatrix(i)(j) + " " ) 317 } 318 319 } 320 } 321 322 /* 323 * Function name: analyse 324 * Function description: 对指定的字符串进行LR(1)分析 325 * Input parameters: -String(输入的指定字符串) 326 * Return value: -Boolean(分析成功则返回true,否则false) 327 * Exception: 未处理(有出错提示) 328 * Author: 来自高山 329 * Created date: Mon Oct 28 2019 +0800 330 * Editor: 来自高山 331 * Edited Date: Mon Oct 28 2019 +0800 332 */ 333 def analyse( expression: String ): Boolean = { 334 val statusStack = new mutable.Stack[String]() 335 val characterStack = new mutable.Stack[String]() 336 val analyseTable = createMatrix() 337 var expr = expression 338 var flag = false 339 var repeat = true 340 statusStack.push("0") 341 characterStack.push("#") 342 var tot = 0 343 staticAnalyseList.append(new Analyse("步骤","状态栈","符号栈","剩余字符串","动作")); 344 staticAnalyseList.append( new Analyse( tot.toString, statusStack.reverse.mkString(","), 345 characterStack.reverse.mkString(""), expr, "initiate") ) 346 tot += 1 347 case class characterToColumn(a: String) { 348 var ans = -1 349 for( j <- 1 to (columnLength - 1) ) { 350 if( analyseTable(0)(j) == a ) { 351 ans = j 352 } 353 } 354 //ans 355 } 356 while ( repeat == true ) { 357 // s = statusTop 358 val statusTop = statusStack.top 359 val a = expr(0) 360 361 val aColumn = characterToColumn(a.toString).ans 362 var sRow = statusTop.toInt 363 if(sRow == 0 ) sRow += 1 else sRow += 1 364 365 if( analyseTable(sRow)(aColumn)(0) == 'S' ) { 366 val newStatus = analyseTable(sRow)(aColumn).drop(1) 367 statusStack.push(newStatus) 368 characterStack.push(a.toString) 369 expr = expr.drop(1) 370 staticAnalyseList.append( new Analyse( tot.toString,statusStack.reverse.mkString(","), 371 characterStack.reverse.mkString(""), expr, "ACTION[" + statusTop + ", " + a + "]," + "状态 " + aColumn + 372 " 与符号 " + a + " 分别入栈") ) 373 tot += 1 374 } 375 else if( analyseTable(sRow)(aColumn)(0) == 'r' ) { 376 val exprLineNO = analyseTable(sRow)(aColumn).drop(1).toInt 377 val currentRelation = relations(exprLineNO) 378 379 var popLength = 0 380 if( currentRelation._3 != "א" ) { 381 popLength = currentRelation._2.length + currentRelation._3.length 382 } 383 else { 384 popLength = currentRelation._2.length 385 } 386 var cnt = popLength 387 val tmpCharacter = characterStack.reverse.toString.replace("Stack(", "").replace(")", 388 "").replace(",", "").replace(" ", "") 389 val reduceCharacter = tmpCharacter.drop(tmpCharacter.length - popLength) 390 while ( cnt >= 1 ) { 391 statusStack.pop() 392 characterStack.pop() 393 cnt -= 1 394 } 395 // s' = characterTop 396 val statusTop2 = statusStack.top.toInt 397 398 var sRow2 = -1 399 if( statusTop2 == 0 ) sRow2 = statusTop2 + 1 else sRow2 = statusTop2 + 1 400 401 val A = currentRelation._1 402 characterStack.push(A) 403 val tmp = analyseTable(sRow2)( characterToColumn(A).ans ) 404 statusStack.push(tmp) 405 406 staticAnalyseList.append( new Analyse( tot.toString, statusStack.reverse.mkString(","), 407 characterStack.reverse.mkString(""), expr, "GOTO[" + statusTop2 + ", " + A + "]" + 408 ",用产生式 " + A + "->" + reduceCharacter + " 进行规约") ) 409 tot += 1 410 } 411 else if( analyseTable(sRow)(aColumn) == "acc" ) { 412 413 staticAnalyseList.append( new Analyse( tot.toString,statusStack.reverse.mkString(","), 414 characterStack.reverse.mkString(""), expr, "ACTION[" + statusTop + ", " + a + "] = " + "acc, succeeded") ) 415 flag = true 416 repeat = false 417 } 418 else { 419 staticAnalyseList.append( new Analyse( tot.toString,statusStack.reverse.mkString(","), 420 characterStack.reverse.toString(), expr, "ACTION[" + statusTop + ", " + a + "] = " + 421 "error in " + "analyseTable[" + sRow + ", " + aColumn + "]") ) 422 flag = true 423 repeat = false 424 } 425 } 426 if(flag) true else false 427 } 428 429 /* 430 * Function name: createMatrix 431 * Function description: 构造ACTION与GOTO分析表 432 * Input parameters: 无 433 * Return value: -Array[ Array[String] ](分析表矩阵元素构成的二维数组) 434 * Exception: 未处理 435 * Author: 来自高山 436 * Created date: Mon Oct 28 2019 +0800 437 * Editor: 来自高山 438 * Edited Date: Mon Oct 28 2019 +0800 439 */ 440 def createMatrix(): Array[ Array[String] ] = { 441 val result = initiateMatrix() 442 val localVT = VT 443 val localVN = VN 444 445 case class getColumn( ch: String ) { 446 val matrix = initiateMatrix() 447 var ans = -1 448 for( j <- 0 to (columnLength - 1) ) { 449 if( matrix(0)(j) == ch ) { 450 ans = j 451 } 452 } 453 } 454 455 for( ex <- itemGroup ) { 456 for( tx <- ex._1 ) { 457 val pointPosition = tx._2.indexOf("·") 458 //· 不在最右边 459 //若项目[A->α·aβ] ∈ Ik,且GO(Ik, a) = Ij,a为终结符,则置ACTION[k, a]为“sj” 460 if (pointPosition < tx._2.length - 1) { 461 val a = tx._2( pointPosition + 1 ) 462 if( localVT.contains(a) == true && findItemOrder(ex._1, a.toString) != -1 ) { 463 val j = findItemOrder(ex._1, a.toString) 464 var tmpRow = -1 465 tmpRow = ex._2 + 1 466 result(tmpRow)( getColumn(a.toString).ans ) = "S" + j.toString 467 } 468 } 469 if (pointPosition == tx._2.length - 1 ) { 470 val a = tx._3 471 var tmpRow = -1 472 tmpRow = ex._2 + 1 473 result(tmpRow)(getColumn(a).ans) = "r" + ( findRelationOrder( (tx._1, 474 tx._2.replace("·", "") ) ) ) 475 } 476 if( tx._1 == relations(0)._1 && tx._2 == relations(0)._2 + "·" && tx._3 == "#" ) { 477 var tmpRow = -1 478 tmpRow = ex._2 + 1 479 result(tmpRow)( getColumn("#").ans ) = "acc" 480 } 481 } 482 for( ch <- localVN ) { 483 if( findItemOrder(ex._1, ch.toString) != -1 ) { 484 val gotoNumber = findItemOrder(ex._1, ch.toString) 485 var tmpRow = -1 486 tmpRow = ex._2 + 1 487 //A = ch 488 result(tmpRow)( getColumn(ch.toString).ans ) = gotoNumber.toString 489 } 490 } 491 } 492 result 493 } 494 495 /* 496 * Function name: findRelationOrder 497 * Function description: 获取产生式的位于文法的第几行,从0开始 498 * Input parameters: -(String, String)(給定的产生式) 499 * Return value: -Int(給定的产生式在給定文法中的行数) 500 * Exception: 未处理 501 * Author: 来自高山 502 * Created date: Mon Oct 28 2019 +0800 503 * Editor: 来自高山 504 * Edited Date: Mon Oct 28 2019 +0800 505 */ 506 def findRelationOrder( expression: (String, String) ): Int ={ 507 var ans = -1 508 var cnt = 0 509 val localRelations = relations 510 for( ex <- localRelations ) { 511 var expr = "" 512 if( ex._3 != "א" ) { 513 expr = ex._1 + ex._2 + ex._3 514 } 515 else { 516 expr = ex._1 + ex._2 517 } 518 if( expr.equals(expression._1 + expression._2) ) { 519 ans = cnt 520 } 521 cnt += 1 522 } 523 ans 524 } 525 526 /* 527 * Function name: findItemOrder 528 * Function description: 获取特定项目对于指定字符在项目集族中的编号,从0开始 529 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), -String(給定字符) 530 * Return value: -Int(給定的项目对于指定字符在项目集族中的编号) 531 * Exception: 未处理 532 * Author: 来自高山 533 * Created date: Mon Oct 28 2019 +0800 534 * Editor: 来自高山 535 * Edited Date: Mon Oct 28 2019 +0800 536 */ 537 def findItemOrder( item: ArrayBuffer[ (String, String, String) ], a: String ): Int = { 538 var ans = -1 539 val givenItem = go( item, a).sorted 540 val localItemGroup = itemGroup 541 for( ex <- localItemGroup ) { 542 if( ex._1.sorted.equals(givenItem) ) { 543 ans = ex._2 544 } 545 } 546 ans 547 } 548 549 /* 550 * Function name: initiateMatrix 551 * Function description: 初始化分析表,即ACTION表与GOTO表 552 * Input parameters: 无 553 * Return value: -Array[ Array[ String] ](已完成初始的分析表) 554 * Exception: 未处理 555 * Author: 来自高山 556 * Created date: Sun Oct 27 2019 +0800 557 * Editor: 来自高山 558 * Edited Date: Sun Oct 27 2019 +0800 559 */ 560 def initiateMatrix(): Array[ Array[ String] ] = { 561 val localVN = VN 562 val localVT = VT 563 val tableRowLength = rowLength 564 val tableColumnLength = columnLength 565 val result = Array.ofDim[String](tableRowLength, tableColumnLength) 566 for( j <- 1 to localVT.length ) { 567 result(0)(j) = localVT(j - 1).toString 568 } 569 for( j <- localVT.length + 1 to tableColumnLength - 1 ) { 570 result(0)(j) = localVN(j - localVT.length - 1).toString 571 } 572 for( i <- 1 to ( tableRowLength - 1 ) ) { 573 result(i)(0) = (i - 1).toString 574 } 575 for( i <- 0 to (tableRowLength - 1) ) { 576 for( j <- 0 to (tableColumnLength - 1) ) { 577 if( result.isEmpty != false ) { 578 result(i)(j) = null 579 } 580 } 581 } 582 583 result 584 } 585 586 /* 587 * Function name: getItemGroup 588 * Function description: 对于输入的文法,建立初始化的项目集 589 * Input parameters: 无 590 * Return value: -Unit 591 * Exception: 未处理 592 * Author: 来自高山 593 * Created date: Wed Oct 23 2019 +0800 594 * Editor: 来自高山 595 * Edited Date: Sun Oct 27 2019 +0800 596 */ 597 def getItemGroup(): Unit = { 598 val ldx = ( relations(0)._1, "·" + relations(0)._2, "#" ) 599 val I0 = getClosure( ArrayBuffer(ldx) ) 600 val wholeCharacters = allCharacters 601 var tot = 0 602 itemGroup(I0) = tot 603 var appendFlag = true 604 while (appendFlag == true) { 605 var originalAns = Map[ ArrayBuffer[ (String, String, String) ], Int ]() 606 originalAns = itemGroup.clone() 607 //为什么用I作为遍历变量不行?! 608 for(item <- itemGroup.keys) { 609 for (ch <- wholeCharacters) { 610 val newItem = go(item, ch.toString).sorted 611 if (newItem.isEmpty == false && itemGroup.contains(newItem) == false) { 612 tot += 1 613 itemGroup(newItem) = tot 614 } 615 } 616 } 617 if( originalAns.equals(itemGroup) == true ) { 618 appendFlag = false 619 } 620 else { 621 originalAns.clear() 622 originalAns = itemGroup.clone() 623 } 624 } 625 } 626 627 /* 628 * Function name: go 629 * Function description: 求給定项目对于特定字符的下一状态 630 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定项目), String(特定字符) 631 * Return value: -ArrayBuffer[ (String, String, String) ](給定项目对于特定字符的下一状态) 632 * Exception: 未处理 633 * Author: 来自高山 634 * Created date: Sat Oct 26 2019 +0800 635 * Editor: 来自高山 636 * Edited Date: Sat Oct 26 2019 +0800 637 */ 638 def go( I: ArrayBuffer[ (String, String, String) ], X: String ): ArrayBuffer[ (String, String, String) ] = { 639 //GO(I, X) = CLOSURE(J) 640 //J = {任何形如[A->αX·β, a]的项目|[A->α·Xβ, a]∈I} 641 val ans = new ArrayBuffer[ (String, String, String) ]() 642 val items = new ArrayBuffer[ (String, String, String) ]() 643 644 for( ex <- I ) { 645 val pointPosition = ex._2.indexOf("·") 646 //· 不在最右边 647 if (pointPosition < ex._2.length - 1) { 648 val A = ex._1 649 val possibleX = ex._2( pointPosition + 1) 650 // αXβ 651 val noPointExpressionPart2 = ex._2.replace("·", "") 652 if( X == possibleX.toString ) { 653 // αX·β 654 val newPart2 = noPointExpressionPart2.substring(0, pointPosition + 1) + "·" + 655 noPointExpressionPart2.substring(pointPosition + 1, noPointExpressionPart2.length) 656 val a = ex._3 657 items += ( (A, newPart2, a) ) 658 } 659 } 660 } 661 ans.appendAll( getClosure(items) ) 662 ans 663 } 664 665 /* 666 * Function name: getClosure 667 * Function description: 求給定项目集的闭包 668 * Input parameters: -ArrayBuffer[ (String, String, String) ](給定的项目集) 669 * Return value: -ArrayBuffer[ (String, String, String) ](給定项目集的闭包) 670 * Exception: 未处理 671 * Author: 来自高山 672 * Created date: Sat Oct 26 2019 +0800 673 * Editor: 来自高山 674 * Edited Date: Sun Oct 27 2019 +0800 675 */ 676 def getClosure( items: ArrayBuffer[ (String, String, String) ] ): ArrayBuffer[ (String, String, String) ] = { 677 val result = new ArrayBuffer[ (String, String, String) ]() 678 result.appendAll(items) 679 val localFIRST = FIRST() 680 var addFlag = true 681 var cnt = 1 682 while (addFlag == true ) { 683 val originalResult = new ArrayBuffer[(String, String, String)]() 684 originalResult.appendAll(result) 685 for (ex <- result) { 686 687 val pointPosition = ex._2.indexOf("·") 688 //· 不在最右边 689 if (pointPosition < ex._2.length - 1) { 690 //B在 · 的右边 691 val B = ex._2(pointPosition + 1) 692 val a = ex._3 693 694 // case 1: β != Φ and a != # or 695 // case 2: β != Φ and a = # 696 if (pointPosition < ex._2.length - 2) { 697 val β = ex._2(pointPosition + 2) 698 // ξ 699 val rightExpressionsOfB = getRightExpressions(B.toString) 700 val FIRST_Of_βa = localFIRST(β.toString) 701 for (b <- FIRST_Of_βa) { 702 for (ksi <- rightExpressionsOfB) { 703 val tmp = ((B.toString, "·" + ksi, b.toString)) 704 705 if (result.contains(tmp) == false) { 706 result += tmp 707 } 708 } 709 } 710 } 711 // case 3: β = Φ and a equals any character 712 if (pointPosition == ex._2.length - 2) { 713 val rightExpressionsOfB = getRightExpressions(B.toString) 714 val FIRST_Of_βa = localFIRST(a.toString) 715 for (b <- FIRST_Of_βa) { 716 for (ksi <- rightExpressionsOfB) { 717 val tmp = ((B.toString, "·" + ksi, b.toString)) 718 if (result.contains(tmp) == false) { 719 result += tmp 720 } 721 } 722 } 723 } 724 } 725 } 726 if (result != originalResult) { 727 originalResult.remove(0, originalResult.length) 728 originalResult.appendAll(result) 729 cnt += 1 730 } 731 else { 732 addFlag = false 733 cnt += 1 734 } 735 } 736 result 737 } 738 739 /* 740 * Function name: getRightExpressions 741 * Function description: 获取給定非终结符所在产生式的右部,可能不止一个,因此返回值是String类型的ArrayBuffer数组 742 * Input parameters: -String(給定的非终结符) 743 * Return value: -ArrayBuffer[String](給定非终结符所在产生式的右部) 744 * Exception: 未处理 745 * Author: 来自高山 746 * Created date: Fri Oct 25 2019 +0800 747 * Editor: 来自高山 748 * Edited Date: Fri Oct 25 2019 +0800 749 */ 750 def getRightExpressions(ch: String): ArrayBuffer[String] = { 751 val result = new ArrayBuffer[String]() 752 val localRelations = relations 753 for( ex <- localRelations ) { 754 if( ex._1 == ch ) { 755 if( ex._3 != "א" ) { 756 result += ex._2 757 result += ex._3 758 } 759 else { 760 result += ex._2 761 } 762 } 763 } 764 result 765 } 766 767 /* 768 * Function name: displayStack 769 * Function description: 输出栈的所有元素 770 * Input parameters: -mutable.Stack[String](待处理的String类型的栈) 771 * Return value: -String(栈所有元素组成的字符串) 772 * Exception: 未处理 773 * Author: 来自高山 774 * Created date: Mon Oct 21 2019 +0800 775 * Editor: 来自高山 776 * Edited Date: Mon Oct 21 2019 +0800 777 */ 778 def displayStack( stack: mutable.Stack[String] ): String = { 779 var result = "" 780 for( ex <- stack ) { 781 result += ex 782 } 783 result 784 } 785 786 /* 787 * Function name: initiate 788 * Function description: 初始化全局变量 789 * Input parameters: the absolute path of the language-rule source file 790 * Return value: 无 791 * Exception: 未处理 792 * Author: 来自高山 793 * Created date: Sat Oct 19 2019 +0800 794 * Editor: 来自高山 795 * Edited Date: Sun Oct 27 2019 +0800 796 */ 797 def initiate( filePath: String ): Unit = { 798 LL1_G = parseFile(filePath) 799 allCharacters = getWholeCharacters(LL1_G) 800 usedCharacters = allCharacters 801 relations = getRelation(LL1_G) 802 VN = getVN(allCharacters) 803 VT = getVT(allCharacters) 804 val leftCharacters = subString(allCandidateLetters, VN) 805 relations.insert(0, ( leftCharacters(0).toString, (relations(0)._1), "א" ) ) 806 VN += leftCharacters(0).toString 807 usedCharacters += leftCharacters(0).toString 808 allCharacters += leftCharacters(0).toString 809 810 allCharacters += "#" 811 usedCharacters += "#" 812 VT += "#" 813 getItemGroup 814 columnLength = VN.length + VT.length + 1 815 rowLength = itemGroup.size + 1 816 } 817 818 /* 819 * Function name: subString 820 * Function description: 获取两输入字符串的差集(要求两者均非空) 821 * Input parameters: 无 822 * Return value: -String(两输入字符串的差集) 823 * Exception: 未处理 824 * Author: 来自高山 825 * Created date: Sat Oct 19 2019 +0800 826 * Editor: 来自高山 827 * Edited Date: Sat Oct 19 2019 +0800 828 */ 829 def subString( usedCharacters: String, localCandidateLetters: String ): String = { 830 require( usedCharacters.length != 0 && localCandidateLetters.length != 0 ) 831 var ans = "" 832 var A = usedCharacters 833 var B = localCandidateLetters 834 if( A.length < B.length ) { 835 val tmp = A 836 A = B 837 B = tmp 838 } 839 for( i <- 0 to (A.length - 1) ) { 840 var j = 0 841 while( j < B.length && B(j) != A(i) ) { 842 j += 1 843 } 844 if( j == B.length ) { 845 ans += A(i) 846 } 847 } 848 ans 849 } 850 851 /* 852 * Function name: displayRelations 853 * Function description: display all he language rules 854 * Input parameters: 无 855 * Return value: 无 856 * Exception: 未处理 857 * Author: 来自高山 858 * Created date: Sat Oct 19 2019 +0800 859 * Editor: 来自高山 860 * Edited Date: Mon Oct 28 2019 +0800 861 */ 862 def displayRelations(): Unit = { 863 for( ex <- relations ) { 864 if( ex._3 != "א" ) { 865 866 staticStringBuilder.append( ex._1 + "->" + ex._2 + "|" + ex._3 + "\r\n") 867 if( ex != relations(0) ) { 868 staticStringBuilder2.append(ex._1 + "->" + ex._2 + "|" + ex._3 + "\r\n") 869 } 870 } 871 else { 872 873 staticStringBuilder.append( ex._1 + "->" + ex._2 + "\r\n") 874 if( ex != relations(0) ) { 875 staticStringBuilder2.append(ex._1 + "->" + ex._2 + "\r\n") 876 } 877 } 878 } 879 } 880 881 /* 882 * Function name: parseFile 883 * Function description: 解析文本文件,保存在数组中 884 * Input parameters: 文本绝对路径 885 * Return value: -ArrayBuffer[ ( String, String ) ](String类型的元组ArrayBuffer数组) 886 * Exception: 未处理 887 * Author: 来自高山 888 * Created date: Fri Oct 18 2019 +0800 889 * Editor: 来自高山 890 * Edited Date: Fri Oct 18 2019 +0800 891 */ 892 def parseFile( filePath: String ): ArrayBuffer[ ( String, String ) ] = { 893 val result = new ArrayBuffer[ ( String, String ) ]( countLines( readFromTxtByLine(filePath) ) ) 894 val sourceFile = readFromTxtByLine(filePath) //filePath 895 for( line <- sourceFile ) { 896 val tmp = line.split( "->", 2 ) 897 result += ( ( tmp.head, tmp.last ) ) 898 } 899 result 900 } 901 902 /* 903 * Function name: countLines 904 * Function description: 计算文本行数,用于创建接收数组时开辟相应空间 905 * Input parameters: -Array[String](文本文件数据构成的数组) 906 * Return value: -Int(文本行数) 907 * Exception: 未处理 908 * Author: 来自高山 909 * Created date: Fri Oct 18 2019 +0800 910 * Editor: 来自高山 911 * Edited Date: Sat Oct 19 2019 +0800 912 */ 913 def countLines( sourceFile: Array[String] ): Int = { 914 var cnt = 0 915 for( line <- sourceFile ) { 916 cnt += 1 917 } 918 cnt 919 } 920 921 /* 922 * Function name: readFromTxtByLine 923 * Function description: 读取文本文件 924 * Input parameters: -String(文本文件绝对路径) 925 * Return value: -Array[String](文本文件构成的数组,每行数据占一个数组元素) 926 * Exception: -未处理 927 * Author: 来自高山 928 * Created date: Fri Oct 18 2019 +0800 929 * Editor: 来自高山 930 * Edited Date: Fri Oct 18 2019 +0800 931 */ 932 def readFromTxtByLine(filePath: String): Array[String] = { 933 import scala.io.Source 934 val source = Source.fromFile(filePath, "UTF-8") 935 //val lineIterator = source.getLines() 936 //lineIterator.foreach() 937 val lines = source.getLines().toArray 938 source.close() 939 // 940 lines 941 } 942 943 /* 944 * Function name: getWholeCharacters 945 * Function description: 获取文法的除“|”之外的所有字符 946 * Input parameters: -ArrayBuffer[ (String, String) ](由文法左右两部分字符构成一个元组的数组,筛掉“|”) 947 * Return value: -String(文法的除“|”之外的所有字符) 948 * Exception: 未处理(有出错提示) 949 * Author: 来自高山 950 * Created date: Fri Oct 11 2019 +0800 951 * Editor: 来自高山 952 * Edited Date: Fri Oct 11 2019 +0800 953 */ 954 def getWholeCharacters( string: ArrayBuffer[ (String, String) ] ): String = { 955 var wholeCharacters = "" 956 for( expression <- string ) { 957 wholeCharacters += expression._1 + expression._2 958 } 959 val pattern = new Regex("\\|") 960 val result = pattern replaceAllIn( wholeCharacters, "" ) 961 if( result.isEmpty ) 962 "function getWholeCharacters failed" 963 else 964 result.distinct 965 } 966 /* 967 * Function name: getVN 968 * Function description: 获取文法的所有非终结符(non-terminal character),默认大写字母为非终结符,使用正则表达式匹配 969 * Input parameters: -String(函数getWholeCharacters传来的文法的所有字符) 970 * Return value: -String(文法的所有非终结符) 971 * Exception: 未处理(有出错提示) 972 * Author: 来自高山 973 * Created date: Fri Oct 11 2019 +0800 974 * Editor: 来自高山 975 * Edited Date: Fri Oct 11 2019 +0800 976 */ 977 def getVN( string: String ): String = { 978 //match big letter: 979 //^[A-Z]+$ 980 val pattern = new Regex("[A-Z]")//("^[A-Z]+$") 981 if( (pattern findAllIn string) != null ) 982 (pattern findAllIn string).mkString("") 983 else 984 "function getVN failed" 985 } 986 987 /* 988 * Function name: getVT 989 * Function description: 获取文法的所有非终结符(terminal character),默认大写字母外的字符为终结符,使用正则表达式匹配 990 * Input parameters: -String(函数getWholeCharacters传来的文法的所有字符) 991 * Return value: -String(文法的所有终结符) 992 * Exception: 未处理(有出错提示) 993 * Author: 来自高山 994 * Created date: Fri Oct 11 2019 +0800 995 * Editor: 来自高山 996 * Edited Date: Fri Oct 11 2019 +0800 997 */ 998 def getVT( string: String ): String = { 999 val pattern1 = new Regex("[A-Z]") 1000 val pattern2 = new Regex("\\|") 1001 val firstFilter = pattern1 replaceAllIn( string, "" ) 1002 val result = pattern2 replaceAllIn( firstFilter, "" ) 1003 if( result.isEmpty == false ) 1004 result 1005 else 1006 return "function getVT failed" 1007 } 1008 /* 1009 * Function name: getRelation 1010 * Function description: 获取文法每一行对应的推导关系,若文法只推出了1项(即没有符号“|”),则返回元组的第三个用希伯来字母“א”示空 1011 * Input parameters: -ArrayBuffer[ (String, String)(已经分割好的文法左右部分构成的数组) 1012 * Return value: -ArrayBuffer[ (String, String, String) ](元组第一个元素为推导式左边符号,第二为右边第二个符号串,第三为右边(若有)第三个符号串) 1013 * Exception: 未处理 1014 * Author: 来自高山 1015 * Created date: Fri Oct 11 2019 +0800 1016 * Editor: 来自高山 1017 * Edited Date: Fri Oct 11 2019 +0800 1018 */ 1019 def getRelation( string: ArrayBuffer[ (String, String) ] ): ArrayBuffer[ (String, String, String) ] = { 1020 val relation = new ArrayBuffer[ (String, String, String) ]() 1021 for( expression <- string ) { 1022 if( expression._2.contains("|") == false ) { 1023 relation += ( ( expression._1, expression._2, "א" ) ) 1024 } 1025 else { 1026 val tmp = expression._2.split("\\|", 2 ) 1027 relation += ( ( expression._1, tmp.head, tmp.last ) ) 1028 } 1029 } 1030 relation 1031 } 1032 1033 /* 1034 * Function name: findFirst 1035 * Function description: 获取指定字符的右边两个(可能是一个)导出字符串的首个非 ε 组成的字符串 1036 * Input parameters: -String(指定字符) 1037 * Return value: -String(指定字符的右边两个(可能是一个)导出字符串的首个非 ε 组成的字符串) 1038 * Exception: 未处理 1039 * Author: 来自高山 1040 * Created date: Fri Oct 11 2019 +0800 1041 * Editor: 来自高山 1042 * Edited Date: Fri Oct 11 2019 +0800 1043 */ 1044 def findFirst( ch: String ): String = { 1045 1046 val localRelations = relations 1047 var result = "" 1048 for( ex <- localRelations ) { 1049 if( ch == ex._1 ) { 1050 if( ex._3 != "א" ) { 1051 if( VT.contains( ex._2(0) ) && ex._2(0) != 'ε' ) { 1052 result += ex._2(0).toString 1053 } 1054 if( VT.contains( ex._3(0) ) && ex._3(0) != 'ε' ) { 1055 result += ex._3(0).toString 1056 } 1057 } 1058 else { 1059 if( VT.contains( ex._2(0) ) && ex._2(0) != 'ε' ) { 1060 result += ex._2(0).toString 1061 } 1062 } 1063 } 1064 } 1065 result 1066 } 1067 1068 /* 1069 * Function name: judgeOnlyOneVoidSuccession 1070 * Function description: 判断指定字符是否可推出唯一的字符ε 1071 * Input parameters: -String(指定字符串) 1072 * Return value: -Boolean(存在则true,否则false) 1073 * Exception: 未处理 1074 * Author: 来自高山 1075 * Created date: Fri Oct 11 2019 +0800 1076 * Editor: 来自高山 1077 * Edited Date: Fri Oct 11 2019 +0800 1078 */ 1079 def judgeOnlyOneVoidSuccession( ch: String ): Boolean = { 1080 val localRelations = relations 1081 var result = 1 1082 for( ex <- localRelations ) { 1083 if( ch == ex._1 ) { 1084 if( ex._3 != "א" ) { 1085 if( ( ex._2.length == 1 && ex._2(0) == 'ε' ) || (ex._3.length == 1 && ex._3(0) == 'ε') ) { 1086 result = 1 1087 } 1088 else { 1089 result = 0 1090 } 1091 } 1092 else { 1093 if( ( ex._2.length == 1 && ex._2(0) == 'ε' ) ) { 1094 result = 1 1095 } 1096 else { 1097 result = 0 1098 } 1099 } 1100 } 1101 } 1102 if( result == 1 ) true else false 1103 } 1104 1105 /* 1106 * Function name: judgeCaseXY 1107 * Function description: 判断构造FIRST集时可能的第3种情况的(1),即若X->Y...是一个产生式且Y∈VN(省略若干描述) 1108 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 1109 * Return value: -Boolean(满足则true,否则false) 1110 * Exception: 未处理 1111 * Author: 来自高山 1112 * Created date: Sat Oct 12 2019 +0800 1113 * Editor: 来自高山 1114 * Edited Date: Sat Oct 12 2019 +0800 1115 */ 1116 def judgeCaseXY( ch: Char ): Boolean = { 1117 val localVN = VN 1118 val localRelations = relations 1119 var result = 0 1120 if( localVN.contains(ch) == true ) { 1121 for( ex <- localRelations ) { 1122 if( ex._1(0) == ch ) { 1123 if( localVN.contains( ex._2(0) ) || localVN.contains( ex._3(0) ) ) { 1124 result += 1 1125 } 1126 } 1127 } 1128 } 1129 if( result > 0 ) 1130 true 1131 else 1132 false 1133 } 1134 1135 /* 1136 * Function name: findCase_Y_In_XY 1137 * Function description: 获取构造FIRST集时可能的第3种情况的(1),即若X->Y...是一个产生式且Y∈VN(省略若干描述)时的Y 1138 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 1139 * Return value: -String(Y构成的String字符串,无则为空) 1140 * Exception: 未处理 1141 * Author: 来自高山 1142 * Created date: Sat Oct 12 2019 +0800 1143 * Editor: 来自高山 1144 * Edited Date: Sat Oct 12 2019 +0800 1145 */ 1146 def findCase_Y_In_XY( ch: Char ): String = { 1147 val localVN = VN 1148 val localRelations = relations 1149 var result = "" 1150 if( localVN.contains(ch) == true ) { 1151 for( ex <- localRelations ) { 1152 if( ex._1(0) == ch ) { 1153 if( ex._3 != "א" ) { 1154 if( localVN.contains( ex._2(0) ) == true ) { 1155 result += ex._2(0).toString 1156 } 1157 if( localVN.contains( ex._3(0) ) == true ) { 1158 result += ex._3(0).toString 1159 } 1160 } 1161 else { 1162 if( localVN.contains( ex._2(0) ) == true ) { 1163 result += ex._2(0).toString 1164 } 1165 } 1166 } 1167 } 1168 } 1169 result 1170 } 1171 1172 /* 1173 * Function name: findCase_Y_In_nY 1174 * Function description: 获取构造FIRST集时可能的第3种情况的(2)时的FIRST(Yi)中所有的非ε-元素(省略描述若干字) 1175 * Input parameters: -Char(指定字符,即可能满足条件的产生式的左边字符) 1176 * Return value: -String(FIRST(Yi)中所有的非ε-元素构成的String字符串,无则为空) 1177 * Exception: 未处理 1178 * Author: 来自高山 1179 * Created date: Sat Oct 12 2019 +0800 1180 * Editor: 来自高山 1181 * Edited Date: Sat Oct 12 2019 +0800 1182 */ 1183 def findCase_Y_In_nY( ch: Char ): String = { 1184 val localVN = VN 1185 val localRelations = relations 1186 var result = "" 1187 for( ex <- localRelations ) { 1188 if (ex._1 == ch.toString) { 1189 var tmp = "" 1190 1191 if (ex._3 != 'א') { 1192 var cnt = 0 1193 for (tx <- ex._2) { 1194 // add the element belongs to tmp 1195 if (localVN.contains(tx)) { 1196 tmp += tx.toString 1197 cnt += 1 1198 } 1199 // otherwise, reset tmp as empty string 1200 else { 1201 tmp = "" 1202 } 1203 } 1204 if (cnt == ex._2.length) { 1205 result += tmp 1206 } 1207 1208 // reset 1209 cnt = 0 1210 tmp = "" 1211 for (tx <- ex._3) { 1212 // add the element belongs to tmp 1213 if (localVN.contains(tx)) { 1214 tmp += tx.toString 1215 cnt += 1 1216 } 1217 // otherwise, reset result as empty string 1218 else { 1219 tmp = "" 1220 } 1221 } 1222 if (cnt == ex._3.length) { 1223 result += tmp 1224 } 1225 } 1226 else { 1227 tmp = "" 1228 var cnt = 0 1229 for (tx <- ex._2) { 1230 // add the element belongs to tmp 1231 if (localVN.contains(tx)) { 1232 tmp += tx.toString 1233 cnt += 1 1234 } 1235 // otherwise, reset tmp as empty string 1236 else { 1237 tmp = "" 1238 } 1239 } 1240 if (cnt == ex._2.length) { 1241 result += tmp 1242 } 1243 } 1244 } 1245 } 1246 result = result.distinct 1247 result 1248 } 1249 1250 /* 1251 * Function name: FIRST 1252 * Function description: 按照教材P78左下角的算法描述实现求解指定文法FIRST集;因用的是循环迭代求解,因此代码较长 1253 * Input parameters: -ArrayBuffer[ (String, String) ](产生式左右两部分分别构成元组的第1个和第2个元素) 1254 * Return value: -Map[ String, String ](Map的key是非终结符,value是其FIRST元素) 1255 * Exception: 未处理 1256 * Author: 来自高山 1257 * Created date: Mon Oct 14 2019 +0800 1258 * Editor: 来自高山 1259 * Edited Date: Sat Oct 19 2019 +0800 1260 */ 1261 def FIRST(): Map[ String, String ] = { 1262 val FIRST_Group = Map[ String, String ]() 1263 val wholeCharacters = allCharacters 1264 val localVT = VT 1265 val localVN = VN 1266 1267 for( character <- wholeCharacters ) { 1268 // case 1 1269 if( localVT.contains(character) ) { 1270 //if there exist the original key that equals the current one 1271 if( FIRST_Group.contains(character.toString) == true ) { 1272 val tmp = character.toString + FIRST_Group(character.toString) 1273 FIRST_Group(character.toString) = tmp.distinct 1274 } 1275 //otherwise 1276 else { 1277 FIRST_Group(character.toString) = character.toString 1278 } 1279 } 1280 1281 // case 2 1282 if( localVN.contains(character.toString) == true ) { 1283 // case 2.1 1284 val value = findFirst(character.toString) 1285 if ( value.length != 0 ) { 1286 if ( FIRST_Group.contains(character.toString) == true ) { 1287 for( ch <- value ) { 1288 val tmp = ch + FIRST_Group(character.toString) 1289 FIRST_Group(character.toString) = tmp.distinct 1290 } 1291 } 1292 else { 1293 FIRST_Group(character.toString) = value.toString 1294 } 1295 } 1296 1297 // case 2.2 1298 if( judgeOnlyOneVoidSuccession(character.toString) == true ) { 1299 if ( FIRST_Group.contains(character.toString) == true ) { 1300 val tmp = "ε" + FIRST_Group(character.toString) 1301 FIRST_Group(character.toString) = tmp.distinct 1302 } 1303 else { 1304 FIRST_Group(character.toString) = "ε" 1305 } 1306 } 1307 } 1308 1309 for( character <- wholeCharacters ) { 1310 // case 3 1311 // case 3.1 1312 if( judgeCaseXY(character) == true ) { 1313 val tmpReply = findCase_Y_In_XY(character) 1314 for( eachTmpReply <- tmpReply ) { 1315 if( FIRST_Group.contains(eachTmpReply.toString) == true ) { 1316 for (ex <- FIRST_Group(eachTmpReply.toString)) { 1317 if (ex != 'ε') { 1318 if (FIRST_Group.contains(character.toString) == true) { 1319 val tmp = ex.toString + FIRST_Group(character.toString) 1320 FIRST_Group(character.toString) = tmp.distinct 1321 } 1322 else { 1323 FIRST_Group(character.toString) = ex.toString 1324 } 1325 } 1326 } 1327 } 1328 } 1329 } 1330 1331 // case 3.2 1332 if( findCase_Y_In_nY(character).length > 0 ) { 1333 var flag = true 1334 val tmpReply = findCase_Y_In_nY(character) 1335 1336 for( ex <- tmpReply ) { 1337 if( localVN.contains(ex.toString) && FIRST_Group.contains(ex.toString) == true ) { 1338 if( FIRST_Group(ex.toString).contains("ε") == false ) { 1339 flag = false 1340 } 1341 } 1342 else { 1343 flag = false 1344 } 1345 if( flag == true ) { 1346 if (FIRST_Group.contains(character.toString) == true) { 1347 val tmp = FIRST_Group(ex.toString).replace( "ε", "" ) + FIRST_Group(character.toString) 1348 FIRST_Group(character.toString) = tmp.distinct 1349 } 1350 else { 1351 FIRST_Group(character.toString) = FIRST_Group(ex.toString).replace( "ε", "" ) 1352 } 1353 1354 } 1355 } 1356 } 1357 // case 3.3 1358 if( findCase_Y_In_nY(character).length > 0 ) { 1359 var flag = true 1360 val tmpReply = findCase_Y_In_nY(character) 1361 for( ex <- tmpReply ) { 1362 if( localVN.contains(ex.toString) && FIRST_Group.contains(ex.toString) == true ) { 1363 if( FIRST_Group(ex.toString).contains("ε") == false ) { 1364 flag = false 1365 } 1366 } 1367 else { 1368 flag = false 1369 } 1370 if( flag == true ) { 1371 1372 if (FIRST_Group.contains(character.toString) == true) { 1373 val tmp = "ε" + FIRST_Group(character.toString) 1374 FIRST_Group(character.toString) = tmp.distinct 1375 } 1376 else { 1377 FIRST_Group(character.toString) = "ε" 1378 } 1379 } 1380 } 1381 } 1382 } 1383 } 1384 FIRST_Group 1385 } 1386 1387 }
FileUtil类(Java):

1 import java.io.*; 2 import java.util.Vector; 3 4 /** 5 * 文件工具类 6 */ 7 public class FileUtil { 8 public static void main(String[] args) throws FileNotFoundException { 9 String s = readFile( new FileInputStream("/home/hadoop001/Desktop/test.data") ); 10 System.out.println(s); 11 } 12 /** 13 * 读取文件内容 14 * 15 * @param is 16 * @return 17 */ 18 public static String readFile(InputStream is) { 19 BufferedReader br = null; 20 StringBuffer sb = new StringBuffer(); 21 try { 22 br = new BufferedReader(new InputStreamReader(is, "UTF-8")); 23 String readLine = null; 24 while ((readLine = br.readLine()) != null) { 25 sb.append(readLine+"\r\n"); 26 } 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } finally { 30 try { 31 br.close(); 32 is.close(); 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 } 37 return sb.toString(); 38 } 39 }
Analyse类(Java):

1 package pojo; 2 3 public class Analyse { 4 private String step; 5 private String analysisStack; 6 private String remainingString; 7 private String productionType; 8 private String action; 9 10 public Analyse(){ 11 12 } 13 14 public Analyse(String step, String analysisStack, String remainingString, String productionType, String action) { 15 this.step = step; 16 this.analysisStack = analysisStack; 17 this.remainingString = remainingString; 18 this.productionType = productionType; 19 this.action = action; 20 } 21 22 public String getStep() { 23 return step; 24 } 25 26 public void setStep(String step) { 27 this.step = step; 28 } 29 30 public String getAnalysisStack() { 31 return analysisStack; 32 } 33 34 public void setAnalysisStack(String analysisStack) { 35 this.analysisStack = analysisStack; 36 } 37 38 public String getRemainingString() { 39 return remainingString; 40 } 41 42 public void setRemainingString(String remainingString) { 43 this.remainingString = remainingString; 44 } 45 46 public String getProductionType() { 47 return productionType; 48 } 49 50 public void setProductionType(String productionType) { 51 this.productionType = productionType; 52 } 53 54 public String getAction() { 55 return action; 56 } 57 58 public void setAction(String action) { 59 this.action = action; 60 } 61 }
运行截图:
图 1 开始界面
图 2 选择文件
图 3 分析界面
图 4 显示初始文法
图 5 分析完成(输入表达死为“i+i*i”)