将字符串从用户输入转换为表达式

时间:2012-05-17 04:41:51

标签: java

所以我花了一天的大部分时间用谷歌搜索和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的内容,但我不知道这是否可行。

无论如何,这仅适用于个人教育和娱乐。提前谢谢。

2 个答案:

答案 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等的复杂解析。