找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1552

积分

0

好友

223

主题
发表于 6 天前 | 查看: 19| 回复: 0

Nop平台为开发自定义DSL(Domain Specific Language,领域特定语言)提供了一套系统性的基础设施。其核心机制是通过XDef元模型定义XML格式的语法结构,然后自动生成AST节点类及解析器、验证器等工具。虽然XDef本身使用XML语法,但这并不意味着Nop平台中的DSL只能以XML格式表达。根据可逆计算理论,同一信息结构可以拥有多种表达形式,并能实现它们之间的自动、可逆转换。

本文将以Nop平台中的ORM模型为例,详细介绍如何为其引入Markdown语法格式,并实现Markdown与XML/JSON之间的双向无损转换。

1. 理解核心模块:nop-kernel

Nop平台支持DSL定义与实现的核心逻辑(即可逆计算理论的实现核心)完全集中在nop-kernel模块中。了解其子模块有助于理解后续的扩展机制:

  1. nop-core: 实现虚拟文件系统、XML/JSON等基础格式解析器和反射机制。
  2. nop-xdefs: 集中存放所有内置的XDef元模型。
  3. nop-xlang: 实现Xpl模板语言、XScript脚本语言及Delta合并算法。
  4. nop-record-mapping: 实现异构对象映射模型,是支撑Markdown与模型对象双向转换的关键。
  5. nop-markdown: 提供简易Markdown解析器,为DSL解析提供额外封装。
  6. nop-kernel-cli: 提供命令行工具(如convert和gen指令),用于模型转换和代码生成。

其中,nop-kernel-cli下的demo目录包含了自定义解析器和代码生成模板的示例。

2. 注册自定义DSL加载器

在Nop平台中,每种DSL文件格式对应一个唯一的fileType。全局加载器ResourceComponentManager会根据此类型选择对应的加载器。

要为orm.xml这类文件增加Markdown格式支持,需要创建注册文件/nop/core/registry/orm.register-model.xml

<model x:schema="/nop/schema/register-model.xdef" xmlns:x="/nop/schema/xdsl.xdef"
       name="orm">
  <loaders>
    <!-- 为XML/JSON/YAML格式注册内置加载器 -->
    <xdsl-loader fileType="orm.xml" schemaPath="/nop/schema/orm/orm.xdef"/>
    <xdsl-loader fileType="orm.json" schemaPath="/nop/schema/orm/orm.xdef"/>
    <xdsl-loader fileType="orm.yaml" schemaPath="/nop/schema/orm/orm.xdef"/>
    <!-- 为Markdown格式注册自定义加载器 -->
    <loader fileType="orm.md" mappingName="orm.Md_to_OrmModel"
            class="io.nop.record_mapping.md.MarkdownDslResourceLoaderFactory"/>
  </loaders>
</model>

配置说明:

  • xdsl-loader: 用于配置XML/JSON/YAML等内置格式的加载器。
  • loader: 用于定义扩展加载器,支持自定义格式。
  • fileType: 文件类型标识符(如 orm.md)。
  • mappingName: 指定用于解析的映射规则名称。
  • class: 加载器工厂类的完整路径,需实现IResourceObjectLoaderFactory接口。

MarkdownDslResourceLoaderFactory返回的加载器实现了资源加载、保存以及DSL节点(XNode)的加载与保存接口,从而支持完整的双向转换功能。

3. 基于RecordMapping实现Markdown解析与生成

RecordMapping是Nop平台内置的对象映射机制,用于定义两个异构Java对象间的双向映射规则。在其基础上补充md:format等扩展信息,即可实现Markdown片段与DSL模型对象间的转换。

