首页 > 其他分享 >DSL 领域特定语言

DSL 领域特定语言

时间:2023-04-19 13:11:50浏览次数:56  
标签:宿主 语言 外部 领域 DSL 特定 内部

一、DSL介绍

DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言。 常用于聚焦指定的领域或问题,这就要求 DSL 具备强大的表现力,同时在使用起来要简单。说到DSL,大家也会自然的想到通用语言(如Java、C等)。

为什么没有一种语言同时 兼具『简洁』和『业务表达』能力呢?

从信息论本质上来讨论这个问题,每个语言的程序都可以抽象为一个字符串,每个字符串由有限数量的合法字符组成,它在运行时会实现某个功能,因而可以看作是一种需求的信源编码。每种需求可以映射到一个或多个正确的程序,但一个程序肯定只对应到一种需求,因而程序包含的信息熵不低于需求的信息熵。而程序中不仅仅需要描述需求的信息,还需要包含 可读性、辩识度,如果是静态语言还需要 静态检查等额外信息。 这里也可以看出来,为什么DSL是特定领域的语言了。
二、DSL分类

最常见的分类方法是按照DSL的实现途径来分类。马丁·福勒曾将DSL分为内部和外部两大类,他的分类法得到了绝大多数业界人士的认可和沿袭。内部与外部之分取决于DSL是否将一种现存语言作为宿主语言,在其上构建自身的实现。
2.1、内部DSL

也称内嵌式DSL。因为它们的实现嵌入到宿主语言中,与之合为一体。内部DSL将一种现有编程语言作为宿主语言,基于其设施建立专门面向特定领域的各种语义。例如:Kotlin DSL、Groovy DSL等;
2.2、外部DSL

也称独立DSL。因为它们是从零开始建立起来的独立语言,而不基于任何现有宿主语言的设施建立。外部DSL是从零开发的DSL,在词法分析、解析技术、解释、编译、代码生成等方面拥有独立的设施。开发外部DSL近似于从零开始实现一种拥有独特语法和语义的全新语言。构建工具make 、语法分析器生成工具YACC、词法分析工具LEX等都是常见的外部DSL。例如:正则表达式、XML、SQL、JSON、 Markdown等;

三、 DSL示例
3.1 内部DSL

HTML: 通过自然语言编写

在Groovy中,通过DSL可以用易读的写法生成XML

最后将生成

这里相对于Java这样的动态语言,最为不同的就是xml.html这个并不存在的方法居然可以通过编译并运行,它内部重写了invokeMethod方法,并进行闭包遍历,少写了许多POJO对象,效率更高。
3.2 外部DSL

以plantUML为例,外部DSL不受限于宿主语言的语法,对用户很友好,尤其是对于不懂宿主语言语法的用户。但外部DSL的自定义语法需要有配套的语法分析器。常见的语法分析器有:YACC、ANTLR等。

四、 DSL & DDD(领域驱动)

DDD和DSL的融合有三点:面向领域、模型的组装方式、分层架构演进。DSL 可以看作是在领域模型之上的一层外壳,可以显著增强领域模型的能力。

 它的价值主要有两个,一是提升了开发人员的生产力,二是增进了开发人员与领域专家的沟通。外部 DSL 就是对领域模型的一种组装方式。

五、 DSL不是银弹

前开篇也提到了,在信息量不变的情况下,代码行数越短,它的“潜规则”信息量就越多,那么如何排查?如何定位?如何扩展?成为一个好的DSL需要考量的点。好的DSL难点在于:

    DSL只是一种声明式的编程语言,无法承载大量业务。

    DSL语句与编译生成的“字节码”的过程是黑盒的,不但对内部工作不明朗,如果报错的话,不但堆栈行数无法与源码对应上,而且无法“断点”或者“日志”。

    DSL对设计者要求高,需要会一个领域有通透的理解,设计时要克制『增加各种特性』,DSL还要文档齐全,支撑充分,甚至要开源以帮助使用者定位。
