com.argot.compiler.ArgotCompiler Maven / Gradle / Ivy
/*
* Copyright (c) 2003-2019, Live Media Pty. Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
* 3. Neither the name of Live Media nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.argot.compiler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import com.argot.TypeException;
import com.argot.TypeLibrary;
import com.argot.TypeLibraryLoader;
import com.argot.TypeLocation;
import com.argot.TypeLocationBase;
import com.argot.TypeLocationDefinition;
import com.argot.TypeLocationName;
import com.argot.TypeLocationRelation;
import com.argot.TypeMap;
import com.argot.TypeMapperCore;
import com.argot.TypeMapperDynamic;
import com.argot.TypeMapperError;
import com.argot.common.CommonLoader;
import com.argot.compiler.dictionary.LibraryBase;
import com.argot.compiler.dictionary.LibraryDefinition;
import com.argot.compiler.dictionary.LibraryLoader;
import com.argot.compiler.dictionary.LibraryName;
import com.argot.compiler.dictionary.LibraryRelation;
import com.argot.compiler.primitive.ArgotPrimitiveParser;
import com.argot.compiler.primitive.MetaNameParser;
import com.argot.compiler.primitive.MetaVersionParser;
import com.argot.compiler.primitive.StringPrimitiveParser;
import com.argot.compiler.primitive.UInt16PrimitiveParser;
import com.argot.compiler.primitive.UInt8PrimitiveParser;
import com.argot.dictionary.Dictionary;
import com.argot.meta.DictionaryBase;
import com.argot.meta.DictionaryDefinition;
import com.argot.meta.DictionaryName;
import com.argot.meta.DictionaryRelation;
import com.argot.meta.MetaDefinition;
import com.argot.meta.MetaIdentity;
import com.argot.meta.MetaLoader;
import com.argot.meta.MetaName;
import com.argot.meta.MetaVersion;
/**
* This compiles a file full of types into a typemap that can be written to a typemap file. The programmer then reads in
* the typemap and binds objects to the definitions.
*/
public class ArgotCompiler {
private TypeLibrary _library;
private InputStream _inputFile;
private URL[] _paths;
private ClassLoader _classLoader;
private boolean _loadCommon;
private boolean _compileDictionary;
private Map _primitiveParsers;
public ArgotCompiler(InputStream inputFile, URL[] paths) throws TypeException {
_inputFile = inputFile;
_paths = paths;
_loadCommon = true;
_compileDictionary = true;
_primitiveParsers = new HashMap();
_library = new TypeLibrary(false);
_library.loadLibrary(new MetaLoader());
_library.loadLibrary(new LibraryLoader());
setPrimitiveParser("meta.name", new StringPrimitiveParser());
setPrimitiveParser("u8ascii", new StringPrimitiveParser());
setPrimitiveParser("u8utf8", new StringPrimitiveParser());
setPrimitiveParser("uint8", new UInt8PrimitiveParser());
setPrimitiveParser("uint16", new UInt16PrimitiveParser());
setPrimitiveParser("uvint28", new UInt16PrimitiveParser());
setPrimitiveParser("meta.version", new MetaVersionParser());
setPrimitiveParser("meta.name", new MetaNameParser(_library));
if (paths == null) {
_classLoader = this.getClass().getClassLoader();
} else {
_classLoader = new URLClassLoader(_paths, this.getClass().getClassLoader());
}
printHeader();
}
public void setLoadCommon(boolean load) {
_loadCommon = load;
}
public void setCompileDictionary(boolean dict) {
_compileDictionary = dict;
}
public void setPrimitiveParser(String type, ArgotPrimitiveParser parser) {
_primitiveParsers.put(type, parser);
}
public ArgotPrimitiveParser getPrimitiveParser(String type) {
return _primitiveParsers.get(type);
}
private void printHeader() {
System.out.println("\nArgot Compiler Version 1.4.0");
System.out.println("Copyright 2004-2019 (C) Live Media Pty Ltd.");
System.out.println("www.argot-sdk.org\n");
}
private Object parse(TypeMap readMap, TypeMap map, InputStream inputFile) throws TypeException, FileNotFoundException, IOException, ArgotCompilerException {
InputStream fin = inputFile;
CharStream in = CharStreams.fromStream(fin);
ArgotLexer lexer = new ArgotLexer(in);
TokenStream tokenStream = new CommonTokenStream(lexer);
ArgotParser parser = new ArgotParser(tokenStream);
try {
ParseTree file = parser.file();
ArgotCompilerListener tree = new ArgotCompilerListener();
//ArgotTreeVisitor tree = new ArgotTreeVisitor(); // create a tree parser
tree.setLibrary(_library);
tree.setTypeMap(map);
tree.setReadTypeMap(readMap);
tree.setArgotCompiler(this);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(tree, file);
//ArgotContext ctx = tree.visit(r);
//List errors = tree.getErrors();
//if (errors.isEmpty())
// return map;
return null;
//throw new ArgotCompilerException(errors);
} catch (RecognitionException e) {
throw new TypeException("Specification not recognised" + e.toString(), e);
}
}
public Object parseData(InputStream inputFile) throws TypeException, IOException, ArgotCompilerException {
InputStream fin = inputFile;
ArgotLexer lexer = new ArgotLexer(CharStreams.fromStream(fin));
CommonTokenStream tokens = new CommonTokenStream(lexer);
ArgotParser parser = new ArgotParser(tokens);
try {
ParseTree file = parser.file();
//CommonTree t = (CommonTree) r.getTree(); // get tree from parser
//CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
TypeMap readMap = new TypeMap(_library, new TypeMapperDynamic(new TypeMapperCore(new TypeMapperError())));
ArgotCompilerListener tree = new ArgotCompilerListener();
tree.setLibrary(_library);
tree.setTypeMap(readMap);
tree.setReadTypeMap(readMap);
//tree.setValidateReference( false );
tree.setArgotCompiler(this);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(tree, file);
//Object data = tree.file();
/*
List errors = tree.getErrors();
if (errors.isEmpty()) {
// If only one item is in the array return the contents.
if (data.getClass().isArray()) {
Object[] dataArray = (Object[]) data;
if (dataArray.length == 1) {
return dataArray[0];
}
}
return data;
}
*/
return null;
//throw new ArgotCompilerException(errors);
} catch (RecognitionException e) {
throw new TypeException("Specification not recognised" + e.toString());
}
}
public void loadDictionary(String fileName, String loaderClass) throws TypeException, FileNotFoundException, IOException {
System.out.println("Loading: " + fileName);
InputStream inStream = null;
inStream = _classLoader.getResourceAsStream(fileName);
if (inStream == null) {
File file = new File(fileName);
if (!file.exists()) {
throw new FileNotFoundException("File not found as resource");
}
inStream = new FileInputStream(file);
}
try {
Dictionary.readDictionary(_library, inStream);
} catch (IOException ex) {
throw new TypeException("Failed to load dictionary: " + fileName, ex);
} catch (Throwable ex) {
throw new TypeException("Failed to load dictionary: " + fileName, ex);
}
if (loaderClass != null) {
try {
Object o = Class.forName(loaderClass).getConstructor().newInstance();
if (!(o instanceof TypeLibraryLoader)) {
throw new TypeException("Failed to load dictionary: " + fileName);
}
_library.loadLibrary((TypeLibraryLoader) o);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) {
throw new TypeException("Failed to load dictionary: " + fileName, ex);
}
}
}
public void loadOptionalDictionary(TypeLibrary library, TypeLibraryLoader loader) {
System.out.println("Loading file: " + loader.getName());
try {
library.loadLibrary(loader);
} catch (TypeException e) {
System.out.println("WARNING: '" + loader.getName() + "' failed to load.");
}
}
public void registerLibraryType(TypeMap map, TypeLocation location, MetaDefinition tds) throws TypeException {
if (location instanceof LibraryDefinition) {
LibraryDefinition libDef = (LibraryDefinition) location;
MetaName name = libDef.getName();
MetaVersion version = libDef.getVersion();
DictionaryName libName = new DictionaryName(name);
int nameState = _library.getTypeState(_library.getTypeId(libName));
int nameId = -1;
if (nameState == TypeLibrary.TYPE_NOT_DEFINED) {
nameId = _library.register(libName, new MetaIdentity());
} else {
nameId = _library.getTypeId(libName);
}
location = new DictionaryDefinition(nameId, name, version);
if (!map.isMapped(nameId)) {
// _map.map( _lastType++, nameId );
// _map.getStreamId( nameId );
}
} else if (location instanceof LibraryRelation) {
LibraryRelation libRel = (LibraryRelation) location;
MetaName name = _library.getName(libRel.getId());
DictionaryDefinition dictDef = new DictionaryDefinition(libRel.getId(), name, libRel.getVersion());
int libRelId = _library.getTypeId(dictDef);
if (!map.isMapped(libRelId)) {
// _map.map( _lastType++, libRelId );
map.getStreamId(libRelId);
}
location = new DictionaryRelation(libRelId, libRel.getTag());
} else if (location instanceof LibraryName) {
LibraryName libName = (LibraryName) location;
location = new DictionaryName(libName.getName());
} else if (location instanceof LibraryBase) {
// LibraryBase libBase = (LibraryBase) location;
location = new DictionaryBase();
}
int id = _library.getTypeId(location);
int state = _library.getTypeState(id);
if (state == TypeLibrary.TYPE_NOT_DEFINED || state == TypeLibrary.TYPE_RESERVED) {
// if ( _library.isReserved( typename.getText() ) )
if (state == TypeLibrary.TYPE_RESERVED) {
_library.register(location, tds);
} else {
int nId = _library.register(location, tds);
map.getStreamId(nId);
}
} else {
if (location instanceof TypeLocationDefinition) {
TypeLocationDefinition libDef = (TypeLocationDefinition) location;
String name = libDef.getName().getFullName() + ":" + libDef.getVersion().toString();
System.out.println("WARNING: can't redefine '" + name + "'. Definition ignored.");
} else if (location instanceof TypeLocationRelation) {
TypeLocationRelation libRel = (TypeLocationRelation) location;
String name = _library.getName(libRel.getId()).getFullName() + ":" + libRel.getTag();
System.out.println("WARNING: can't redefine '" + name + "'. Definition ignored.");
} else if (location instanceof TypeLocationName) {
TypeLocationName libName = (TypeLocationName) location;
String name = libName.getName().getFullName();
System.out.println("WARNING: can't redefine '" + name + "'. Definition ignored.");
} else if (location instanceof TypeLocationBase) {
System.out.println("WARNING: can't redefine library base.");
} else {
System.out.println("WARNING: can't redefine library type of unknown location type: " + location.getClass().getName());
}
try {
map.getStreamId(_library.getTypeId(location));
} catch (TypeException ex) {
System.out.println("import into map failed - " + ex.getMessage());
}
}
}
public void compileDictionary(OutputStream out) throws TypeException, IOException, ArgotCompilerException {
if (_loadCommon) {
loadOptionalDictionary(_library, new CommonLoader());
}
String argotHomeString = System.getProperty("ARGOT_HOME");
if (argotHomeString == null) {
argotHomeString = ".";
}
//System.out.println("Compiling: " + _inputFile.getName() );
TypeMap readMap = new TypeMap(_library, new TypeMapperDynamic(new TypeMapperCore(new TypeMapperError())));
TypeMap map = new TypeMap(_library, new TypeMapperDynamic(new TypeMapperError()));
parse(readMap, map, _inputFile);
if (_compileDictionary) {
Dictionary.writeDictionary(out, map);
} else {
throw new TypeException("not implemented");
}
}
public static Object compileData(TypeLibrary library, InputStream data) throws TypeException, IOException, ArgotCompilerException {
ArgotCompiler compiler = new ArgotCompiler(data, null);
compiler._library = library;
return compiler.parseData(data);
}
public static void argotCompile(String[] args) throws FileNotFoundException, TypeException, IOException {
if (args.length == 0) {
System.out.println("Usage: ac ");
System.exit(-1);
}
String inputFileName = args[0];
String outputFileName = null;
File inputFile = new File(inputFileName);
if (!inputFile.exists()) {
System.out.println("Input File not found");
System.out.println("Usage: ac ");
System.exit(-1);
}
int lastIndex = inputFileName.lastIndexOf(".");
if (lastIndex != -1) {
outputFileName = inputFileName.substring(0, lastIndex) + ".dictionary";
} else {
outputFileName = inputFileName + ".dictionary";
}
File outputFile = new File(outputFileName);
FileInputStream fin = new FileInputStream(inputFile);
FileOutputStream fout = new FileOutputStream(outputFile);
ArgotCompiler compiler = new ArgotCompiler(fin, null);
try {
compiler.compileDictionary(fout);
} catch (ArgotCompilerException e) {
e.printErrors(System.err);
}
}
public static void main(String[] args) {
try {
argotCompile(args);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TypeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy