A Java interface is now available for using CodeWorker in Java applications. This enables calling parse and
generation tasks directly from Java. Hence, the Java application can handle the parse tree, iterating node arrays,
accessing to subtrees (the attributes) and so on. Moreover, the developer has all native functions of the
CodeWorker scripting language at his disposal.
2 Calling CodeWorker from Java
There are some points to know before using CodeWorker in a Java software.
2.1 JNI library and the "org.codeworker.jni" package
Once you have downloaded CodeWorker, you'll find the directory "java" just below the main directory of the
setup. This directory concerns all about CodeWorker in Java. The JNI library is directly available under the "java"
directory, in "java/JNICodeWorker.dll" (Windows only; for other platforms, you must build the dynamic library). The
Java classes implementing the bridge with the native interface are distributed in "java/org/codeworker/jni".
From here, you have to put the JNI library somewhere in your Java library paths (we assume here that you
have a minimal knowledge of the Java platform).
2.2 Building the JNI library
2.2.1 Windows platform
Under Windows, you should find easily the binary of the JNI library to download on the
official Web site of CodeWorker. However, you can recompile
the JNI library.
The Visual C++ 7.1 project is located in "java/CodeWorker.JNI.vcproj". The include path to your JNI C++ header
files ("YOUR_JAVA_DISTRIBUTION/include") must be changed in the properties of the project. Once this small
adjustment done, you just have to build the project.
Note that the Debug configuration generates the JNI library "java/JNICodeWorkerD.dll".
2.2.2 Other platforms
All sources of the JNI library are located in "java/src". You could write a little Makefile, which specifies an
include path to your JNI C++ header files ("YOUR_JAVA_DISTRIBUTION/include"), compiles the sources and links with
"libcodeworker.a" (the static library of CodeWorker).
2.3 Activating the JNI library
Before the first call to the CodeWorker API, the software must load the JNI library. Here is an example of
what you could write at the beginning of your application:
// load the JNI library of CodeWorker
try {
System.loadLibrary("JNICodeWorker");
} catch(Exception exception) {
System.out.println("Unable to load the library: '" + exception.toString() + "'");
}
2.4 Example
The following Java application behaves like a CodeWorker's leader script. It asks for the parsing of a file,
then it generates an HTML file by exploring the parse tree. A very classical process in Design-Specific Modeling.
// ... skipping the beginning of main()
// compile a BNF and parse a DSL
org.codeworker.jni.ParseTree tree = new org.codeworker.jni.ParseTree();
org.codeworker.jni.CompiledBNFScript BNF = new org.codeworker.jni.CompiledBNFScript();
BNF.buildFromFile("My_DSL_Parser.cwp");
theBNF.parse(tree, "requirements.dsl");
// generate the documentation in HTML
org.codeworker.jni.CompiledTemplateScript genDoc = new org.codeworker.jni.CompiledTemplateScript();
genDoc.buildFromFile("docHTML.cwp");
genDoc.generate(tree, "doc.html");
// to finish, display of the whole parse
// tree, up to depth = 4
org.codeworker.jni.Runtime.traceObject(tree, 4);
// ... skipping the end of Main()
The class "org.codeworker.jni.CompiledBNFScript" allows the precompilation of an extended-BNF script and its execution. The
execution requires a "org.codeworker.jni.ParseTree" object as the context to populate.
The class "org.codeworker.jni.CompiledTemplateScript" precompiles a template-based script and generates an output file,
traversing the parse tree previously populated by the BNF script.
At the end, the parse tree is displayed, up to a depth of 4, using a classical function of the scripting
language: "traceObject()". All functions of the scripting language are accessible via the class "org.codeworker.jni.Runtime".
You'll find more examples in "java/org/codeworker/jni/tests".
3 The Java API of CodeWorker
3.1 org.codeworker.jni.ParseTree
This class represents a CodeWorker variable, able to contain an association table, to have some attributes (branches through subtrees),
to be worth a string value or to point to another parse tree.
Example of declaration:
org.codeworker.jni.ParseTree tree = new org.codeworker.jni.ParseTree();
The equivalent declaration in CodeWorker is:
local tree;
3.1.1 public ParseTree()
This constructor creates an internal parse tree, which will be deleted once the garbage collector will free this
instance. Note that this parse tree will have no name (the property "getName()" will return null).
3.1.2 public ParseTree(ParseTree)
This constructor points to another parse tree, but will never delete the internal parse tree it refers to. It is a
kind of copy-by-reference.
Example:
org.codeworker.jni.ParseTree secondTree = new org.codeworker.jni.ParseTree(firstTree);
The equivalent declaration in CodeWorker is:
localref secondTree = firstTree;
3.1.3 public String getName()
This property returns the name of the node (null if the node was declared on the stack of the Java application).
3.1.4 public String get[String]Value() / void setValue(String)
This property contains the string value attached to the node, which may be null.
Note that getValue() may return a null string (no value attached to the node or empty string),
while getStringValue() always returns a string instance, even if the node doesn't have a value.
Example:
if tree.expression {
traceLine(tree.expression);
}
3.1.9 public ParseTree insertNode(String attr)
This function inserts a new attribute to the node and returns the subtree newly created. If the attribute
already exists, it returns the attached subtree.
Example:
tree.insertNode("expression").setValue("a + b");
The equivalent in CodeWorker is:
insert tree.expression = "a + b";
3.2 org.codeworker.jni.CompiledCommonScript
This class represents a CodeWorker common script, so called because it doesn't process parse tasks and it doesn't
generate outputs, like a leader script.
It encapsulates a precompiled common script, which can be executed at any time, without requiring a new
compilation of the script.
Do not forget to build the precompiled script before executing it.
Example:
org.codeworker.jni.ParseTree theContext = new org.codeworker.jni.ParseTree();
// ... [skipping]
org.codeworker.jni.CompiledCommonScript script = new org.codeworker.jni.CompiledCommonScript();
// precompilation of the common script
script.buildFromFile("my_script.cws");
// execution of the script
script.execute(theContext);
3.2.1 public CompiledCommonScript()
The constructor of a common script precompilator.
3.2.2 void buildFromFile(string filename)
It precompiles a common script coming from a file.
3.2.3 void buildFromString(string text)
It precompiles a common script stored in the string argument "text".
Example: precompilation of a script that displays the content of the attribute 'message', belonging to the context.
org.codeworker.jni.CompiledCommonScript script = new org.codeworker.jni.CompiledCommonScript();
script.buildFromString("traceLine(this.message);");
3.2.4 void execute(ParseTree context)
It executes the precompiled common script, passing the argument "context" as 'this'.
Example:
org.codeworker.jni.ParseTree theContext = new org.codeworker.jni.ParseTree();
// ... skipping creation and precompilation of the script
script.execute(theContext);
3.3 org.codeworker.jni.CompiledBNFScript
This class represents a CodeWorker extended-BNF script.
It encapsulates a precompiled BNF script, which can be executed at any time, without requiring a new
compilation of the script.
Do not forget to build the precompiled script before executing it.
Example:
org.codeworker.jni.ParseTree theContext = new org.codeworker.jni.ParseTree();
// ... [skipping]
org.codeworker.jni.CompiledBNFScript script = new org.codeworker.jni.CompiledBNFScript();
// precompilation of the common script
script.buildFromFile("my_grammar.cwp");
// execution of the script
script.parse(theContext, "my_DSL.dsl");
3.3.1 public CompiledBNFScript()
The constructor of an extended-BNF script precompilator.
3.3.2 void buildFromFile(string filename)
It precompiles an extended-BNF script coming from a file.
3.3.3 void buildFromString(string text)
It precompiles an extended-BNF script stored in the string argument "text".
Example: precompilation of a script that extracts all identifiers of an input.
org.codeworker.jni.CompiledBNFScript script = new org.codeworker.jni.CompiledBNFScript();
script.buildFromString("grammar ::= [->[#readIdentifier:id => pushItem this = id;]]*;");
The precompiled BNF script parses a string, passing the argument "context" as 'this'.
3.4 org.codeworker.jni.CompiledTemplateScript
This class represents a CodeWorker template script.
It encapsulates a template-based script, which can be executed at any time, without requiring a new
compilation of the script.
Do not forget to build the precompiled script before executing it.
Example:
org.codeworker.jni.ParseTree theContext = new org.codeworker.jni.ParseTree();
// ... [skipping]
org.codeworker.jni.CompiledTemplateScript script = new org.codeworker.jni.CompiledTemplateScript();
// precompilation of the common script
script.buildFromFile("my_script.cwt");
// execution of the script
script.generate(theContext);
3.4.1 public CompiledTemplateScript()
The constructor of a template-based script precompilator.
3.4.2 void buildFromFile(string filename)
It precompiles a template-based script coming from a file.
3.4.3 void buildFromString(string text)
It precompiles a template-based script stored in the string argument "text".
Example: precompilation of a script that writes all identifiers precedently pushed into the context.
org.codeworker.jni.CompiledTemplateScript script = new org.codeworker.jni.CompiledTemplateScript();
script.buildFromString("list of values:\n<%foreach i in this { %>\t- \"<%i%>\"\n<%}");
The precompiled template-based script generates an output, which is returned as a string. The string argument
"text" contains the precedent version of this output (preserved areas, for instance).
It passes the argument "context" as 'this'.
The precompiled template-based script expands a file, passing the argument "context" as 'this'.
3.5 org.codeworker.jni.CompiledTranslationScript
This class represents a CodeWorker translation script.
It encapsulates a translation script, which can be executed at any time, without requiring a new
compilation of the script.
Do not forget to build the precompiled script before executing it.
Example:
org.codeworker.jni.ParseTree theContext = new org.codeworker.jni.ParseTree();
// ... [skipping]
org.codeworker.jni.CompiledTranslationScript script = new org.codeworker.jni.CompiledTranslationScript();
// precompilation of the common script
script.buildFromFile("my_script.cwp");
// execution of the script
script.translate(theContext, "my_source.txt", "my_target.txt");
3.5.1 public CompiledTranslationScript()
The constructor of a translation script precompilator.
3.5.2 void buildFromFile(string filename)
It precompiles a translation script coming from a file.
3.5.3 void buildFromString(string text)
It precompiles a translation script stored in the string argument "text".
Example: precompilation of a script that extracts identifiers from an input and writes them on the flow to the
output. Following a straightforward process, It does something similar to the merge of examples given for the
BNF and template scripts above.
org.codeworker.jni.CompiledTranslationScript script = new org.codeworker.jni.CompiledTranslationScript();
script.buildFromString("translator ::= =>{%>list of values:\n<%}[->[#readIdentifier:id => {%>- \"<%id%>\"\n<%}]]*;");
The precompiled template-based script translates the content of the string parameter "inputText" and returns
the result as a string.
It passes the argument "context" as 'this'.
4 Conclusion
The Java package of CodeWorker allows the developer to drive easily DSL parsing and code generation from the
Java platform. The parse tree can be traversed and decorated directly in Java, rather
than only in the scripting language of CodeWorker.
CodeWorker is maintained by Cedric Lemaire.
Please send a mail to Submit a bug or feature