摘要: 这篇是这个系列的最后一篇了,对于BlockExpression不再深入展开了,只对之前的泛型调用支持及typeof操作补漏。这次是进一步完善了grammar,现在能正常解析泛型调用及typeof操作,这使得我们能对这2种表达式进行正确的转换了。大家可以从http://tinynetevent.googlecode.com/files/ExpressionParser0809.zip下载到最新的代码。由于对grammar作了一点修正,所以之前PareeTreeNode的扩展方法GetClrType也需要跟着改了:view plaincopy to clipboardprint?public st 阅读全文
posted @ 2011-10-13 22:50 小芒果 阅读(509) 评论(0) 推荐(0) 编辑
摘要: C#里用来创建对象的方式有以下几种调用构造函数 new obj(...)初始化成员列表 new obj { f1 = xxx, f2 = xxx, ... }创建数组 new arraytype[] { e1, e2, e3, ...}如果是匿名对象话,创建方式只有后2种。非匿名对象的创建:view plaincopy to clipboardprint?private Expression ProcessNewExpression(ParseTreeNode expNode) { var typeName = expNode.GetChild("qual_name_with_tar 阅读全文
posted @ 2011-10-13 22:49 小芒果 阅读(1459) 评论(0) 推荐(0) 编辑
摘要: 成员访问的解析稍微有点复杂,从字符串角度看,访问一个实例的成员有三种形式:访问成员字段或属性 instance.field instance.property访问索引器 instance[]访问方法 instance.method(...)在解析的时候就按这三种形式进行解析,目前由于grammar修改的不完美所以还不支持显示进行泛型方法的调用。view plaincopy to clipboardprint?private Expression ProcessMemberAccessExpression(ParseTreeNode expNode) { Expression self = nu 阅读全文
posted @ 2011-10-13 22:48 小芒果 阅读(635) 评论(0) 推荐(0) 编辑
摘要: 在讲述如何解析转换成员访问表达式之前,先来讲一些预备知识。一个标准的lambda表达式应该是( 参数列表 ) => 表达式或表达式块其中参数列表和方法的参数列表类似,不过lambda表达式更灵活,允许用的时候不用显示声明参数的类型甚至在一个参数的时候括号也可以不用加,也就是(int a) => ... 和 (a)=> ... 以及 a=> ... 都是允许的。我们之前说了不少表达式的解析,都是针对lambda表达式的右半边进行的。对于左半边的参数列表的解析是非常简单的,不过最大的问题在于解析之后如何把参数应用到表达式中。从语言特性上来说,C#里所有变量是不会影响在它范围 阅读全文
posted @ 2011-10-13 22:47 小芒果 阅读(546) 评论(0) 推荐(0) 编辑
摘要: 一元、二元、三元运算符的转换大多都非常有规律,先看这个一元树:主要就是一个运算符跟一个表达式,转换起来很简单:view plaincopy to clipboardprint?private Expression ProcessUnaryExpression(ParseTreeNode expNode) { string op; var first = expNode.FirstChild; var second = expNode.LastChild; switch (first.GetName()) { case "unary_operator": op = first 阅读全文
posted @ 2011-10-13 22:46 小芒果 阅读(401) 评论(0) 推荐(0) 编辑
摘要: 接 上篇的常量表达式的转换,接下来要讲的是怎么产生操作运算表达式。和C#通常意义上的3种操作符不同,我们的grammar把类型转换操作()从unary expression里拿出来独立成一个typecast_expression,也就是说要转换的操作符节点有4种。而且对于unary expression来说也有特别的地方,++,-- 这2个操作符不属于unray_operator下,grammar是把它们独立成pre_incr_decr_expression和post_incr_decr_expression 2块单独处理。还有就是在C#里as这个操作符是被定义成一元的,而我们的grammar 阅读全文
posted @ 2011-10-13 22:45 小芒果 阅读(2514) 评论(0) 推荐(0) 编辑
摘要: 在继续探讨如何生成Expression前先对委托和表达式关系做下简单介绍,方便更好的理解后面的内容。.net提供的Expression涵盖的表达式范围很大,从一般的含操作符表达式到带语句的表达式都支持,比如像if, foreach, try ... catch这些都可以成为表达式的一部分,但是带语句体的表达式很难被转换成SQL语句,而expression很大程度上是为LINQ服务的,所以VS编译的时候是不支持静态编译带语句体的表达式的,所有带语句体的表达式都会被直接编译成执行代码也就是做成一个委托,这样做的好处一来是简化编写DLINQ provider的工作,二来也是能消除歧义。比如void 阅读全文
posted @ 2011-10-13 22:44 小芒果 阅读(769) 评论(0) 推荐(0) 编辑
摘要: 当你要把一个表达式字符串转换成一个lambda expression,本篇也许能帮到你。把一个字符串解析成lambda要做的工作其实就2个,第一步把字符串通过语法解析转换一颗语法树,第二步就是遍历这棵树把它转换成.lambda expression。做一个C#语法解析器是件麻烦事,好在有一些现成的解析器可以使用,这里选用Irony来完成这个工作。Irony的包里含有一个Sample的C# grammar,这个grammar除了不支持linq外已经非常完整了,接下来只要稍微修改下就能用来解析C#的表达式。sample里默认的C# grammar对表达式支持不完善的地方有:1.不能把强类型转换解析 阅读全文
posted @ 2011-10-13 22:43 小芒果 阅读(962) 评论(1) 推荐(0) 编辑