Streamlining Deveolpment with JavaCC and FMPP
In software development, code generation is an essential technique for reducing repetitive work and increasing productivity. For highly repetitive and template-based code, manual implementation can be time-consuming and error-prone. This article explores two powerful tools—JavaCC and FMPP—that automate code generation tasks, along with practical examples demonstrating their usage.
JavaCC: Parser Generator for Java
JavaCC is a popular parser generator and lexical analyzer generator. It reads a grammar specification and converts it into a Java program that can recognize matches to the grammar. Let's explore JavaCC through a practical example.
Example: Building a Mathematical Expression Parser
We'll create a parser that can evaluate mathematical expressions like "5 + 3 * 2". First, we need to define the grammar in a .jj file:
options {
STATIC = false;
}
PARSER_BEGIN(MathEvaluator)
public class MathEvaluator {
public static void main(String[] args) throws ParseException {
MathEvaluator evaluator = new MathEvaluator(System.in);
evaluator.parseInput();
}
void parseInput() : {}
{
expression() <eof>
}
void expression() : {}
{
term() ( "+" term() | "-" term() )*
}
void term() : {}
{
factor() ( "*" factor() | "/" factor() )*
}
void factor() : {}
{
<integer>
}
}
PARSER_END(MathEvaluator)
SKIP : {
" " | "\t" | "\n" | "\r"
}
TOKEN : {
<integer :="">
}
</integer></integer></eof>
Next, we generate the Java code by running:
javacc MathEvaluator.jj
This command creates the MathEvaluator.java file. Now, let's create a test class to verify our parser:
import java.io.StringReader;
public class ParserTest {
public static void main(String[] args) {
String input = "5 + 3 * 2";
MathEvaluator evaluator = new MathEvaluator(new StringReader(input));
try {
evaluator.parseInput();
System.out.println("Expression parsed successfully!");
} catch (Exception e) {
System.out.println("Parsing failed: " + e.getMessage());
}
}
}
When executed, this test will confirm that our parser correctly handles the mathematical expression. This example demonstrates JavaCC's capability to quickly generate parsers for various languages and formats.
FMPP: FreeMarker-based Text Processing Tool
FMPP is a general-purpose text file preprocessing tool that uses FreeMarker templates. It's particularly useful for generating code, documentation, and other text-based content from templates and data models. Let's see how it works with an example.
Example: Generating Java Classes from Templates
First, we'll create a template file named class_template.ftl:
package ${packageName};
public class ${className} {
public static void main(String[] args) {
System.out.println("${greetingMessage}");
}
public void displayInfo() {
System.out.println("Class: ${className}");
System.out.println("Author: ${authorName}");
}
}
Next, we'll create a data file config.properties:
packageName=com.example.generated
className=SampleApplication
greetingMessage=Welcome to FMPP code generation!
authorName=Developer
Now, we can execute FMPP with the following command:
fmpp -C config.properties -S . -O . class_template.ftl
This command generates a Java class file named SampleApplication.java with the following content:
package com.example.generated;
public class SampleApplication {
public static void main(String[] args) {
System.out.println("Welcome to FMPP code generation!");
}
public void displayInfo() {
System.out.println("Class: SampleApplication");
System.out.println("Author: Developer");
}
}
This example illustrates how FMPP can automate the generation of boilerplate code, significantly reducing manual coding effort and ensuring consistency across generated files.