All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.itemis.xtext.antlr.toolrunner.AntlrToolRunner Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *******************************************************************************/
package de.itemis.xtext.antlr.toolrunner;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.nio.charset.Charset;

import org.antlr.Tool;
import org.antlr.codegen.CodeGenerator;
import org.antlr.tool.CompositeGrammar;
import org.antlr.tool.Grammar;

/**
 * @author Jan K?hnlein - Initial contribution and API
 * @author Sebastian Zarnekow
 */
public class AntlrToolRunner {
	
	public static void runWithEncodingAndParams(String grammarFullPath, String explicitEncoding, String... furtherArgs) {
		final String encoding = explicitEncoding != null ? explicitEncoding : Charset.defaultCharset().name();
		String[] args = new String[furtherArgs.length + 1];
		System.arraycopy(furtherArgs, 0, args, 0, furtherArgs.length);
		args[furtherArgs.length] = grammarFullPath;
		Tool antlr = new Tool(args) {
        	/**
        	 * Use a writer that suppresses the first comment line of java files, because
        	 * we don't want to have a timestamp in our generated parsers and lexers.
        	 */
			@Override
			public Writer getOutputFile(Grammar g, String fileName) throws IOException {
				Writer result = superGetOutputFile(g, fileName);
				if (fileName.endsWith(".java")) //$NON-NLS-1$
					result = new TailWriter(result, 2);
				return result;
			}
			
			/** Get a grammar mentioned on the command-line and any delegates */
		    @Override
			public Grammar getRootGrammar(String grammarFileName) throws IOException {
		        //StringTemplate.setLintMode(true);
		        // grammars mentioned on command line are either roots or single grammars.
		        // create the necessary composite in case it's got delegates; even
		        // single grammar needs it to get token types.
		        CompositeGrammar composite = new CompositeGrammar();
		        Grammar grammar = new Grammar(this, grammarFileName, composite);
		        composite.setDelegationRoot(grammar);
		        File f = null;

		        if (isSet("haveInputDir")) {
		            f = new File(this.get("inputDirectory"), grammarFileName);
		        }
		        else {
		            f = new File(grammarFileName);
		        }

		        // Store the location of this grammar as if we import files, we can then
		        // search for imports in the same location as the original grammar as well as in
		        // the lib directory.
		        //
		        set("parentGrammarDirectory", f.getParent());

		        if (grammarFileName.lastIndexOf(File.separatorChar) == -1) {
		        	set("parentGrammarDirectory", ".");
		        }
		        else {
		        	set("parentGrammarDirectory", grammarFileName.substring(0, grammarFileName.lastIndexOf(File.separatorChar)));
		        }
		        FileInputStream inputStream = new FileInputStream(f);
		        InputStreamReader reader = new InputStreamReader(inputStream, encoding);
		        BufferedReader br = new BufferedReader(reader);
		        grammar.parseAndBuildAST(br);
		        composite.watchNFAConversion = internalOption_watchNFAConversion;
		        br.close();
		        reader.close();
		        inputStream.close();
		        return grammar;
		    }
		    
		    @Override
		    public void sortGrammarFiles() throws IOException {
		    	// nothing to do, we have only one grammar file
		    	// so it's save to skip the GrammarSpelunker which uses
		    	// the default encoding internally
		    }
			
			protected Writer superGetOutputFile(Grammar g, String fileName) throws IOException {
				if (getOutputDirectory() == null) {
		            return new StringWriter();
		        }
		        // output directory is a function of where the grammar file lives
		        // for subdir/T.g, you get subdir here.  Well, depends on -o etc...
		        // But, if this is a .tokens file, then we force the output to
		        // be the base output directory (or current directory if there is not a -o)
		        //
		        File outputDir;
		        if (fileName.endsWith(CodeGenerator.VOCAB_FILE_EXTENSION)) {
		            if (isSet("haveOutputDir")) {
		                outputDir = new File(getOutputDirectory());
		            }
		            else {
		                outputDir = new File(".");
		            }
		        }
		        else {
		            outputDir = getOutputDirectory(g.getFileName());
		        }
		        File outputFile = new File(outputDir, fileName);

		        if (!outputDir.exists()) {
		            outputDir.mkdirs();
		        }
		        // CHANGE is here
		        // pass the encoding to the file output stream
		        FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
		        OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream, encoding);
		        return new BufferedWriter(writer);
			}
			
			private boolean isSet(String fieldName) {
				try {
					Field field = Tool.class.getDeclaredField(fieldName);
					field.setAccessible(true);
					boolean result = field.getBoolean(this);
					return result;
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}

			private  T get(String fieldName) {
				try {
					Field field = Tool.class.getDeclaredField(fieldName);
					field.setAccessible(true);
					@SuppressWarnings("unchecked")
					T result = (T) field.get(this);
					return result;
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
			
			private void set(String fieldName, Object value) {
				try {
					Field field = Tool.class.getDeclaredField(fieldName);
					field.setAccessible(true);
					field.set(this, value);
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
        };
        antlr.process();
	}
	
	public static void runWithParams(String grammarFullPath, String... furtherArgs) {
		runWithEncodingAndParams(grammarFullPath, Charset.defaultCharset().name(), furtherArgs);
	}
	
    public static void run(String grammarFullPath) {
    	runWithParams(grammarFullPath);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy