One approach that uses a rather sophisticated toolchain and could be considered as an "overkill", but is not as much effort as writing an own compiler or so:
- Download ANTLR4 from http://www.antlr.org/download.html
- Download the Java Grammar at https://github.com/antlr/grammars-v4/blob/master/java/Java.g4
- Modify the Java Grammar according to your needs...
Run
java -classpath "antlr-4.4-complete.jar" org.antlr.v4.Tool Java.g4
This will generate some files, one of them being JavaLexer.java
.
- Create a Java Project that contains the ANTLR JAR and the
JavaLexer.java
Create a class like the following, which does the translation:
import java.io.IOException;
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
public class Main {
public static void main(String[] args) throws IOException {
CharStream s = new ANTLRFileStream("Input.javaX");
JavaLexer lexer = new JavaLexer(s);
TokenStream t = new CommonTokenStream(lexer);
int i = 1;
while (true) {
if (t.LA(i) == -1) {
break;
}
if (t.LA(i) == JavaLexer.IMPORT) {
System.out.print("import ");
} else {
System.out.print(t.LT(i).getText() + " ");
}
i++;
}
}
}
(of course, this is only an example that only translates the IMPORT
token, which was defined in the grammar file to be "uvoziti"
. For a more general and flexible translation, one would define the translation in an external file, and probably read this file to create a map Map<Integer, String>
that maps JavaLexer.IMPORT
to "import"
etc...)
Create the input file from the example: Input.javaX
:
uvoziti java.io.File;
public class Input
{
public static void main(String args[])
{
File file = null;
System.out.println("done");
}
}
When you then run the Main
, it will read this input file, eventually find the IMPORT
token, and instead of the original text (uvoziti
) it will print import
.
The result will be the contents of a Java file, with an awful formatting...
import java . io . File ; public class Input { public static void main ( String args [ ] ) { File file = null ; System . out . println ( "done" ) ; } }
but fortuntately, the compiler does not care about the formatting: You may write this output directly to a .java
file, and the compiler will swallow it.
As it is described here, it is only a proof of concept. For a flexible and generic translation of many (all) keywords, one would have to build some infrastructure around all that. The input files should be read automatically (File.listFiles()
, recursively for packages). Each of them would have to be translated (using the Map<Integer, String>
that I mentioned earlier). Then the output files would have to be written and compiled, either with the runtime JavaCompiler, or by manually invoking the javac
with Runtime#exec.
But in general, I think that this should be doable within a few hours in the best case, and within one week when considering that everything takes longer than you think.
Writing an own Java compiler, on the other hand, might take a bit longer, even when you consider that everything takes longer than you think...