【问题标题】:Add or modify keywords in java languagejava语言中添加或修改关键字
【发布时间】:2014-10-26 17:41:03
【问题描述】:

我知道我的问题似乎无效,但它是真实的。在编写 java 时,我必须使用单词import 以便从类路径中导入类。需要用户new在java中启动某些对象和其他关键字。我的问题是,通过定义新关键字及其作用或修改现有关键字来做同样的事情,我们是否有任何改进和改进这种伟大语言的能力。例如,不要写:

import java.io.File;

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

uvoziti java.io.File;

所有的工作方式都是一样的。在我得到想法之前请不要关闭。

【问题讨论】:

  • 您可以使用任何您喜欢的保留字编写自己的“Java”编译器。
  • 一切顺利!
  • 唯一的可能就是编写自己的语言。 Java有开源,不知道分支的license怎么样。
  • 用波斯尼亚语定义 Java 比更新现有的 Java 更容易!!
  • 想象一下必须使用具有自己的自定义关键字的代码...

标签: java keyword


【解决方案1】:

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

如果您在 Java 语言中添加或删除关键字,那么它就不再是 Java。

您可以编写自己的语言来编译为 Java。这可以像编写一个程序一样简单,该程序将 uvoziti 的字符串替换为 import,然后通过 javac 编译器运行它。

【讨论】:

  • 不,它不会,因为它会复制关键字,而不是替换它们。
  • 我不太明白你的评论@donaudampfschifffreizeitfahrt。我试图解释,如果你修改语言,它就不是 Java。如果您想创建自己的语言,那么您始终可以像 TypeScript、CoffeeScript 等那样交叉编译/转译为 Java。如果您可以给我更多关于我的答案不清楚/错误的地方的信息,那么我很乐意更新它.
  • 我指的是当您建议预处理文件并将其发送到 java 编译器时的部分。 “新”关键字将转换为“旧”关键字,但“旧”关键字仍将是“关键字”。所以这不会给 OP 提供他想要的东西。
  • 我仍然不确定我是否得到了这个问题。如果您在文件包含 NewShinyLang 时提前处理该文件,那么您可以将 NewShinyLang 定义为具有您想要的任何关键字。然后,您将该语言“编译”为 Java,然后将其发送给 Java 编译器。在 NewShinyLang 中,你可以定义任何你想要的东西。在进入字节码之前首先将其编译为 Java 的事实是 NewShinyLang 编译器的一个实现细节。
【解决方案2】:

作为一种选择,使用预处理器之类的东西或编写自己的预处理器,通过将波斯尼亚语单词替换为英语单词来处理 java 代码,然后再将该代码传递给 javac 编译器。

我认为这种方法应该适用于您的情况。

【讨论】:

    【解决方案3】:

    Java 本身并不能帮助您。

    您可能希望通过预处理器传递您的代码,但事情开始看起来有点疯狂:Can I have macros in Java source files。 我从来没有做过这样的事情,所以我不确定它是否会按预期工作。

    另外,请考虑在此更改之后,您的代码只有了解波斯尼亚语的人才能阅读。

    【讨论】:

    • 英文写的只有懂英文的人才懂;
    • @Stanley 是的,但如果你衡量人们理解英语与理解波斯尼亚语的人,你可以知道为什么代码语法是英文的
    • 这是正确的,但请考虑在英文中定义新关键字和新执行顺序和命令的灵活性。
    【解决方案4】:

    JVM和JDK理解Java关键词。如果你想改成你的语言,那么你也必须改变JDK和JVM。

    【讨论】:

    • JVM与关键字无关。
    【解决方案5】:

    您无法真正解决这个问题以通用工作; java在其语言规范中严格定义了关键字,java语言中没有添加关键字(例如宏)的机制。

    部分解决方案是创建一个预处理器,将您的新关键字转换为纯 java。不用说,集成到通用工具链中会很痛苦,而且对于预处理器创建的构造,您将不会再收到有用的编译器错误消息。

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

    这个想法很吸引人;这些障碍使其对于通用用途非常不切实际。

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

    【讨论】:

      【解决方案6】:

      一种使用相当复杂的工具链的方法可以被认为是“矫枉过正”,但不如编写自己的编译器那么费力:

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

        (当然,这只是翻译IMPORT标记的示例,该标记在语法文件中定义为"uvoziti"。为了更通用和灵活的翻译,一个将在外部文件中定义翻译,并可能读取此文件以创建映射 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 编写和编译输出文件,或者使用Runtime#exec 手动调用javac

      但总的来说,我认为这在最好的情况下应该在几个小时内完成,考虑到一切都需要比你想象的更长的时间,在一周内就可以完成。

      另一方面,编写自己的 Java 编译器可能需要更长的时间,即使您认为一切都比您想象的要长...

      【讨论】:

      • 我在编写外部文件时迷路了input.javax 如何在不编写外部文件的情况下实现这一点。我已经运行了这些文件,并且我的项目中有 javaLexer.java 文件。
      • Input.javaX 旨在作为带有修改后关键字的输入文件的一个示例。当您将程序编写为“javaX”文件(带有修改的关键字)后,您可以处理它们(如上面的Main 类所示)以生成有效的.java 文件(带有real 关键字)。然后可以使用javac 正常编译这些。
      • 好吧,我想我已经咬得比我能咀嚼的多,我会仔细学习这方面的教程,然后再开始做一些我以后可能会后悔的事情:)
      • 请注意,我描述的过程只是我想到的一个。可能有替代方案,其中一些可能更容易。 (stackoverflow.com/questions/6525059/… 之类的东西看起来很简单。它可能有一些限制,但是当意图替换关键字时,它也可能是一种可行的方法)。但是,如果你告诉你目前卡在哪里,也许我可以用更多信息来扩展答案。
      • 我实际上已经看到了那个例子,我更喜欢你的方法,我已经完成了所有步骤,直到 Create a Java Project that contains the ANTLR JAR and the JavaLexer.java input.javax 文件进来我很困惑,因为我不知道文件的内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2020-07-27
      相关资源
      最近更新 更多