At work we use a Business Rules language that was original designed for 'business' people to program but now has fallen on use, the programmers. The IDE/Eclipse plugin isn't what a we would call an 'IDE', but now that a Eclipse plugin has been added in the latest release of the standalone IDE we want to create a Eclipse Editor plugin with syntax coloring, checking etc.
I've been looking at Xtext tutorials but just can't seem to get a grasp on the concept of the grammarlanguage and was hopping if I provided some examples of the Business language someone could provide a grammarexample and some explanation and to what it was doing.
Examples:
varString is a string initially "Dog"; //String - 'a' can be interchanged with 'an'
varInteger is a integer initially 0; //Integer - 'a' can be interchanged with 'an'
varObject is some MyObject initially MyObject.newInstance( "Foo" ); //Object Creation
while ( varInteger < varObject.size() ) do {
varTemp = methodCall( parm1,
parm2,
parm3, );
varTemp1 = methodCallWithCast( parm1,
parm2,
parm3, ) as a MyObject; //'a' can be interchanged with 'an'
}
if ( varObject.size() > 0 ) then {
}
if ( varObject is not null and
varObject.size() < 0 ) then {
}
Note that the styling (spaces after/before the brackets, parameters on seperate lines) I'm hopping to be able to checking as this is the coding standard the we adhear to, and to throw an error if it is not followed
Thanks!
You need to learn about BNF (see http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) so you can understand how grammar rules are written, and then you need to either find the reference document for your business rules languages, or write your own grammar rules.
With that, you can then consider how XText might be configured to help you.
I suspect that given where you are in your understanding of language processing tools, integrating your business rules language into XText may be more than you are ready to do.
Related
How can I change the to_tsvector configuration to use a simple tokenization rule like:
lowercase
split by spaces only
Executing the following query:
SELECT to_tsvector('english', 'birthday=19770531 Name=John-Oliver Age=44 Code=AAA-345')
I get these lexemes:
'-345':9 '19770531':2 '44':6 'aaa':8 'age':5 'birthday':1 'code':7 'john':4 'name':3
The kind of searching I'm looking for is like:
(!birthday | birthday=19770531) & (code=AAA-345)
It means, get me all records that has a text "birthday=19770531" or doesn't have "birthday" at all, and a text equals to "code=AAA-345"). The way lexemes are being created it is not possible. I was expecting to have something like this:
'birthday=19770531':1 'age=44':2 'code=aaa-345':4 'name=john-oliver':3
You would have to code a custom parser. This can only be done in C.
But you might be able to use the existing testing parser test_parser, it seems to do what you want. If not, it would at least be a good starting point.
The problem may be that this is in src/test/modules/, and I don't think it ships with most installation packaging. So it might take some effort to get it to install. It would depend on your OS, version, and package manager.
So I wanted to try my hand out creating a decision table from a rule that I've already made in a .drl file. Then I wanted to convert it back to a .drl. Didn't see any nifty conversions from drl to xls/csv nor was the jboss documentation comprehensive enough. It could be the rule is too complicated for a simple decision table but I was hoping this community could help me out.
Here is the drl:
rule "Patient: Compute BMI"
when
$basic : BasicInfoModel(
notPresent('bmi'),
isPresent('height'),
isPresent('weight'),
$height : value('height', 0.0),
$weight : value('weight', 0.0))
then
modify($basic){
put('bmi', $weight / Math.pow($height,2))
};
end
So this rule basically looks at an objects weight and height field and then computes the bmi. I've tried basically taking what I have and putting it into the decision table format but with little success. Nothing really parses (I'm just using the droolsSpreadSheet.compile and printing out what I get, which is a whole of empty rules). Any help would be appreciated!
Update:
This is what my excel sheet looks like
This is what my rule parses out to:
package DROOLS;
//generated from Decision Table
import basic.BasicInfoModel;
// rule values at A11, header at A6
rule "Computing BMI"
when
$patient:BasicInfoModel(notPresent('bmi'), isPresent('height'),isPresent('weight'), $height:value('height', 0.0), $weight:value('weight',0.0) == "20,4")
then
end
Update #2: I think I figured out my parse issues. Here is my new and improved spreadsheet., Basically found out that I cannot have the Computing BMI: data blank, there must be something in there in order to have the rule parse (Which isn't entirely clear in the docs I read, though that could be because my experience with decision tables is novice putting it lightly).
So now the compile looks more like what I want:
// rule values at A11, header at A6
rule "Computing BMI"
when
$patient:BasicInfoModel(notPresent('bmi'), isPresent('height'), isPresent('weight') == "TRUE")
$weight:value('weight',0.0), $height:value('height', 0.0)
then
modify($patient){put('bmi', $weight / Math.pow($height,2))};
end
Can someone confirm that I have to have real, specific data in the rules in order for them to parse? Can I just use injection elsewhere? Perhaps I should ask a new question on this.
So the answer is yes, you do need parameters, but what I didn't know was that the data doesn't have to be hardcoded like every example I've come across. Thanks to stumbling onto this answer. So now the table looks like this. I hope this helps others who've come across this issue. Also my recommendation is to just make your drools in a .drl rather than go through the spreadsheet, unless you have a bunch of rules that are pretty much copy and paste replicas. That's my two cents anyways.
I come from PHP/JS/AS3/... this kind languages. Now I'm learning basic for Libreoffice and I'm kind of struggling to find how to get something similar as associative array I use to use with others languages.
What I'm trying to do is to have this kind structure:
2016 => October => afilename.csv
2016 => April => anotherfilename.csv
with the year as main key, then the month and some datas.
More I try to find informations and more I confuse, so if someone could tell me a little bit about how to organise my datas I would be so pleased.
Thanks!
As #Chrono Kitsune said, Python and Java have such features but Basic does not. Here is a Python-UNO example for LibreOffice Writer:
def dict_example():
files_by_year = {
2016 : {'October' : 'afilename.csv',
'November' : 'bfilename.csv'},
2017 : {'April' : 'anotherfilename.csv'},
}
doc = XSCRIPTCONTEXT.getDocument()
oVC = doc.getCurrentController().getViewCursor()
for year in files_by_year:
for month in files_by_year[year]:
filename = files_by_year[year][month]
oVC.getText().insertString(
oVC, "%s %d: %s\n" % (month, year, filename), False)
g_exportedScripts = dict_example,
Create a file with the code above using a text editor such as Notepad or GEdit. Then place it here.
To run it, open Writer and go to Tools -> Macros -> Run Macro, and find the file under My Macros.
I'm not familiar with LibreOffice (or OpenOffice.org) BASIC or VBA, but I haven't found anything in the documentation for any sort of associative array, hash, or whatever else someone calls it.
However, many modern BASIC dialects allow you to define your own type as a series of fields. Then it's just a matter of using something like
Dim SomeArray({count|range}) As New MyType
I think that's as close as you'll get without leveraging outside libraries. Maybe the Python-UNO bridge would help since Python has such a feature (dictionaries), but I wouldn't know for certain. I also don't know how it would impact performance. You might prefer Java instead of Python for interfacing with UNO, and that's okay too: there's the java.util.HashMap type. Sorry I can't help more, but the important thing to remember is that any BASIC code in tends to live up to the meaning of the word "basic" in English without external assistance.
This question was asked a long ago, but answers are only half correct.
It is true that LibreOffice Basic does not have a native associative array type. But the LibreOffice API provides services. The com.sun.star.container.EnumerableMap service will meet your needs.
Here's an example:
' Create the map
map = com.sun.star.container.EnumerableMap.create("long", "any")
' The values
values = Array( _
Array(2016, "October", "afilename.csv"), _
Array(2016, "April", "anotherfilename.csv") _
)
' Fill the map
For i=LBound(values) to UBound(values)
value = values(i)
theYear = value(0)
theMonth = value(1)
theFile = value(2)
If map.containsKey(theYear) Then
map2 = map.get(theYear)
Else
map2 = com.sun.star.container.EnumerableMap.create("string","string")
map.put(theYear, map2)
End If
map2.put(theMonth, theFile)
Next
' Access to an element
map.get(2016).get("April") ' anotherfilename.csv
As you see, the methods are similar to what you can find in more usual languages.
Beware: if you experience IllegalTypeException you might have to use CreateUNOValue("<type>", ...) to cast a value into the declared type. (See this very old issue https://bz.apache.org/ooo/show_bug.cgi?id=121192 for an example.)
Is it possible to reuse a when/condition statement into another when/condition statement in a DSL file?
For example, I have two conditions:
[condition][]The client is invalid = Client( name == null || email == null )
[condition][]All the clients are invalid = forall( Client( name == null || email == null ) )
Note that the second condition just diff the first for the forall command, but the statement inside is equals. In these case, I want to reuse the first condition into the second.
Is it possible? How?
Thank you.
even the most recent version of drools will only let you substitute values into a template from pojo's or a corresponding map as per their documentation here.
This won't work for your use case though.
Since drool files are simply text files, there is nothing preventing you from considering a more powerful templating toolkit.
Possibilities include Apache Velocity, ANTLR or Scala!
Suppose you're concerned with clarity of your code and would like to make sure users of your api are crystal clear as to how objects are created. You make them do things like
new MomentInTime(new DayOfMonth(15), new HourOfDay(10), new MinuteOfHour(49), new SecondOfMinute(0));
Where each class DayOfMonth, HourOfDay is pretty much identical to one another, a value store of some kind.
Now, when the time comes for you to use the value, using Java's Calendar, should value be illegal, we will get some kind of RunTimeException. Great.
Now .. Is it possible for us to set up Min, Max boundaries in our IDE (Eclipse or Intellij) that would warn us that value we're about to send to a method will result in an error?
Is there a plug-in and an annotation that would work together that would allow for such a warning?
Something along the lines of #Boundaries {low=1, high=31} along with IDE actually recognizing it would be great.
Please let me know if something like this exists.
Have a look at Contracts for Java. It does have a rudimentary integration into Eclipse.
interface Time {
...
#Ensures({
"result >= 0",
"result <= 23"
})
int getHour();
#Requires({
"h >= 0",
"h <= 23"
})
#Ensures("getHour() == h")
void setHour(int h);
...
}