是否可以为Java 8创建预编译器插件?

时间:2018-03-01 14:20:00

标签: java regex plugins compiler-construction compiler-optimization

一些背景:

我喜欢在Java中进行code-golf挑战,其目标是以尽可能少的字节/字符执行某项任务。作为一个简单的例子:检查整数n是否是一个尽可能短(lambda)函数的素数 47字节

n->{for(int i=2;i<n;n=n%i++<1?0:n);return n>1;}

Try it online.

Code-golf答案通常非常难以理解,缺少空格和新行,只使用单字符变量,方法和类名,可能会给编译器警告等等。但是我们并不关心这些只要它在代码打高尔夫球时尽可能短。

所以,这就是代码 - 简单地打高尔夫球。虽然我已经回答了loads of code-golfing challenges in Java,但我希望Java能够多次使用一个函数:使用正则表达式的捕获组来获得类似于JavaScript或Retina的东西。

例如,如果在Java中可以实现这些目标,那就太棒了:
A

// Converting the capture group to an Integer:
s->n->s.replaceAll("\\D*(\\d+)",new Integer("$1")+n+"")
// i.e. "test123" & 7 will become 130 (123 + 7)

// Getting the length of a capture group:
s->s.replaceAll("(\\D*(\\d+))",new Integer("$2")+"$1".length()+"")
// i.e. "test123" will become 130 (123 + the length of "test123")

// Getting a character or substring of a capture group:
s->s.replaceAll(".(.+)",s+"$1".charAt(0))
// i.e. "test" will become "teste" ("test" + "est".charAt(0))

当然,通过一些小的修改可以实现上述目的:

s->n->new Integer(s.replaceAll("\\D*(\\d+)","$1"))+n+""
s->new Integer(s.replaceAll("(\\D*(\\d+))","$2"))+s.replaceAll("(\\D*(\\d+))","$1").length()+""
s->s.replaceAll(".(.+)",s)+s.replaceAll(".(.+)","$1").charAt(0)

Try it online.

问题本身:

现在我的问题:是否可以创建一个修改编译器代码的插件,因此上面 A 显示捕获组的replaceAll将被修改为即可。基本上创建插件/库/编译器标志或在String#replaceAllString#replaceFirst专门使用捕获组时修改预编译代码的任何内容。

PS:我不确定 A 的代码到底是不是我想要的代码,也许我会更喜欢JavaScript(或Retina):

// Syntax used above at A:
s->s.replaceAll("\\D*(\\d+)","$1".length()+"")
// JavaScript syntax alternative:
s->s.replaceAll("\\D*(\\d+)",a->a.length()+"") // a-> is the capture group 1
// Retina syntax alternative:
s->s.replaceAll("\\D*(\\d+)",new Integer("$#1")+"") // $#1 is the length of capture group 1

但这与问题本身无关:如何创建预编译插件,对代码的String#replaceAll(...,"$#")String#replaceFirst(...,"$#")部分进行某些修改。 (这是否有可能开始。)

1 个答案:

答案 0 :(得分:0)

我从没去过Code Golf,但我认为,您需要一个Transpiler。 Google代表“ Building Transpiler”。您也可以使用编译器或解释器。使用ANTLR来指定A和B语法,或者在Java中对其进行硬编码,然后根据lexer和parser对其进行映射。这并不困难,但我认为对于个人而言,这是一个漫长的过程,因为您需要在A中映射B提供的所有内容。