`
javasee
  • 浏览: 965494 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

为脚本语言平反-JavaScript篇(2)

阅读更多

http://blog.csdn.net/aimingoo/archive/2009/09/08/4532394.aspx
(书接上回,开讲!)

一、QoBean的元编程框架

===========

现在开讲“DSL in JavaScript,with QoBean’s meta programming framework”。先说说QoBean的元编程框架。这是一个仅仅100来行的小小框架,里面有几个关键函数是我们在讲DSL时要用到的:

  1. Weave(where, code):表示对于一个函数f,在指定where的位置,替换成代码code。如果where是正则表达式,则code中可以使用获取匹配;如果where是字符串,则表明将第一个查找到的该字符串替换成code。
  2. Block(func, tag):对函数func(或直接是它的代码文本)进行结构分析。tag标志为['body', 'param', 'name']之一时,返回该函数源代码相应位置的一个字符串;tag标志为’scope’时,返回一个字符串str,用eval(str)可以在当前位置生成一个新的、具有该代码上下文位置上的闭包的函数;tag标志为’anonymous’时,直接返回一个函数,但该函数是全局函数。对于tag是['scope','anonymous']之一的情况,所得到的新函数是传入参数func的一个完全相同的副本,只是新函数所在的闭包位置不同。
  3. Unique(obj):生成obj对象的一个唯一化的实例。新实例obj2具有原obj对象的全部属性,但修改新对象obj2的成员时,不会影响到原obj对象。这个过程,与Block(func, tag)调用时,tag为['scope','anonymous']之一的情况有类似之处:都是生成一个新的复制,不同的是Block针对函数,Unique针对对象。
  4. Scope(obj, func):使函数func(或直接是它的代码文本)执行在obj的对象闭包中。当func执行在obj的闭包中之后,func所访问到的变量名,即是obj的属性;func访问到的函数名,即是obj的方法。
  5. Owner(obj, func):使函数func(或直接是它的代码文本)执行在以obj为this对象的环境中。在JS中,当一个函数执行时,this关键字要么指向全局的window对象(func是普通函数);要么指向方法所属的对象实例(func是对象方法)。Owner()函数用于改变这种关系,使得函数func在执行时,this关键字总是指向obj。——一般来说,这个功能在其它的JS框架中被实现为Function.prototype.bind()。

QoBean的元编程系统中还有一些其它的函数,但对于我们讲DSL不关键,所以先不讨论。除了上述讨论的函数之外,我们在DSL部分不会用到其它的任何函数,也不会用到某种JavaScript引擎的独特功能——甚至不会用到arguments.caller。所以,我们在这里实现的DSL,可以跑在ECMS Script标准中的任何一个JavaScript引擎之中。

最后综述一下上面的五个函数。他们其实对于Meta Programming有着特殊的含义。

  1. Block(),其实是一个简单的Parser。他能够快速分析一个代码文本块,以使重新组织它。相当于我们在书写代码时的重构、改写。
  2. Unique()与Scope()是功能近似的函数,只是一个作用于函数,一个作用于对象。作用是得到一个复制,相当于我们书写代码时的ctrl + C操作。
  3. Scope()与Owner()也是功能近似的函数,前者用于改变代码的上下文,相当于书写代码时移动一段代码(例如把局部函数变成全局公共的),有点类似于ctrl+V操作;后者用于改变代码(作为对象方法时)的属主,相当于基类中的方法,或重构,或范型等等。

我们注意到,上面几个函数,事实上模拟了我们书写代码时的很多行为。在前面讲到过的文章中,我说到过“那么QoBean如何定义‘元语言’呢?QoBean对此有两项解释”:
– 元语言定义程序(program)的基础元素:算法与数据结构
– 元语言说明编程(programming)的基本方法:代码的组织形式

这里的五个函数,就是第二项解释中的“编程(书写程序)的基本方法”的抽象、实现。

二、DSL的基本设计

===========

现在我们来考虑一个“通用DSL”应该是什么样子,也就是如何设计它的问题。首先,它是一种语言——这很废话对吧?哈哈。其实不是,这是一个语言,表明它应该有语法、语义、语用的问题。语法就意味着需要一个解析器(parser);语义就意味着对于语言中的关键字要有功能实现,即要有执行器(evaluator);语用,就意味着说相同的话——相同的代码文本,在不同的环境下效果未必一致,所以也就意味着要有环境(environment)设定,亦即是“上下文相关文法”或“上下文无关文法”的问题。

这三个方面的问题有点令人挠头,但用个类比,就挺简单的。例如说“吃饭了吗”这句话,首先就包括汉语语法的问题,例如省略主语、疑问句和主谓结构等等。所以,我们可以改变一种新语法来陈述它,例如“饭,吃了吗”,或“吃了吗,饭”。这些,只是语法上的变化。说话的、写程序的人,先约定一种规则,然后按这个规则来理解它,就行了。

那么语用呢?或者说所谓的“上下文相关/无关”是什么意思呢?同样的,上面这句话,如果是早晨我跟你碰面在公司楼下,我问这句话的意义,跟说“Hello”,或者“今天天气不错”其实差不多,只是个问候语。但如果是朱镕基同学在汶川问某个老乡,那可就真是问“有饭吃没”。话是一样的话,语法是一样的语法,放在不同的环境中,语义上是有差别的。这个,就是语用学讨论的问题。我们用的计算机很笨,没有人那么复杂的思维能力,所以一般来说,要求我们设计的语言是“上下文无关的”,以便于将来开发出来一个机器人,你问“吃饭没”,他真的能回答你“电能充足”,而不是做泪流满面状。

所以,回到DSL的设计上来。所谓一个语言,也就是“通过某种规则来解析(parser)一段文本,将它执行(evaluator)在某个上下文环境(environment)”中。这个体系中,有一个东西是不变的,也就parser/evaluator/environment的关系。所以,一个新的dsl语言的产生过程,可以描述成这样的一个模式:

而这个语言执行——或说是讲述、表达、运行、生效——起来,则可以描述成下面这样一个模式:

至于这个语言的规则部分,是parser负责的;表述效果部分,是evaluator负责的。而要让JavaScript DSL对这个新的dsl起来“维护”作用的,应该是对语境的(语用的)设定——简单的说,我们要帮助新的语言管理上下文环境,其它的则由“创建语言”的人来做。

三、DSL的基本实现

===========

由于在

中,dsl最终是需要有调用能力的(表达成”dls(…)”的形式。所以

  1. DSL函数应该返回一个函数,并且它被执行在environment环境中;
  2. 考虑到dsl应该与JavaScript的环境无关,它的this对象应该指向environment而非window。

而上述两件事情,在QoBean meta programming中用两个函数来实现,即:

OK. 这个结构基本就完成了。但是还有个问题,就是上面Scope()调用中的“…”,他表明我们要在environment中执行代码的内容和方法。如何执行呢?简单的说,就是“先分析输入的代码,然后调用执行器执行它”。要实现这两个步骤,我们可以:

  1. 把它连在一起,
  2. 放在environment中去run一下。

就好了。这个“连在一起”的事情,就是Weave()函数能做的。所以完整的DSL()函数的代码是下面这样:

其中的Weave()调用表明:

  1. 将parser()函数的body部分,放到evaluator()函数的开始部分之前执行;
  2. 将上述的结果(代码文本),放在environment的scope闭包中执行。

OK。我们的“通用DSL语言生成器”就做完了。它只有两行代码。

四、示例

===========

这样的一个示例其实很简单。比如说我们想要有一种语言,它具有如下的性质:

  1. 可以调用一些函数;
  2. 可以访问一些预定义的值;
  3. (为了方便),我们假定它跟JavaScript的基本语法是一样的。

我们简单的用DSL来实现一下它,以便对这个QoBean’s DSL framework有个概要认识。它还相当不完善,下一段落里,我们再来补全这个DSL系统。

实现上面的这个小小的语言的方案是:

OK。结果出来了,显示97、194两个值。对于dsl()后面执行的代码来说,环境environment为他们准备了min/max/show/calc这四个标识符;myeval()提供了执行能力;myparser()则用于将dsl()调用传入的函数中的代码块取出来——之所以传入一个函数,是这样一来,就可以省了一个“语法分析器”(能当函数传入,当然是能通过JavaScript的语法分析过程的)。

先到这里,吃饭去也。下午来继续扩充这个过程,然后我们就知道一个完整的……相当完整的DSL()实现……其实也并不复杂了。

下一篇:

http://blog.csdn.net/aimingoo/archive/2009/09/08/4532567.aspx

分享到:
评论

相关推荐

    photoshop-cc-javascript-ref-2019.pdf

    1. **JavaScript在Photoshop中的应用**:JavaScript是一种广泛使用的脚本语言,它在Photoshop中允许用户通过编写脚本来自动化重复任务,创建自定义工作流程,以及扩展Photoshop的功能。这包括调整图像参数、处理图层...

    photoshop-cc-javascript参考2019

    JavaScript在Photoshop中的应用是通过ECMAScript实现的,这是一种基于标准的、广泛使用的脚本语言,它为Photoshop提供了强大的编程接口(API),使得开发者可以深入操控图像处理、图层管理、颜色调整等多个方面。...

    photoshop-cc-javascript-ref-2015.pdf

    首先,JavaScript在Photoshop CC中的核心功能是提供一个脚本接口,允许开发者直接操控Photoshop的对象模型。对象模型包含了所有可用的面板、菜单项、图层、选区等元素,可以通过JavaScript进行访问和操作。例如,你...

    Photoshop-CS6-JavaScript.zip

    2. **Photoshop对象模型**:JavaScript在Photoshop中的工作原理是通过与Photoshop的对象模型交互。对象模型包含了所有可以操作的元素,如文档、图层、选区等。了解这些对象及其属性和方法是编写有效脚本的关键。 3....

    04-JavaScript脚本语言基础(二)DOM(L)

    04-JavaScript脚本语言基础(二)DOM(L)

    网页javascript脚本语言提取器

    JavaScript是一种广泛应用于网页开发的脚本语言,它允许在用户浏览器上动态地更新内容,实现交互性和动画效果。"网页JavaScript脚本语言提取器"是一个工具,专门设计用于从网页中抓取并分析JavaScript代码,这在进行...

    基于神经网络的恶意脚本分类-JavaScript&VBScript.pdf

    基于神经网络的恶意脚本分类-JavaScript&VBScript Neural Classification of Malicious Scripts: A study with JavaScript and VBScript

    Photoshop-CS6-JavaScript-Ref

    《Photoshop CS6 JavaScript 脚本参考指南》是一份由Adobe Systems Incorporated出版的专业文档,旨在为使用Adobe Creative Suite 6中的Photoshop软件进行JavaScript脚本编程的用户提供全面的指导和参考。...

    WEB中javascript脚本语言

    JavaScript是一种广泛使用的脚本语言,主要用于Web前端开发,可以实现动态效果、交互功能等。JavaScript与HTML和CSS一起构成了现代Web开发的基础。 #### 二、基本示例 1. **生成文本** ```html ...

    项目14-JavaScript脚本编程.pptx

    项目14-JavaScript脚本编程.pptx

    JavaScript应用实例-脚本商店界面-增加点击事件.js

    JavaScript应用实例-脚本商店界面-增加点击事件.js

    纯Java 实现的一个脚本语言 语法类似javascript.zip

    标题中的“纯Java实现的一个脚本语言 语法类似javascript.zip”揭示了这是一个使用Java编程语言构建的脚本引擎,其语法设计受到了JavaScript的影响。这意味着它可能提供了一个在Java环境中执行类似JavaScript语法的...

    廖雪峰-JavaScript教程-PDF版

    JavaScript作为世界上最流行的脚本语言之一,在Web开发领域占据着举足轻重的地位。无论是个人开发者还是大型企业,都离不开JavaScript的支持。本教程旨在帮助初学者快速掌握JavaScript的基础知识,同时也适合有一定...

    奔梦向前-脚本循环代码-2020-04-28-2.zip

    奔梦向前:学编程其实很简单,html、css、JavaScript、html5、css3、vue、Canvas实现网页特效页面、新手入门学习、了解网页动画的制作、代码实现网页动态画面-脚本循环代码-2020-04-28-2。

    如何在C 程序中嵌入JavaScript脚本语言.pdf

    "如何在C++程序中嵌入JavaScript脚本语言" 本文主要介绍了如何在C++程序中嵌入JavaScript脚本语言,旨在帮助开发人员更好地理解和实现脚本语言在C++程序中的嵌入。 首先,文章简要介绍了脚本语言的兴起和重要性,...

    奔梦向前-表白代码脚本-2020-04-28-1.zip

    奔梦向前:学编程其实很简单,html、css、JavaScript、html5、css3、vue、Canvas实现网页特效页面、新手入门学习、了解网页动画的制作、代码实现网页动态画面-表白代码脚本-2020-04-28-1。

    CGI脚本入门学习--HTML格式

    你应该用什么编程语言? 你的服务器设置正确吗? 如果你的服务器不是UNIX系统呢? 解剖CGI脚本 输出头部 输出数据部 带阐述的脚本 传递其他信息给脚本 创建特殊的脚本输出 以装载另一个文本响应 无响应 ...

    浅谈关于JavaScript脚本语言的学习.pdf

    "浅谈关于JavaScript脚本语言的学习" JavaScript脚本语言的基本特点: 1. 简单性:JavaScript是一种解释性语言,不需要提前进行编译,在程序运行过程中由浏览器边解释边执行,因此不需要额外的运行环境。 2. 跨...

    如何在C++程序中嵌入JavaScript脚本语言.pdf

    如何在C++程序中嵌入JavaScript脚本语言.pdf

    javascript课件-javascript初步

    JavaScript是一种轻量级的、基于对象和事件驱动的脚本语言,主要应用于Web页面中,为用户提供交互式体验。它由Netscape公司开发,起初名为Live Script,后来改名为JavaScript,以利用当时流行的Java语言的知名度。...

Global site tag (gtag.js) - Google Analytics