Custom interpreter in java - java

Hi
I want to write a program to be able to parse & execute some files
The file consists of some custom commands (I want to be able to define commands and appropriate methods so when program see that command it should execute the appropriate method)
It's grammar is not important for me; I just want to be able to define commands
Something like a simple and small interpreter written in java.
Is there any library for this purpose?
Or I need to write by myself?
Thanks

Java 6 (and newer) have this in the standard library: have a look at the API documentation of the package javax.script. You can use this to run scripts from your Java program (for example to automate your program) using any scripting language for which there is a plug-in engine available for the javax.script API. By default, support for JavaScript is supplied.
See the Java Scripting Programmer's Guide.
Simple example from that guide:
import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
// evaluate JavaScript code from String
engine.eval("print('Hello, World')");
}
}

Have you considered looking at BeanShell?
Provides for having Java-like snippets interpreted at runtime.
If you need a bit more than that, then consider embedding e.g. JPython or another small interpreter. Just choose one that is JSR-233 compliant to get generic debugging support.

What you need is called "scripting engine". Quick search reveals Rhino. This is a good option cause it's JavaScript, and many people know JavaScript and there exists a certain amount of third-party extensions (libraries and code snippets) for it.

You could use ANTLR, but you will have to define a grammar (the parser will be generated for you).
Check this expression elevator example, it is similar to your problem, but instead of reading files it reads from the standard input.
If you choose ANTLR, take I look at ANTLRWorks, it is a GUI that will help with ANTLR development (I think it is also available as an Eclipse plugin).

I know this an old thread, but some time ago I've implemented a small interpreter for language similar with JavaScript (with more restrictions), the code is published in Github at https://github.com/guilhermelabigalini/interpreter
But it does support IF/CASE/LOOPS/FUNCTIONs, see below:
function factorial(n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}
var x = factorial(6);

Related

Translating logic into Kotlin (or Java) code

I have a use-case where I want to enable users to write simple logic, and behind the scenes, convert this logic into a condition in the code.
For example, the user might write:
someFieldName > 10 AND otherFieldName is NULL
And I'd like that to generate the following code:
if (data["someFieldName"] > 10 && data["otherFieldName"] == null) {
// Do something
}
After doing some research, I saw that one of the options is using eval (by leveraging a JS engine), although it doesn't fit all use cases.
I also saw that it's possible to use tools like ANTLR, which seems a bit like overkill.
Are there any simple off-the-shelf products we can use for such purposes? Or would creating a simple parser ourselves be the best way to handle it?
Your use case can be adequately addressed by MVEL2.
There is no need for you to write a parser and AST with ANTLR or convert to Java code, just evaluate the expression with appropriate parameters.
In fact any Java expression language library would do. You could also look at JUEL.
However, looking at the expression, I would say it aligns more towards MVEL2.
Give both the libraries a try.

Sandboxed java scripting replacement for Nashorn

I've been using Nashorn for awk-like bulk data processing. The idea is, that there's a lot of incoming data, coming row by row, one by another. And each row consists of named fields. These data are processed by user-defined scripts stored somewhere externally and editable by users. Scripts are simple, like if( c>10) a=b+3, where a, b and c are fields in the incoming data rows. The amount of data is really huge. Code is like that (an example to show the use case):
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
new String[]{"-strict", "--no-java", "--no-syntax-extensions", "--optimistic-types=true"},
null,
scr -> false);
CompiledScript cs;
Invocable inv=(Invocable) engine;
Bindings bd=engine.getBindings(ScriptContext.ENGINE_SCOPE);
bd.remove("load");
bd.remove("loadWithNewGlobal");
bd.remove("exit");
bd.remove("eval");
bd.remove("quit");
String scriptText=readScriptText();
cs = ((Compilable) engine).compile("function foo() {\n"+scriptText+"\n}");
cs.eval();
Map params=readIncomingData();
while(params!=null)
{
Map<String, Object> res = (Map) inv.invokeFunction("foo", params);
writeProcessedData(res);
params=readIncomingData();
}
Now nashorn is obsolete and I'm looking for alternatives. Was googling for a few days but didn't found exact match for my needs. The requirements are:
Speed. There's a lot of data so it shall be really fast. So I assume as well, precompilation is the must
Shall work under linux/openJDK
Support sandboxing at least for data access/code execution
Nice to have:
Simple, c-like syntax (not lua;)
Support sandboxing for CPU usage
So far I found that Rhino is still alive (last release dated 13 Jan 2020) but I'm not sure is it still supported and how fast it is - as I remember, one of reasons Java switched to Nashorn was speed. And speed is very important in my case. Also found J2V8 but linux is not supported. GraalVM looks like a bit overkill, also didn't get how to use it for such a task yet - maybe need to explore further if it is suitable for that, but looks like it is complete jvm replacement and cannot be used as a library.
It's not necessary shall be javascript, maybe there are other alternatives.
Thank you.
GraalVM's JavaScript can be used as a library with the dependencies obtained as any Maven artifact. While the recommended way to run it is to use the GraalVM distribution, there are some explanations how to run it on OpenJDK.
You can restrict things script should have access to, like Java classes, creating threads, etc:
From the documentation:
The following access parameters may be configured:
* Allow access to other languages using allowPolyglotAccess.
* Allow and customize access to host objects using allowHostAccess.
* Allow and customize host lookup to host types using allowHostLookup.
* Allow host class loading using allowHostClassLoading.
* Allow the creation of threads using allowCreateThread.
* Allow access to native APIs using allowNativeAccess.
* Allow access to IO using allowIO and proxy file accesses using fileSystem.
And it is several times faster than Nashorn. Some measurements can be found for example in this article:
GraalVM CE provides performance comparable or superior to Nashorn with
the composite score being 4 times higher. GraalVM EE is even faster.

