玩具语言LLL之Lex

最近真是很倒霉,一系列糟糕的心情后,开罐头伤了手。看网络小说感觉无聊,玩魔兽意趣阑珊,最后只好拿起这个玩具继续摆弄。这部分代码里的空格是用一个包得像粽子一样的大母指敲出来的。

 

语言嘛,总要涉及语法分析。其实,这在服务器开发方面并不罕见,很多协议都是基于文本的。在实现词法分析上一般使用两种方式,第一是使用lex生成工具,第二是自己写(我称之为硬写)。就我自己的编程习惯来说,对于相对简单的词法分析来说我使用lex分析工具(linux下是flex),对于大型的综合性的语法分析来说我选择硬写。这好像跟普通的观点有点背道而驰,但是对于复杂词法分析来说flex确实有点让人疯狂。我们需要在若干的condition里来回跳转,整个lex描述文件甚至比硬写还要多得多。并且,非常的晦涩难懂,毕竟这玩意要和yacc(bison)配合使用。在这里,我使用硬写lex的方式,大家基本都能看懂。

 

词法分析的本身不值得令人关注,这些被切出来的token的存储模式其实是更加本质性、更加急需处理的问题。lex切分文本流,产生token,供后端处理。token往往是一过性的,但是token的文本往往参与后期的运算。如何组织这些文本的存储,关系到整个程序的走向。在考虑这个问题的时候,我的脑海里产生很多套方案,并且为此推敲了数个小时。后来,我发现我很愚蠢,我本来是打算做个玩具,但是在考虑V8引擎怎么设计。但是使用简单的内存复制,我又不是很舒服。最终,我选择使用一个非常简单,但是又不是那么直接的方式。所有的文本经过lex,lex经过一个unistr映射产生unistr。字符串经过一个hash映射,产生唯一字符串。这样做的好处是在后期的hash字符串处理中,不需要重新计算hash值,另外字符串的比对从文本比对变成了指针比对。这解决了hash表计算的两个性能瓶颈。

 

剩下的lex编码冗长且缺乏趣味。整个代码秉承一个关键问题look ahead,根据当前字符,并且看下一个字符,决定程序走向。编码的核心就是,始终手握下一个字符。这种代码要比编译原理书上写的相对轻松,没那么多理论上的教条。keyword.h是对关键字的定义,现阶段还没有考虑完全。比如前++和后++有不同的优先级,现在不知道是放在词法分析里还是放到语法分析里。不过,对于大多数的语法环境来说,这个优先级是足够的了。有些事情,只能在以后认识中去辩证。

 

keyword.h是对关键字的定义。之所以写成这样,完全是为了恶搞,是对反对“宏”主义者的逆袭。

 

svn co http://www.svnchina.com/svn/lll

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值