我们来看一下正常的字符串是如何解析的,实现代码如下所示:
// 进入该函数,说明肯定不是数字,不是单行注释,不是多行注释,也不是子字符串
// 进入该函数只有两种类型的字符串,即不带双引号或单引号的字符串以及specialChar
private _getString ( token: Doom3Token ): void {
// 获取当前字符,因为前面已经判断为字符串了
let c : string = this . _getChar ( ) ;
token . setType ( ETokenType . STRING ) ;
// 进入循环
do {
//将当前的char添加到token中
token . addChar ( c ) ;
if ( ! this . _isSpecialChar ( c ) ) {
c = this . _getChar ( ) ; // 只有不是特殊操作符号的字符,才调用_getChar移动当前索引
}
//如果this . _isSpecialChar ( c )为true,不会调用_getChar函数,并且满足了跳出while循环的条件
//结束条件:数据源解析全部完成或下一个是空白符或者当前字符是特殊符号
} while ( c . length > 0 && ! this._isWhitespace ( c ) && ! this._isSpecialChar ( c ) ) ;
}
代码注释比较详细,各位读者可以了解一下。这里会看到,和子字符串不同的一点是,我们的_getString会将一些特殊的字符(标点符号)作为单独的Token返回,具体有哪些特殊的字符,其实依赖于你的决策。在默认情况下,我们的实现代码如下所示:
// 我们将左右大中小括号以及点号逗号都当作单独的Token进行处理
// 如果想要增加更多的标点符号作为token,可以在本函数中进行添加
private _isSpecialChar ( c : string ) : boolean {
switch ( c ) {
case '(' :
return true ;
case ')' :
return true ;
case '[' :
return true ;
case ']' :
return true ;
case '{' :
return true ;
case '}' :
return true ;
case ',' :
return true ;
case '.' :
return true ;
}
return false ;
}
Doom3文本文件词法解析器的源码都演示完毕,最好的研究源码方式是断点调试,大家可以去本书备注的网站下载本章的源码进行调试。