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 package org.antlr.tool;
29 
30 import org.antlr.Tool;
31 import org.antlr.runtime.*;
32 import org.antlr.runtime.tree.ParseTree;
33 
34 import java.io.BufferedReader;
35 import java.io.FileReader;
36 import java.util.Collection;
37 import java.util.HashSet;
38 import java.util.List;
39 import java.util.Set;
40 import java.util.StringTokenizer;
41 
42 /** Interpret any ANTLR grammar:
43  *
44  *  java Interp file.g tokens-to-ignore start-rule input-file
45  *
46  *  java Interp C.g 'WS COMMENT' program t.c
47  *
48  *  where the WS and COMMENT are the names of tokens you want to have
49  *  the parser ignore.
50  */
51 public class Interp {
52     public static class FilteringTokenStream extends CommonTokenStream {
FilteringTokenStream(TokenSource src)53         public FilteringTokenStream(TokenSource src) { super(src); }
54         Set<Integer> hide = new HashSet<Integer>();
55 		@Override
sync(int i)56         protected void sync(int i) {
57             super.sync(i);
58             if ( hide.contains(get(i).getType()) ) get(i).setChannel(Token.HIDDEN_CHANNEL);
59         }
setTokenTypeChannel(int ttype, int channel)60         public void setTokenTypeChannel(int ttype, int channel) {
61             hide.add(ttype);
62         }
63     }
64 
65 	// pass me a java file to parse
main(String[] args)66 	public static void main(String[] args) throws Exception {
67 		if ( args.length!=4 ) {
68 			System.err.println("java Interp file.g tokens-to-ignore start-rule input-file");
69 			return;
70 		}
71 		String grammarFileName = args[0];
72 		String ignoreTokens = args[1];
73 		String startRule = args[2];
74 		String inputFileName = args[3];
75 
76 		// TODO: using wrong constructor now
77 		Tool tool = new Tool();
78 		CompositeGrammar composite = new CompositeGrammar();
79 		Grammar parser = new Grammar(tool, grammarFileName, composite);
80 		composite.setDelegationRoot(parser);
81 		FileReader fr = new FileReader(grammarFileName);
82 		BufferedReader br = new BufferedReader(fr);
83 		parser.parseAndBuildAST(br);
84 		br.close();
85 
86 		parser.composite.assignTokenTypes();
87 		parser.composite.defineGrammarSymbols();
88 		parser.composite.createNFAs();
89 
90 		List<? extends Collection<? extends Rule>> leftRecursiveRules = parser.checkAllRulesForLeftRecursion();
91 		if ( leftRecursiveRules.size()>0 ) {
92 			return;
93 		}
94 
95 		if ( parser.getRule(startRule)==null ) {
96 			System.out.println("undefined start rule "+startRule);
97 			return;
98 		}
99 
100 		String lexerGrammarText = parser.getLexerGrammar();
101 		Grammar lexer = new Grammar(tool);
102 		lexer.importTokenVocabulary(parser);
103 		lexer.fileName = grammarFileName;
104 		lexer.setTool(tool);
105 		if ( lexerGrammarText!=null ) {
106 			lexer.setGrammarContent(lexerGrammarText);
107 		}
108 		else {
109 			System.err.println("no lexer grammar found in "+grammarFileName);
110 		}
111 		lexer.composite.createNFAs();
112 
113 		CharStream input =
114 			new ANTLRFileStream(inputFileName);
115 		Interpreter lexEngine = new Interpreter(lexer, input);
116 		FilteringTokenStream tokens = new FilteringTokenStream(lexEngine);
117 		StringTokenizer tk = new StringTokenizer(ignoreTokens, " ");
118 		while ( tk.hasMoreTokens() ) {
119 			String tokenName = tk.nextToken();
120 			tokens.setTokenTypeChannel(lexer.getTokenType(tokenName), 99);
121 		}
122 
123 		if ( parser.getRule(startRule)==null ) {
124 			System.err.println("Rule "+startRule+" does not exist in "+grammarFileName);
125 			return;
126 		}
127 		Interpreter parseEngine = new Interpreter(parser, tokens);
128 		ParseTree t = parseEngine.parse(startRule);
129 		System.out.println(t.toStringTree());
130 	}
131 }
132