|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
最后就是我对java的几点希望:首先是IDE工具,有人说java已经很好了,有jbuilder,eclipse,netBeans等等,但是我认为如果java想超越.net,那么他首先要解决的就是IDE工具的整合。计划1、引子
实在没有甚么好的例子引进注释器形式,由于它形貌了怎样组成一个复杂的言语注释器,次要使用在利用面向对象言语开辟编译器中;在实践使用中,我们大概很少碰着往机关一个言语的文法的情形。
固然你几近用不到这个形式,可是看一看仍是能遭到必定的启示的。
2、界说与布局
注释器形式的界说以下:界说言语的文法,而且创建一个注释器来注释该言语中的句子。它属于类的举动形式。这里的言语意义是利用划定格局和语法的代码。
在GOF的书中指出:假如一种特定范例的成绩产生的频次充足高,那末大概就值得将该成绩的各个实例表述为一个复杂言语中的句子。如许就能够构建一个注释器,该注释器经由过程注释这些句子来办理该成绩。并且当文法复杂、效力不是关头成绩的时分效果最好。
这也就是注释器形式使用的情况了。
让我们来看看奥秘的注释器形式是由甚么来构成的吧。
1)笼统表达式脚色:声明一个笼统的注释操纵,这个接口为一切详细表达式脚色(笼统语法树中的节点)都要完成的。
甚么叫做笼统语法树呢?《java与形式》中给的注释为:笼统语法树的每个节点都代表一个语句,而在每一个节点上都能够实行注释办法。这个注释办法的实行就代表这个语句被注释。因为每个语句都代表这个语句被注释。因为每个语句都代表一个罕见的成绩的实例,因而每个节点上的注释操纵都代表对一个成绩实例的解答。
2)闭幕符表达式脚色:详细表达式。
a)完成与文法中的闭幕符相干联的注释操纵
b)并且句子中的每一个闭幕符必要该类的一个实例与之对应
3)非闭幕符表达式脚色:详细表达式。
a)文法中的每条划定规矩R::=R1R2…Rn都必要一个非闭幕符表带式脚色
b)关于从R1到Rn的每一个标记都保护一个笼统表达式脚色的实例变量
c)完成注释操纵,注释一样平常要递回地挪用暗示从R1到Rn的那些对象的注释操纵
4)高低文(情况)脚色:包括注释器以外的一些全局信息。
5)客户脚色:
a)构建(大概被给定)暗示该文法界说的言语中的一个特定的句子的笼统语法树
b)挪用注释操纵
放上张注释器布局类图吧,这也是来自于GOF的书中。
对每个脚色都给出了具体的职责,并且在类图中给出五个脚色之间的干系。如许完成起来也不是很坚苦了,上面举了一个复杂的例子,但愿能加深你对注释器形式的了解。
3、举例
来举一个加减乘除的例子吧,完成思绪来自于《java与形式》中的例子。每一个脚色的功效依照下面提到的标准来完成。
//高低文(情况)脚色,利用HashMap来存储变量对应的数值
classContext
{
privateMapvalueMap=newHashMap();
publicvoidaddValue(Variablex,inty)
{
Integeryi=newInteger(y);
valueMap.put(x,yi);
}
publicintLookupValue(Variablex)
{
inti=((Integer)valueMap.get(x)).intValue();
returni;
}
}
//笼统表达式脚色,也能够用接口来完成
abstractclassExpression
{
publicabstractintinterpret(Contextcon);
}
//闭幕符表达式脚色
classConstantextendsExpression
{
privateinti;
publicConstant(inti)
{
this.i=i;
}
publicintinterpret(Contextcon)
{
returni;
}
}
classVariableextendsExpression
{
publicintinterpret(Contextcon)
{
//this为挪用interpret办法的Variable对象
returncon.LookupValue(this);
}
}
//非闭幕符表达式脚色
classAddextendsExpression
{
privateExpressionleft,right;
publicAdd(Expressionleft,Expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(Contextcon)
{
returnleft.interpret(con)+right.interpret(con);
}
}
classSubtractextendsExpression
{
privateExpressionleft,right;
publicSubtract(Expressionleft,Expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(Contextcon)
{
returnleft.interpret(con)-right.interpret(con);
}
}
classMultiplyextendsExpression
{
privateExpressionleft,right;
publicMultiply(Expressionleft,Expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(Contextcon)
{
returnleft.interpret(con)*right.interpret(con);
}
}
classDivisionextendsExpression
{
privateExpressionleft,right;
publicDivision(Expressionleft,Expressionright)
{
this.left=left;
this.right=right;
}
publicintinterpret(Contextcon)
{
try{
returnleft.interpret(con)/right.interpret(con);
}catch(ArithmeticExceptionae)
{
System.out.println("被除数为0!");
return-11111;
}
}
}
//测试程序,盘算(a*b)/(a-b+2)
publicclassTest
{
privatestaticExpressionex;
privatestaticContextcon;
publicstaticvoidmain(String[]args)
{
con=newContext();
//设置变量、常量
Variablea=newVariable();
Variableb=newVariable();
Constantc=newConstant(2);
//为变量赋值
con.addValue(a,5);
con.addValue(b,7);
//运算,对句子的布局由我们本人来剖析,机关
ex=newDivision(newMultiply(a,b),newAdd(newSubtract(a,b),c));
System.out.println("运算了局为:"+ex.interpret(con));
}
}
注释器形式并没有申明怎样创立一个笼统语法树,因而它的完成能够多种多样,在下面我们是间接在Test中供应的,固然另有更好、更专业的完成体例。
关于闭幕符,GOF倡议接纳享元形式来共享它们的拷贝,由于它们要屡次反复呈现。可是思索到享元形式的利用范围性,我倡议仍是当你的体系中闭幕符反复的充足多的时分再思索享元形式。
4、优弱点
注释器形式供应了一个复杂的体例来实行语法,并且简单修正大概扩大语法。一样平常体系中良多类利用类似的语法,可使用一个注释器来取代为每个划定规矩完成一个注释器。并且在注释器中分歧的划定规矩是由分歧的类来完成的,如许使得增加一个新的语律例则变得复杂。
可是注释器形式关于庞大文法难以保护。能够设想一下,每个划定规矩要对应一个处置类,并且这些类还要递回挪用笼统表达式脚色,多如乱麻的类交叉在一同是何等可怕的一件事啊!
5、总结
如许对注释器形式应当有了些大致的熟悉了吧,因为这个形式利用的案例匮乏,以是本文年夜部分概念间接来自于GOF的原著。只是实例代码是亲身完成并调试经由过程的。
C#跟java类似,但是在跨平台方面理论上可以跨平台,实际上应用不大,执行性能优于java,跟C++基本一致,但是启动速度还是慢.代码安全,但容易性能陷阱. |
|