This project demonstrates transformation of a DSL into LUA code.
The DSL is defined using a grammar (*.g4) file. The parser for this grammar is generated automatically by ANTLR from the .g4 grammar, at compile time. At run time, we transform a script the follows the DSL's specification, into executable LUA code, with the help of FreeMarker templates.
The DSL
Valid scripts include a collection of rules that have the form if <predicate> then <action>
.
Preciates are comparisons such as height < 30
, weight >= 40
or age >= 6
,
and actions are only accept
and reject
.
See 1.rules for an example of a valid script:
if age < 50 then accept
if height >= 180 then reject
if weight == 40 then accept
The formal grammar for our DSL is in the file IfThen.g4:
grammar IfThen;
prog : conditional * ;
conditional : 'if' predicate 'then' action ;
predicate : measurement comp value ;
measurement: 'age' | 'height' | 'weight' ;
comp : '<' | '>' | '<=' | '>=' | '==' | '~=' ;
value : NON_NEGATIVE_NUMBER ;
action : 'accept' | 'reject' ;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
NON_NEGATIVE_NUMBER : [0-9]+ ;
The use of LUA for executing the rules
The LUA code runs through the generated rules, and stops when one rule returns
an accept
or reject
decision. As output, we get not only the decision, but also information the
reasoning behind the decision, i.e. which rule was fired to trigger that decision.
How to build the project and generate the DSL parser
Assuming you have Maven installed, run
mvn clean package
From the project folder. This includes invoking the antlr4
goal, which generate the code for parsing the DSL,
under the folder target/generated-sources/
, provided by Antlr4 Maven plugin.
Notice the <visitor>
and <listener>
options in pom.xml, which cause the generation of Visitor
base classes, as opposed to the Listener pattern.
The antlr4
goal can also be invoked separately, by running
mvn antlr4:antlr4
in the project folder, or by invoking the goal antlr4:antlr4
under Plugins -> antlr4
in the Maven Projects
window in IntelliJ.
How to run the LUA code generator
Assuming you have Maven installed, run the class App by typing
mvn exec:java -Dexec.mainClass="com.github.adilevin.App"
in the project folder.
This will read the DSL script in the resource file /dsl-scripts/1.rules
if age < 50 then accept
if height >= 180 then reject
if weight == 40 then accept
and will turn it into LUA code, generating the file rules.lua:
-- This code was auto-generated using ANTLR4
return {
{ ["pred"] = function(person)
return (person.age < 50)
end,
["action"] = "accept",
["text"] = "if age < 50 then accept" },
{ ["pred"] = function(person)
return (person.height >= 180)
end,
["action"] = "reject",
["text"] = "if height >= 180 then reject" },
{ ["pred"] = function(person)
return (person.weight == 40)
end,
["action"] = "accept",
["text"] = "if weight == 40 then accept" },
}
How to execute the LUA code
As a prerequisite, install LUA. Windows users - install from here. After generating the LUA code, run the following command in the project folder:
lua main.lua