grammerLR.java
上传用户:jzksjx
上传日期:2022-07-12
资源大小:14k
文件大小:19k
源码类别:

词法分析

开发平台:

Java

  1. import java.util.*;
  2. import java.io.*;
  3. class pair{
  4. public int x, y;
  5. pair(int a, int b){
  6. x = a;
  7. y = b;
  8. }
  9. }
  10. public class grammerLR {
  11. String[][] syntax;//保存文法
  12. String[][] syntax2;//消除左递归的文法
  13. LinkedList<String> term;//终结符
  14. LinkedList<String> nonterm;//非终结符
  15. LinkedList<String> term2;//副本,求first, follow用
  16. LinkedList<String> nonterm2;//副本,求first, follow用
  17. LinkedList<HashSet<String>> nontermFirst;//记录first
  18. LinkedList<HashSet<String>> nontermFollow;//记录follow
  19. boolean[] hasFirst;//记录first 是否求完
  20. boolean[] hasFollow;//记录follow 是否求完
  21. LinkedList<HashSet<pair>> state;//项集族
  22. int[][][] table1;// ACTION表  // table1 第一层操作类型:1=s, 2=r,3=accept,0=error=默认;
  23. int[][] table2;//GOTO表
  24. String path;
  25. Scanner in;
  26. String[] inExpr;//保存输入的需要判断的表达式
  27. int pindex;
  28. int exprIndex;
  29. String readLine(){
  30. return in.nextLine();
  31. }
  32. void readExpr(){//读入表达式
  33. inExpr = readLine().trim().split("[ ]+");
  34. pindex = 0;
  35. }
  36. String readNext(){//每次读入一个词 
  37. exprIndex++;
  38. if(pindex < inExpr.length){
  39. return inExpr[pindex++];
  40. }else if(pindex == inExpr.length){
  41. pindex++;
  42. return "$";
  43. }else{
  44. return null;
  45. }
  46. }
  47. void scanS() throws IOException{//读入文法 ,并处理文法 
  48. File source = new File(path);
  49. BufferedReader in = new BufferedReader(new FileReader(source));
  50. String s;
  51. while((s = in.readLine()) != null){
  52. if(s.equals("%%1")){
  53. int i = 0;
  54. LinkedList<String> list = new LinkedList<String>();
  55. while((s = in.readLine()) != null && !s.equals("%%")){
  56. String[] st = s.trim().split("[ ]+");
  57. for(String one : st){
  58. list.add(one);
  59. i++;
  60. }
  61. }
  62. term = list;
  63. }else if(s.equals("%%2")){
  64. int i = 0;
  65. LinkedList<String> list = new LinkedList<String>();
  66. while((s = in.readLine()) != null && !s.equals("%%")){
  67. String[] st = s.trim().split("[ ]+");
  68. for(String one : st){
  69. list.add(one);
  70. i++;
  71. }
  72. }
  73. nonterm =  list;  
  74. }else if(s.equals("%%3")){
  75. LinkedList<String[]> list = new LinkedList<String[]>();
  76. while((s = in.readLine()) != null && !s.equals("%%")){
  77. String[] st = s.trim().split("[ ]+");
  78. list.add(st);
  79. }
  80. syntax = list.toArray(new String[0][0]);
  81. }
  82. }
  83. in.close();
  84. }
  85. grammerLR(){
  86. in = new Scanner(System.in);
  87. System.out.println("Enter the path of syntax : ");
  88. path = readLine();
  89. try{//读取文法文件 
  90. scanS();
  91. }catch(IOException e){
  92. System.out.println("IOExcpetion error");
  93. }
  94. exprIndex = 0;
  95. //removeLeftRecursion();//消除左递归等
  96. removeLeftRecursion2();//只是简单的复制,term2, nonterm2, syntax2
  97. extendSyntax();//扩展文法
  98. table1 = new int[50][term.size()+1][2];//-----------------------分析表-第一维 行的大小无法确定,只能尽量合适--------------------------
  99. table2 = new int[50][nonterm.size()];
  100. //table1初始化
  101. for(int i = 0; i < table1.length; i++){
  102. for(int j = 0; j < table1[i].length; j++){
  103. table1[i][j][0] = 0;
  104. table1[i][j][1] = -1;
  105. }
  106. }
  107. //table2初始化
  108. for(int i = 0; i < table2.length; i++){
  109. for(int j = 0 ; j < table2[i].length; j++){
  110. table2[i][j] = -1;
  111. }
  112. }
  113. term.add("$");
  114. items();
  115. firstAll();
  116. followAll();
  117. makeTable();
  118. }
  119. void extendSyntax(){//扩展文法
  120. LinkedList<String[]> syntax0 = new LinkedList<String[]>();
  121. String s = "E_` "+"::= " + syntax[0][0];
  122. String[] st = s.trim().split("[ ]+");
  123. syntax0.add(st);
  124. for(String[] one : syntax){//用syntax填充syntax0
  125. syntax0.add(one);
  126. }
  127. syntax = new String[syntax0.size()][];
  128. for(int i = 0; i < syntax0.size(); i++){
  129. syntax[i] = syntax0.get(i).clone();
  130. }
  131. }
  132. void removeLeftRecursion2(){//只是简单的复制
  133. term2 = new LinkedList<String>(term);
  134. nonterm2 = new LinkedList<String>(nonterm);
  135. LinkedList<LinkedList<String>> syntax1 = new LinkedList<LinkedList<String>>();
  136. for(String[] one : syntax){//用syntax填充syntax1
  137. LinkedList<String> temp1 = new LinkedList<String>();
  138. for(String two : one){
  139. temp1.add(two);
  140. }
  141. syntax1.add(temp1);
  142. }
  143. syntax2 = new String[syntax1.size()][];
  144. for(int i = 0; i < syntax1.size(); i++){
  145. syntax2[i] = syntax1.get(i).toArray(new String[0]);
  146. }
  147. }
  148. void removeLeftRecursion(){//消除左递归
  149. term2 = new LinkedList<String>(term);
  150. nonterm2 = new LinkedList<String>(nonterm);
  151. LinkedList<LinkedList<String>> syntax1 = new LinkedList<LinkedList<String>>();
  152. for(String[] one : syntax){//用syntax填充syntax1
  153. LinkedList<String> temp1 = new LinkedList<String>();
  154. for(String two : one){
  155. temp1.add(two);
  156. }
  157. syntax1.add(temp1);
  158. }
  159. for(int i = 0; i < nonterm.size(); i++){
  160. for(int j = 0; j < i; j++){
  161. for(int k = 0; k < syntax1.size(); k++){
  162. if(nonterm.get(i).equals(syntax1.get(k).get(0)) && nonterm.get(j).equals(syntax1.get(k).get(2)) ){
  163. for(int m = 0; m < syntax1.size(); m++){
  164. if(nonterm.get(j).equals(syntax1.get(m).get(0))){//找到所有非终结符j的产生式
  165. syntax1.get(k).addAll(2+1, syntax1.get(m));
  166. syntax1.get(k).remove(2);
  167. }
  168. }
  169. }
  170. }
  171. }
  172. //消除立即左递归
  173. String newMark = nonterm.get(i) + "`";//创造新符号
  174. for(int j = 0; j < syntax1.size(); j++){
  175. if(syntax1.get(j).get(0).equals(nonterm.get(i))){
  176. if(syntax1.get(j).get(0).equals(syntax1.get(j).get(2))){//有左递归
  177. nonterm2.add(newMark);
  178. syntax1.get(j).add(0+1, newMark);
  179. syntax1.get(j).remove(0);
  180. syntax1.get(j).remove(2);
  181. syntax1.get(j).add(newMark);
  182. for(int k = 0; k < syntax1.size(); k++){
  183. if(syntax1.get(k).get(0).equals(nonterm.get(i))){
  184. if(!syntax1.get(k).get(0).equals(syntax1.get(k).get(2))){
  185. syntax1.get(k).add((newMark));
  186. //移动到前面去
  187. LinkedList<String> temp3 = new LinkedList<String>(syntax1.get(k));
  188. syntax1.remove(k);
  189. syntax1.add(k-1, temp3);
  190. }
  191. }
  192. }
  193. LinkedList<String> temp2 = new LinkedList<String>();
  194. temp2.add(newMark);
  195. temp2.add("::=");
  196. temp2.add("ε");
  197. syntax1.add(j+2, temp2);
  198. if(!term2.contains("ε")){
  199. term2.add("ε");
  200. }
  201. }
  202. }
  203. }
  204. }
  205. syntax2 = new String[syntax1.size()][];
  206. for(int i = 0; i < syntax1.size(); i++){
  207. syntax2[i] = syntax1.get(i).toArray(new String[0]);
  208. }
  209. }
  210. HashSet<pair> closure(HashSet<pair> one){
  211. LinkedList<pair> list = new LinkedList<pair>(one);
  212. for(int i = 0; i < list.size(); i++){
  213. pair two = list.get(i);
  214. if(two.y < syntax[two.x].length && nonterm.contains((syntax[two.x][two.y])) && !syntax[two.x][0].equals(syntax[two.x][two.y])){//点后紧跟非终结符,不在末尾,需要被扩展 , 
  215. String signal = new String(syntax[two.x][two.y]);
  216. int index = 0;
  217. for(String three[] : syntax){
  218. if(three[0].equals(signal) && !list.contains(new pair(index, 2))){//找到其产生式,并且未包含
  219. list.add(new pair(index, 2));
  220. }
  221. index++;
  222. }
  223. }
  224. }
  225. one = new HashSet<pair>(list);
  226. return one;
  227. }
  228. void items(){
  229. state = new LinkedList<HashSet<pair>>();
  230. HashSet<pair> i0 = new HashSet<pair>();
  231. i0.add(new pair(0,2));
  232. i0 = closure(i0);
  233. state.add(i0);
  234. int index = 0;
  235. while(true){
  236. LinkedList<HashSet<pair>> other = new LinkedList<HashSet<pair>>(state);
  237. int num = 0;
  238. for(ListIterator<HashSet<pair>> it = other.listIterator(index); it.hasNext(); ){
  239. HashSet<pair> one = it.next();
  240. HashSet<String> signal = new HashSet<String>();//保存 只能接受的那些输入
  241. for(pair pattern : one){
  242. if(syntax[pattern.x].length > pattern.y){
  243. signal.add(syntax[pattern.x][pattern.y]);
  244. }
  245. }
  246. for(String mark : signal){
  247. HashSet<pair> temp = new HashSet<pair>();
  248. for(pair pattern : one){//对于项集的每个项
  249. if(syntax[pattern.x].length > pattern.y && syntax[pattern.x][pattern.y].equals(mark)){
  250. temp.add(new pair(pattern.x, pattern.y+1));
  251. }
  252. }
  253. temp = closure(temp);
  254. boolean isContain = false;
  255. int stateIndex = -1;
  256. for(HashSet<pair> four : state){//判断是否已经包含此项集
  257. boolean isThere = true;
  258. for(pair five : four){
  259. boolean isFind = false;
  260. for(pair six : temp){
  261. if(five.x == six.x  && five.y == six.y){
  262. isFind = true;
  263. break;
  264. }
  265. }
  266. if(!isFind){
  267. isThere = false;
  268. break;
  269. }
  270. }
  271. if(isThere){
  272. isContain = true;
  273. stateIndex = state.indexOf(four);
  274. break;
  275. }
  276. }
  277. if(!isContain){//判断是否已经包含此项集
  278. state.add(temp);
  279. if(term.contains(mark)){//生成分析表的 规则 2-1
  280. int row = state.indexOf(one);
  281. int cell = term.indexOf(mark);
  282. int value = state.indexOf(temp);
  283. table1[row][cell][0] = 1;//操作为 s,即移入
  284. table1[row][cell][1] = value;
  285. }
  286. if(nonterm.contains(mark)){//生成分析表的 规则 3
  287. int row = state.indexOf(one);
  288. int cell = nonterm.indexOf(mark);
  289. int value = state.indexOf(temp);
  290. table2[row][cell] = value;
  291. }
  292. }else{
  293. if(term.contains(mark)){//生成分析表的 规则 2-1
  294. int row = state.indexOf(one);
  295. int cell = term.indexOf(mark);
  296. int value = stateIndex;;
  297. table1[row][cell][0] = 1;//操作为 s,即移入
  298. table1[row][cell][1] = value;
  299. }
  300. if(nonterm.contains(mark)){//生成分析表的 规则 3
  301. int row = state.indexOf(one);
  302. int cell = nonterm.indexOf(mark);
  303. int value = stateIndex;
  304. table2[row][cell] = value;
  305. }
  306. }
  307. }
  308. num++;
  309. }
  310. index++;
  311. if(state.size() <= other.size()){
  312. break;
  313. }
  314. }
  315. }
  316. void appendFirst(HashSet<String> a, HashSet<String> b){
  317. HashSet<String> temp = new HashSet<String>(b);
  318. temp.remove("ε");
  319. a.addAll(temp);
  320. }
  321. HashSet<String> makeFirst(String token){//求token的first 集合 ,递归 
  322. if(term2.contains(token)){//是终结符 
  323. HashSet<String> temp = new HashSet<String>();
  324. temp.add(token);
  325. return temp;
  326. }else if(nonterm2.contains(token)){//是非终结符 
  327. int index = nonterm2.indexOf(token);
  328. if(!hasFirst[index]){//还没生成first,现在生成
  329. for(String[] one : syntax2){
  330. if(one[0].equals(token)){
  331. if(one[0].equals(one[2])){//对于会左递归的文法
  332. continue;
  333. }
  334. boolean isZero = false;
  335. for(int i = 2; i < one.length; i++){
  336. appendFirst(nontermFirst.get(index), makeFirst(one[i]));
  337. if(term2.contains(one[i]) && !one[i].equals("ε") ){
  338. isZero = true;
  339. break;
  340. }else if(nonterm2.contains(one[i]) && !nontermFirst.get(nonterm2.indexOf(one[i])).contains("ε")){
  341. isZero = true;
  342. break;
  343. }
  344. }
  345. if(!isZero){//每个都有 ε  ,则最后加入 ε 到 集合里 
  346. nontermFirst.get(index).add("ε");
  347. }
  348. }
  349. }
  350. hasFirst[index] = true;//标记 此 符号 的 first 已经找完了
  351. }
  352. return nontermFirst.get(index);
  353.  
  354. }else{//基本不会到这里面
  355. System.out.println(token + " : " + "Error! 没有这个符号");
  356. System.exit(0);
  357. return null;
  358. }
  359. }
  360. void firstAll(){//first集合生成 主程序
  361. hasFirst = new boolean[nonterm2.size()];
  362. nontermFirst = new LinkedList<HashSet<String>>();
  363. for(int i = 0; i < nonterm2.size(); i++){
  364. hasFirst[i] = false;
  365. HashSet<String> temp0 = new HashSet<String>();
  366. nontermFirst.add(temp0);
  367. }
  368.  
  369. for(String one : nonterm2){//生成 非终结符 的 first
  370. makeFirst(one);// makeFirst里已经计算完了 吧
  371. }
  372. }
  373.  
  374.  
  375. void appendFollow(HashSet<String> a, HashSet<String> b){
  376. HashSet<String> temp = new HashSet<String>(b);
  377. temp.remove("ε");
  378. a.addAll(temp);
  379. }
  380. Map<String, Integer> cicle;//防止 文法里出现循环递归
  381. HashSet<String> makeFollow(String token){//生成token 的 follow集合 
  382. if(cicle.get(token) != null){//已经存在这个符号, 说明 出现递归 环 了
  383. return nontermFollow.get(nonterm2.indexOf(token));
  384. }
  385. cicle.put(token, 1);
  386. if(hasFollow[nonterm2.indexOf(token)]){
  387. return nontermFollow.get(nonterm2.indexOf(token));
  388. }
  389. for(String[] one : syntax2){//计算 follow
  390. for(int i = 2; i < one.length; i++){
  391. if(one[i].equals(token)){
  392. boolean allZero = true;
  393. for(int j = i+1; j < one.length; j++){//规则2
  394. if(nonterm2.contains(one[j])){//非终结符
  395. appendFollow(nontermFollow.get(nonterm2.indexOf(token)), nontermFirst.get(nonterm2.indexOf(one[j])));
  396. if(!nontermFirst.get(nonterm2.indexOf(one[j])).contains("ε")){
  397. allZero = false;
  398. break;
  399. }
  400. }else if(term2.contains(one[j])){//终结符
  401. HashSet<String> temp  = new HashSet<String>();
  402. temp.add(one[j]);
  403. appendFollow(nontermFollow.get(nonterm2.indexOf(token)), temp);
  404. if(!one[j].equals("ε")){
  405. allZero = false;
  406. break;
  407. }
  408. }
  409.  
  410. }
  411. if(allZero){//规则3
  412. appendFollow(nontermFollow.get(nonterm2.indexOf(one[i])), makeFollow(one[0]));
  413. }
  414. }
  415. }
  416. }
  417. hasFollow[nonterm2.indexOf(token)] = true;
  418. return nontermFollow.get(nonterm2.indexOf(token));
  419. }
  420. void followAll(){//follow集合生成 主程序
  421. hasFollow = new boolean[nonterm2.size()];
  422. nontermFollow = new LinkedList<HashSet<String>>();
  423. for(int i = 0; i < nonterm2.size(); i++){
  424. hasFollow[i] = false;
  425. HashSet<String> temp0 = new HashSet<String>();
  426. nontermFollow.add(temp0);
  427. }
  428. //把 $ 加入到 开始符号 里
  429. HashSet<String> temps = new HashSet<String>();
  430. temps.add("$");
  431. appendFollow(nontermFollow.get(0), temps);// 开始符号
  432. for(String one : nonterm2){
  433. cicle = new HashMap<String, Integer>();
  434. makeFollow(one);
  435. }
  436. }
  437.  
  438. void makeTable(){
  439. // table1 第一层操作类型:1=s, 2=r,3=accept,0=error=默认;
  440. int index = 0;
  441. for(HashSet<pair> one : state){
  442. for(pair two : one){
  443. if(two.y == syntax[two.x].length){//
  444. if(two.x == 0){//规则 2-3
  445. table1[index][term.indexOf("$")][0] = 3;
  446. table1[index][term.indexOf("$")][1] = -3;
  447. }else{//规则 2-2
  448. for(String token : nontermFollow.get(nonterm.indexOf(syntax[two.x][0]))){
  449. table1[index][term.indexOf(token)][0] = 2;
  450. table1[index][term.indexOf(token)][1] = two.x;
  451. }
  452. }
  453. }
  454. }
  455. index++;
  456. }
  457. }
  458. void analysisDriver(){
  459. Stack<Integer> stateStack = new Stack<Integer>();
  460. Stack<String> signalStack = new Stack<String>();
  461. exprIndex = 0;
  462. stateStack.push(0);
  463. String mark = readNext();
  464. int now;
  465. // table1 第一层操作类型:1=s, 2=r,3=accept,0=error=默认;
  466. System.out.println("n**************************");
  467. while(true){
  468. now = stateStack.peek();
  469. //System.out.println("now = " + now + "," + term.indexOf(mark));
  470. //打印分析栈
  471. for(int i : stateStack){
  472. System.out.print(i + ",");
  473. }
  474. if(stateStack.size() > 3){
  475. System.out.print("t");
  476. }else{
  477. System.out.print("tt");
  478. }
  479. for(String one : signalStack){
  480. System.out.print(one + ",");
  481. }
  482. if(signalStack.size() > 3){
  483. System.out.print("t");
  484. }else{
  485. System.out.print("tt");
  486. }
  487. System.out.print(mark + " ");
  488. for(int i = exprIndex; i < inExpr.length; i++){
  489. System.out.print(inExpr[i] + " ");
  490. }
  491. System.out.println();
  492. if(table1[now][term.indexOf(mark)][0] == 1){
  493. stateStack.push(table1[now][term.indexOf(mark)][1]);
  494. signalStack.push(mark);
  495. mark = readNext();
  496. }else if(table1[now][term.indexOf(mark)][0] == 2){
  497. int syntaxIndex = table1[now][term.indexOf(mark)][1];
  498. for(int i = 2; i < syntax[syntaxIndex].length; i++){
  499. signalStack.pop();
  500. stateStack.pop();
  501. }
  502. signalStack.push(syntax[syntaxIndex][0]);
  503. now = stateStack.peek();
  504. stateStack.push(table2[now][nonterm.indexOf(signalStack.peek())]);
  505. }else if(table1[now][term.indexOf(mark)][0] == 3){
  506. System.out.println("***  Accept  ***");
  507. break;
  508. }else{
  509. System.out.println("*** UnAccept ***");
  510. break;
  511. }
  512. }
  513. }
  514. void printAll(){//输入中间产生的各种信息
  515. int index = 0;
  516. System.out.println("n********************    syntax   ********************");
  517. for(String[] one : syntax){
  518. System.out.print("" + index++ + ":t");
  519. for(String two : one){
  520. System.out.print(two + "t");
  521. }
  522. System.out.println();
  523. }
  524. index = 0;
  525. System.out.println("n********************   syntax2   ********************");
  526. for(String[] one : syntax2){
  527. System.out.print("" + index++ + ":t");
  528. for(String two : one){
  529. System.out.print(two + "t");
  530. }
  531. System.out.println();
  532. }
  533. System.out.println("n********************    term     ********************");
  534. for(String one : term){
  535. System.out.print(one + "t");
  536. }
  537. System.out.println();
  538. System.out.println("n********************   nonterm   ********************");
  539. for(String one : nonterm){
  540. System.out.print(one + "t");
  541. }
  542. System.out.println();
  543. System.out.println("n********************    term2    ********************");
  544. for(String one : term2){
  545. System.out.print(one + "t");
  546. }
  547. System.out.println();
  548. System.out.println("n********************  nonterm2   ********************");
  549. for(String one : nonterm2){
  550. System.out.print(one + "t");
  551. }
  552. System.out.println();
  553. index = 0;
  554. System.out.println("n********************nontermFirst ********************");
  555. for(HashSet<String> one : nontermFirst){
  556. System.out.print("" + index++ + ":t");
  557. for(String two : one){
  558. System.out.print(two + "t");
  559. }
  560. System.out.println();
  561. }
  562. index = 0;
  563. System.out.println("n********************nontermFollow********************");
  564. for(HashSet<String> one : nontermFollow){
  565. System.out.print("" + index++ + ":t");
  566. for(String two : one){
  567. System.out.print(two + "t");
  568. }
  569. System.out.println();
  570. }
  571. index = 0;
  572. System.out.println("n********************    state    ********************");
  573. for(HashSet<pair> one : state){
  574. System.out.print("" + index++ + ":t");
  575. for(pair two : one){
  576. System.out.print("(" + two.x + "," + two.y + ")t");
  577. }
  578. System.out.println();
  579. }
  580. index = 0;
  581. System.out.println("n********************    table    ********************");
  582. System.out.print("t");
  583. for(String one : term){
  584. System.out.print(one + "t");
  585. }
  586. System.out.println();
  587. for(int i = 0; i < state.size(); i++){
  588. System.out.print("" + index++ + ":t");
  589. for(int j = 0; j < table1[i].length; j++){
  590. if(table1[i][j][0] != 0){
  591. System.out.print(table1[i][j][0] + ",");
  592. System.out.print(table1[i][j][1] + "t");
  593. }else{
  594. System.out.print("---t");
  595. }
  596. }
  597. System.out.println();
  598. }
  599. index = 0;
  600. System.out.println("--------------------");
  601. System.out.print("t");
  602. for(String one : nonterm){
  603. System.out.print(one + "t");
  604. }
  605. System.out.println();
  606. for(int i = 0; i < state.size(); i++){
  607. System.out.print("" + index++ + ":t");
  608. for(int j = 0; j < table2[i].length; j++){
  609. if(table2[i][j] != -1){
  610. System.out.print(table2[i][j] + "t");
  611. }else{
  612. System.out.print("-t");
  613. }
  614. }
  615. System.out.println();
  616. }
  617. }
  618. public static void main(String[] args){
  619. grammerLR myLR = new grammerLR();
  620. myLR.printAll();
  621. while(true){
  622. System.out.println("n*****************************************************");
  623. System.out.print("Enter expr:");
  624. myLR.readExpr();
  625. myLR.analysisDriver();
  626. }
  627. }
  628. }