STRJ compiles [[Stratego Language][Stratego]] to Java, and is a Java-based variation of the [[Stratego Compiler]]. %TOC% ---++ Introduction The compiler comes in two flavors: one called =strj=, compiled with the standard C-based [[http://releases.strategoxt.org/strategoxt-manual/unstable/manual/chunk-chapter/ref-strc.html][strc]]. The second is a bootstrapped, cross-platform compiler that lives in strategoxt.jar. Note that Stratego executables compiled with strj do not support XTC (since it depends on forking native executables and assumes filesystem access) and the strategoxt.jar compiler is no exception. This means that you have to explicitly specify the import path of dependencies that would otherwise be resolved using XTC. Another difference between the two is that strj still uses the C-based SGLR parser, while strategoxt.jar uses JSGLR. Compiling a simple application from the command line with either compiler is similar to doing so with the [[%MANUAL%/ref-strc.html][strc]] command:
strj -i foo.str -la stratego-libor
java -jar strategoxt.jar -i foo.str -la stratego-libIt should be noted that at this time the compiler only outputs =.java= source files and not =.class= files. Subsequent compilation should be done using a standard Java compiler (ideally, in an automated fashion using an Ant build script or Eclipse). The (non-portable) =strj-jar= shell script can also help with command-line or scripted builds. ---+++ Known Issues and Limitations The Stratego/J runtime implements most of the primitives of the natively compiled version of Stratego, but some compatibility issues might arise. In particular, the parsing primitives are implemented using JSGLR, the Java version of SGLR, which may not be bug-for-bug compatible with the C version of SGLR. Mainly, the post-parse filter implementation might not always produce the same results. This especially impacts the heuristic filters, which are disabled by default, but used for Stratego's concrete syntax embedding. To work around any problems, the native =strj= executable can be used to compile these files, or they can be pre-parse them to =.rtree= files using [[%MANUAL%/ref-parse-stratego.html][parse-stratego]]. A general recommendation may be to disable the heuristic filters in the =.meta= files using the =HeuristicFilters(Off())= directive. The standard Sun compiler can be quite slow when compiling large Stratego projects. We recommend using ECJ (Eclipse Compiler for Java) instead, which is much faster and less memory-intensive. ECJ is distributed as part of Eclipse, and can be executed as follows:
java -cp plugins/org.eclipse.jdt.core_*.jar org.eclipse.jdt.internal.compiler.batch.MainMany Linux distributions also provide a stand-alone version of ECJ through their package manager. (Note that ECJ 3.3 and lower have a bug that can be worked around with the =-Xecj33= flag.) When using the Sun compiler, you may need to add option =-J-mx256m= to increase the available heap space, and likely need to have a fair amount of patience ;) Stratego programs compiled to Java do not have the same performance characteristics as those compiled using the native Stratego compiler strc. The exact numbers vary per application (some, such as the somewhat artificial ASF+SDF benchmark, actually run faster on Java), but natively compiled Stratego applications that include parsing and pretty-printing are typically a factor two faster. Future optimizations, particularly in the term library and in I/O, may make this gap smaller. A final open issue is the stack usage by typical Stratego programs, putting JVM implementations with a small default stack size at risk of throwing a =StackOverflowException= (notably the Sun JVM on Linux). For these systems, running the JVM with option =-ss4m= avoids the stack overflow problem. (When this parameter is not set and a stack overflow occurs, compiled applications will hint at this setting.) While the XTC standard library strategies (such as =xtc-io-wrap=) are supported, support for the XTC repository is not implemented as this time because of portability concerns. Any =xtc-transform= or =xtc-call= invocations report a warning, and simply invoke executables on the path. For the interest of portability, applications that make use of these strategies should use library strategies instead, as discussed in the following section. ---+++ Using External Applications and Libraries A trend in Stratego programs has been to use the standard libraries in favor of the (slower, less portable) XTC interface. For example, the =parse-file= strategy from =libstratego-sglr= can be used to parse files. Since XTC depends on native executables and a centralized repository, it is not portable and not supported on the Java platform. As an alternative, library calls should be used instead, which is generally the preferred method for invoking external components. Libraries in the Java environment have a package name. For example, the Stratego standard library resides in the =org.strategoxt.stratego_lib= package. To maintain compatibility, these package names are not used within the Stratego language, but only at compile time and when the components are linked. For example, to link a program to the standard library the option =-la org.strategoxt.stratego_lib= can be specified. The standard libraries also have aliases that correspond to the XTC names commonly used with strc; =-la stratego-lib= is also accepted. To define a package name for your own library, use the =-p= and =--library= options. For example:
java -jar strategoxt.jar -i foo.str --library --clean -p org.foo -o bin/org/foo/Main.javaNote that each Stratego component may specify a different main class (=Main= in this case), but that they must still reside in different packages as to avoid overlap between strategy classes. ---+++ Java Integration A typical use case of compiling Stratego applications to Java is to integrate them into an existing Java application or environment. Interaction with the other Java components is possible in a number of ways: * Java components can directly call Stratego strategies, by calling the =Main.init()= method in the appropriate package and invoking a Strategy using =some_strategy_0_0.instance.invoke()=. If the =exit= strategy is called at any point, a =StrategoExit= exception will be thrown; a call to =fatal-err= will throw a =StrategoErrorExit= exception. * Normal Java components can be used to implement or override Stratego strategies, allowing for tighter coupling between Stratego and a Java application. See for example https://svn.strategoxt.org/repos/StrategoXT/ strc-java/trunk/java/runtime/org/strategoxt/lang/compat/libstratego_rtg_compat where two strategies (originally implemented natively in C) are implemented in Java. Every strategy has an =instance= field that allows it to be dynamically redefined. * Instead of just plain ATerms, Stratego can operate on any Java object tree or graph that implements the =IStrategoTerm= and associated interfaces. This way, it can operate on arbitrary object structures, or deeply integrate into a Java-based compiler front-end or editor. See also [[http://www.ii.uib.no/~karltk/phd/papers/ldta07-pomadapter.pdf][Fusing a transformation language with an open compiler]] by Kalleberg and Visser, and [[http://www.lclnet.nl/publications/composable-editor-plugins][Domain-Specific Languages for Composable Editor Plugins]] by Kats, Kalleberg, and Visser. * Compiled Stratego components can be dynamically loaded from JAR files and may be combined with interpreted components using the =HybridInterpreter= class. To interpret a Stratego component, pre-compile it to a =.ctree= file using STRJ and the =-F --library= options. ---++ Download Native builds of the Jompiler ("strc-java") are available from Hydra: * http://hydra.nixos.org/view/strategoxt-java/strc-java-trunk the pure Java version (included in the above distribution) can also be downloaded from: * http://hydra.nixos.org/job/strategoxt-java/strc-java-trunk/build/latest/download-by-type/file/jar The Java version of STRJ is also integrated in the [[Spoofax.WebHome][Spoofax plugin]] that allows you to develop languages and Eclipse plugins with Stratego. ---++ Project Information ---+++ Source Code Source code is available directly from SVN at * https://svn.strategoxt.org/repos/StrategoXT/strategoxt-java-backend/trunk or can be downloaded as a package at [[http://hydra.nixos.org][hydra.nixos.org]]. ---+++ Contributors Contributors * Lennart Kats (main !STRJ development and maintainer; Stratego/J compatibility components) * Karl Trygve Kalleberg (main Stratego/J and JSGLR development; original s2j prototype) * Valentin David (parts of the Stratego/J runtime) The development of !STRJ would not have been possible without the efforts of Eelco Visser and his team in developing the STRC reference stratego compiler. Martin Bravenboer's [[JavaFront][Java-front]] library and syntax definition have also been indispensable for the development !STRJ. ---+++ License !STRJ is licensed under the GNU Lesser General Public License ([[LGPL]]). ---+++ Contact and Mailing List Please send questions to the [[https://mailman.st.ewi.tudelft.nl/listinfo/users][users@strategoxt.org mailing list]] or [[http://www.lclnet.nl/contact/][contact Lennart Kats]] directly. Also, we can usually be found online on IRC at [[irc://irc.freenode.net/stratego][#stratego on freenode.net]] ([[http://java.freenode.net/index.php?channel=stratego][web version]]). Feel free to drop by! ---++ Related Software The [[Spoofax-IMP][Spoofax/IMP]] IDE development environment incorporates the !STRJ compiler. By default, it interprets Stratego definitions, using the [[#hybrid][hybrid interpreter]], but by changing the =build.xml= and =<myproject>-Analysis.esv= files, it can also compile them.