maven fmpp+javacc 集成使用简单说明

dremio 以及apache calcite 使用到fmpp + javacc 进行代码生成处理,以下是一个简单的集成测试

fmpp 的作用

fmpp 实际上是包装了freemarker ,提供了cli 以及java api 可以方便的进行模版处理,目前apache calcite 就基于了fmpp 进行sql 解析的代码生成
实际上fmpp 是一个很不错而且强大的模版处理工具,以下是一个简单的试用(基于前边包装的fmpp maven 扩展)
fmpp 支持基于配置对于生成模版的控制,我们可以以工程化的模式进行模版的管理以及数据处理

javacc 与fmpp 的集成

实际上就是fmpp 插件与javacc 插件集成,同时控制好不同插件的执行生命周期,一般推荐代码模版放到与src/main 同级的位置,最好别放到resources
下边(编译会打包,而且很多是否我们并不想暴露)

参考使用

  • 项目结构
 
├── pom.xml
└── src
    └── main
        ├── codegen  // 模版代码
        ├── config.fmpp
        ├── data
        ├── app.json
        └── style.tdd
        ├── includes
        ├── footer.html
        ├── func
        └── agg.ftl
        └── macros
        └── login.ftl
        └── templates
        ├── app.jj
        └── index.html
        ├── java
        └── resources
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.dalong</groupId>
    <artifactId>javacc-app</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <repositories>
        <repository>
            <id>github</id>
            <url>https://maven.pkg.github.com/rongfengliang/fmpp-maven-plugin</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <build>
        <plugins>
           # initialize 阶段拷贝文件到构建位置的特定目录,方便fmpp 以及javacc 使用
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>copy-fmpp-resources</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/codegen</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/codegen</directory>
                                    <filtering>false</filtering>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
              # 基于dremio fmpp 扩展独立的fmpp 插件,基于fmpp 进行配置生成
                <groupId>com.rongfengliang</groupId>
                <artifactId>fmpp-maven-plugin</artifactId>
                <version>1.0</version>
                <executions>
                    <execution>
                        <id>generate-fmpp-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <config>${project.build.directory}/codegen/config.fmpp</config>
                            <output>${project.build.directory}/generated-sources/fmpp</output>
                            <templates>${project.build.directory}/codegen/templates</templates>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
          # 使用javacc 扩展进行代码生成
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>javacc-maven-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <id>javacc</id>
                        <goals>
                            <goal>javacc</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>${project.build.directory}/generated-sources/</sourceDirectory>
                            <includes>
                                <include>**/app.jj</include>
                            </includes>
                            <lookAhead>2</lookAhead>
                            <isStatic>false</isStatic>
                            <outputDirectory>${project.build.directory}/generated-sources/</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  • fmpp 项目代码说明
    config.fmpp 属于通用配置,编译进行的通用设置
 
recommendedDefaults: 0.9.16
sourceRoot: templates
dataRoot: data
data: {
   app: tdd(style.tdd),
   parser:json(parser.json)
   myappinfo: {
    version: "v1",
    author: "dalong"
   },
   items:json(app.json)
}
freemarkerLinks: {
    inc: includes/
}

app.jj 一个特别简单的基于javacc 定义的解析

PARSER_BEGIN(${parser.parserName})
 
package ${parser.packageName};
/** Simple brace matcher. */
public class ${parser.parserName} {
 
  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
    MyApp parser = new MyApp(System.in);
    parser.Input();
  }
 
}
 
PARSER_END(${parser.parserName})
 
/** Root production. */
void Input() :
{}
{
  MatchedBraces() ("\n"|"\r")* <EOF>
}
 
/** Brace matching production. */
void MatchedBraces() :
{}
{
  "{" [ MatchedBraces() ] "}"
}

数据定义
主要说明 app.jj 依赖的数据项(使用了json dataloader)

 
{
  "parserName":"MyApp",
  "packageName":"com.dalongapp"
}

运行

  • 命令
mvn clean package
  • 效果

 

 

说明

很多时候我们需要集成maven-dependency-plugin 对于三方依赖jj 文件的加载,注意应该在maven 的initialize 阶段处理通过unpack copy
依赖到我们的项目中,比如当我们如果需要扩展apache calcite 的时候就需要了(dremio 也是使用了此方法)

参考资料

https://github.com/mojohaus/javacc-maven-plugin
https://www.mojohaus.org/javacc-maven-plugin/plugin-info.html
https://github.com/rongfengliang/fmpp-maven-plugin-learning
https://github.com/rongfengliang/fmpp-maven-plugin
https://maven.apache.org/plugins/maven-dependency-plugin/index.html

posted on 2022-12-15 17:46  荣锋亮  阅读(627)  评论(0编辑  收藏  举报

导航