————————————————
版权声明:本文为CSDN博主「Impl_Sunny」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011487470/article/details/124583051

标签:宿主,语言,外部,领域,DSL,特定,内部
From: https://www.cnblogs.com/cnhk19/p/17332963.html

相关文章

  • C语言函数大全-- l 开头的函数
    C语言函数大全本篇介绍C语言函数大全--l开头的函数1.labs,llabs1.1函数说明函数声明函数功能longlabs(longn);计算长整型的绝对值longlongintllabs(longlongintn);计算longlongint类型整数的绝对值1.2演示示例#include<stdio.h>#include<......
  • 用于图像识别的编程语言,你知道几个?
    图像识别是大多数现代设备和程序中部署的主要功能之一。该功能具有广泛的应用程序,最常见的是安全系统。它可以使设备通过图像来识别人员或物体的身份。而面部识别是图像识别的产物。那么,创建具有图像识别功能的应用程序或软件需要些什么?你只需要使用编程语言对其进行编程。当然,有些......
  • python语言编程能力
    python语言编程能力函数默认参数实例1:classTest(object):defprocess(self,data=[]):data.sort()data.append("end")returndatatest1=Test()print(test1.process())//不会重新创建test2=Test()print(test2.process())//不会重新创......
  • C语言 正确理解二维数组首地址
    在一维数组中,数组名表示的是数组第一个元素的地址inta[10],*p=a;那么二维数组呢inta[3][4],a表示的是元素a[0][0]的地址吗?不是!二维数组就是一维数组,二维数组a[3][4]就是有三个元素a[0]、a[1]、a[2]的一维数组,所以数组a的第一个元素不是a[0][0],而是a[0],所以数组名......
  • 不懂自然语言处理技术,怎么才能做一个人工智能产品?
    一、选择第三方NLP开放平台NLP技术沉淀周期过长,投入会很大,选择第三方开放平台想必是小公司最好的选择,推荐三个AI语音开放平台:科大讯飞开放平台;百度AI开放平;搜狗云知音。二、明确技术分工没有NLP技术背景,如何造一款AI产品?上图是引入单个NLP的对接方案,通过任务分解,可以很清楚知道,哪些......
  • go语言中如何把数字转换成字节切片并在网络中传输
    客户端:先把数字转换成uint32类型:varpkgLen=uint32(len(data))再定义一个字节切片:varbuf=make([]byte,4)最后通过encoding.binary包中的方法,把无符号数字装载到字节切片中:binary.BigEndian.PutUint32(buf[0:4],pkgLen)这样就可以在网络中发送数字了:conn.Wri......
  • 在Go语言中,如何优化内存使用效率?
    在Go语言中,可以通过以下几种方式来优化内存使用效率:避免使用过多的内存尽可能地避免使用过多的内存是最有效的内存优化方法之一。在编写代码时,应该尽可能地避免使用全局变量和大量的临时变量。同时,可以使用常量、静态变量和缓存等方式来避免频繁地分配和释放内存。及时释放不......
  • Elasticsearch搜索功能的实现(二)--Elasticsearch中的核心概念与DSL
    一、Elasticsearch中的核心概念1、索引index一个索引就是一个拥有几分相似特征的文档的集合。比如说,可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、......
  • 自然语言处理:词嵌入简介
    动动发财的小手,点个赞吧!WordEmbeddings机器学习模型“查看”数据的方式与我们(人类)的方式不同。例如,我们可以轻松理解“我看到一只猫”这一文本,但我们的模型却不能——它们需要特征向量。此类向量或词嵌入是可以输入模型的词的表示。工作原理:查找表(词汇)在实践中,你有一个允许......
  • 编程打卡:C语言趣味编程习题做
    编程打卡:C语言趣味编程习题做存钱问题问题描述给定不同期限档次整存整取的月利率,期限和本金,求出使利息最大的存款方案。设计思路遍历每种可能的存钱方案,求出利息最大的方案,然后输出。流程图graphA[开始]-->B[定义各种各样的变量]-->C[遍历所有存款方案,保存利率最大的......