user-defined rules

N

neuneudr

Hi,

In a java client-side program, I need to allow the end-user to define
"rules". Similar to scoring rules (no unlike what some newsreader
have to rate posts).

For example the user can choose some "stat" (say 'A'), then some
operator (say '>='), then define a value (say '30') and then some
action happen (say give +1 to the score). And if A >= 30 then it
'scores' one point, etc.

The 'action' may be, for example, modify some scoring, coloring a row,
triggering a sms-alert, applying another rule, etc.

I don't even know what's the name of such a 'thing' (which hinders my
Google-Fu).

Note that I don't necessarily need a parser for I shall use the GUI to
confine the 'stat', 'operator', 'value' and 'action' parts in their
respective textfield/combobox, etc.

I have some idea as to how to this but I don't want or reinvent the
wheel and I don't want to violate Greenspun's Tenth rule of
programming:

" Any sufficiently complicated C or Fortran program contains
" an ad hoc, informally-specified, bug-ridden, slow
" implementation of half of Common Lisp.

I'm looking for help as to how I should design this. Maybe there's
some clean open-source *OO* project that does something similar?

The requirements are going to evolve over time (new actions, new
operators, etc.).

Any hints / help / pointers is most welcome,
 
A

Alessio Stalla

Hi,

In a java client-side program, I need to allow the end-user to define
"rules".  Similar to scoring rules (no unlike what some newsreader
have to rate posts).

For example the user can choose some "stat" (say 'A'), then some
operator (say '>='), then define a value (say '30') and then some
action happen (say give +1 to the score).  And if A >= 30 then it
'scores' one point, etc.

The 'action' may be, for example, modify some scoring, coloring a row,
triggering a sms-alert, applying another rule, etc.

I don't even know what's the name of such a 'thing' (which hinders my
Google-Fu).

Note that I don't necessarily need a parser for I shall use the GUI to
confine the 'stat', 'operator', 'value' and 'action' parts in their
respective textfield/combobox, etc.

I have some idea as to how to this but I don't want or reinvent the
wheel and I don't want to violate Greenspun's Tenth rule of
programming:

" Any sufficiently complicated C or Fortran program contains
" an ad hoc, informally-specified, bug-ridden, slow
" implementation of half of Common Lisp.

I'm looking for help as to how I should design this.  Maybe there's
some clean open-source *OO* project that does something similar?

The requirements are going to evolve over time (new actions, new
operators, etc.).

Any hints / help / pointers is most welcome,

I'd do this with an embedded language if no other constraints are
involved (i.e. if the GUI thing is not mandatory). With JSR-223
included in Java 6 there's a proliferation of scripting languages you
can use out there, and you get JavaScript built in the JRE (there's
even a Common Lisp implementation to make Greenspun happy :D). Just
pick one and write a little glue library in the embedded language so
that the rules and the actions can easily access the relevant parts of
your application.
If the GUI is mandatory, you could still use an embedded language and
compose code fragments from the GUI, however I think in this case
there are better solutions (e.g. to directly manipulate a sort of
abstract syntax tree representing the rules and the operations that
make up an action... this would make Greenspun happy too :D).

hth,
Alessio
 
M

markspace

Hi,

In a java client-side program, I need to allow the end-user to define
"rules". Similar to scoring rules (no unlike what some newsreader
have to rate posts).
I don't even know what's the name of such a 'thing' (which hinders my
Google-Fu).
The requirements are going to evolve over time (new actions, new
operators, etc.).


If the grammar and execution are going to stay simple, then a classic
Interpreter Pattern might be work considering:

<http://en.wikipedia.org/wiki/Interpreter_pattern>

The benefits of the Interpreter (from memory, from GOF) are that it is
simpler to modify later. And it's self-contained, which can also be
easier on the maintenance programmer.

Its disadvantages are that it's slower than things like state machines
for execution, and for more complex grammars the Interpreter is more
hassle than a compiler compiler.

For contrast see compiler compiler:

<http://en.wikipedia.org/wiki/Compiler-compiler>
<http://java-source.net/open-source/parser-generators>

And state machine:

