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