1 package fri.patterns.interpreter.parsergenerator.util; 2 3 import java.io.File ; 4 import java.util.*; 5 import fri.patterns.interpreter.parsergenerator.Token; 6 import fri.patterns.interpreter.parsergenerator.syntax.*; 7 import fri.patterns.interpreter.parsergenerator.syntax.builder.*; 8 9 23 24 public class SyntaxChecker 25 { 26 private boolean diagnosis = true; 27 28 public SyntaxChecker(Object syntaxFile) 29 throws Exception 30 { 31 this(new SyntaxBuilder(syntaxFile).getSyntax()); 32 } 33 34 public SyntaxChecker(Syntax syntax) { 35 if (syntax.size() <= 0) { 36 System.out.println("ERROR: Found no rules in syntax!"); 37 diagnosis = false; 38 return; 39 } 40 41 System.out.println("Number of rules (after resolving parenthesis, alternations and wildcards): "+syntax.size()); 42 43 List topLevelRules = syntax.findStartRules(); 45 if (topLevelRules.size() > 1) { 46 System.out.println("WARNING: More than one toplevel rules:"); 47 for (int i = 0; i < topLevelRules.size(); i++) 48 System.out.println(" "+topLevelRules.get(i)); 49 } 50 else 51 if (topLevelRules.size() < 1) { 52 System.out.println("WARNING: Found no toplevel rule, first rule (default START rule) is: "+syntax.getRule(0)); 53 } 54 else { 55 System.out.println("Start rule is \""+topLevelRules.get(0)+"\""); 56 } 57 58 Set unresolved = syntax.getUnresolvedNonterminals(); 60 if (unresolved.size() > 0) { 61 System.out.println("Found "+unresolved.size()+" unresolved nonterminals:"); 62 diagnosis = false; 63 for (Iterator it = unresolved.iterator(); it.hasNext(); ) 64 System.out.println(" "+it.next()); 65 } 66 else { 67 System.out.println("Found no unresolved nonterminals."); 68 } 69 70 for (int i = syntax.size() - 1; i >= 0; i--) { 72 Rule rule = syntax.getRule(i); 73 74 boolean found = topLevelRules.contains(rule) || 75 rule.getNonterminal().equals(Token.TOKEN) || 76 rule.getNonterminal().equals(Token.IGNORED); 77 78 for (int j = 0; found == false && j < syntax.size(); j++) { 79 if (j != i) { 80 Rule rule2 = syntax.getRule(j); 81 for (int k = 0; found == false && k < rule2.rightSize(); k++) 82 if (rule2.getRightSymbol(k).equals(rule.getNonterminal())) 83 found = true; 84 } 85 } 86 87 if (found == false) 88 System.out.println("WARNING: Found isolated (unused, redundant) rule: "+rule); 89 } 90 91 int singulars = 0; 93 for (int i = syntax.size() - 1; i >= 0; i--) { 94 Rule rule = syntax.getRule(i); 95 boolean singular = (rule.rightSize() == 1 && topLevelRules.contains(rule) == false); 97 for (int j = 0; singular && j < syntax.size(); j++) 99 if (j != i && syntax.getRule(j).getNonterminal().equals(rule.getNonterminal())) 100 singular = false; 102 if (singular) { 103 System.out.println("INFO: Found singular rule (nonterminal could be substituted by its right symbol): "+rule); 104 singulars++; 105 } 106 } 107 System.out.println("Found "+singulars+" singular rules."); 108 } 109 110 111 112 public boolean getDiagnosis() { 113 return diagnosis; 114 } 115 116 117 public static void main(String [] args) { 118 if (args.length <= 0) { 119 System.err.println("SYNTAX: java "+SyntaxChecker.class.getName()+" file.syntax [file.syntax ...]"); 120 System.err.println(" Prints out a diagnosis of passed syntax file(s)."); 121 System.exit(2); 122 } 123 124 boolean ok = true; 125 for (int i = 0; i < args.length; i++) { 126 try { 127 SyntaxChecker checker = new SyntaxChecker(new File (args[i])); 128 ok = ok && checker.getDiagnosis(); 129 } 130 catch (Exception e) { 131 ok = false; 132 e.printStackTrace(); 133 } 134 } 135 136 System.exit(ok ? 0 : 1); 137 } 138 139 } 140 | Popular Tags |