0

所以我大部分时间都在谷歌搜索和 StackExchange 寻求答案或指导,我已经放弃了。我必须问以下问题:

我想制作一个要求用户输入类似于此的表达式的 Java 应用程序:

t>>7|t|t>>6

让我们假设它被存储为一个字符串。我想要的是将此字符串转换为一个表达式,该表达式t成为一个变量>>|成为运算符。基本上我想弄清楚如何实现这个http://www.redcode.nl/blog/2011/12/bytebeat-algorithmic-symphony/但不知何故将用户输入传递给private static int f(int t)而不是硬编码表达式。

我一直在阅读一些有关 ScriptEngineManager 和使用 JavaScript 的内容,但我不知道这是否是正确的方法。

无论如何,这只是为了个人教育和娱乐。提前致谢。

4

2 回答 2

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 类中。

希望能帮助到你。

于 2012-05-17T06:39:54.800 回答
0

这听起来像是语言识别工作。你试过antlr吗?据我所知,它用于 solr、hibernate 等中的复杂解析。

于 2012-05-17T04:46:56.180 回答