10

I know my question does not seem valid, but it is genuine. When writing java I must use the word import so as to import classes from classpath. It is required to user new to initiate certain objects and other keywords in java. My question is whether we have even the slightest ability to improve and this great language by way of defining new keywords and what they do or modifying the exisiting keyword to do the same thing. For example instead of writing:

import java.io.File;

What possibility is there to modify the import word to bosnian for example:

uvoziti java.io.File;

and it all works the same way. Please do not close before I get ideas.

Stanley Mungai
  • 4,044
  • 30
  • 100
  • 168

7 Answers7

11

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...

lax1089
  • 3,403
  • 3
  • 17
  • 37
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • Iam getting lost at the point of writing an external file `input.javax` how can I achieve this without writing an external file. I have run the files and I have the javaLexer.java fle in my project. – Stanley Mungai Sep 02 '14 at 17:07
  • The `Input.javaX` was intended as one example of an input file with the modified keywords. When you have written your program as "javaX" files (with the modified keywords), you can process them (as shown in the `Main` class above) to generate valid `.java` files (with the *real* keywords). These can then be compiled normally with `javac`. – Marco13 Sep 02 '14 at 19:53
  • Well then, I think I have bitten more than I can chew, I will carefully take tutorials on this Before I embark on doing something I might regret later :) – Stanley Mungai Sep 03 '14 at 03:08
  • Note that the process that I described was only *one* that I thought of. There may be alternatives, and some of them may be even easier. (Something like http://stackoverflow.com/questions/6525059/can-i-have-macros-in-java-source-files looks very easy. It might have some limitation, but when the intention is to *only* replace *keywords*, it might also be a feasible approach). However, maybe I can extend the answer with further information, if you tell where you are currently stuck. – Marco13 Sep 03 '14 at 08:12
  • I had actually seen that example and I kind of like your approach more, I have done all the steps up to `Create a Java Project that contains the ANTLR JAR and the JavaLexer.java` where input.javax file came in I got all confused since I did not know the content of the file. – Stanley Mungai Sep 03 '14 at 08:26
  • A more high-level view: The approach was to create a project that consists of Java files with translated keywords (I called them `.javaX` to indicate that they are not "normal" `.java` files). One example of such a file is the `Input.javaX` that is contained in the answer, where `uvoziti` was used instead of `import`. This project, consisting of all the `javaX` files, could then be translated back to "normal" Java. This is shown in the `Main` class that I posted, for a single example file (namely, for the `Input.javaX`). After the translation, the resulting files can be compiled with `javac` – Marco13 Sep 03 '14 at 08:40
  • OK got it. I was hoping I was going to be able to write plain .java files with `uvoziti` but this is fine. – Stanley Mungai Sep 03 '14 at 08:46
0

Java doesn't provide any way to redefine keywords.

If you add or remove keywords to the Java language, then it isn't Java anymore.

You could write your own language that compiles to Java. This could be as simple as writing a program that does a string replace of uvoziti for import and then runs it through the javac compiler.

Kevin Boyle
  • 457
  • 2
  • 7
  • No, it wouldn't, because it would duplicate the keyword, not replace them. – Danubian Sailor Sep 02 '14 at 12:49
  • I don't really understand your comment @donaudampfschifffreizeitfahrt. I was trying to explain that if you modify the language, it isn't Java. If you want to create your own language then you can always cross-compile/transpile to Java as happens with TypeScript, CoffeeScript etc. If you can give me more info on where my answer is unclear/wrong then I'm happy to update it. – Kevin Boyle Sep 03 '14 at 09:07
  • I'm refering to the part when you recomend pre-processing the file and send it to the java compiler. The 'new' keywords would be converted to the 'old' keywords, but the 'old' keywords would still be 'keywords'. So that wouldn't give the OP exactly that what he wanted. – Danubian Sailor Sep 03 '14 at 13:13
  • 1
    I'm still not sure I get the issue. If you process the file ahead of time when it contains NewShinyLang, then you can define NewShinyLang to have whatever keywords you want. You then 'compile' that language to Java which you then send to the Java compiler. In NewShinyLang, you can define whatever you want. The fact that it is first compiled to Java before going to bytecode is an implementation detail of the NewShinyLang compiler. – Kevin Boyle Sep 04 '14 at 15:42
0

As an option, use something like preprocessor or write your own one, to process java code via replacement of bosnian words to english ones before passing this code to the javac compiler.

I think this approach should work for your case.

0

Java by itself doesn't help you in this.

You might want to pass your code through a pre-processor, but things start to look a bit crazy: Can I have macros in Java source files. I've never done something like this, so I'm not sure it will work as intended.

Also, consider that after this change your code is only readable by people understanding bosnian.

Community
  • 1
  • 1
Alberto Zaccagni
  • 30,779
  • 11
  • 72
  • 106
  • 2
    The one Written in English is only understood by people who understand english; – Stanley Mungai Sep 02 '14 at 12:47
  • 2
    @Stanley , true but if you measure people understand English vs those you understand Bosnian you can have a clue why code syntax is in english – apomene Sep 02 '14 at 12:50
  • That is Correct but please consider who flexible it would be even in English to define new keywords and new execution sequence and commands. – Stanley Mungai Sep 02 '14 at 12:53
0

You can't really solve this to work generically; java strictly defines the keywords in its language specification and there is no mechanism in the java language to add keywords (e.g. macros).

A partial solution would be to create a preprocessor that translates your new keywords into plain java. Needless to say that this is a pain to integrate into common tool chains and you won't get useful compiler error messages any more for constructs created by the preprocessor.

One step further would be to write your own compiler; again this integrates poorly with existing toolchains. You still don't get proper support from your IDE.

As fascinating as the idea is; the obstacles make it highly impractical for generic use.

The situation is different in languages that come with a compile time macro language (most assembler langauges have this). C's define is another example. They still all have the problem that they are preprocessor based, so added constructs are more complicated (only basic syntax checking etc.)

Durandal
  • 19,919
  • 4
  • 36
  • 70
-1

JVM and JDK understands Java key words. If you want to change into you language, then you have to change JDK and JVM also.

Chowdappa
  • 1,580
  • 1
  • 15
  • 31
-1

Just use a preprocessor. If java doesn't have one , then write one.

Paul
  • 177
  • 3