1/*
2 * [The "BSD license"]
3 *  Copyright (c) 2010 Terence Parr
4 *  All rights reserved.
5 *
6 *  Redistribution and use in source and binary forms, with or without
7 *  modification, are permitted provided that the following conditions
8 *  are met:
9 *  1. Redistributions of source code must retain the above copyright
10 *      notice, this list of conditions and the following disclaimer.
11 *  2. Redistributions in binary form must reproduce the above copyright
12 *      notice, this list of conditions and the following disclaimer in the
13 *      documentation and/or other materials provided with the distribution.
14 *  3. The name of the author may not be used to endorse or promote products
15 *      derived from this software without specific prior written permission.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package org.antlr.tool;
30
31/** Simplifying report dramatically for LL(*) paper.  Old results were
32 *  wrong anyway it seems.  We need:
33 *
34 * 		percent decisions that potentially backtrack
35 *  	histogram of regular lookahead depth (int k or *)
36 */
37public class GrammarReport2 {
38	public static final String newline = System.getProperty("line.separator");
39
40	public Grammar root;
41
42	public GrammarReport2(Grammar rootGrammar) {
43		this.root = rootGrammar;
44	}
45
46	public String toString() {
47		StringBuilder buf = new StringBuilder();
48		stats(root, buf);
49		CompositeGrammar composite = root.composite;
50		for (Grammar g : composite.getDelegates(root)) {
51			stats(g, buf);
52		}
53		return buf.toString();
54	}
55
56	void stats(Grammar g, StringBuilder buf) {
57		int numDec = g.getNumberOfDecisions();
58		for (int decision=1; decision<=numDec; decision++) {
59			Grammar.Decision d = g.getDecision(decision);
60			if ( d.dfa==null ) { // unusued decisions in auto synpreds
61				//System.err.println("no decision "+decision+" dfa for "+d.blockAST.toStringTree());
62				continue;
63			}
64			int k = d.dfa.getMaxLookaheadDepth();
65			Rule enclosingRule = d.dfa.decisionNFAStartState.enclosingRule;
66			if ( enclosingRule.isSynPred ) continue; // don't count synpred rules
67			buf.append(g.name+"."+enclosingRule.name+":" +
68					   "");
69			GrammarAST decisionAST =
70				d.dfa.decisionNFAStartState.associatedASTNode;
71			buf.append(decisionAST.getLine());
72			buf.append(":");
73			buf.append(decisionAST.getCharPositionInLine());
74			buf.append(" decision "+decision+":");
75
76			if ( d.dfa.isCyclic() ) buf.append(" cyclic");
77			if ( k!=Integer.MAX_VALUE ) buf.append(" k="+k); // fixed, no sempreds
78			if ( d.dfa.hasSynPred() ) buf.append(" backtracks"); // isolated synpred not gated
79			if ( d.dfa.hasSemPred() ) buf.append(" sempred"); // user-defined sempred
80//			else {
81//				buf.append("undefined");
82//				FASerializer serializer = new FASerializer(g);
83//				String result = serializer.serialize(d.dfa.startState);
84//				System.err.println(result);
85//			}
86			nl(buf);
87		}
88	}
89
90	void nl(StringBuilder buf) {
91		buf.append(newline);
92	}
93}
94