Use a SPIN function defined in TopBraid in my Java project

I'm writing my first Java project for Semantic Web using Jena framework.
My ontology was peopled and now I'd like to use some SPIN function (they weren't written by me) in my project.
They are very simple: they receive 2 string arguments and return 1 string.
I never do this kind of project so I don't know from where I can begin.
Can you help me?
The question lacks far too many details, but a wild guess may be that you want to use this in the form:
SELECT *
WHERE {
...
BIND(spin-function(?param1, ?param2) AS ?result)
...
}
That assumes that the Jena framework you are using has SPIN installed.

Real Life Scenarios to use ScriptEngineManager in Java

I am aware we can use ScriptEngineManager to execute scripts for example: java script.
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Test {
public static void main(String[] args) throws Exception{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
But this is a very trivial example and I am not sure in what real scenarios ScriptEngineManager can be used? Please elaborate.
Let me try to answer this from my project standpoint.
We have a framework that will make outbound calls and allow the integrators to extract the portions from json response and map it into internal data model.
This is completely driven by metadata, integrator uses the jsonpath (similar to xpath but for json ) to specify what to extract and what to map it to.
But there are times, where the integrator want to specify some of these conditionally.
For example, if the json value extracted is null, I want model to have 0.
If the array length is 0, then i want to use certain value.
We have exposed these logic as javascript. We execute the javascript using this engine to find out what the inetgrator wanted to do with the data ( basically we execute the script provided by integrator on the data obtained and set that value on the model, which eventually gets persisted )
Hope this answers your question.
There are many possible uses. For example: automation. The Microsoft Office programs and also Adobe Photoshop can run scripts to automatically execute functions of the program. You could use the Java script engine API for something similar in a Java application.
I used it once in a project where our software had to do some complex data processing. Certain parts of the processing could be customized by running a script. The advantage of this was that the script could be modified easily; if we would have written the custom processing in Java that would mean that every time when some small change was necessary, we would have to make a whole new build of the system.
Going by the differences, Java is statically typed, implying, the program written in Java, is first compiled and then run but in case of dynamically typed languages, like JavaScript and Python, we can execute even a part of the program for it is not compiled as a whole as such.
Coming to the question, suppose you have a server(eg: WildFly) on which you have deployed your application. Now building and hosting is a time intensive process, thus if you have to make any small change, you'll have to rebuild it and then again go through that time consuming process but if you could have used any dynamically typed language like JavaScript in place of it, it would have taken no time and in the next implementation, you would have been ready with the updated code. That's the main advantage of using JS and thus ScriptEngine was added in JSR.
Currently I'm working with JBoss to add ScriptEngine functionality to their WildFly server so have been spending time with it in the real time.

How to script input for a Java program

I'm writing a Java program that requires its (technical) users to write scripts that it uses as input; it interprets these scripts into a series of actions and executes them. I am currently looking for the cleanest way to implement the script/configuration language. I was originally thinking of heading down the XML route, but the nature of the required input really is a procedural, linear flow of actions that need to be executed:
function move(Block b, Position p) {
// user-defined algorithm for moving block "b" to position "p"
}
Block a = getBlockA();
Position p = getPositionP();
move(a, p);
Etc. Please note: the above is an example only and does not constitute the exact syntax I am looking to achieve. I am still in the "30,000 ft view"-design phase, and don't know what my concreted scripting language will ultimately look like. I only provide this example to show that it is a flow/procedural script that the users must write, and that XML is probably not the best candidate for its implementation.
XML, perfect for hierarchial data, just doesn't feel like the best choice for such an implementation (although I could force it to work if need-be).
Not knowing a lick about DSLs, I've begun to read up on Groovy DSLs and they feel like a perfect match for what I need.
My uderstanding is that I could write, say, a Groovy (I'm stronger in Groovy than Scala, JRuby, etc.) DSL that would allow users to write scripts (.groovy files) that my program could then execute as input at runtime.
Is this correct, or am I misunderstanding the intent of DSLs altogether? If I am mistaken, does anybody have any suggestions for me? And if I am correct then how would a Java program read and execute a .groovy file (in other words, how would my program "consume" their script)?
Edit: I'm beginning to like ANTLR. Although I would love to roll up my sleeves and write a Groovy DSL, I don't want my users to be able to write any old Groovy program they want. I want my own "micro-language" and if users step outside of it I want the interpreter to invalidate the script. It's beginning to seem like Groovy/DSLs aren't the right choice, and maybe ANTLR could be the solution I need...?
I think you are on a really good path. Your users can write their files using your simple DSL and them you can run them by Evaling them at runtime. Your biggest challenge will be helping them to use the API of your DSL correctly. Unless they use an IDE this will be pretty tough.
Equivalent of eval() in Groovy
Yes, you can write a Groovy program that will accept a script as input and execute it. I recently wrote a BASIC DSL/interpreter in this way using groovy :
http://cartesianproduct.wordpress.com/binsic-is-not-sinclair-instruction-code/
(In the end it was more interpreter than DSL but that was to do with a peculiarity of Groovy that likely won't affect you - BASIC insists on UPPER CASE keywords which Groovy finds hard to parse - hence they have to be converted to lower case).
Groovy allows you to extend the script environment in various ways (eg injecting variables into the binding and transferring execution from the current script to a different, dynamically loaded script) which make this relatively simple.

Categories

Resources