文章介绍:Sexy Lexing with Python

这里:http://www.evanfosmark.com/2009/02/sexy-lexing-with-python/

最近玩了玩Python,有优点、有缺点, 一个比较有意思的事情是,有新的风格、信仰和教条。数数我比较认真的使用过的语言,如果按照现在普遍的简历写法,可以算“精通”甚至“专家”的也不算少了;所以现在能比较可观的看待这些事。接下来的一步是将这些经验升华为一种真正的语言表现能力(针对人类来说)的评估系统,不过这就是个漫长的道路了。

了解我的都知道,我最不爱碰的语言是Java,其实这倒不是说Java有什么明显的缺点,就是Java语言社区太强势了,强势的有点不知道天高地厚。另外一种我也不打算摸的语言是Ruby,也是基于同样的道理。很多人说Ruby是一个魔幻语言;可Ruby提供和支撑的技术,用任何一种动态语言都可以做到,而且一点也不会比Ruby更复杂。

Ruby和Java有一个特别大的共同点:折腾来折腾去,仍然是老生常谈居多,让人感觉乏味的很(可偏偏就有人以为看见新花样甚至银弹了);对于我来说,它们真正让人感觉有劲的特点也忒少了一些。说的险恶一点,这两种语言不过是一些夸夸其谈者不断证明他们自己一向以来的思路的(新)工具罢了。

发现我总是以尖酸刻薄那些无聊的人事物为乐。打住。

上面这篇文章相当不错,虽然咱们这用Python的人不多,不过正则表达式这个基本工具哪儿都有,解析含有一定规则的文本的需求也会偶尔产生。很多聪明的非科班(不以上没上过计算机系为分界,而是是不是真正学了为分界)程序员,总能凭高智商写出一大堆if...else...解决自己的任务,不过我仍然觉得,接触一下稍微标准一些的做法总是好的。

在这里并不想强调编译原理这些东西的重要性,所以觉得上面这篇完全基于实用性的文章是个很好的切入点:没有理论,不过做法相对标准。可惜这里面仅仅有词法分析部分,并不涉及语法。不过对于简单任务,仍旧可以对于每一个读入的Token,暂时性的if...else...解决 :P,虽然我不赞成这么做。

其实ASP.NET引擎解析aspx文件的做法,在词法部分和上面的Python代码也是一个意思,不想看Python代码的可以自己Reflector一下。只是ASP.NET中的代码结构该紧凑的部分不紧凑,该清晰的地方不清晰;这是因为任务更有针对性,所以觉得上面介绍的这段代码更适合于学习。

另外向和我一样刚接触Python的朋友提醒一句,就拿篇文章的评论来看,Python的正则表达式引擎是基于某种回溯的,效率可能很一般;当然.NET的应该是优化的NFA的,会好一些(DFA效率更高但一些特殊功能就不容易实现了)。

还有一个有意思的事情是Python自带的HTMLParser(也是一堆类似于这些东西的代码)。刚开始使用的时候,在网上搜了搜想看看别人的经验,大多数人嫌这玩意简单,很少有使用的。其实它也仅仅是提供一个初步的词法解析的功能,因为人家并不知道你剩下要干什么。比如构筑DOM树一类,可以自己解决:大家真正需要的往往是节点上的信息,这需要一个数据结构;其次是父子兄弟的关系。

仔细分析一下HTML的形式,就知道子节点的标签一定在父节点的标签之内,所以父节点的开始标签会先获得,而父节点的关闭标签会后获得。这样当获得每一个开始标签的时候,将它压到栈里,获得一个结束标签,直接弹出就可以了。这样,栈顶所存放的开始标签所对应的元素,永远是当前获得的标签的父元素。

其实这些都是很简单的东西,也不一定需要一本教科书。我觉得,即使不关心计算机技术,而是致力于技术应用的兄弟也应该适当的了解一下。因为现实世界中的业务,不会比解析文本更容易,这是其一;其二,当我们对业务进行设计和实现的时候,实际上也经常会用到类似的模型。所以我觉得,这些基本常识,不是一个想扎根于技术的人,在职业生涯中可以避免的。

回到HTMLParser身上,为什么国内Python论坛上,很多人觉得这玩意还没有直接使用正则合用呢?因为我发现大家的需求都是从网站上扒数据,在这个时候,并不关心文档结构和全部的节点信息,自然而然的没必要使用这种东西。想必这些朋友最后也顺利的完成了工作,不过却并没有认识到问题的根源所在。我想说的是,如果仅仅关心眼前的任务,恐怕提高总是有限的。

另一个比较有意思的事情(对我来说),是偶尔在这些社区看到那些我熟悉的话题,虽然由于他们那边比较冷清,相应的也少很多。比如各种各样的设计原则之类,发言的往往也有很显然更加了解C#、Java、C++的,相对似乎主要使用Python的“高手”并不多。而且就国内的情况来看,实际上Python社区中的“菜鸟”帖子所占比例似乎更大一些。但就我这几天看过的Python代码,却也有不少体现出不错的思路,而这些人是不活跃在一般的开发者社区的。总之,从我的视角来看,Python社区是个奇怪的社区:而且一点也不欣欣向荣。

我确实是一个八卦的人,嗯,再次打住。

再说一个我看了这么多语言的体会,Template C++,从组织能力上来说,绝对超过任何一种我所接触过的其他语言。可惜的是,它本身设计的太晦涩,其次是对于这种组织方式,其实缺乏一种在高层次上模块化的设计:比如DLL或者LIB这个层次上的,又真正能表现该组织形式特性的高层次模块接口。

至于内存管理之类的历史遗留问题,也是应该彻底解决的。对GC的讨论,天天都是集中在性能上,这忽略了一个重要的问题。由于内存泄漏是必须考虑的问题,没有GC,就不得不在设计接口的时候,考虑非抽象层次的一个问题:内存的控制权由库还是由调用者处理。

我对这个问题有一个相当自暴自弃的想法,就是在当前的肮脏环境下,库作者不应该对内存进行任何管理。“谁创建,谁负责”的说法需要认真考虑,因为东西可能是从库里头出去的,但却是调用者要求的。如果库作者有一个内存管理框架,就剥夺了用户自行处理的权利,况且库很难知道出去的东西现在是不是已经是垃圾了。

但这样,用户的工作就变得复杂起来了。这还不是关键的,库作者完全不管理内存,还会导致另外一个问题:如果在库的内部,某个逻辑要求要持有某一个内存对象,而用户要回收它,怎么办?库作者不得不把很多用户本来不关心的事情,交代清楚;而用户不得不学习它们。总之,在内存管理掺和进来以后,接口的设计和使用变成了非常要命的事情。

在一个进程或者说一个高层次的完整运行过程之中,内存管理被独立成第三方,总揽全局,是必须的。最多最多的,每一个程序员只能标记“我不在需要它”,而不是真的有权力摧毁一个会四处传播的对象。这个问题不解决,C++这个作为Template C++基础的东西,走向没落也是自然而然的了。在这种形势下,C++ 0x的动作那么慢,而且一个GC的部分议题居然还有可能没时间在这次解决,唉。

除了以上的问题,Template C++或者类似的形式,应该还有一个进步的方向,就是改进与动多态的融合能力。这恐怕需要一个新的自动化机制,甚至要配上一个更强大的JIT才能解决。什么叫做更强大呢?就是比.NET的JIT更强大,或者说,为Template的组织能力针对性的设计。现在缺的就是这个,可惜了了。

唠叨的太多了,干活去也。

posted on 2009-03-06 06:14  怪怪  阅读(2085)  评论(5编辑  收藏  举报

导航