/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.frontend.parser;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.jar.JarEntry;
import javax.xml.parsers.ParserConfigurationException;
import choco.kernel.model.constraints.Constraint;
import abs.frontend.mtvl.ChocoSolver;
import abs.common.Constants;
import abs.common.WrongProgramArgumentException;
import abs.frontend.analyser.SemanticCondition;
import abs.frontend.analyser.SemanticConditionList;
import abs.frontend.antlr.parser.ABSParserWrapper;
import abs.frontend.ast.*;
import abs.frontend.configurator.preprocessor.ABSPreProcessor; //Preprocessor
import abs.frontend.configurator.visualizer.FMVisualizer;
import abs.frontend.delta.DeltaModellingException;
import abs.frontend.delta.ProductLineTypeAnalysisHelper;
import abs.frontend.typechecker.locationtypes.LocationType;
import abs.frontend.typechecker.locationtypes.infer.LocationTypeInferrerExtension;
import abs.frontend.typechecker.locationtypes.infer.LocationTypeInferrerExtension.LocationTypingPrecision;
/**
* @author rudi
*
*/
public class Main {
public static final String ABS_STD_LIB = "abs/lang/abslang.abs";
protected boolean preprocess = false; //Preprocessor
protected boolean verbose = false;
protected boolean typecheck = true;
protected boolean stdlib = true;
protected boolean dump = false;
protected boolean debug = false;
protected boolean allowIncompleteExpr = false;
protected LocationType defaultLocationType = null;
protected boolean locationTypeInferenceEnabled = false;
// Must be public for AspectJ instrumentation
public boolean fullabs = false;
public String product;
protected boolean locationTypeStats = false;
protected LocationTypingPrecision locationTypeScope = null;
// mTVL options
protected boolean solve = false ;
protected boolean solveall = false ;
protected boolean solveWith = false ;
protected boolean minWith = false ;
protected boolean maxProduct = false ;
protected boolean check = false ;
protected boolean numbersol = false ;
protected boolean ignoreattr = false ;
protected boolean minimise = false ;
protected boolean maximise = false ;
public static void main(final String... args) {
new Main().mainMethod(args);
}
public void mainMethod(final String... args) {
try {
java.util.List<String> argslist = Arrays.asList(args);
if (argslist.contains("-maude")) {
abs.backend.maude.MaudeCompiler.main(args);
} else if(argslist.contains("-java")) {
abs.backend.java.JavaBackend.main(args);
} else if (argslist.contains("-erlang")) {
abs.backend.erlang.ErlangBackend.main(args);
} else if (argslist.contains("-prolog")) {
abs.backend.prolog.PrologBackend.main(args);
} else if (argslist.contains("-coreabs")) {
abs.backend.coreabs.CoreAbsBackend.main(args);
} else if (argslist.contains("-prettyprint")) {
abs.backend.prettyprint.PrettyPrinterBackEnd.main(args);
} else if (argslist.contains("-keyabs")) {
abs.backend.keyabs.KeyAbsBackend.main(args);
} else if (argslist.contains("-outline")) {
abs.backend.outline.OutlinePrinterBackEnd.main(args);
} else {
Model m = parse(args);
if (m.hasParserErrors()) {
printParserErrorAndExit();
}
}
} catch (Exception e) {
printErrorAndExit(e.getMessage());
}
}
public void setWithStdLib(boolean withStdLib) {
this.stdlib = withStdLib;
}
public void setAllowIncompleteExpr(boolean b) {
allowIncompleteExpr = b;
}
public void setTypeChecking(boolean b) {
typecheck = b;
}
public java.util.List<String> parseArgs(String[] args) {
ArrayList<String> remainingArgs = new ArrayList<String>();
for (String arg : args) {
if (arg.equals("-dump"))
dump = true;
else if (arg.equals("-debug"))
debug = true;
else if (arg.equals("-v"))
verbose = true;
else if (arg.equals("-version"))
printVersionAndExit();
else if (arg.startsWith("-product=")) {
fullabs = true;
product = arg.split("=")[1];
} else if (arg.startsWith("-allproducts")) {
fullabs = true;
product = null;
}
else if (arg.equals("-notypecheck"))
typecheck = false;
else if (arg.equals("-nostdlib"))
stdlib = false;
else if (arg.equals("-loctypestats"))
locationTypeStats = true;
else if (arg.equals("-loctypes")) {
locationTypeInferenceEnabled = true;
} else if (arg.startsWith("-locdefault=")) {
String def = arg.split("=")[1];
defaultLocationType = LocationType.createFromName(def);
} else if (arg.startsWith("-locscope=")) {
String def = arg.split("=")[1];
locationTypeScope = LocationTypingPrecision.valueOf(def);
} else if (arg.equals("-solve")) {
solve = true;
} else if (arg.equals("-solveall")) {
solveall = true;
} else if (arg.startsWith("-solveWith=")) {
solveWith = true;
product = arg.split("=")[1];
} else if (arg.startsWith("-minWith=")) {
minWith = true;
product = arg.split("=")[1];
} else if (arg.startsWith("-maxProduct")) {
maxProduct = true;
} else if (arg.startsWith("-min=")) {
minimise = true;
product = arg.split("=")[1];
} else if (arg.startsWith("-max=")) {
maximise = true;
product = arg.split("=")[1];
} else if (arg.equals("-sat")) {
check = true;
} else if (arg.startsWith("-check=")) {
check = true;
product = arg.split("=")[1];
} else if (arg.equals("-nsol")) {
numbersol = true;
} else if (arg.equals("-noattr")) {
ignoreattr = true;
} else if (arg.equals("-preprocess")) { //Preprocessor
preprocess = true;
} else if (arg.equals("-h") || arg.equals("-help")
|| arg.equals("--help")) {
printUsageAndExit();
} else
remainingArgs.add(arg);
}
return remainingArgs;
}
public Model parse(final String[] args) throws IOException, DeltaModellingException, WrongProgramArgumentException, ParserConfigurationException {
Model m = parseFiles(parseArgs(args).toArray(new String[0]));
analyzeModel(m);
return m;
}
public Model parseFiles(String... fileNames) throws IOException {
if (fileNames.length == 0) {
printErrorAndExit("Please provide at least one input file");
}
java.util.List<CompilationUnit> units = new ArrayList<CompilationUnit>();
for (String fileName : fileNames) {
if (fileName.startsWith("-")) {
throw new IllegalArgumentException("Illegal option " + fileName);
}
File f = new File(fileName);
if (!f.canRead()) {
throw new IllegalArgumentException("File "+fileName+" cannot be read");
}
if (!f.isDirectory() && !isABSSourceFile(f) && !isABSPackageFile(f)) {
throw new IllegalArgumentException("File "+fileName+" is not a legal ABS file");
}
}
for (String fileName : fileNames) {
parseFileOrDirectory(units, new File(fileName));
}
if (stdlib)
units.add(getStdLib());
List<CompilationUnit> unitList = new List<CompilationUnit>();
for (CompilationUnit u : units) {
unitList.add(u);
}
Model m = new Model(unitList);
Main.exceptionHack(m);
return m;
}
public void analyzeModel(Model m) throws WrongProgramArgumentException, DeltaModellingException, FileNotFoundException, ParserConfigurationException {
m.verbose = verbose;
m.debug = debug;
// drop attributes before calculating any attribute
if (ignoreattr)
m.dropAttributes();
if (verbose) {
System.out.println("Analyzing Model...");
}
//Preprocessor
if (preprocess) {
System.out.println("Preprocessing Model...");
ABSPreProcessor oABSPreProcessor = new ABSPreProcessor();
oABSPreProcessor.preProcessModel(m); //For Pre-processing...
// Transformation of microTVL to Future Model Editor compatible XML
FMVisualizer oFMVisualizer = new FMVisualizer();
oFMVisualizer.ParseMicroTVLFile(m);
}
if (m.hasParserErrors()) {
System.err.println("Syntactic errors: " + m.getParserErrors().size());
for (ParserError e : m.getParserErrors()) {
System.err.println(e.getHelpMessage());
System.err.flush();
}
return;
}
m.evaluateAllProductDeclarations();
rewriteModel(m, product);
m.flattenTraitOnly();
m.collapseTraitModifiers();
// type check PL before flattening
if (typecheck)
typeCheckProductLine(m);
// flatten before checking error, to avoid calculating *wrong* attributes
if (fullabs) {
if (product==null) {
// Build all SPL configurations (valid feature selections, ignoring attributes), one by one (for performance measuring)
if (verbose)
System.out.println("Building ALL " + m.getFeatureModelConfigurations().size() + " feature model configurations...");
ProductLineTypeAnalysisHelper.buildAllConfigurations(m);
return;
}
if (typecheck)
// apply deltas that correspond to given product
m.flattenForProduct(product);
else
m.flattenForProductUnsafe(product);
}
if (dump) {
m.dumpMVars();
m.dump();
}
final SemanticConditionList semErrs = m.getErrors();
if (semErrs.containsErrors()) {
System.err.println("Semantic errors: " + semErrs.getErrorCount());
}
for (SemanticCondition error : semErrs) {
// Print both errors and warnings
System.err.println(error.getHelpMessage());
System.err.flush();
}
if (!semErrs.containsErrors()) {
typeCheckModel(m);
analyzeMTVL(m);
}
}
/**
* Perform various rewrites that cannot be done in JastAdd
*
* JastAdd rewrite rules can only rewrite the current node using
* node-local information. ("The code in the body of the rewrite may
* access and rearrange the nodes in the subtree rooted at A, but not any
* other nodes in the AST. Furthermore, the code may not have any other
* side effects." --
* http://jastadd.org/web/documentation/reference-manual.php#Rewrites)
*
* We use this method to generate Exception constructors and the
* information in ABS.Productline.
*
* @param m the model.
* @param productname The name of the product.
* @throws WrongProgramArgumentException
*/
private static void rewriteModel(Model m, String productname)
throws WrongProgramArgumentException
{
// Generate reflective constructors for all features
ProductLine pl = m.getProductLine();
if (pl != null) {
// Let's assume the module and datatype names in abslang.abs did
// not get changed, and just crash otherwise. If you're here
// because of a NPE: Hi! Make the standard library and this code
// agree about what the feature reflection module is called.
ModuleDecl modProductline = null;
DataTypeDecl featureDecl = null;
FunctionDecl currentFeatureFun = null;
FunctionDecl productNameFun = null;
for (ModuleDecl d : m.getModuleDecls()) {
if (d.getName().equals(Constants.PL_NAME)) {
modProductline = d;
break;
}
}
for (Decl d : modProductline.getDecls()) {
if (d instanceof DataTypeDecl && d.getName().equals("Feature")) {
featureDecl = (DataTypeDecl)d;
} else if (d instanceof FunctionDecl && d.getName().equals("product_features")) {
currentFeatureFun = (FunctionDecl)d;
} else if (d instanceof FunctionDecl && d.getName().equals("product_name")) {
productNameFun = (FunctionDecl)d;
}
}
// Adjust Feature datatype
for (Feature f : pl.getFeatures()) {
// TODO: when/if we incorporate feature parameters into the
// productline feature declarations (as we should), we need to
// adjust the DataConstructor arguments here.
featureDecl.addDataConstructor(new DataConstructor(f.getName(), new List<ConstructorArg>()));
}
// Adjust product_name() function
productNameFun.setFunctionDef(new ExpFunctionDef(new StringLiteral(productname)));
// Adjust product_features() function
ProductDecl p = null;
if (productname != null) p = m.findProduct(productname);
if (p != null) {
DataConstructorExp feature_arglist = new DataConstructorExp("Cons", new List<PureExp>());
DataConstructorExp current = feature_arglist;
for (Feature f : p.getProduct().getFeatures()) {
DataConstructorExp next = new DataConstructorExp("Cons", new List<PureExp>());
// TODO: when/if we incorporate feature parameters into
// the productline feature declarations (as we should), we
// need to adjust the DataConstructorExp arguments here.
current.addParam(new DataConstructorExp(f.getName(), new List<PureExp>()));
current.addParam(next);
current = next;
}
current.setConstructor("Nil");
currentFeatureFun.setFunctionDef(new ExpFunctionDef(feature_arglist));
}
}
}
/** Handle exceptions: add exceptions as constructors to the
ABS.StdLib.Exception datatype.
*/
public static void exceptionHack(Model m) {
assert m != null;
if (m.getExceptionType() == null) {
return; // Eclipse?
}
DataTypeDecl e = (DataTypeDecl)(m.getExceptionType().getDecl());
if (e != null) {
// TODO: if null and not -nostdlib, throw an error
for (Decl decl : m.getDecls()) {
if (decl.isException()) {
ExceptionDecl e1 = (ExceptionDecl)decl;
// KLUDGE: what do we do about annotations to exceptions?
DataConstructor d = new DataConstructor(e1.getName(), e1.getConstructorArgs().treeCopyNoTransform());
d.setPositionFromNode(e1);
d.setFileName(e1.getFileName());
d.exceptionDecl = e1;
e1.dataConstructor = d;
e.addDataConstructor(d);
}
}
}
}
/**
* TODO: Should probably be introduced in Model through JastAdd by MTVL package.
* However, the command-line argument handling will have to stay in Main. Pity.
*/
private void analyzeMTVL(Model m) {
ProductDecl p_product = null;
try {
p_product = product == null ? null : m.findProduct(product);
} catch (WrongProgramArgumentException e) {
// ignore in case we're just solving.
}
if (m.hasMTVL()) {
if (solve) {
if (verbose)
System.out.println("Searching for solutions for the feature model...");
ChocoSolver s = m.instantiateCSModel();
System.out.print(s.resultToString());
}
if (minimise) {
assert product != null;
if (verbose)
System.out.println("Searching for minimum solutions of "+product+" for the feature model...");
ChocoSolver s = m.instantiateCSModel();
System.out.print(s.minimiseToString(product));
}
if (maximise) {
assert product != null;
if (verbose)
System.out.println("Searching for maximum solutions of "+product+" for the feature model...");
ChocoSolver s = m.instantiateCSModel();
//System.out.print(s.maximiseToInt(product));
s.addConstraint(ChocoSolver.eqeq(s.vars.get(product), s.maximiseToInt(product)));
ChocoSolver s1 = m.instantiateCSModel();
int i=1;
while(s1.solveAgain()) {
System.out.println("------ "+(i++)+"------");
System.out.print(s1.resultToString());
}
}
if (solveall) {
if (verbose)
System.out.println("Searching for all solutions for the feature model...");
ChocoSolver s = m.instantiateCSModel();
int i=1;
while(s.solveAgain()) {
System.out.println("------ "+(i++)+"------");
System.out.print(s.resultToString());
}
}
if (solveWith) {
assert product != null;
if (verbose)
System.out.println("Searching for solution that includes " + product + "...");
if (p_product != null) {
ChocoSolver s = m.instantiateCSModel();
HashSet<Constraint> newcs = new HashSet<Constraint>();
p_product.getProduct().getProdConstraints(s.vars, newcs);
for (Constraint c: newcs) s.addConstraint(c);
System.out.println("checking solution: "+s.resultToString());
} else {
System.out.println("Product '" + product + "' not found.");
if (!product.contains("."))
System.out.println("Maybe you forgot the module name?");
}
}
if (minWith) {
assert product != null;
if (verbose)
System.out.println("Searching for solution that includes " + product + "...");
ChocoSolver s = m.instantiateCSModel();
HashSet<Constraint> newcs = new HashSet<Constraint>();
s.addIntVar("difference", 0, 50);
if (p_product != null) {
m.getDiffConstraints(p_product.getProduct(), s.vars, newcs, "difference");
for (Constraint c: newcs) s.addConstraint(c);
System.out.println("checking solution: " + s.minimiseToString("difference"));
} else {
System.out.println("Product '" + product + "' not found.");
if (!product.contains("."))
System.out.println("Maybe you forgot the module name?");
}
}
if (maxProduct) {
assert product != null;
if (verbose)
System.out.println("Searching for solution that includes "+product+"...");
ChocoSolver s = m.instantiateCSModel();
HashSet<Constraint> newcs = new HashSet<Constraint>();
s.addIntVar("noOfFeatures", 0, 50);
if (m.getMaxConstraints(s.vars,newcs, "noOfFeatures")) {
for (Constraint c: newcs) s.addConstraint(c);
System.out.println("checking solution: "+s.maximiseToString("noOfFeatures"));
}
else {
System.out.println("---No solution-------------");
}
}
if (check) {
assert product != null;
ChocoSolver s = m.instantiateCSModel();
if (p_product == null ){
System.out.println("Product '"+product+"' not found.");
if (!product.contains("."))
System.out.println("Maybe you forgot the module name?");
} else {
Map<String,Integer> guess = p_product.getProduct().getSolution();
System.out.println("checking solution: "+s.checkSolution(guess,m));
}
}
if (numbersol && !ignoreattr) {
ChocoSolver s = m.instantiateCSModel();
System.out.println("Number of solutions found: "+s.countSolutions());
}
else if (numbersol && ignoreattr) {
ChocoSolver s = m.instantiateCSModel();
System.out.println("Number of solutions found (without attributes): "+s.countSolutions());
}
}
}
private void typeCheckModel(Model m) {
if (typecheck) {
if (verbose)
System.out.println("Typechecking Model...");
registerLocationTypeChecking(m);
SemanticConditionList typeerrors = m.typeCheck();
for (SemanticCondition se : typeerrors) {
System.err.println(se.getHelpMessage());
}
}
}
private void registerLocationTypeChecking(Model m) {
if (locationTypeInferenceEnabled) {
if (verbose)
System.out.println("Registering Location Type Checking...");
LocationTypeInferrerExtension ltie = new LocationTypeInferrerExtension(m);
if (locationTypeStats) {
ltie.enableStatistics();
}
if (defaultLocationType != null) {
ltie.setDefaultType(defaultLocationType);
}
if (locationTypeScope != null) {
ltie.setLocationTypingPrecision(locationTypeScope);
}
m.registerTypeSystemExtension(ltie);
}
}
private void typeCheckProductLine(Model m) {
int n = m.getFeatureModelConfigurations().size();
if (n == 0)
return;
if (verbose) {
System.out.println("Typechecking Software Product Line (" + n + " products)...");
}
SemanticConditionList typeerrors = m.typeCheckPL();
for (SemanticCondition se : typeerrors) {
System.err.println(se.getHelpMessage());
}
}
private void parseFileOrDirectory(java.util.List<CompilationUnit> units, File file) throws IOException {
if (!file.canRead()) {
System.err.println("WARNING: Could not read file "+file+", file skipped.");
}
if (file.isDirectory()) {
parseDirectory(units, file);
} else {
if (isABSSourceFile(file))
parseABSSourceFile(units,file);
else if (isABSPackageFile(file))
parseABSPackageFile(units,file);
}
}
public java.util.List<CompilationUnit> parseABSPackageFile(File file) throws IOException {
java.util.List<CompilationUnit> res = new ArrayList<CompilationUnit>();
parseABSPackageFile(res, file);
return res;
}
private void parseABSPackageFile(java.util.List<CompilationUnit> units, File file) throws IOException {
ABSPackageFile jarFile = new ABSPackageFile(file);
try {
if (!jarFile.isABSPackage())
return;
Enumeration<JarEntry> e = jarFile.entries();
while (e.hasMoreElements()) {
JarEntry jarEntry = e.nextElement();
if (!jarEntry.isDirectory()) {
if (jarEntry.getName().endsWith(".abs")) {
parseABSSourceFile(units, "jar:"+file.toURI()+"!/"+jarEntry.getName(), jarFile.getInputStream(jarEntry));
}
}
}
} finally {
jarFile.close();
}
}
private void parseDirectory(java.util.List<CompilationUnit> units, File file) throws IOException {
if (file.canRead() && !file.isHidden()) {
for (File f : file.listFiles()) {
if (f.isFile() && !isABSSourceFile(f) && !isABSPackageFile(f))
continue;
parseFileOrDirectory(units, f);
}
}
}
public static boolean isABSPackageFile(File f) {
ABSPackageFile absPackageFile;
final boolean isPackage;
try {
absPackageFile = new ABSPackageFile(f);
isPackage = absPackageFile.isABSPackage();
absPackageFile.close();
} catch (IOException e) {
return false;
}
return f.getName().endsWith(".jar") && isPackage;
}
public static boolean isABSSourceFile(File f) {
return f.getName().endsWith(".abs") || f.getName().endsWith(".mtvl");
}
private void parseABSSourceFile(java.util.List<CompilationUnit> units, String name, InputStream inputStream) throws IOException {
parseABSSourceFile(units, new File(name), new InputStreamReader(inputStream, "UTF-8"));
}
private void parseABSSourceFile(java.util.List<CompilationUnit> units, File file) throws IOException {
parseABSSourceFile(units, file, getUTF8FileReader(file));
}
private void parseABSSourceFile(java.util.List<CompilationUnit> units, File file, Reader reader) throws IOException {
if (verbose)
System.out.println("Parsing file "+file.getPath());//getAbsolutePath());
units.add(parseUnit(file, null, reader));
}
protected static void printParserErrorAndExit() {
System.err.println("\nCompilation failed with syntax errors.");
System.exit(1);
}
protected static void printErrorAndExit(String error) {
System.err.println("\nCompilation failed:\n");
System.err.println(" " + error);
System.err.println();
System.exit(1);
}
protected void printUsageAndExit() {
printUsage();
System.exit(1);
}
protected static void printVersionAndExit() {
System.out.println("ABS Tool Suite v"+getVersion());
System.exit(1);
}
public CompilationUnit getStdLib() throws IOException {
InputStream stream = Main.class.getClassLoader().getResourceAsStream(ABS_STD_LIB);
if (stream == null) {
printErrorAndExit("Could not find ABS Standard Library");
}
return parseUnit(new File(ABS_STD_LIB), null, new InputStreamReader(stream));
}
protected void printUsage() {
printHeader();
System.out.println(""
+ "Usage: java " + this.getClass().getName()
+ " [backend] [options] <absfiles>\n\n"
+ " <absfiles> ABS files/directories/packages to parse\n\n"
+ "Available backends:\n"
+ " -maude generate Maude code\n"
+ " -java generate Java code\n"
+ " -erlang generate Erlang code\n"
+ " -haskell generate Haskell code\n" // this is just for help printing; the execution of the compiler is done by the bash scipt absc
+ " -prolog generate Prolog\n"
+ " -prettyprint pretty-print ABS code\n\n"
+ "type 'absc -<backend> -help' to see backend-specific options\n\n"
+ "Common options:\n"
+ " -version print version\n"
+ " -v verbose output\n"
+ " -product=<PID> build given product by applying deltas (PID is the product ID)\n"
+ " -notypecheck disable typechecking\n"
+ " -nostdlib do not include the standard lib\n"
+ " -loctypes enable location type checking\n"
+ " -locdefault=<loctype> \n"
+ " sets the default location type to <loctype>\n"
+ " where <loctype> in " + Arrays.toString(LocationType.ALLUSERTYPES) + "\n"
+ " -locscope=<scope> \n"
+ " sets the location aliasing scope to <scope>\n"
+ " where <scope> in " + Arrays.toString(LocationTypingPrecision.values()) + "\n"
+ " -dump dump AST to standard output \n"
+ " -solve solve constraint satisfaction problem (CSP) for the feature\n"
+ " model\n"
+ " -solveall get ALL solutions for the CSP\n"
+ " -solveWith=<PID>\n"
+ " solve CSP by finding a product that includes PID.\n"
+ " -min=<var> minimise variable <var> when solving the CSP for the feature\n"
+ " model\n"
+ " -max=<var> maximise variable <var> when solving the CSP for the feature\n"
+ " model\n"
+ " -maxProduct get the solution that has the most number of features\n"
+ " -minWith=<PID> \n"
+ " solve CSP by finding a solution that tries to include PID\n"
+ " with minimum number of changes.\n"
+ " -nsol count the number of solutions\n"
+ " -noattr ignore the attributes\n"
+ " -check=<PID> check satisfiability of a product with name PID\n"
+ " -preprocess Preprocessing the Model\n" //Preprocessor
+ " -h print this message\n");
}
protected static void printHeader() {
String[] header = new String[] {
"The ABS Compiler" + " v" + getVersion(),
"Copyright (c) 2009-2013, The HATS Consortium",
"Copyright (c) 2013-2016, The Envisage Project",
"http://www.abs-models.org/" };
int maxlength = header[0].length();
StringBuilder starline = new StringBuilder();
for (int i = 0; i < maxlength + 4; i++) {
starline.append("*");
}
System.out.println(starline);
for (String h : header) {
System.out.print("* "+h);
for (int i = 0; i < maxlength-h.length(); i++) {
System.out.print(' ');
}
System.out.println(" *");
}
System.out.println(starline);
}
private static String getVersion() {
String version = Main.class.getPackage().getImplementationVersion();
if (version == null)
return "HEAD";
else
return version;
}
public CompilationUnit parseUnit(File file) throws Exception {
Reader reader = getUTF8FileReader(file);
BufferedReader rd = null;
// Set to true to print source before parsing
boolean dumpinput = false;
if (dumpinput) {
try {
rd = getUTF8FileReader(file);
String line = null;
int i = 1;
while ((line = rd.readLine()) != null) {
System.out.println(i++ + "\t" + line);
}
} catch (IOException x) {
System.out.flush();
System.err.println(x);
System.err.flush();
} finally {
if (rd != null)
rd.close();
}
}
return parseUnit(file, null, reader);
}
private BufferedReader getUTF8FileReader(File file) throws UnsupportedEncodingException, FileNotFoundException {
return new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
}
public static Iterable<File> toFiles(Iterable<String> fileNames) {
ArrayList<File> files = new ArrayList<File>();
for (String s : fileNames) {
files.add(new File(s));
}
return files;
}
public Model parse(File file, String sourceCode, InputStream stream) throws IOException {
return parse(file, sourceCode, new BufferedReader(new InputStreamReader(stream)));
}
public Model parse(File file, String sourceCode, Reader reader) throws IOException {
List<CompilationUnit> units = new List<CompilationUnit>();
if (stdlib)
units.add(getStdLib());
units.add(parseUnit(file, sourceCode, reader));
return new Model(units);
}
public CompilationUnit parseUnit(File file, String sourceCode, Reader reader)
throws IOException
{
try {
return new ABSParserWrapper(file, false, stdlib).parse(reader);
} finally {
reader.close();
}
}
public static Model parseString(String s, boolean withStdLib) throws Exception {
return parseString(s,withStdLib,false);
}
/**
* Calls {@link #parseString(String, boolean, boolean, boolean)} with withDbLib set to false.
*
* @param s
* @param withStdLib
* @param allowIncompleteExpr
* @return Model
* @throws Exception
*/
public static Model parseString(String s, boolean withStdLib, boolean allowIncompleteExpr) throws Exception {
Main m = new Main();
m.setWithStdLib(withStdLib);
m.setAllowIncompleteExpr(allowIncompleteExpr);
return m.parse(null, s, new StringReader(s));
}
}