Skip to content
Snippets Groups Projects
Commit 04e5a2f4 authored by Johannes Mey's avatar Johannes Mey
Browse files

switch to base directory approach

parent 9074eeb8
No related branches found
No related tags found
No related merge requests found
build
src/gen-res/
src/gen/
out/
out*/
*.class
......@@ -31,8 +31,8 @@ import org.jastadd.option.ArgumentParser;
import org.jastadd.option.Option;
import java.io.PrintStream;
import java.util.Collection;
import java.util.LinkedList;
import java.util.*;
import java.util.stream.Collectors;
/**
* Tracks JastAdd configuration options.
......@@ -46,22 +46,52 @@ public class JastAddConfiguration extends org.jastadd.Configuration {
*/
final boolean unknownOptions;
private boolean isJastAddCompliant;
public boolean isJastAddCompliant() {
return isJastAddCompliant;
}
/**
* Parse options from an argument list.
*
* @param args Command-line arguments to build configuration from
* @param err output stream to print configuration warnings to
*/
public JastAddConfiguration(String[] args, PrintStream err, Collection<Option<?>> extraOptions) {
public JastAddConfiguration(String[] args, PrintStream err, boolean isJastAddCompliant, Collection<Option<?>> extraOptions) {
ArgumentParser argParser = new ArgumentParser();
argParser.addOptions(allJastAddOptions());
this.isJastAddCompliant = isJastAddCompliant;
if (isJastAddCompliant) {
Collection<Option<?>> jastAddOptions = allJastAddOptions();
argParser.addOptions(jastAddOptions);
// if the JastAdd options are supported, we have to check for duplicates!
Set<String> jastAddOptionNames = jastAddOptions.stream().map(o -> o.name()).collect(Collectors.toSet());
for (Option option : extraOptions) {
if (jastAddOptionNames.contains(option.name())) {
System.err.println("Unable to add option '" + option.name() + "', because there is a JastAdd option with the same name.");
} else {
argParser.addOption(option);
}
}
} else {
argParser.addOptions(extraOptions);
}
unknownOptions = !argParser.parseArgs(args, err);
filenames = argParser.getFilenames();
}
/**
* @return all files
*/
@Override
public Collection<String> getFiles() {
return Collections.unmodifiableCollection(filenames);
}
private Collection<Option<?>> allJastAddOptions() {
Collection<Option<?>> allOptions = new LinkedList<Option<?>>();
Collection<Option<?>> allOptions = new LinkedList<>();
allOptions.add(ASTNodeOption);
allOptions.add(ListOption);
allOptions.add(OptOption);
......
......@@ -31,13 +31,8 @@ public abstract class AbstractCompiler {
options = new ArrayList<>();
initOptions();
if (jastAddCompliant) {
configuration = new JastAddConfiguration(args, System.err, options);
} else {
commandLine = new ArgumentParser();
commandLine.addOptions(options);
commandLine.parseArgs(args, System.err);
}
configuration = new JastAddConfiguration(args, System.err, jastAddCompliant, options);
return compile();
}
......
......@@ -10,16 +10,18 @@ import org.jastadd.relast.scanner.RelAstScanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
public class RelastSourceToSourceCompiler extends AbstractCompiler {
protected ValueOption optionOutputDir;
protected ValueOption optionInputDir;
protected ValueOption optionOutputBaseDir;
protected ValueOption optionInputBaseDir;
public RelastSourceToSourceCompiler(String name, boolean jastAddCompliant) {
super(name, jastAddCompliant);
......@@ -34,94 +36,107 @@ public class RelastSourceToSourceCompiler extends AbstractCompiler {
}
}
protected static boolean isGrammarFile(String fileName) {
String extension = fileName.subSequence(fileName.lastIndexOf("."), fileName.length()).toString();
return extension.equals(".relast") || extension.equals(".ast");
}
@Override
protected void initOptions() {
optionOutputDir = addOption(new ValueOption("outputDir", "target directory for the generated files."));
optionInputDir = addOption(new ValueOption("inputDir", "input directory."));
optionOutputBaseDir = addOption(new ValueOption("outputBaseDir", "base directory for generated files"));
optionInputBaseDir = addOption(new ValueOption("inputBaseDir", "base directory for input files"));
}
@Override
protected int compile() throws CompilerException {
Path inputPath;
if (optionInputDir.isMatched()) {
inputPath = Paths.get(optionInputDir.value());
final Path inputBasePath;
if (optionInputBaseDir.isMatched()) {
inputBasePath = Paths.get(optionInputBaseDir.value()).toAbsolutePath();
} else {
inputPath = Paths.get(".");
printMessage("No input dir is set. Assuming current directory '" + inputPath.toAbsolutePath().toString() + "'.");
inputBasePath = Paths.get(".").toAbsolutePath();
printMessage("No input base dir is set. Assuming current directory '" + inputBasePath.toAbsolutePath().toString() + "'.");
}
if (!inputPath.toFile().exists()) {
printMessage("Input path '" + inputPath.toAbsolutePath().toString() + "' does not exist. Exiting...");
if (!inputBasePath.toFile().exists()) {
printMessage("Input path '" + inputBasePath.toAbsolutePath().toString() + "' does not exist. Exiting...");
System.exit(-1);
} else if (!inputPath.toFile().isDirectory()) {
printMessage("Input path '" + inputPath.toAbsolutePath().toString() + "' is not a directory. Exiting...");
} else if (!inputBasePath.toFile().isDirectory()) {
printMessage("Input path '" + inputBasePath.toAbsolutePath().toString() + "' is not a directory. Exiting...");
System.exit(-1);
}
Path outputPath;
if (optionOutputDir.isMatched()) {
outputPath = Paths.get(optionOutputDir.value());
final Path outputBasePath;
if (optionOutputBaseDir.isMatched()) {
outputBasePath = Paths.get(optionOutputBaseDir.value()).toAbsolutePath();
} else {
outputPath = Paths.get("./gen/");
printMessage("No output dir is set. Assuming '" + outputPath.toAbsolutePath().toString() + "'.");
throw new CompilerException("No output base dir is set.");
}
if (outputPath.toFile().exists() && !outputPath.toFile().isDirectory()) {
printMessage("Output path '" + inputPath.toAbsolutePath().toString() + "' exists, but is not a directory. Exiting...");
if (outputBasePath.toFile().exists() && !outputBasePath.toFile().isDirectory()) {
printMessage("Output path '" + inputBasePath.toAbsolutePath().toString() + "' exists, but is not a directory. Exiting...");
}
printMessage("Running RelAST Preprocessor");
Program program = parseProgram(inputPath);
// gather all files
Collection<Path> inputFiles = new ArrayList<>();
getConfiguration().getFiles().forEach(name -> relativizeFileName(inputBasePath, Paths.get(name)).ifPresent(path -> inputFiles.add(path)));
Program program = parseProgram(inputFiles);
printMessage("Writing output files");
for (GrammarFile grammarFile : program.getGrammarFileList()) {
// TODO decide and document what the file name should be, the full path or a simple name?
writeToFile(outputPath + grammarFile.getFileName() + "/Grammar.relast", grammarFile.generateAbstractGrammar());
writeToFile(outputBasePath.resolve(inputBasePath.relativize(Paths.get(grammarFile.getFileName()))), grammarFile.generateAbstractGrammar());
}
writeToFile(outputPath + "/Grammar.relast", program.generateAbstractGrammar());
return 0;
}
private Optional<Path> relativizeFileName(Path inputBasePath, Path filePath) {
if (filePath.isAbsolute()) {
if (filePath.startsWith(inputBasePath)) {
return Optional.of(filePath.relativize(inputBasePath));
} else {
printMessage("Path '" + filePath + "' is not contained in the base path '" + inputBasePath + "'.");
return Optional.empty();
}
} else {
return Optional.of(inputBasePath.resolve(filePath));
}
}
private void printMessage(String message) {
System.out.println(message);
}
private void writeToFile(String filename, String str) throws CompilerException {
try {
PrintWriter writer = new PrintWriter(filename);
private void writeToFile(Path path, String str) throws CompilerException {
try (PrintWriter writer = new PrintWriter(path.toFile())) {
writer.print(str);
writer.close();
} catch (Exception e) {
throw new CompilerException("Could not write to file " + filename, e);
throw new CompilerException("Could not write to file " + path, e);
}
}
private Program parseProgram(Path inputPath) throws CompilerException {
private Program parseProgram(Collection<Path> inputFiles) throws CompilerException {
Program program = new Program();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(inputPath, "*.relast")) {
RelAstParser parser = new RelAstParser();
stream.forEach(path -> {
inputFiles.stream().filter(path -> isGrammarFile(path.toString())).forEach(
path -> {
try (BufferedReader reader = Files.newBufferedReader(path)) {
RelAstScanner scanner = new RelAstScanner(reader);
GrammarFile inputGrammar = (GrammarFile) parser.parse(scanner);
inputGrammar.dumpTree(System.out);
inputGrammar.setFileName(path.toString());
program.addGrammarFile(inputGrammar);
inputGrammar.treeResolveAll();
} catch (IOException | Parser.Exception e) {
printMessage("Could not parse grammar file " + path);
e.printStackTrace();
}
});
} catch (IOException e) {
printMessage("Unable to iterate over input path '" + inputPath.toAbsolutePath().toString() + "'. Exiting...");
e.printStackTrace();
System.exit(-1);
}
);
return program;
}
......
......@@ -29,8 +29,9 @@ public class RelAstTest {
}
String[] args = {
"--outputDir=" + outputDir,
"--inputDir=" + inputDir
"--outputBaseDir=" + outputDir,
"--inputBaseDir=" + inputDir,
"Example.relast"
};
new RelastSourceToSourceCompiler("testCompiler", jastAddCompliant).run(args);
......@@ -38,7 +39,7 @@ public class RelAstTest {
@Test
void transformMinimalExample() throws CompilerException {
transform(false,"src/test/resources/in", "src/test/resources/out");
transform(true,"src/test/resources/in", "src/test/resources/out");
transform(false,"src/test/resources/in", "src/test/resources/out-simple");
transform(true,"src/test/resources/in", "src/test/resources/out-compliant");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment