在Java语言中添加或修改关键词

10

我知道我的问题似乎不太合法,但它是真实的。在编写Java时,我必须使用单词import来从类路径中导入类。必须使用new来初始化某些对象和其他关键字。我的问题是,我们是否有能力通过定义新关键字并指定其功能或修改现有关键字来改进这种优秀的语言,即使只有微小的改进。例如,可以将以下代码:

import java.io.File;

有没有可能将import这个词修改为波斯尼亚语,例如:

uvoziti java.io.File;

而且它们都是以同样的方式工作的。在我得到想法之前,请不要关闭。


1
你可以用任何保留字来编写自己的“Java”编译器。 - Eran
1
祝你的努力一切顺利! - Vihar
4
唯一的可能性就是编写自己的语言。Java有开源,我不确定分支的许可证是什么。 - Danubian Sailor
1
用波斯尼亚语定义Java比更新现有的Java容易多了! - Chowdappa
1
可能是对Java的新版本的请求,该版本支持一种字典。这意味着JDK包含了这样一个字典,其中包含了翻译关键字和原始关键字之间的映射。至于“添加关键字”,这应该是不可能的,因为关键字代表了固定的操作。 - Reporter
显示剩余4条评论
7个回答

11

一种使用相当复杂的工具链的方法,可能被认为是“过度设计”,但不需要像编写自己的编译器那样费力:

  • http://www.antlr.org/download.html下载ANTLR4
  • https://github.com/antlr/grammars-v4/blob/master/java/Java.g4下载Java语法文件
  • 根据您的需求修改Java语法文件...
  • 运行

    java -classpath "antlr-4.4-complete.jar" org.antlr.v4.Tool Java.g4
    

    这将生成一些文件,其中之一是JavaLexer.java

  • 创建一个包含ANTLR JAR和JavaLexer.java的Java项目
  • 创建一个类,如下所示,用于进行翻译:

    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++;
            }
        }
    }
    

    (当然,这只是一个示例,仅翻译了在语法文件中定义为"uvoziti"IMPORT标记。对于更通用和灵活的翻译,应该在外部文件中定义翻译,并可能读取此文件以创建映射Map<Integer,String>JavaLexer.IMPORT映射到"import"等...)

  • 从示例创建输入文件:Input.javaX

    uvoziti java.io.File;
    
    public class Input
    {
        public static void main(String args[])
        {
            File file = null;
            System.out.println("done");
        }
    }
    

    然后运行Main,它将读取此输入文件,最终找到IMPORT标记,并在原始文本(uvoziti)的位置打印import

  • 结果将是一个Java文件的内容,格式非常糟糕...

    import java . io . File ; public class Input { public static void main ( String args [ ] ) { File file = null ; System . out . println ( "done" ) ; } } 
    

    但幸运的是,编译器不关心格式:您可以直接将此输出写入.java文件,编译器将接受它。

正如此处所描述的,这只是一个概念验证。为了实现许多(全部)关键字的灵活和通用翻译,必须围绕所有这些构建一些基础设施。输入文件应该自动读取(对于包进行递归使用File.listFiles())。每一个文件都必须被翻译(使用我之前提到的Map<Integer, String>)。然后输出文件必须被编写和编译,可以使用JavaCompiler运行时,或通过手动调用javac来执行Runtime#exec
但总体而言,在最好的情况下,我认为这应该在几个小时内完成,在考虑到一切事情都需要比你想象的时间更长时,则需要一周时间。
另一方面,编写自己的Java编译器可能需要更长的时间,即使考虑到一切都需要比你想象的时间更长...

我在编写外部文件input.javax时遇到了困难,如何在不编写外部文件的情况下实现这一点。我已经运行了文件,并且在我的项目中有javaLexer.java文件。 - Stanley Mungai
请注意,我描述的过程只是我想到的其中一种。可能有其他选择,而且其中一些甚至可能更容易。(类似于https://dev59.com/62w15IYBdhLWcg3wkcqq这样的网站看起来非常容易。它可能有一些限制,但当意图仅*替换*关键字时,也可能是可行的方法)。但是,如果您告诉我目前卡在哪里,也许我可以通过进一步的信息扩展答案。 - Marco13
我之前看过那个例子,但我更喜欢你的方法。我已经完成了所有步骤,直到创建一个包含ANTLR JAR和JavaLexer.java的Java项目,但当input.javax文件出现时,我变得很困惑,因为我不知道文件的内容。 - Stanley Mungai
更高层次的视角:这种方法是创建一个项目,该项目由具有翻译关键字的Java文件组成(我称它们为.javaX以表示它们不是“正常”的.java文件)。其中一个示例文件是包含在答案中的Input.javaX,其中使用了uvoziti代替import。由所有javaX文件组成的此项目可以被翻译回“正常”的Java。这在我发布的Main类中得到了展示,针对单个示例文件(即Input.javaX)。翻译后,生成的文件可以使用javac编译。 - Marco13
好的,我明白了。我本来希望能够使用“uvoziti”编写普通的.java文件,但这样也可以。 - Stanley Mungai
显示剩余2条评论

0

Java 不提供重新定义关键字的任何方法。

如果您添加或删除 Java 语言中的关键字,则它将不再是 Java。

您可以编写自己的语言,使其编译为 Java。这可能只需编写一个程序,将 uvoziti 替换为 import,然后通过 javac 编译器运行该程序即可。


不会,因为它会复制关键字,而不是替换它们。 - Danubian Sailor
我不是很理解你的评论 @donaudampfschifffreizeitfahrt。我试图解释,如果你修改了语言,它就不再是Java了。如果你想创建自己的语言,那么你可以像TypeScript、CoffeeScript等一样交叉编译/转译成Java。如果你能告诉我我的回答哪里不清楚/错误,我很乐意更新它。 - Kevin Boyle
我指的是您推荐预处理文件并将其发送到Java编译器的部分。 “new”关键字将转换为“old”关键字,但“old”关键字仍将是“keywords”。因此,这不会完全满足OP的要求。 - Danubian Sailor
1
我仍然不确定我是否理解了这个问题。如果您在文件包含NewShinyLang时提前处理该文件,则可以定义NewShinyLang具有任何关键字。然后,您将该语言“编译”为Java,然后将其发送到Java编译器。在NewShinyLang中,您可以定义任何您想要的内容。在转换成字节码之前首先编译成Java的事实是NewShinyLang编译器的实现细节。 - Kevin Boyle

0
作为一种选择,您可以使用像预处理器或编写自己的预处理器来处理Java代码,通过将波斯尼亚语单词替换为英语单词,然后将此代码传递给javac编译器。
我认为这种方法应该适用于您的情况。

0

Java本身并不能帮助你解决这个问题。

你可能想要通过一个预处理器来传递你的代码,但事情开始变得有点疯狂:我可以在Java源文件中使用宏吗。我从未做过这样的事情,所以我不确定它是否会按预期工作。

此外,请考虑一下,在进行这些更改之后,只有理解波斯尼亚语的人才能阅读您的代码。


2
只有懂英语的人才能理解用英语写的内容。 - Stanley Mungai
2
@Stanley,没错,但是如果你衡量懂英语的人和懂波斯尼亚语的人,你就可以知道为什么代码语法是英语了。 - apomene
这是正确的,但请考虑一下,在英语中定义新关键字、新执行顺序和命令会有多么灵活。 - Stanley Mungai

0

你无法通用地解决这个问题;Java 严格定义了其语言规范中的关键字,并且在 Java 语言中没有机制可以添加关键字(例如宏)。

部分解决方案是创建一个预处理器,将您的新关键字转换为普通的 Java。不用说,这很难集成到常见的工具链中,并且您将不再为预处理器创建的结构获得有用的编译器错误消息。

更进一步的一步是编写自己的编译器;同样,这与现有工具链的集成效果不佳。您仍然无法从 IDE 中获得适当的支持。

尽管这个想法很迷人,但障碍使其在通用使用中高度不实际。

在带有编译时宏语言的语言中情况有所不同(大多数汇编语言都有此功能)。C 的 define 是另一个例子。它们仍然存在一个问题,即它们基于预处理器,因此添加的结构更加复杂(仅进行基本语法检查等)。


-1

JVM和JDK理解Java关键字。如果你想要将其翻译成你的语言,那么你也需要改变JDK和JVM。


2
JVM与关键字无关。 - Marco13

-1

只需使用预处理器。如果Java没有预处理器,那就自己写一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接