<http://en.wikipedia.org/wiki/Finite-state_machine>
<http://www.complang.org/ragel/>

(Regex often use a state machine when compiled, you might want to look
into that aspect too.)
 
R

Roedy Green

Note that I don't necessarily need a parser for I shall use the GUI to
confine the 'stat', 'operator', 'value' and 'action' parts in their
respective textfield/combobox, etc.

One way you can organise this is with objects that implement an
interface. Your gui creates a string of such token objects. You then
can do your computation with generic code that invokes some of the
interface methods.

You can add new operators etc by adding new classes and factories for
them.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"I mean, source code in files; how quaint, how seventies!"
~ Kent Beck (born: 1961 age: 48), evangelist for extreme programming.
 
R

Roedy Green

In a java client-side program, I need to allow the end-user to define
"rules". Similar to scoring rules (no unlike what some newsreader
have to rate posts).

One technique I have used with great success a number of times is to
use a simple parser to translate the expression language into some
base language, in this case Java. Then you compile on the fly. This
is the approach JSP uses.


see http://mindprod.com/jgloss/onthefly.html
http://mindprod.com/jgloss/delelegate.html
http://mindprod.com/jgloss/jsp.html

The big advantage of this approach is you can augment your expression
language with embedded Java to do fancy stuff. You rarely find
anything you can't do.

The other advantage is the code runs very fast compared with other
approaches.

--
Roedy Green Canadian Mind Products
http://mindprod.com

"I mean, source code in files; how quaint, how seventies!"
~ Kent Beck (born: 1961 age: 48), evangelist for extreme programming.
 
A

Alessio Stalla

One technique I have used with great success a number of times is to
use a simple parser to translate the expression language into some
base language, in this case Java.  Then you compile on the fly. This
is the approach JSP uses.

seehttp://mindprod.com/jgloss/onthefly.htmlhttp://mindprod.com/jgloss/delelegate.htmlhttp://mindprod.com/jgloss/jsp.html

The big advantage of this approach is you can augment your expression
language with embedded Java to do fancy stuff.  You rarely find
anything you can't do.

The other advantage is the code runs very fast compared with other
approaches.

Or you can use a JSR-223 implementation that supports compilation to
jvm bytecode. You'd probably lose the ability to embed Java (at least,
I'm not aware of any compiler allowing this), but you can always
isolate the fancy stuff in a static Java method and call it from the
"scripting" language; you'd still get reasonable speed if you need it.
That way, you don't have to reimplement a parser and a translator
yourself.

Cheers,
Alessio
 
N

neuneudr

I'd do this with an embedded language if no other constraints are
involved (i.e. if the GUI thing is not mandatory). With JSR-223
included in Java 6...

Ouch!