<definitions xmlns:x="/nop/schema/xdsl.xdef" x:schema="/nop/schema/record/record-mappings.xdef"
             xmlns:md="md" x:dump="true">
  <!-- 定义从Markdown到ORM模型的映射规则 -->
  <mapping name="Md_to_OrmModel" md:titleField="displayName">
    <fields>
      <field name="displayName" from="displayName"/>
      <field name="x:extends" from="extends" alias="Extends">
        <schema stdDomain="string"/>
      </field>
      <!-- 映射“实体定义”章节,其内容为列表,每个子项使用Md_to_EntityModel规则 -->
      <field name="entities" from="实体定义" alias="Entities" keyProp="name"
             itemMapping="Md_to_EntityModel">
      </field>
    </fields>
  </mapping>

  <!-- 定义从Markdown到实体模型的映射规则 -->
  <mapping name="Md_to_EntityModel" md:titleField="name">
    <fields>
      <field name="name" from="对象名" alias="Object Name">
        <schema stdDomain="class-name"/>
        <valueExpr>
          value?.$fullClassName(rootRecord['ext:entityPackageName'])
        </valueExpr>
      </field>
      <field name="tableName" from="表名" mandatory="true" alias="Table Name">
        <schema stdDomain="prop-name"/>
      </field>
      <!-- “字段列表”和“关联列表”在Markdown中以表格形式呈现 -->
      <field name="columns" from="字段列表" keyProp="name"
             alias="Column List" itemMapping="Md_to_ColumnModel" md:format="table">
      </field>
      <field name="relations" from="关联列表" alias="Relation List"
             itemMapping="Md_to_RelationModel" md:format="table">
      </field>
    </fields>
  </mapping>
</definitions>

关键扩展属性:

  • md:titleField: 指定Markdown章节标题对应的模型字段。
  • md:format: 指定字段的Markdown呈现格式,目前支持table(表格)和code(代码块)。

一个遵循上述规则的Markdown格式ORM模型示例:

# AI模型管理
- extends:  demo.orm.md

## 5 实体定义
### 5.1 NopAiProject
- 表名: nop_ai_project
- 类名: NopAiProject
- 中文名: AI项目
- 备注: 存储AI项目基本信息

#### 5.1.1 字段列表
|编号|标签|主键|非空|字段名|属性名|显示|中文名|英文名|数据域|标准域|类型|长度|小数位数|字典|备注|缺省值|控件|根节点级别|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | seq | true | true | id | id | X | 主键 |  |  |  | VARCHAR | 36 |  |  |  |  |  |  |
| 2 |  | false | true | language | language |  | 项目语言 |  |  |  | VARCHAR | 4 |  | ai/project_language | 项目使用的编程语言类型:JAVA, PYTHON等 |  |  |  |

此Markdown文件可被正确解析并转换为等价的XML格式,表格内容被精准映射为<columns>节点集合。

4. 利用元编程自动生成反向映射

Nop平台的元编程能力允许我们基于正向映射自动生成反向映射。例如,定义了Md_to_OrmModel后,可以自动生成OrmModel_to_Md

在RecordMapping配置中引入生成逻辑:

<definitions xmlns:x="/nop/schema/xdsl.xdef" x:schema="/nop/schema/record/record-mappings.xdef"
             xmlns:md="md" x:dump="true">
    <x:post-extends>
        <c:import from="/nop/record/xlib/record-mapping-gen.xlib"/>
        <record-mapping-gen:GenReverseMappings/>
    </x:post-extends>
    <!-- 原有的正向映射配置 Md_to_OrmModel 等 -->
</definitions>

系统执行后会自动创建反向映射。如需微调,可以直接在文件中以相同的全量格式添加差量修正,例如调整反向映射中某个字段的生成表达式,这体现了可逆计算理论的灵活性。

5. 使用CLI工具进行转换与生成

配置完成后,即可使用nop-kernel-cli.jar执行模型转换和代码生成,验证双向转换效果。

# 将XML格式的ORM模型转换为Markdown格式
java -jar nop-kernel-cli.jar convert demo.orm.xml -o=demo.orm.md

# 将Markdown格式的ORM模型转换回XML格式
java -jar nop-kernel-cli.jar convert demo.orm.md -o=demo.orm.xml

# 基于Markdown格式的ORM模型生成代码
java -jar nop-kernel-cli.jar gen demo.orm.md -t=/nop/templates/orm -o=target

通过以上步骤,我们成功为Nop平台的ORM模型扩展了Markdown格式的支持,并实现了与标准XML格式的无损双向转换。这不仅丰富了DSL的书写形式,也实践了可逆计算理论中“同一逻辑,多种表象”的核心思想,显著提升了开发效率和模型的可读性。




上一篇:Wake测试教程:使用Python与ERC1967代理安全测试可升级合约
下一篇:Python类方法、静态方法与实例方法核心区别解析及最佳实践
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 21:11 , Processed in 0.207650 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表