微软的VBScript ,JavaScript尽管好用,但是由于不支持私有命名项,故对于大量脚本存在的工程来说,脚本的管理就尤为困难.最近网上看到某公司由国人实现一种脚本语言,这里简称为V-G脚本语言,它实现了面向对象,支持类似VBscript的易语言书写,支持私有的命名项,对VBScript的某些关键字进行了简化, 重要的是脚本管理起来简单多了. 这里摘抄一段供大家分析欣赏:其中红色部分为从属于一个对象实例的脚本.<sheet name="MainMenuItem" visible="false" submenu="">
<rect name="rect1" origin="148,123" bounds="72,107,126,127" backcolor="$8000000D" pattern="1"/>
<text name="Text1" origin="76,99.25" bounds="76,109,122,125" backcolor="$8000000F" autosize="true" border="0" fontname="宋体" fontsize="12" fontcolor="$80000012" textalign="4" text="File(F)"/>
<programe>
<!--
property Caption read GetCaption write SetCaption
property Enable read GetEnable write SetEnable editor Bool
property Focused read GetFocused write SetFocused editor Bool
private function GetCaption()
return Text1.Text
end function
private function GetEnable()
return Enabled
end function
private function GetFocused()
return Text1.BackColor = $8000000D
end functionprivate function OnMouseEnter(Sender)
i = 0
while i < Parent.UnitCount
d = Parent.Units[i]
if d <> this and d.Type = "MainMenuItem" then
if d.Shown() then
Focused = true
PopDoc()
return
end if
end if
i = i + 1
wend
Focused = true
end function
private function OnMouseExit(Sender)
Focused = false
end function -->
</programe>
</sheet>
<sheet name="MenuPanel" visible="false">
<rect name="Rect1" origin="88,48" bounds="0,0,172,215" backcolor="$80000004" pattern="1"/>
<line name="Line1" origin="89,49" linecolor="$80000014" points="1,214,6 1,1,2 171,1,2"/>
<line name="Line2" origin="89,49" linecolor="$80000010" points="1,214,6 171,214,2 171,1,2"/>
<programe>
<!--
private function OnResize(Sender)
if Width < 3 then
Width = 3
end if
if Height < 3 then
height = 3
end if
Rect1.SetBounds( Left, Top, Width, Height )
Line1.SetBounds( Left + 1, Top + 1, Width - 2, Height - 2 )
Line2.SetBounds( Left + 1, Top + 1, Width - 2, Height - 2 )
end function
-->
</programe>
</sheet>
<sheet name="Separator" visible="false">
<line name="Line3" origin="78.909091,0.545455" linecolor="$80000010" backcolor="$8000000A" points="0,0,6 152,0,2"/>
<line name="Line4" origin="78.909091,1.545455" linecolor="$80000014" backcolor="$8000000A" points="0,1,6 152,1,2"/>
</sheet>
请问哪位高人知道这是如何实现的吗?
<rect name="rect1" origin="148,123" bounds="72,107,126,127" backcolor="$8000000D" pattern="1"/>
<text name="Text1" origin="76,99.25" bounds="76,109,122,125" backcolor="$8000000F" autosize="true" border="0" fontname="宋体" fontsize="12" fontcolor="$80000012" textalign="4" text="File(F)"/>
<programe>
<!--
property Caption read GetCaption write SetCaption
property Enable read GetEnable write SetEnable editor Bool
property Focused read GetFocused write SetFocused editor Bool
private function GetCaption()
return Text1.Text
end function
private function GetEnable()
return Enabled
end function
private function GetFocused()
return Text1.BackColor = $8000000D
end functionprivate function OnMouseEnter(Sender)
i = 0
while i < Parent.UnitCount
d = Parent.Units[i]
if d <> this and d.Type = "MainMenuItem" then
if d.Shown() then
Focused = true
PopDoc()
return
end if
end if
i = i + 1
wend
Focused = true
end function
private function OnMouseExit(Sender)
Focused = false
end function -->
</programe>
</sheet>
<sheet name="MenuPanel" visible="false">
<rect name="Rect1" origin="88,48" bounds="0,0,172,215" backcolor="$80000004" pattern="1"/>
<line name="Line1" origin="89,49" linecolor="$80000014" points="1,214,6 1,1,2 171,1,2"/>
<line name="Line2" origin="89,49" linecolor="$80000010" points="1,214,6 171,214,2 171,1,2"/>
<programe>
<!--
private function OnResize(Sender)
if Width < 3 then
Width = 3
end if
if Height < 3 then
height = 3
end if
Rect1.SetBounds( Left, Top, Width, Height )
Line1.SetBounds( Left + 1, Top + 1, Width - 2, Height - 2 )
Line2.SetBounds( Left + 1, Top + 1, Width - 2, Height - 2 )
end function
-->
</programe>
</sheet>
<sheet name="Separator" visible="false">
<line name="Line3" origin="78.909091,0.545455" linecolor="$80000010" backcolor="$8000000A" points="0,0,6 152,0,2"/>
<line name="Line4" origin="78.909091,1.545455" linecolor="$80000014" backcolor="$8000000A" points="0,1,6 152,1,2"/>
</sheet>
请问哪位高人知道这是如何实现的吗?
如果说它是自己独创的语言,就像采用LEX/yacc那样,那么是否有这方面的高人讲讲这方面的进行思路?
1、这个关键字是必须的吗?如果没有这个关键字,是否某些功能就无法实现?
2、这个关键字能给开发者节省多少工作量?
3、关键字跟其它关键字有没有功能重叠?在解析上会不会产生二义性?
4、关键字必须在上下文中是易懂的,不仅人易懂,也得机器易懂
5、property Enable read GetEnable write SetEnable editor Bool 这句里面的关键字有多少?按我的猜测,property read write editor都是关键字,谁见过哪个语言中一个语句需要这么多关键字的?记住关键字越少越好,关键字越多,产生二义性的机会就越大。随便加个干扰字,能马上准确识别出干扰字吗?从我对脚本语言的了解来看,这段代码中的语言设计得很不好,最大的问题是关键字滥用。如果是我设计,我可能设计成这样:
private function Get Caption()
return Text1.Text
end functionprivate function Set Caption(v)
Text1.Text = v
end function这里只有Get和Set两个关键字,甚至可以不要关键字,根据方法里面有没有参数来确定是Get还是Set,因为解释器能够识别出来的尽量不要增加编程者的工作量和记忆量。参考一下VB中是如何设计事件响应函数的:function Form1_OnLoad(...),函数名称用“对象名_事件名”就搞定了,哪里需要额外的语法?
我希望国人能搞出自己的语言,但首先要清楚和其它语言的区别在哪里,能解决哪些其它语言解决不了的问题。否则,没有更好的理由,推广就是一个大问题。
你自己知道答案的话,为什么不自己说出来大家一起分享?
简单的看了下V-G的介绍,感觉并不是那么神奇。当然,东西是非常不错的,只是还不至于楼主说的那么一个高度而已。就这一套脚本机制,从关键字选择和组织方式来看,几乎完全照搬了delphi的语法。这个独创性就大打折扣了。当然也没什么不好,借鉴好的对象模型嘛。以这家公司的产品和楼主列出的实际示例来推测,这个脚本引擎不大可能是什么崭新的东东,顶多是在现有jscript, vbscript脚本引擎上自己封装了一层,加了点东西而已。 这么说有人可能不服,但是说实在的 1,这家公司的产品虽然很不错,但是要独立创立一套语言引擎,实力还差点。2,就算有那么多的牛人也未必有那个财力投入来研究这些底层的东东。 3,如果完全没必要做一个全新的东东,为什么要去做呢。从目前实现的功能来看,如果让我来指导的话,一个稍具com经验的程序员都能在不长的时间内完成。至于 私有命名项, jsscript, vbscript的脚本引擎毫无疑问是支持的(楼主不看msdn的么?)。并且这一套“国产脚本引擎”多半就是基于这一jsscript,vbscript机制实现的。
1、简易性
<text name="Text1" origin="76,99.25" bounds="76,109,122,125" backcolor="$8000000F" autosize="true" border="0" fontname="宋体" fontsize="12" fontcolor="$80000012" textalign="4" text="File(F)"/>
<programe>
<!--
property Caption read GetCaption write SetCaption
property Enable read GetEnable write SetEnable editor Bool
property Focused read GetFocused write SetFocused editor Bool
private function GetCaption()
return Text1.Text
end function
private function GetEnable()
return Enabled
end function
private function GetFocused()
return Text1.BackColor = $8000000D
end function private function OnMouseEnter(Sender)
i = 0
while i < Parent.UnitCount
d = Parent.Units[i]
if d <> this and d.Type = "MainMenuItem" then
if d.Shown() then
Focused = true
PopDoc()
return
end if
end if
i = i + 1
wend
Focused = true
end function
private function OnMouseExit(Sender)
Focused = false
end function -->
</programe>
且看HTML中的实现:
<text name="Text1" onmouseover="this.Focused=true" onmouseout="this.Focused=false" ... />2、自定义属性和方法
property Caption read GetCaption write SetCaption
property Enable read GetEnable write SetEnable editor Bool
property Focused read GetFocused write SetFocused editor Bool
private function GetCaption()
return Text1.Text
end function
private function GetEnable()
return Enabled
end function
private function GetFocused()
return Text1.BackColor = $8000000D
end function
HTML中的使用方法(我对JS比VBS更熟,所以暂时以JS为例):
Text1.Text = "abc";
var t = Text1.Text;
if (Text1.Focused)
Text1.BackColor = ...;
不得不解释一下,在JS和VBS中,自定义属性都是天然就具备的,了解一下IDispatchEx接口去。3、私有命名项
不想再解释了,不如先由楼主告诉我什么是命名项吧,再告诉我JS/VBS为什么不支持私有命名项。顺便给我解释一下HTML的脚本代码中为何能调用setTimeout(),也能调用window.setTimeout()4、即使是使用时间最长的C/C++语言,到现在都有无数人在骂。想想看这个社会接受一种新语言有多难,更不用说去评价一种语言好坏了。楼主好自为之吧。
关于私有命名项:
请大家注意看我摘抄的内容,两段脚本是分别从属于两个对象的实例的,第一段是属于"MainMenuItem"私有的,注意不是像楼上的理解为从属于Text1的, 这有本质的区别,详见后面的分析;第二段是属于"MenuPanel"私有的.
为什么说有本质的区别呢?
V-G中的"Text1"可以作为一个私有命名项出现在命名项"MainMenuItem"的脚本里,并注意"Text1"这个命名项不指向一个脚本内部创建的对象,是外部引入的com元素,通常采用AddNameItem加载,由GetItemInfo来映射这个元素;而HTML的windowX和textX都是依靠脚本内部语句来创建的元素,这只能算是私有成员,不能讲是私有命名项.
再请大家看看我摘抄的内容,第二段脚本里有一个对于Rect1的操作Rect1.SetBounds,它表示对于MenuPanel的Rect1呢还是MainMenuItem的Rect1呢? 很显然是对于MenuPanel的Rect1.这两段脚本运行时都加载到内存中待命,引擎要能区别这两端脚本中可能重名的命名项,这是问题的关键.
Private html,Strings,pic
Private Sub Class_Initialize()end sub Private Sub class_terminate()end subPrivate Property Let Value(ByVal vNewValue)
'Do something
End PropertyEnd Class
这个你怎么解释呢?
而且你说得V-G我感觉就是从vbs改装过来,借鉴了Asp.net的后台代码前台实现或者说是类似asp那种方式。第三:LZ所说的“私有命名项”说实话我不是很理解,你是说私有函数呢,还是私有变量?抑或是别的什么新名词?不妨您来解释下给我听第四:您说的TextBox1我不得不说设计得很巧妙,做这套语言的人确实花了很多功夫。但是,JS调COM那是再简单不过的了,问题是看您怎么掉。你突然代码中就这么个冒出来个,系统就能从一堆COM中去找?那也太智能化了?怎么说也给个接口或是ID吧?不然去哪里找?随客户嘴说吗?第五:“第二段脚本里有一个对于Rect1的操作Rect1.SetBounds,它表示对于MenuPanel的Rect1呢还是MainMenuItem的Rect1呢? 很显然是对于MenuPanel的Rect1.这两段脚本运行时都加载到内存中待命,引擎要能区别这两端脚本中可能重名的命名项,这是问题的关键. ”这太简单了。嵌套在哪个元素中的Programe的标记就作为该标记的父的结构的成员不就OK了? 面向对象的么
1 你说的类与要讨论的命名项问题是两回事,类里面可以采用命名项引入的元素,但同样存在私有命名项的问题.
2 再次说说私有命名项:对于同一个VBS或JS脚本引擎来说,通过AddNameItem引入的命名项具有全局特性,命名项重复引入就容易出现错乱问题.换句话说,VBS或JS脚本引擎不支持某个域范围的命名项. 不知你用过AddNameItem没有?
3 不知道你所讲的"嵌套在哪个元素中的Programe的标记就作为该标记的父的结构的成员"是如何实现的?
<rect name="rect1" origin="148,123" bounds="72,107,126,127" backcolor="$8000000D" pattern="1"/>
<text name="Text1" origin="76,99.25" bounds="76,109,122,125" backcolor="$8000000F" autosize="true" border="0" fontname="宋体" fontsize="12" fontcolor="$80000012" textalign="4" text="File(F)"/>
<programe> </programe>
</sheet> programe不是在sheet中么,那么就属于它的集合元素中和<div>里面嵌套<form>而<form>里面又嵌套<table>一样,父子级传递下来
2、当脚本引擎用在IE中时,浏览器控件会向脚本引擎添加window和form命名项对象,这些对象都是DOM对象,不是引擎内部创建的,全部由MSHTML自己来管理,引擎只负责解释脚本并调用这些对象的方法。
3、从一个命名项对象直接定位另一个对象的功能也是由mshtml提供的,根本无需向引擎中注入如此之多的命名项,除非想消耗更多的内存,况且脚本引擎并没有提供类似RemoveNamedItem的方法,万一你的对象必须删除怎么办?怎么从引擎中释放它占用的内存?
下面有一个最好的解释代码,实现的功能应该跟楼主的要求一致。<html>
<body>
<form name="form1">
<input name="input1" type="text" />
<script>
input1.value = "hello world";
</script>
</form>
</body>
</html>请看上面的红色脚本代码,
input1 算不算“私有命名项”?跟你需要的功能是不是相同?
它是引擎创建的对象吗?不是。input1 是 form 下的一个input元素,也是外部元素。
input1 需要调用AddNamedItem添加进来吗?不需要,因为脚本代码运行在 form1 的上下文里。
input1 是 form1 对象的属性吗?不是,它只是 form1 下的一个子孙元素名称而已。
既然 input1 对象既不需要AddNamedItem添加,也不是 form1 对象的属性,为什么还能直接使用?因为mshtml有这个能力,它提供了IHTMLFormElement3::namedItem()方法。
为什么脚本引擎知道要调用IHTMLFormElement3::namedItem()方法而不是别的什么方法来获取 input1 对象?对不起,我知道原因,但不想说,因为能设计自己的脚本引擎的人一定知道原因,根本无需我说出来。最后,我还有一个问题一直不解:你说你用到了AddNamedItem来添加外部对象,说明你使用了系统提供的脚本引擎(VBS或者JS),但是你又说V-G脚本语言的关键词比VBS少,我很想知道V-G是如何从系统脚本引擎中把多余的关键词抠掉了的。本人愚钝,还请赐教方法。再次申明:纯粹技术讨论!