Reputation: 170
I'm currently working on a small project in java where I need to process a very lightweight scripting language for a robot that I've made up.
It doesn't need to deal with arithmetic or any complicated functionality, it only needs to run certain commands and deal with if and while statements.
It could look something like this:
turn(90,cw)
move(25)
sleep(5000)
get(temp)
turn(90,ccw)
get(image)
This is something that I've had no problem with and was able to get it working very quickly. However once I started considering if and while statements, I realised that things might be a lot more complex.
For instance, It would be quite simple to manage something like this:
while(temp > 50)
move(25)
turn(90,cw)
But I'm getting very confused as to how I can start to process statements like this:
while(temp > 50)
if(light < 100)
move(25)
turn(90,cw)
move(10)
Looking at it, I can see things getting very confusing very quickly!
Is there a preferred method for processing "lightweight scripts" like these? Or would I be better off just sticking with it and working out some kind of manual parser?
Thanks for any help you can give me!
EDIT - Thanks for the help everyone, I got it working really quickly using the Java Scripting Engine!
Upvotes: 4
Views: 4568
Reputation: 1460
I have used Jython (Python ported on JVM) for a similar task. The key benefits include strong interoperability between the "host" (Java environment) and the Jython interpreter (invoked from Java). You can access your JVM universe from the script: classes, methods, fields, defined in the Java env. are all available to manipulate from your scripts.
Upvotes: 0
Reputation: 122374
Groovy has good support for writing domain-specific languages like this, if you're prepared to use Java-like braces for nesting rather than Python-like indentation levels.
while(temp > 50) {
if(light < 100) {
move(25)
}
turn(90,cw)
move(10)
}
This could be implemented something like
GroovyShell gs = new GroovyShell()
Script script = gs.parse(stringContainingTheScript)
Binding b = script.binding
// utility values
b.cw = true
b.ccw = false
b.light = theRobot.getLight()
b.temp = theRobot.getTemperature()
def mc = script.metaClass
mc.move = { distance ->
theRobot.move(distance)
// update from sensors
b.light = theRobot.getLight()
b.temp = theRobot.getTemperature()
}
mc.turn = { angle, direction ->
if(direction) theRobot.turnClockwise(angle)
else theRobot.turnCounterclockwise(angle)
}
mc.sleep = { time ->
sleep(time) // Groovy builtin
// update from sensors
b.light = theRobot.getLight()
b.temp = theRobot.getTemperature()
}
script.run()
Upvotes: 0
Reputation: 1239
I would consider using BeanShell and not parsing at all. You just need to write your statements as beanshell commands.
Upvotes: 2
Reputation: 340763
Writing custom language is hard, seriously.
Since 6.0 Java has a built-in JavaScript engine. Use it instead, and your users will be very happy that you use syntax they are familiar with. Other alternatives are Groovy, JRuby, or even Lua.
Upvotes: 2