lambda表达式的解析(三) 类型转换表达式
2011-07-29 15:55
211 查看
接 上篇的常量表达式的转换,接下来要讲的是怎么产生操作运算表达式。
和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则视它为二元操作符。
类型转换的操作很简单,这是grammar树:
![](http://hi.csdn.net/attachment/201107/29/729107_1311926509k8H9.png)
在这里是做了一个int到int?的强类型转换,所以可以看type_ref里有一个qmark_opt,这表明是个nullable类型。
转换入口:
具体转换代码:
可以看到这里为了取到要被强类型转换的对象,采用了递归调用ProcssExpression处理方式,而子节点里是一个literal,所以子节点会返回一个ConstantExpression。而GetClrType是treenode的扩展方法,它的代码在第一章里有提到。
就是根据type_ref子节点返回正确的clr类型。其中ExpressionParser.GetType方法如下:
就是通过typename得到Type,这里要注意的是int、char、string这些内建类型的名字并不是int、char、string,所以会有个knownTypes表来帮助返回正确的类型:
正确的类型和正确的对象,创建个ConvertExpression也就非常简单了
和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则视它为二元操作符。
类型转换的操作很简单,这是grammar树:
![](http://hi.csdn.net/attachment/201107/29/729107_1311926509k8H9.png)
在这里是做了一个int到int?的强类型转换,所以可以看type_ref里有一个qmark_opt,这表明是个nullable类型。
转换入口:
case "typecast_expression": return ProcessConvertExpression(expNode);
具体转换代码:
private Expression ProcessConvertExpression(ParseTreeNode expNode) { var type = expNode.GetChild("typecast_parenthesized_expression").GetClrType(); var exp = ProcessExpression(expNode.GetChild("primary_expression")); return Expression.Convert(exp, type); }
可以看到这里为了取到要被强类型转换的对象,采用了递归调用ProcssExpression处理方式,而子节点里是一个literal,所以子节点会返回一个ConstantExpression。而GetClrType是treenode的扩展方法,它的代码在第一章里有提到。
public static Type GetClrType(this ParseTreeNode node) { if (node.HasChild("type_ref")) { var isNullable = node.GetDescendant("qmark_opt").FindTokenAndGetText() == "?"; var typeName = node.FindTokenAndGetText(); var type = ExpressionParser.GetType(typeName); if (isNullable) return typeof(Nullable<>).MakeGenericType(type); return type; } return null; }
就是根据type_ref子节点返回正确的clr类型。其中ExpressionParser.GetType方法如下:
internal static Type GetType(string typeName) { var type = Type.GetType(typeName); if (type == null) knownTypes.TryGetValue(typeName, out type); return type; }
就是通过typename得到Type,这里要注意的是int、char、string这些内建类型的名字并不是int、char、string,所以会有个knownTypes表来帮助返回正确的类型:
private static ConcurrentDictionary<string, Type> knownTypes = new ConcurrentDictionary<string, Type>(); #region BuiltinTypes knownTypes["bool"] = typeof(bool); knownTypes["sbyte"] = typeof(sbyte); knownTypes["byte"] = typeof(byte); knownTypes["short"] = typeof(short); knownTypes["ushort"] = typeof(ushort); knownTypes["int"] = typeof(int); knownTypes["uint"] = typeof(uint); knownTypes["long"] = typeof(long); knownTypes["ulong"] = typeof(ulong); knownTypes["float"] = typeof(float); knownTypes["double"] = typeof(double); knownTypes["char"] = typeof(char); knownTypes["string"] = typeof(string); knownTypes["decimal"] = typeof(decimal); knownTypes["object"] = typeof(object); knownTypes["void"] = typeof(void); #endregion
正确的类型和正确的对象,创建个ConvertExpression也就非常简单了
相关文章推荐
- (转)lambda表达式的解析(三) 类型转换表达式
- lambda表达式的解析(五) Lambda表达式与闭包类型
- (转)lambda表达式的解析(五) Lambda表达式与闭包类型
- Java 8 动态类型语言Lambda表达式实现原理解析
- 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型
- 无法将lambda表达式转换为类型“System.Delegate”
- 无法将 lambda 表达式 转换为类型“System.Delegate”,因为它不是委托类型
- javascript各种类型数据在表达式中转换成布尔型值的规则总结
- C++11 lambda 表达式解析
- C++11 lambda 表达式解析
- C++11 lambda 表达式解析
- 表达式类型转换问题
- C++11 lambda 表达式解析
- C++11 lambda 表达式解析
- C++11 lambda 表达式解析
- C++11 lambda 表达式解析
- 小白Java笔记——基本类型的类型转换和表达式类型的自动提升
- CYQ.Data 数据框架 V5 的语法糖 外置开源原理解析 [类似lambda表达式]
- (转)lambda表达式的解析(四) 运算符表达式
- C++11 lambda 表达式解析