所以我花了一天的大部分时间用谷歌搜索和StackExchanging寻求答案或指导,我已经放弃了。我不得不问以下问题:
我想创建一个Java应用程序,要求用户输入类似于此的表达式:
t>>7|t|t>>6
我们假设它然后存储为String。我想要的是将此String转换为t
变为变量且>>
和|
成为运算符的表达式。基本上我想弄清楚如何实现这个http://www.redcode.nl/blog/2011/12/bytebeat-algorithmic-symphonies/但是以某种方式将用户输入传递给private static int f(int t)
而不是硬编码表达式。
我一直在阅读有关ScriptEngineManager和使用JavaScript的内容,但我不知道这是否可行。
无论如何,这仅适用于个人教育和娱乐。提前谢谢。
答案 0 :(得分:1)
您可以使用javassist库执行此操作。从http://sourceforge.net/projects/jboss/files/Javassist/3.16.1-GA/下载它并将其添加到您的项目中。
// ExpressionEvaluator.java
public class ExpressionEvaluator {
}
// AudioPump.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Loader;
import javassist.NotFoundException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class AudioPump {
private static String expression;
public static void main(String[] args) throws Exception {
System.out.print("Enter expression(use t as variable):");
BufferedReader consoleReader = new BufferedReader(
new InputStreamReader(System.in));
expression = consoleReader.readLine();
generateMethod(expression);
AudioFormat format = new AudioFormat(8000f, 8, 1, false, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine soundLine = (SourceDataLine) AudioSystem.getLine(info);
soundLine.open(format, 32000);
soundLine.start();
byte[] buffer = new byte[8];
int t = 0;
while (true) {
for (int n = 0; n < buffer.length; n++) {
buffer[n] = (byte) invokeF(t++);
}
soundLine.write(buffer, 0, buffer.length);
}
}
private static byte invokeF(int i) {
java.lang.reflect.Method method = null;
try {
ClassPool pool = ClassPool.getDefault();
Loader cl = new Loader(pool);
Class expressionEvaluatorClass = cl.loadClass("ExpressionEvaluator");
method = expressionEvaluatorClass.getMethod("f", Integer.TYPE);
} catch (SecurityException e) {
e.printStackTrace();System.exit(-1);
} catch (NoSuchMethodException e) {
e.printStackTrace();System.exit(-1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();System.exit(-1);
}
try {
return (Byte) method.invoke(null, i);
} catch (IllegalArgumentException e) {
e.printStackTrace();System.exit(-1);
} catch (IllegalAccessException e) {
e.printStackTrace();System.exit(-1);
} catch (InvocationTargetException e) {
e.printStackTrace();System.exit(-1);
}
return 0;
}
private static void generateMethod(String expression2) {
ClassPool pool = ClassPool.getDefault();
try {
CtClass pt = pool.get("ExpressionEvaluator");
String methodString = "public static byte f(int t) { return (byte)(" + expression2 + ");}";
System.out.println(methodString);
CtMethod m = CtNewMethod.make(methodString, pt);
pt.addMethod(m);
pt.writeFile();
} catch (NotFoundException e) {
e.printStackTrace();System.exit(-1);
} catch (CannotCompileException e) {
e.printStackTrace();System.exit(-1);
} catch (IOException e) {
e.printStackTrace();System.exit(-1);
}
}
// return (t*(t>>5|t>>8))>>(t>>16);
// return t*(((t>>12)|(t>>8))&(63&(t>>4)));
}
这里我们使用用户提供的表达式动态生成方法,并使用Javassist将其添加到ExpressionEvaluator类。
希望它有所帮助。
答案 1 :(得分:0)
这听起来像语言识别工作。你试过antlr吗?据我所知,它用于solr,hibernate等的复杂解析。