I'm pretty much stuck with Java 5 for quite some users are
running the application on pre-Core 2 Duo Macs that do not
have Java 6 :-(
If the GUI is mandatory, you could still use an embedded language and
compose code fragments from the GUI, however I think in this case
there are better solutions (e.g. to directly manipulate a sort of
abstract syntax tree representing the rules and the operations that
make up an action... this would make Greenspun happy too :D).

But, yup, I think I can do away with the parser
and directly manipulate/create the AST.
 
N

neuneudr

If the grammar and execution are going to stay simple, then a classic
Interpreter Pattern might be work considering:

<http://en.wikipedia.org/wiki/Interpreter_pattern>

The benefits of the Interpreter (from memory, from GOF) are that it is
simpler to modify later. And it's self-contained, which can also be
easier on the maintenance programmer.

Great pointer, I'll be analysing this.

Its disadvantages are that it's slower than things like state machines
for execution, and for more complex grammars the Interpreter is more
hassle than a compiler compiler.

Speed in this case should not be a problem as it s for relatively
simple things: only a few rules at most, not a complex language
nor long programs in that 'language'.

So a clean and maintainable, self-contained and 'evolvable' option
like you suggested seems great.

And state machine:

<http://en.wikipedia.org/wiki/Finite-state_machine>
<http://www.complang.org/ragel/>

(Regex often use a state machine when compiled, you might want to look>
into that aspect too.)

Changing the subject a little bit: when regexp use FSMs, isn't
it to simplify (and speed up) the parsing part? (in my case parsing
isn't
an issue).

I mean, if you have a regexp like :

replaceAll("([^.]++)(\\.[^.]*$)", "$1 \\$0 : '$0' \\$1 : '$1'")

isn't the FSM meant to find what $1 and $0 are (ie the 'parsing')?

After that it's just substituting the values!?

I'm asking because I'm my case the parsing shall be easy
due to the fact that my 'language constructs' are inside
well-defined GUI fields, so I don't really need a complex
parser.

Thanks a lot for your answer, going to read on that
interpreter pattern,
 
N

neuneudr

On Sep 9, 8:22 am, Roedy Green <[email protected]>
wrote:
....
One technique I have used with great success a number of times is to
use a simple parser to translate the expression language into some
base language, in this case Java. Then you compile on the fly. This
is the approach JSP uses.

seehttp://mindprod.com/jgloss/onthefly.htmlhttp://mindprod.com/jgloss/delelegate.htmlhttp://mindprod.com/jgloss/jsp.html

The big advantage of this approach is you can augment your expression
language with embedded Java to do fancy stuff. You rarely find
anything you can't do.

That's interesting, I didn't think of it and I can see how powerful
it would be.

But the problem is, I'd then need a compiler/JDK to be installed
right!?

This is for a client-side app deployed on systems that very often just
have a JRE...

Too bad I have to support systems where Java 6 is unavailable
otherwise
the JSR-223 approach suggested by Alessio looks great too.

Thanks all for the informative answers,
 
A

Alessio Stalla

If the grammar and execution are going to stay simple, then a classic
Interpreter Pattern might be work considering:

The benefits of the Interpreter (from memory, from GOF) are that it is
simpler to modify later.  And it's self-contained, which can also be
easier on the maintenance programmer.

Great pointer, I'll be analysing this.
Its disadvantages are that it's slower than things like state machines
for execution, and for more complex grammars the Interpreter is more
hassle than a compiler compiler.

Speed in this case should not be a problem as it s for relatively
simple things: only a few rules at most, not a complex language
nor long programs in that 'language'.

So a clean and maintainable, self-contained and 'evolvable' option
like you suggested seems great.
And state machine:

(Regex often use a state machine when compiled, you might want to look>
into that aspect too.)

Changing the subject a little bit: when regexp use FSMs, isn't
it to simplify (and speed up) the parsing part?  (in my case parsing
isn't
an issue).

I mean, if you have a regexp like :

replaceAll("([^.]++)(\\.[^.]*$)", "$1 \\$0 : '$0'  \\$1 : '$1'")

isn't the FSM meant to find what $1 and $0 are (ie the 'parsing')?

No, an FSM, deterministic or non-deterministic (also called DFA and
NFA, respectively), is a popular implementation technique for regular
expression engines. Basically they parse the regex and convert it to a
(D|N)FA, then simulate the automaton on the given input to find
matches.
 
R

Roedy Green

the JSR-223 approach suggested by Alessio looks great too.

There is a guy in the Netherlands named Jeroen Frijters who did some
work on generating byte code on the fly back in the 90s. I met him at
the Colorado Software conference. I thought this was the coolest
thing. I think the links to his stuff are still working. See

http://mindprod.com/jgloss/jasm.html
http://mindprod.com/jgloss/onthefly.html
--
Roedy Green Canadian Mind Products
http://mindprod.com

"The coolest thing to do with your data will be thought of by someone else."
~ Rufus Pollock (born: 1978 age: 31) in Talk.
 
R

Roedy Green

One technique I have used with great success a number of times is to
use a simple parser to translate the expression language into some
base language, in this case Java. Then you compile on the fly. This
is the approach JSP uses.

You might do your parser with a simple finite state automaton. But if
you need something fancier, you can use a parser generator, such as
JavaCC. See http://mindprod.com/jgloss/parser.html
http://mindprod.com/jgloss/javacc.html

--
Roedy Green Canadian Mind Products
http://mindprod.com

"The coolest thing to do with your data will be thought of by someone else."
~ Rufus Pollock (born: 1978 age: 31) in Talk.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top