博客
关于我
·使用Xtext/Xtend 实现域专用语言DSL(1)
阅读量:596 次
发布时间:2019-03-12

本文共 3153 字,大约阅读时间需要 10 分钟。

建立一个DSL语言来描述会议信息

我们常常需要定义自己的领域特定语言(DSL),以便更方便地描述特定的领域知识。在本文中,我们将使用Eclipse Xtext来定义一个简单的DSL,来描述一个会议的信息。

简单的例子

首先,让我们明确我们要描述的会议信息。最终的描述大致如下:

datatype Stringdatatype Boolentity Session {title: StringisTutorial : Bool}entity Conference {name : Stringattendees : Person*speakers : Speaker*}entity Person {name : String}entity Speaker extends Person {sessions : Session*}

接下来,我们将深入探讨如何使用Xtext来设计这个DSL的语法。

语法的基本结构

Xtext的语法定义模板通常包括以下几个关键部分:

  • 语法起始语句grammar org.eclipse.xtext.example.Domainmodelwith org.eclipse.xtext.common.Terminals这里,org.eclipse.xtext.example.Domainmodel 是语法的名称,org.eclipse.xtext.common.Terminals 是语法的状态,表示该语法重用和覆盖了特定的语法。org.eclipse.xtext.common.Terminals 是Xtext库中的预定义语法,提供了许多通用终结符,如ID、STRING和INT等。

  • 生成代码:```generate domainmodel "http://www.eclipse.org/xtext/example/Domainmodel"`这行命令指定了我们从该语法导出的EMF Ecore 包(Ecore package)。

  • 理解常用符号

    在Xtext语法中,以下是一些常用的符号:

    符号 描述 允许的子元素 最大允许数目
    ? 零个或一个 0或1
    * 零个或多个 0或多个
    + 至少一个 1或多个

    例如:

    grammar DomainModel : Entity*;表示DomainModel可以包含零个或多个Entity实例。

    简化说明

    ENTITY及其子类

    entity 是一个基本的实体类型,可以扩展到其他更具体的类型。例如,Speaker可以扩展Person类,并定义自己的属性和方法。

    数据类型定义

    在我们给出的例子中,我们定义了两种基本数据类型和实体类型:

    grammar DomainModel :(elements+=Type)*; Type: DataType | Entity; DataType:'datatype' name=ID;startup_code这意味着:

    • DomainModel 是一个包含零个或多个Type元素的集合。
    • Type 可以是 DataType 或 Entity。
    • DataType 是一个带有名称的数据类型。
    • Entity 是一个可以扩展的实体类型。

    Fields 定义

    Feature 的语法规则定义如下:

    grammar Feature:name=ID ':' type=TypeRef;

    这意味着:

    • Feature 有一个名称(ID)。
    • 它对应一个TypeRef,即一个数据类型引用。

    TypeRef 的定义如下:

    grammar TypeRef:referenced=[Type] (multi?='*')?;所以:

    • TypeRef 可以引用一个或多个Type。
    • 可以带有*来表示多个,这可能用于复数形式。

    Terminal 规则

    在编译过程中,Xtext 处理语法不仅包括语法规则,还包括词法规则(terminal rules)。例如:

    terminal INT returns ecore::EInt:    ('0'..'9')+;``` 这些规则定义了ID 和INT这些终结符,并指定了它们分别映射到Eclipse EMF中的EString和EInt。完整的语法定义---------------- 将以上各部分拼接起来,完整的语法定义如下:```grammar org.eclipse.xtext.example.Domainmodelwith org.eclipse.xtext.common.Terminalsgenerate domainmodel "http://www.eclipse.org/xtext/example/Domainmodel"DomainModel :(elements+=Type)*;Type:DataType | Entity;DataType:'datatype' name=ID;Entity:'entity' name=ID ('extends' superType=[Entity])? '{'(features+=Feature)*'}';Feature:name=ID ':' type=TypeRef;TypeRef:referenced=[Type] (multi?='*')?;```另一个示例------------ 假设计算器表达式的语法可能看起来像这样:```grammar expr.ExprDemo with org.eclipse.xtext.common.Terminalsgenerate exprDemo "http://www.ExprDemo.expr"import "http://www.eclipse.org/emf/2002/Ecore" as ecoreModel:  elements+=Element*;Element:  VarDecl | Formula;VarDecl returns Symbol:  {VarDecl} "var" type=Type name=ID ";";Type:  IntType | BoolType | FloatType;IntType:  {IntType} "int";BoolType:  {BoolType} "bool";FloatType:  {FloatType} "float";Formula:  "calc" type=Type name=ID "=" expr=Expr ";";Expr:  Addition;Addition returns Expression:  Multiplication ({Plus.left=current}"+" right=Multiplication)*;Multiplication returns Expression:  Atomic ( {Multi.left=current} "*" right=Atomic)*;Atomic returns Expression:  {SymbolRef} symbol=[Symbol|QID] |  {NumberLiteral} value=NUMBER;terminal NUMBER returns ecore::EBigDecimal:  ('0'..'9')* ('.' ('0'..'9')+)?; terminal QID:   ID ("." ID)*;```总结----- 使用Xtext定义语法的核心是了解每个符号的含义,并将这些符号按照您确定的领域模型进行组合。通过实践您会越来越熟悉这些概念,并能够根据具体需求定制自己的语法。

    转载地址:http://cazxz.baihongyu.com/

    你可能感兴趣的文章
    Memcached:Node.js 高性能缓存解决方案
    查看>>
    memcache、redis原理对比
    查看>>
    memset初始化高维数组为-1/0
    查看>>
    Metasploit CGI网关接口渗透测试实战
    查看>>
    Metasploit Web服务器渗透测试实战
    查看>>
    MFC模态对话框和非模态对话框
    查看>>
    Moment.js常见用法总结
    查看>>
    MongoDB出现Error parsing command line: unrecognised option ‘--fork‘ 的解决方法
    查看>>
    mxGraph改变图形大小重置overlay位置
    查看>>
    MongoDB可视化客户端管理工具之NoSQLbooster4mongo
    查看>>
    Mongodb学习总结(1)——常用NoSql数据库比较
    查看>>
    MongoDB学习笔记(8)--索引及优化索引
    查看>>
    mongodb定时备份数据库
    查看>>
    mppt算法详解-ChatGPT4o作答
    查看>>
    mpvue的使用(一)必要的开发环境
    查看>>
    MQ 重复消费如何解决?
    查看>>
    mqtt broker服务端
    查看>>
    MQTT 保留消息
    查看>>
    MQTT 持久会话与 Clean Session 详解
    查看>>
    MQTT工作笔记0007---剩余长度
    查看>>