KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fri > patterns > interpreter > parsergenerator > util > SyntaxChecker


1 package fri.patterns.interpreter.parsergenerator.util;
2
3 import java.io.File JavaDoc;
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 /**
10     SyntaxChecker checks a EBNF syntax (file) for following things:
11     <ul>
12         <li>unresolved nonterminals (nonterminals without rule)</li>
13         <li>singular rules (nonterminal can be substituted by its singular right symbol)</li>
14         <li>isolated rules (redundant, can be removed)</li>
15         <li>None or more than one toplevel rule</li>
16     </ul>
17     <pre>
18     SYNTAX: java fri.patterns.interpreter.parsergenerator.util.SyntaxChecker file.syntax [file.syntax ...]
19     </pre>
20
21     @author (c) 2000, Fritz Ritzberger
22 */

23
24 public class SyntaxChecker
25 {
26     private boolean diagnosis = true;
27     
28     public SyntaxChecker(Object JavaDoc syntaxFile)
29         throws Exception JavaDoc
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         // Find start rule(s)
44
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         // check for unresolved nonterminals
59
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         // check for isolated rules
71
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         // check for singular rules
92
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); // has only one symbol on right side
96

97             // check if defined only once on any left side
98
for (int j = 0; singular && j < syntax.size(); j++)
99                 if (j != i && syntax.getRule(j).getNonterminal().equals(rule.getNonterminal()))
100                     singular = false; // nonterm has been found once more on left side
101

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     /** Returns false when the checked syntax is not able to be used as lexer or parser configuration. */
112     public boolean getDiagnosis() {
113         return diagnosis;
114     }
115
116
117     public static void main(String JavaDoc [] 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 JavaDoc(args[i]));
128                 ok = ok && checker.getDiagnosis();
129             }
130             catch (Exception JavaDoc e) {
131                 ok = false;
132                 e.printStackTrace();
133             }
134         }
135         
136         System.exit(ok ? 0 : 1);
137     }
138
139 }
140
Popular Tags