001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.languages.parser;
043:
044: import org.netbeans.api.languages.ASTToken;
045: import java.io.PrintWriter;
046: import java.util.ArrayList;
047: import java.util.Collections;
048: import java.util.HashMap;
049: import java.util.HashSet;
050: import java.util.Iterator;
051: import java.util.LinkedList;
052: import java.util.List;
053: import java.util.Map;
054: import java.util.Set;
055: import org.netbeans.modules.languages.Language;
056: import org.netbeans.modules.languages.Rule;
057: import org.netbeans.modules.languages.parser.LLSyntaxAnalyser.T;
058:
059: /**
060: *
061: * @author Jan Jancura
062: */
063: public class AnalyserAnalyser {
064:
065: public static void printRules(List<Rule> rules, PrintWriter writer) {
066: if (writer == null)
067: System.out.println("Rules:");
068: else
069: writer.println("Rules:");
070: List<String> l = new ArrayList<String>();
071: Map<String, List> m = new HashMap<String, List>();
072: Map<String, List> mm = new HashMap<String, List>();
073: int i = 0;
074: Iterator<Rule> it = rules.iterator();
075: while (it.hasNext()) {
076: Rule r = it.next();
077: if (!m.containsKey(r.getNT()))
078: l.add(r.getNT());
079: List ll = m.get(r.getNT());
080: if (ll == null) {
081: ll = new ArrayList();
082: m.put(r.getNT(), ll);
083: mm.put(r.getNT(), new ArrayList());
084: }
085: ll.add(r);
086: mm.get(r.getNT()).add(new Integer(i++));
087: }
088: Collections.sort(l);
089: Iterator<String> it2 = l.iterator();
090: while (it2.hasNext()) {
091: String nt = it2.next();
092: List ll = m.get(nt);
093: Iterator it3 = ll.iterator();
094: Iterator it4 = mm.get(nt).iterator();
095: while (it3.hasNext())
096: if (writer == null)
097: System.out.println(" " + it3.next() + " ("
098: + it4.next() + ")");
099: else
100: writer.println(" " + it3.next() + " ("
101: + it4.next() + ")");
102: }
103: if (writer == null)
104: System.out.println("");
105: else
106: writer.println("");
107: }
108:
109: public static void printUndefinedNTs(List<Rule> rules,
110: PrintWriter writer) {
111: Set f = new HashSet();
112: Iterator<Rule> it = rules.iterator();
113: while (it.hasNext())
114: f.add(it.next().getNT());
115: Set result = new HashSet();
116: it = rules.iterator();
117: while (it.hasNext()) {
118: Rule r = it.next();
119: Iterator it2 = r.getRight().iterator();
120: while (it2.hasNext()) {
121: Object e = it2.next();
122: if (e instanceof ASTToken)
123: continue;
124: if (e instanceof T && !f.contains(e))
125: result.add(e);
126: }
127: }
128: if (result.isEmpty())
129: return;
130: if (writer == null)
131: System.out.println("Undefined nonterminals:");
132: else
133: writer.println("Undefined nonterminals:");
134: it = result.iterator();
135: while (it.hasNext()) {
136: if (writer == null)
137: System.out.println(" " + it.next());
138: else
139: writer.println(" " + it.next());
140: }
141: if (writer == null)
142: System.out.println("");
143: else
144: writer.println("");
145: }
146:
147: public static boolean hasConflicts(Map<String, Map> first) {
148: boolean[] ff = new boolean[] { true };
149: Iterator<String> it = first.keySet().iterator();
150: while (it.hasNext()) {
151: String nt = it.next();
152: if (pf2(nt, first.get(nt), new LinkedList(), ff))
153: return true;
154: }
155: return false;
156: }
157:
158: private static boolean pf2(String nt, Map m, LinkedList l,
159: boolean[] f) {
160: if (((Set) m.get("&")).size() < 2)
161: return false;
162: boolean end = true;
163: Iterator it = m.keySet().iterator();
164: while (it.hasNext()) {
165: Object e = it.next();
166: if (e instanceof T) {
167: end = false;
168: l.addLast(e);
169: pf2(nt, (Map) m.get(e), l, f);
170: l.removeLast();
171: }
172: }
173: return end;
174: }
175:
176: public static boolean printConflicts(Map f, PrintWriter writer) {
177: boolean[] ff = new boolean[] { true };
178: Iterator it = f.keySet().iterator();
179: while (it.hasNext()) {
180: String nt = (String) it.next();
181: pf(nt, (Map) f.get(nt), new LinkedList(), ff, writer);
182: }
183: return !ff[0];
184: }
185:
186: private static void pf(String nt, Map m, LinkedList l, boolean[] f,
187: PrintWriter writer) {
188: if (((Set) m.get("&")).size() < 2)
189: return;
190: boolean end = true;
191: Iterator it = m.keySet().iterator();
192: while (it.hasNext()) {
193: Object e = it.next();
194: if (e instanceof T) {
195: end = false;
196: l.addLast(e);
197: pf(nt, (Map) m.get(e), l, f, writer);
198: l.removeLast();
199: }
200: }
201: if (end) {
202: if (f[0]) {
203: f[0] = false;
204: if (writer == null)
205: System.out.println("Conflicts:");
206: else
207: writer.println("Conflicts:");
208: }
209: if (writer == null)
210: System.out.println(" " + nt + ":" + l + " "
211: + m.get("&"));
212: else
213: writer.println(" " + nt + ":" + l + " " + m.get("&"));
214: }
215: }
216:
217: public static void printF(Map<String, Map> first,
218: PrintWriter writer, Language language) {
219: if (writer == null)
220: System.out.println("First:");
221: else
222: writer.println("First:");
223: Iterator<String> it = first.keySet().iterator();
224: while (it.hasNext()) {
225: String nt = it.next();
226: Map m = first.get(nt);
227: String s = m.containsKey("#") ? ("#" + m.get("#")
228: .toString()) : "";
229: // int d = 1;
230: // if (m2.containsKey ("*"))
231: // d = ((Integer) m2.get ("*")).intValue ();
232: if (writer == null)
233: System.out.println(" " + nt + " : " + m.get("&")
234: + " " + s /*+ " d=" + d*/);
235: else
236: writer.println(" " + nt + " : " + m.get("&") + " "
237: + s /*+ " d=" + d*/);
238: p(m, " ", writer, language);
239: }
240: }
241:
242: private static void p(Map m, String i, PrintWriter writer,
243: Language language) {
244: Iterator it = m.keySet().iterator();
245: while (it.hasNext()) {
246: Object e = it.next();
247: if ("&".equals(e))
248: continue;
249: if ("#".equals(e))
250: continue;
251: if ("*".equals(e))
252: continue;
253: T t = (T) e;
254: Map m1 = (Map) m.get(e);
255: String s = m1.containsKey("#") ? ("#" + m1.get("#")
256: .toString()) : "";
257: if (writer == null)
258: System.out.println(i + t.toString(language) + " "
259: + m1.get("&") + " " + s);
260: else
261: writer.println(i + t.toString(language) + " "
262: + m1.get("&") + " " + s);
263: p(m1, i + " ", writer, language);
264: }
265: }
266:
267: public static void printDepth(Map f, PrintWriter writer) {
268: if (writer == null)
269: System.out.println("Depth:");
270: else
271: writer.println("Depth:");
272: int dd = 0;
273: Iterator it = f.keySet().iterator();
274: while (it.hasNext()) {
275: String mt = (String) it.next();
276: Map m = (Map) f.get(mt);
277: Iterator it2 = m.keySet().iterator();
278: while (it2.hasNext()) {
279: String nt = (String) it2.next();
280: Map mm = (Map) m.get(nt);
281: int[] r = pd(mm);
282: dd += r[1];
283: // int d = 1;
284: // if (mm.containsKey ("*"))
285: // d = ((Integer) mm.get ("*")).intValue ();
286: if (writer == null)
287: System.out.println(" " + nt + ": "
288: + /*d + ", " +*/r[0] + ", " + r[1]);
289: else
290: writer.println(" " + nt + ": "
291: + /*d + ", " +*/r[0] + ", " + r[1]);
292: }
293: }
294: if (writer == null)
295: System.out.println("d = " + dd);
296: else
297: writer.println("d = " + dd);
298: }
299:
300: private static int[] pd(Map m) {
301: int[] r = new int[] { 0, 0 };
302: Iterator it = m.keySet().iterator();
303: while (it.hasNext()) {
304: Object e = it.next();
305: if (e instanceof T) {
306: int[] rr = pd((Map) m.get(e));
307: r[0] = Math.max(r[0], rr[0] + 1);
308: r[1] += rr[1] + 1;
309: }
310: }
311: return r;
312: }
313: }
|