0

So I've spent most of the day Googling and StackExchanging for answers or guidance and I've given up. I have to ask the following:

I want to make a Java application that asks for the user to enter an expression similar to this:

t>>7|t|t>>6

Let's assume that this is then stored as a String. What I want is to convert this String into an expression where t becomes a variable and >> and | become operators. Basically I would like to figure out how implement this http://www.redcode.nl/blog/2011/12/bytebeat-algorithmic-symphonies/ but somehow pass user input to private static int f(int t) instead of hard coding the expression.

I've been reading a bit about ScriptEngineManager and using JavaScript but I don't know if that's the way to go.

Anyway, this is just for personal education and entertainment. Thanks in advance.

5
  • How complex can the expression get? The link's code is pretty simple - a single variable (incremented in a loop), OR'd together with some right bit shifts. Commented May 17, 2012 at 4:48
  • Ideally the expression can be as long as the user would like it to be, but complexity-wise there is only one variable t, any number of integers, and all operators including bit-wise. Commented May 17, 2012 at 4:51
  • You could use JavaScript to evaluate the expression, having supplied the execution environment with a the current binding for t - yes, that should work. (I'm not familiar with what it's like to deal with bit shifting in JS though) Commented May 17, 2012 at 4:53
  • you should look at some math expression parsers. It's basically the same thing, and there's tons of them. It's also a university type assignment for students, so simple ones are out there. Commented May 17, 2012 at 4:54
  • @Roberto: A quick read of this suggests that JavaScript doesn't have an integer data type, so perhaps bit shifting is out of the question (numeric appears to be floating point). Commented May 17, 2012 at 5:02

2 Answers 2

1

You can do this using javassist library. Download ithe library from http://sourceforge.net/projects/jboss/files/Javassist/3.16.1-GA/ and add it your project.

//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)));
}

Here we are dynamically generating a method using user provided expression and adding it to ExpressionEvaluator class using Javassist.

Hope it helps.

Sign up to request clarification or add additional context in comments.

1 Comment

(Is it too late to reply?) That's great. I'll look into that, and I guess I should study Reflection while I'm at it.
0

It sounds like language recognition job. Have you tried antlr. As far as I know it's used for complex parsing in solr, hibernate, etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.