1dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org/*
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org * [The "BSD license"]
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org *  Copyright (c) 2010 Terence Parr
4dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  All rights reserved.
55de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org *
65de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org *  Redistribution and use in source and binary forms, with or without
7dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  modification, are permitted provided that the following conditions
8e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org *  are met:
9dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  1. Redistributions of source code must retain the above copyright
10dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *      notice, this list of conditions and the following disclaimer.
11248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org *  2. Redistributions in binary form must reproduce the above copyright
12dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *      notice, this list of conditions and the following disclaimer in the
13dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *      documentation and/or other materials provided with the distribution.
14dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  3. The name of the author may not be used to endorse or promote products
15dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *      derived from this software without specific prior written permission.
16e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org *
17e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org */
28dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgpackage org.antlr.test;
29dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
30dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
31dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.Tool;
32dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.analysis.Label;
33248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.orgimport org.antlr.runtime.CommonTokenStream;
34dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.runtime.Token;
35dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.runtime.TokenSource;
36dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.stringtemplate.v4.ST;
37dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.stringtemplate.v4.STGroup;
38dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.tool.ANTLRErrorListener;
39dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.tool.ErrorManager;
40dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.tool.GrammarSemanticsMessage;
41dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.antlr.tool.Message;
42dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.junit.After;
43dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.junit.Assert;
44dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport org.junit.Before;
45dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
46dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport javax.tools.*;
47dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport java.io.*;
48dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgimport java.util.*;
49dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
50dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
51dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgpublic abstract class BaseTest {
52dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	public static final String newline = System.getProperty("line.separator");
53dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
54dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	public static final String jikes = null;//"/usr/bin/jikes";
55dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	public static final String pathSep = System.getProperty("path.separator");
56dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
57dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org   /**
58dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    * When runnning from Maven, the junit tests are run via the surefire plugin. It sets the
59dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    * classpath for the test environment into the following property. We need to pick this up
60dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    * for the junit tests that are going to generate and try to run code.
61dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    */
62dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    public static final String SUREFIRE_CLASSPATH = System.getProperty("surefire.test.class.path", "");
63dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
64e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    /**
65e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org     * Build up the full classpath we need, including the surefire path (if present)
66e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org     */
67e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    public static final String CLASSPATH = System.getProperty("java.class.path") + (SUREFIRE_CLASSPATH.equals("") ? "" : pathSep + SUREFIRE_CLASSPATH);
68e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
69e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org	public String tmpdir = null;
70e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org
71e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org    /** reset during setUp and set to true if we find a problem */
72dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    protected boolean lastTestFailed = false;
73dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
74dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	/** If error during parser execution, store stderr here; can't return
75dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org     *  stdout and stderr.  This doesn't trap errors from running antlr.
76dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org     */
77dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String stderrDuringParse;
78dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
79dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    @Before
80dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	public void setUp() throws Exception {
81dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        lastTestFailed = false; // hope for the best, but set to true in asserts that fail
82dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        // new output dir for each test
83dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        tmpdir = new File(System.getProperty("java.io.tmpdir"),
84dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org						  "antlr-"+getClass().getName()+"-"+
85dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org						  System.currentTimeMillis()).getAbsolutePath();
86dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        ErrorManager.resetErrorState();
87dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        STGroup.defaultGroup = new STGroup();
88dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    }
89dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
90dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    @After
91dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    public void tearDown() throws Exception {
92dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        // remove tmpdir if no error.
93dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        if ( !lastTestFailed ) eraseTempDir();
94dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
95dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    }
96dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
97dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org    protected Tool newTool(String[] args) {
98dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		Tool tool = new Tool(args);
99dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		tool.setOutputDirectory(tmpdir);
100dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return tool;
101dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
102dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
103dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected Tool newTool() {
104dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		Tool tool = new Tool();
105dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		tool.setOutputDirectory(tmpdir);
106dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return tool;
107dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
108dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
109dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected boolean compile(String fileName) {
110dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		String classpathOption = "-classpath";
111dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
112dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		String[] args = new String[] {
113dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					"javac", "-d", tmpdir,
114dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					classpathOption, tmpdir+pathSep+CLASSPATH,
115dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					tmpdir+"/"+fileName
116dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		};
117dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		String cmdLine = "javac" +" -d "+tmpdir+" "+classpathOption+" "+tmpdir+pathSep+CLASSPATH+" "+fileName;
118dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		//System.out.println("compile: "+cmdLine);
119dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
120dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
121dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		File f = new File(tmpdir, fileName);
122dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
123dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
124dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		StandardJavaFileManager fileManager =
125dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			compiler.getStandardFileManager(null, null, null);
126dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
127dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		Iterable<? extends JavaFileObject> compilationUnits =
128dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			fileManager.getJavaFileObjectsFromFiles(Arrays.asList(f));
129dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
130dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		Iterable<String> compileOptions =
131dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			Arrays.asList(new String[]{"-d", tmpdir, "-cp", tmpdir+pathSep+CLASSPATH} );
132dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
133dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		JavaCompiler.CompilationTask task =
134dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			compiler.getTask(null, fileManager, null, compileOptions, null,
135dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							 compilationUnits);
136dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean ok = task.call();
137dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
138dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		try {
139dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			fileManager.close();
140dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
141dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		catch (IOException ioe) {
142dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			ioe.printStackTrace(System.err);
143dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
144dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return ok;
145dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
146dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
147dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	/** Return true if all is ok, no errors */
148dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected boolean antlr(String fileName, String grammarFileName, String grammarStr, boolean debug) {
149dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean allIsWell = true;
150dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		mkdir(tmpdir);
151dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		writeFile(tmpdir, fileName, grammarStr);
152dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		try {
153dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			final List options = new ArrayList();
154dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( debug ) {
155dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				options.add("-debug");
156dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			}
157dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			options.add("-o");
158dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			options.add(tmpdir);
159dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			options.add("-lib");
160dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			options.add(tmpdir);
161248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org			options.add(new File(tmpdir,grammarFileName).toString());
162dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			final String[] optionsA = new String[options.size()];
163dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			options.toArray(optionsA);
164dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			/*
165dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			final ErrorQueue equeue = new ErrorQueue();
166dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			ErrorManager.setErrorListener(equeue);
167dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			*/
168dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			Tool antlr = newTool(optionsA);
169dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			antlr.process();
170dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			ANTLRErrorListener listener = ErrorManager.getErrorListener();
171dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( listener instanceof ErrorQueue ) {
172dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				ErrorQueue equeue = (ErrorQueue)listener;
173dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				if ( equeue.errors.size()>0 ) {
174dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					allIsWell = false;
175dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					System.err.println("antlr reports errors from "+options);
176dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					for (int i = 0; i < equeue.errors.size(); i++) {
177dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org						Message msg = (Message) equeue.errors.get(i);
178dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org						System.err.println(msg);
179dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org					}
180dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                    System.out.println("!!!\ngrammar:");
181dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                    System.out.println(grammarStr);
182dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                    System.out.println("###");
183dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org                }
184dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			}
185dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
186dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		catch (Exception e) {
187dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			allIsWell = false;
188dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			System.err.println("problems building grammar: "+e);
189dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			e.printStackTrace(System.err);
190dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
191dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return allIsWell;
192dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
193dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
194dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String execLexer(String grammarFileName,
195dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							   String grammarStr,
196dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							   String lexerName,
197dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							   String input,
198dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							   boolean debug)
199dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	{
200dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		rawGenerateAndBuildRecognizer(grammarFileName,
201dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  grammarStr,
202c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org									  null,
203c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org									  lexerName,
204c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org									  debug);
205c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org		writeFile(tmpdir, "input", input);
206c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org		return rawExecRecognizer(null,
207c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org								 null,
208c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org								 lexerName,
209c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org								 null,
210c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org								 null,
211e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org								 false,
212e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org								 false,
213e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org								 false,
214e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org								 debug);
215dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
216dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
217dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String execParser(String grammarFileName,
218dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								String grammarStr,
219dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								String parserName,
220dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								String lexerName,
221dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								String startRuleName,
222dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								String input, boolean debug)
223dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	{
224dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		rawGenerateAndBuildRecognizer(grammarFileName,
225dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  grammarStr,
226dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  parserName,
227dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  lexerName,
228dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  debug);
229dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		writeFile(tmpdir, "input", input);
230dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean parserBuildsTrees =
231dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			grammarStr.indexOf("output=AST")>=0 ||
232dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			grammarStr.indexOf("output = AST")>=0;
233dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean parserBuildsTemplate =
234dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			grammarStr.indexOf("output=template")>=0 ||
235dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			grammarStr.indexOf("output = template")>=0;
236dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return rawExecRecognizer(parserName,
237dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 null,
238dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 lexerName,
239dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 startRuleName,
240dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 null,
241dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 parserBuildsTrees,
242dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 parserBuildsTemplate,
243dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 false,
244dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 debug);
245dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
246dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
247dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String execTreeParser(String parserGrammarFileName,
248dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserGrammarStr,
249dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserName,
250dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserGrammarFileName,
251dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserGrammarStr,
252dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserName,
253dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String lexerName,
254dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserStartRuleName,
255dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserStartRuleName,
256dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String input)
257dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	{
258dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return execTreeParser(parserGrammarFileName,
259dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  parserGrammarStr,
260dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  parserName,
261dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  treeParserGrammarFileName,
262dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  treeParserGrammarStr,
263dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  treeParserName,
264dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  lexerName,
265dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  parserStartRuleName,
266dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  treeParserStartRuleName,
267dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  input,
268dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org							  false);
269dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
270dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
271dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String execTreeParser(String parserGrammarFileName,
272dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserGrammarStr,
273dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserName,
274dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserGrammarFileName,
275dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserGrammarStr,
276dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserName,
277dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String lexerName,
278dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String parserStartRuleName,
279dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String treeParserStartRuleName,
280dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									String input,
281dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									boolean debug)
282dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	{
283dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		// build the parser
284dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		rawGenerateAndBuildRecognizer(parserGrammarFileName,
285dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  parserGrammarStr,
286dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  parserName,
287dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  lexerName,
288dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  debug);
289dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
290dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		// build the tree parser
291dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		rawGenerateAndBuildRecognizer(treeParserGrammarFileName,
292dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  treeParserGrammarStr,
293dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  treeParserName,
294dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  lexerName,
295dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									  debug);
296dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
297dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		writeFile(tmpdir, "input", input);
298248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org
299dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean parserBuildsTrees =
300dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			parserGrammarStr.indexOf("output=AST")>=0 ||
301dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			parserGrammarStr.indexOf("output = AST")>=0;
302dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean treeParserBuildsTrees =
303dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			treeParserGrammarStr.indexOf("output=AST")>=0 ||
304dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			treeParserGrammarStr.indexOf("output = AST")>=0;
305dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		boolean parserBuildsTemplate =
306dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			parserGrammarStr.indexOf("output=template")>=0 ||
307dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			parserGrammarStr.indexOf("output = template")>=0;
308dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
309dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return rawExecRecognizer(parserName,
310dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 treeParserName,
311dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 lexerName,
312dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 parserStartRuleName,
313d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org								 treeParserStartRuleName,
314d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org								 parserBuildsTrees,
315d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org								 parserBuildsTemplate,
316d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org								 treeParserBuildsTrees,
317dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org								 debug);
318dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
319dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
320dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	/** Return true if all is well */
321c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org	protected boolean rawGenerateAndBuildRecognizer(String grammarFileName,
322c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org													String grammarStr,
323c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org													String parserName,
324c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org													String lexerName,
325c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org													boolean debug)
326c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org	{
327c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org		//System.out.println(grammarStr);
328c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org		boolean allIsWell =
329c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org			antlr(grammarFileName, grammarFileName, grammarStr, debug);
330dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		if ( lexerName!=null ) {
331dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			boolean ok;
332dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( parserName!=null ) {
333dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				ok = compile(parserName+".java");
334dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				if ( !ok ) { allIsWell = false; }
335dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			}
336dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			ok = compile(lexerName+".java");
337dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( !ok ) { allIsWell = false; }
338dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
339dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		else {
340dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			boolean ok = compile(parserName+".java");
341dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( !ok ) { allIsWell = false; }
342dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
343dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return allIsWell;
344dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
345dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
346dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	protected String rawExecRecognizer(String parserName,
347dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   String treeParserName,
348dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   String lexerName,
349dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   String parserStartRuleName,
350dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   String treeParserStartRuleName,
351dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   boolean parserBuildsTrees,
352dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   boolean parserBuildsTemplate,
353dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   boolean treeParserBuildsTrees,
354dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org									   boolean debug)
355dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	{
356dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org        this.stderrDuringParse = null;
357dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		writeRecognizerAndCompile(parserName, treeParserName, lexerName, parserStartRuleName, treeParserStartRuleName, parserBuildsTrees, parserBuildsTemplate, treeParserBuildsTrees, debug);
358dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
359dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return execRecognizer();
360dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	}
361dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
362dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org	public String execRecognizer() {
363dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		try {
364dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			String inputFile = new File(tmpdir, "input").getAbsolutePath();
365dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			String[] args = new String[] {
366dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				"java", "-classpath", tmpdir+pathSep+CLASSPATH,
367dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				"Test", inputFile
368dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			};
369dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			//String cmdLine = "java -classpath "+CLASSPATH+pathSep+tmpdir+" Test " + new File(tmpdir, "input").getAbsolutePath();
370dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			//System.out.println("execParser: "+cmdLine);
371dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			Process process =
372dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				Runtime.getRuntime().exec(args, null, new File(tmpdir));
373dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream(), inputFile);
374dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream(), inputFile);
375dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			stdoutVacuum.start();
376dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			stderrVacuum.start();
377dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			process.waitFor();
378dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			stdoutVacuum.join();
379dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			stderrVacuum.join();
380dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			String output = null;
381dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			output = stdoutVacuum.toString();
382dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			if ( stderrVacuum.toString().length()>0 ) {
383dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				this.stderrDuringParse = stderrVacuum.toString();
384dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org				System.err.println("exec stderrVacuum: "+ stderrVacuum);
385dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			}
386dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			return output;
387dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		}
388dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		catch (Exception e) {
389dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			System.err.println("can't exec recognizer");
390dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org			e.printStackTrace(System.err);
3915de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org		}
392dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org		return null;
3935de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org	}
394
395	public void writeRecognizerAndCompile(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean parserBuildsTrees, boolean parserBuildsTemplate, boolean treeParserBuildsTrees, boolean debug) {
396		if ( treeParserBuildsTrees && parserBuildsTrees ) {
397			writeTreeAndTreeTestFile(parserName,
398									 treeParserName,
399									 lexerName,
400									 parserStartRuleName,
401									 treeParserStartRuleName,
402									 debug);
403		}
404		else if ( parserBuildsTrees ) {
405			writeTreeTestFile(parserName,
406							  treeParserName,
407							  lexerName,
408							  parserStartRuleName,
409							  treeParserStartRuleName,
410							  debug);
411		}
412		else if ( parserBuildsTemplate ) {
413			writeTemplateTestFile(parserName,
414								  lexerName,
415								  parserStartRuleName,
416								  debug);
417		}
418		else if ( parserName==null ) {
419			writeLexerTestFile(lexerName, debug);
420		}
421		else {
422			writeTestFile(parserName,
423						  lexerName,
424						  parserStartRuleName,
425						  debug);
426		}
427
428		compile("Test.java");
429	}
430
431	protected void checkGrammarSemanticsError(ErrorQueue equeue,
432											  GrammarSemanticsMessage expectedMessage)
433		throws Exception
434	{
435		/*
436				System.out.println(equeue.infos);
437				System.out.println(equeue.warnings);
438				System.out.println(equeue.errors);
439				assertTrue("number of errors mismatch", n, equeue.errors.size());
440						   */
441		Message foundMsg = null;
442		for (int i = 0; i < equeue.errors.size(); i++) {
443			Message m = (Message)equeue.errors.get(i);
444			if (m.msgID==expectedMessage.msgID ) {
445				foundMsg = m;
446			}
447		}
448		assertNotNull("no error; "+expectedMessage.msgID+" expected", foundMsg);
449		assertTrue("error is not a GrammarSemanticsMessage",
450				   foundMsg instanceof GrammarSemanticsMessage);
451		assertEquals(expectedMessage.arg, foundMsg.arg);
452		if ( equeue.size()!=1 ) {
453			System.err.println(equeue);
454		}
455	}
456
457	protected void checkGrammarSemanticsWarning(ErrorQueue equeue,
458												GrammarSemanticsMessage expectedMessage)
459		throws Exception
460	{
461		Message foundMsg = null;
462		for (int i = 0; i < equeue.warnings.size(); i++) {
463			Message m = (Message)equeue.warnings.get(i);
464			if (m.msgID==expectedMessage.msgID ) {
465				foundMsg = m;
466			}
467		}
468		assertNotNull("no error; "+expectedMessage.msgID+" expected", foundMsg);
469		assertTrue("error is not a GrammarSemanticsMessage",
470				   foundMsg instanceof GrammarSemanticsMessage);
471		assertEquals(expectedMessage.arg, foundMsg.arg);
472	}
473
474    protected void checkError(ErrorQueue equeue,
475                              Message expectedMessage)
476        throws Exception
477    {
478        //System.out.println("errors="+equeue);
479        Message foundMsg = null;
480        for (int i = 0; i < equeue.errors.size(); i++) {
481            Message m = (Message)equeue.errors.get(i);
482            if (m.msgID==expectedMessage.msgID ) {
483                foundMsg = m;
484            }
485        }
486        assertTrue("no error; "+expectedMessage.msgID+" expected", equeue.errors.size()>0);
487        assertTrue("too many errors; "+equeue.errors, equeue.errors.size()<=1);
488        assertNotNull("couldn't find expected error: "+expectedMessage.msgID, foundMsg);
489        /*
490        assertTrue("error is not a GrammarSemanticsMessage",
491                   foundMsg instanceof GrammarSemanticsMessage);
492         */
493        assertEquals(expectedMessage.arg, foundMsg.arg);
494        assertEquals(expectedMessage.arg2, foundMsg.arg2);
495        ErrorManager.resetErrorState(); // wack errors for next test
496    }
497
498    public static class StreamVacuum implements Runnable {
499		StringBuffer buf = new StringBuffer();
500		BufferedReader in;
501		Thread sucker;
502		String inputFile;
503		public StreamVacuum(InputStream in, String inputFile) {
504			this.in = new BufferedReader( new InputStreamReader(in) );
505			this.inputFile = inputFile;
506		}
507		public void start() {
508			sucker = new Thread(this);
509			sucker.start();
510		}
511		public void run() {
512			try {
513				String line = in.readLine();
514				while (line!=null) {
515					if (line.startsWith(inputFile))
516						line = line.substring(inputFile.length()+1);
517					buf.append(line);
518					buf.append('\n');
519					line = in.readLine();
520				}
521			}
522			catch (IOException ioe) {
523				System.err.println("can't read output from process");
524			}
525		}
526		/** wait for the thread to finish */
527		public void join() throws InterruptedException {
528			sucker.join();
529		}
530		public String toString() {
531			return buf.toString();
532		}
533	}
534
535    public static class FilteringTokenStream extends CommonTokenStream {
536        public FilteringTokenStream(TokenSource src) { super(src); }
537        Set<Integer> hide = new HashSet<Integer>();
538        protected void sync(int i) {
539            super.sync(i);
540            if ( hide.contains(get(i).getType()) ) get(i).setChannel(Token.HIDDEN_CHANNEL);
541        }
542        public void setTokenTypeChannel(int ttype, int channel) {
543            hide.add(ttype);
544        }
545    }
546
547	protected void writeFile(String dir, String fileName, String content) {
548		try {
549			File f = new File(dir, fileName);
550			FileWriter w = new FileWriter(f);
551			BufferedWriter bw = new BufferedWriter(w);
552			bw.write(content);
553			bw.close();
554			w.close();
555		}
556		catch (IOException ioe) {
557			System.err.println("can't write file");
558			ioe.printStackTrace(System.err);
559		}
560	}
561
562	protected void mkdir(String dir) {
563		File f = new File(dir);
564		f.mkdirs();
565	}
566
567	protected void writeTestFile(String parserName,
568								 String lexerName,
569								 String parserStartRuleName,
570								 boolean debug)
571	{
572		ST outputFileST = new ST(
573			"import org.antlr.runtime.*;\n" +
574			"import org.antlr.runtime.tree.*;\n" +
575			"import org.antlr.runtime.debug.*;\n" +
576			"\n" +
577			"class Profiler2 extends Profiler {\n" +
578			"    public void terminate() { ; }\n" +
579			"}\n"+
580			"public class Test {\n" +
581			"    public static void main(String[] args) throws Exception {\n" +
582			"        CharStream input = new ANTLRFileStream(args[0]);\n" +
583			"        <lexerName> lex = new <lexerName>(input);\n" +
584			"        CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
585			"        <createParser>\n"+
586			"        parser.<parserStartRuleName>();\n" +
587			"    }\n" +
588			"}"
589			);
590		ST createParserST =
591			new ST(
592			"        Profiler2 profiler = new Profiler2();\n"+
593			"        <parserName> parser = new <parserName>(tokens,profiler);\n" +
594			"        profiler.setParser(parser);\n");
595		if ( !debug ) {
596			createParserST =
597				new ST(
598				"        <parserName> parser = new <parserName>(tokens);\n");
599		}
600		outputFileST.add("createParser", createParserST);
601		outputFileST.add("parserName", parserName);
602		outputFileST.add("lexerName", lexerName);
603		outputFileST.add("parserStartRuleName", parserStartRuleName);
604		writeFile(tmpdir, "Test.java", outputFileST.render());
605	}
606
607	protected void writeLexerTestFile(String lexerName, boolean debug) {
608		ST outputFileST = new ST(
609			"import org.antlr.runtime.*;\n" +
610			"import org.antlr.runtime.tree.*;\n" +
611			"import org.antlr.runtime.debug.*;\n" +
612			"\n" +
613			"class Profiler2 extends Profiler {\n" +
614			"    public void terminate() { ; }\n" +
615			"}\n"+
616			"public class Test {\n" +
617			"    public static void main(String[] args) throws Exception {\n" +
618			"        CharStream input = new ANTLRFileStream(args[0]);\n" +
619			"        <lexerName> lex = new <lexerName>(input);\n" +
620			"        CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
621			"        System.out.println(tokens);\n" +
622			"    }\n" +
623			"}"
624			);
625		outputFileST.add("lexerName", lexerName);
626		writeFile(tmpdir, "Test.java", outputFileST.render());
627	}
628
629	protected void writeTreeTestFile(String parserName,
630									 String treeParserName,
631									 String lexerName,
632									 String parserStartRuleName,
633									 String treeParserStartRuleName,
634									 boolean debug)
635	{
636		ST outputFileST = new ST(
637			"import org.antlr.runtime.*;\n" +
638			"import org.antlr.runtime.tree.*;\n" +
639			"import org.antlr.runtime.debug.*;\n" +
640			"\n" +
641			"class Profiler2 extends Profiler {\n" +
642			"    public void terminate() { ; }\n" +
643			"}\n"+
644			"public class Test {\n" +
645			"    public static void main(String[] args) throws Exception {\n" +
646			"        CharStream input = new ANTLRFileStream(args[0]);\n" +
647			"        <lexerName> lex = new <lexerName>(input);\n" +
648			"        TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" +
649			"        <createParser>\n"+
650			"        <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" +
651			"        <if(!treeParserStartRuleName)>\n" +
652			"        if ( r.tree!=null ) {\n" +
653			"            System.out.println(((Tree)r.tree).toStringTree());\n" +
654			"            ((CommonTree)r.tree).sanityCheckParentAndChildIndexes();\n" +
655			"		 }\n" +
656			"        <else>\n" +
657			"        CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree);\n" +
658			"        nodes.setTokenStream(tokens);\n" +
659			"        <treeParserName> walker = new <treeParserName>(nodes);\n" +
660			"        walker.<treeParserStartRuleName>();\n" +
661			"        <endif>\n" +
662			"    }\n" +
663			"}"
664			);
665		ST createParserST =
666			new ST(
667			"        Profiler2 profiler = new Profiler2();\n"+
668			"        <parserName> parser = new <parserName>(tokens,profiler);\n" +
669			"        profiler.setParser(parser);\n");
670		if ( !debug ) {
671			createParserST =
672				new ST(
673				"        <parserName> parser = new <parserName>(tokens);\n");
674		}
675		outputFileST.add("createParser", createParserST);
676		outputFileST.add("parserName", parserName);
677		outputFileST.add("treeParserName", treeParserName);
678		outputFileST.add("lexerName", lexerName);
679		outputFileST.add("parserStartRuleName", parserStartRuleName);
680		outputFileST.add("treeParserStartRuleName", treeParserStartRuleName);
681		writeFile(tmpdir, "Test.java", outputFileST.render());
682	}
683
684	/** Parser creates trees and so does the tree parser */
685	protected void writeTreeAndTreeTestFile(String parserName,
686											String treeParserName,
687											String lexerName,
688											String parserStartRuleName,
689											String treeParserStartRuleName,
690											boolean debug)
691	{
692		ST outputFileST = new ST(
693			"import org.antlr.runtime.*;\n" +
694			"import org.antlr.runtime.tree.*;\n" +
695			"import org.antlr.runtime.debug.*;\n" +
696			"\n" +
697			"class Profiler2 extends Profiler {\n" +
698			"    public void terminate() { ; }\n" +
699			"}\n"+
700			"public class Test {\n" +
701			"    public static void main(String[] args) throws Exception {\n" +
702			"        CharStream input = new ANTLRFileStream(args[0]);\n" +
703			"        <lexerName> lex = new <lexerName>(input);\n" +
704			"        TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" +
705			"        <createParser>\n"+
706			"        <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" +
707			"        ((CommonTree)r.tree).sanityCheckParentAndChildIndexes();\n" +
708			"        CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree);\n" +
709			"        nodes.setTokenStream(tokens);\n" +
710			"        <treeParserName> walker = new <treeParserName>(nodes);\n" +
711			"        <treeParserName>.<treeParserStartRuleName>_return r2 = walker.<treeParserStartRuleName>();\n" +
712			"		 CommonTree rt = ((CommonTree)r2.tree);\n" +
713			"		 if ( rt!=null ) System.out.println(((CommonTree)r2.tree).toStringTree());\n" +
714			"    }\n" +
715			"}"
716			);
717		ST createParserST =
718			new ST(
719			"        Profiler2 profiler = new Profiler2();\n"+
720			"        <parserName> parser = new <parserName>(tokens,profiler);\n" +
721			"        profiler.setParser(parser);\n");
722		if ( !debug ) {
723			createParserST =
724				new ST(
725				"        <parserName> parser = new <parserName>(tokens);\n");
726		}
727		outputFileST.add("createParser", createParserST);
728		outputFileST.add("parserName", parserName);
729		outputFileST.add("treeParserName", treeParserName);
730		outputFileST.add("lexerName", lexerName);
731		outputFileST.add("parserStartRuleName", parserStartRuleName);
732		outputFileST.add("treeParserStartRuleName", treeParserStartRuleName);
733		writeFile(tmpdir, "Test.java", outputFileST.render());
734	}
735
736	protected void writeTemplateTestFile(String parserName,
737										 String lexerName,
738										 String parserStartRuleName,
739										 boolean debug)
740	{
741		ST outputFileST = new ST(
742			"import org.antlr.runtime.*;\n" +
743			"import org.antlr.stringtemplate.*;\n" +
744			"import org.antlr.stringtemplate.language.*;\n" +
745			"import org.antlr.runtime.debug.*;\n" +
746			"import java.io.*;\n" +
747			"\n" +
748			"class Profiler2 extends Profiler {\n" +
749			"    public void terminate() { ; }\n" +
750			"}\n"+
751			"public class Test {\n" +
752			"    static String templates = \"group T; foo(x,y) ::= \\\"\\<x> \\<y>\\\"\";\n" +
753			"    static StringTemplateGroup group ="+
754			"    		new StringTemplateGroup(new StringReader(templates)," +
755			"					AngleBracketTemplateLexer.class);"+
756			"    public static void main(String[] args) throws Exception {\n" +
757			"        CharStream input = new ANTLRFileStream(args[0]);\n" +
758			"        <lexerName> lex = new <lexerName>(input);\n" +
759			"        CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
760			"        <createParser>\n"+
761			"		 parser.setTemplateLib(group);\n"+
762			"        <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" +
763			"        if ( r.st!=null )\n" +
764			"            System.out.print(r.st.toString());\n" +
765			"	 	 else\n" +
766			"            System.out.print(\"\");\n" +
767			"    }\n" +
768			"}"
769			);
770		ST createParserST =
771			new ST(
772			"        Profiler2 profiler = new Profiler2();\n"+
773			"        <parserName> parser = new <parserName>(tokens,profiler);\n" +
774			"        profiler.setParser(parser);\n");
775		if ( !debug ) {
776			createParserST =
777				new ST(
778				"        <parserName> parser = new <parserName>(tokens);\n");
779		}
780		outputFileST.add("createParser", createParserST);
781		outputFileST.add("parserName", parserName);
782		outputFileST.add("lexerName", lexerName);
783		outputFileST.add("parserStartRuleName", parserStartRuleName);
784		writeFile(tmpdir, "Test.java", outputFileST.render());
785	}
786
787    protected void eraseFiles(final String filesEndingWith) {
788        File tmpdirF = new File(tmpdir);
789        String[] files = tmpdirF.list();
790        for(int i = 0; files!=null && i < files.length; i++) {
791            if ( files[i].endsWith(filesEndingWith) ) {
792                new File(tmpdir+"/"+files[i]).delete();
793            }
794        }
795    }
796
797    protected void eraseFiles() {
798        File tmpdirF = new File(tmpdir);
799        String[] files = tmpdirF.list();
800        for(int i = 0; files!=null && i < files.length; i++) {
801            new File(tmpdir+"/"+files[i]).delete();
802        }
803    }
804
805    protected void eraseTempDir() {
806        File tmpdirF = new File(tmpdir);
807        if ( tmpdirF.exists() ) {
808            eraseFiles();
809            tmpdirF.delete();
810        }
811    }
812
813	public String getFirstLineOfException() {
814		if ( this.stderrDuringParse ==null ) {
815			return null;
816		}
817		String[] lines = this.stderrDuringParse.split("\n");
818		String prefix="Exception in thread \"main\" ";
819		return lines[0].substring(prefix.length(),lines[0].length());
820	}
821
822	public List realElements(List elements) {
823		List n = new ArrayList();
824		for (int i = Label.NUM_FAUX_LABELS+Label.MIN_TOKEN_TYPE - 1; i < elements.size(); i++) {
825			Object o = (Object) elements.get(i);
826			if ( o!=null ) {
827				n.add(o);
828			}
829		}
830		return n;
831	}
832
833	public List<String> realElements(Map<String, Integer> elements) {
834		List n = new ArrayList();
835		Iterator iterator = elements.keySet().iterator();
836		while (iterator.hasNext()) {
837			String tokenID = (String) iterator.next();
838			if ( elements.get(tokenID) >= Label.MIN_TOKEN_TYPE ) {
839				n.add(tokenID+"="+elements.get(tokenID));
840			}
841		}
842		Collections.sort(n);
843		return n;
844	}
845
846    public String sortLinesInString(String s) {
847        String lines[] = s.split("\n");
848        Arrays.sort(lines);
849        List<String> linesL = Arrays.asList(lines);
850        StringBuffer buf = new StringBuffer();
851        for (String l : linesL) {
852            buf.append(l);
853            buf.append('\n');
854        }
855        return buf.toString();
856    }
857
858    /**
859     * When looking at a result set that consists of a Map/HashTable
860     * we cannot rely on the output order, as the hashing algorithm or other aspects
861     * of the implementation may be different on differnt JDKs or platforms. Hence
862     * we take the Map, convert the keys to a List, sort them and Stringify the Map, which is a
863     * bit of a hack, but guarantees that we get the same order on all systems. We assume that
864     * the keys are strings.
865     *
866     * @param m The Map that contains keys we wish to return in sorted order
867     * @return A string that represents all the keys in sorted order.
868     */
869    public String sortMapToString(Map m) {
870
871        System.out.println("Map toString looks like: " + m.toString());
872        // Pass in crap, and get nothing back
873        //
874        if  (m == null) {
875            return null;
876        }
877
878        // Sort the keys in the Map
879        //
880        TreeMap nset = new TreeMap(m);
881
882        System.out.println("Tree map looks like: " + nset.toString());
883        return nset.toString();
884    }
885
886    // override to track errors
887
888    public void assertEquals(String msg, Object a, Object b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
889    public void assertEquals(Object a, Object b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
890    public void assertEquals(String msg, long a, long b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
891    public void assertEquals(long a, long b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
892
893    public void assertTrue(String msg, boolean b) { try {Assert.assertTrue(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} }
894    public void assertTrue(boolean b) { try {Assert.assertTrue(b);} catch (Error e) {lastTestFailed=true; throw e;} }
895
896    public void assertFalse(String msg, boolean b) { try {Assert.assertFalse(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} }
897    public void assertFalse(boolean b) { try {Assert.assertFalse(b);} catch (Error e) {lastTestFailed=true; throw e;} }
898
899    public void assertNotNull(String msg, Object p) { try {Assert.assertNotNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} }
900    public void assertNotNull(Object p) { try {Assert.assertNotNull(p);} catch (Error e) {lastTestFailed=true; throw e;} }
901
902    public void assertNull(String msg, Object p) { try {Assert.assertNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} }
903    public void assertNull(Object p) { try {Assert.assertNull(p);} catch (Error e) {lastTestFailed=true; throw e;} }
904}
905