《TypeScript图形渲染实战:2D架构设计与实现》 —2.2.8 核心的getNextToken方法

举报
华章计算机 发表于 2019/12/11 16:57:08 2019/12/11
【摘要】 本节书摘来自华章计算机《TypeScript图形渲染实战:2D架构设计与实现》 一书中第2章,第2.2.9节,作者是步磊峰。

2.2.8  核心的getNextToken方法

  IDoom3Tokenizer的getNextToken方法是一个相对复杂的实现,其工作原理就是一个有限状态机(Finite State Machine,简称FSM)。所谓有限状态机就是指状态是有限的,并且根据当前的状态来执行某个操作。那么来看一下getNextToken这个有限状态机相关的问题:

* 有哪几个状态(即有限的状态数量)

* 每个状态的开始条件是什么

* 每个状态的结束条件是什么

* 在某个状态下要做什么(操作)

  带着上面的问题来看一下getNextToken的源码。具体代码如下:

 

public getNextToken ( tok : IDoom3Token ) : boolean {

  //使用as关键字将IDoom3Token 向下转型为Doom3Token类型

    let token : Doom3Token = tok as Doom3Token ;

    //初始化为空字符串

    let c : string = "" ;

    //重用Token,每次调用reset()函数时,将Token的索引重置为0

    //避免发生内存重新分配

    token . reset ( ) ;

    do {

        // 第一步:跳过所有的空白字符,返回第一个可显示的字符

        //开始条件:当前字符是空白符

        c = this . _skipWhitespace ( );

        // 第二步:判断非空白字符的第一个字符是什么

        if ( c === '/' && this . _peekChar ( ) === '/' ) {

            // 开始条件:如果是//开头,则跳过单行注释中的所有字符

            c = this . _skipComments0 ( ) ;

        } else if ( c === '/' && this . _peekChar ( ) === '*' ) {

            //开始条件:如果是/*开头的字符,则跳过多行注释中的所有字符

            c = this . _skipComments1 ( ) ;

        } else if ( this . _isDigit( c ) || c === '-' || ( c === '.' && this .

        _isDigit( this . _peekChar ( ) ) ) ) {

            //开始条件:如果当前字符是数字、符号或者以点号且数字开头

            //则返回到上一个字符索引处,因为第一个字符被读取并处理过了,而_getNumber

            会重新处理数字情况,这样需要恢复到数字解析的原始状态

            this . _ungetChar ( ) ;

            this . _getNumber ( token ) ;

            return true ;

        } else if ( c === '\" ' || c === '\' ' ) {

            //开始条件:如果以\"或\'开头的字符,例如'origin'或'Body'

            this . _getSubstring ( token , c ) ;

            return true ;

        } else if ( c.length > 0 ) {

            //开始条件:排除上述所有的条件并且在确保数据源没有解析完成的情况下

      //返回到上一个字符索引处,因为_getString会重新处理相关情况

            this . _ungetChar ();

            this . _getString ( token ) ;

            return true ;

        }

    } while ( c . length > 0 ) ;

    return false ;

}

 

  这段代码的关键点都在注释里面,其中状态的开始条件都已标注出来。状态的结束条件都注释在对应的状态处理函数中。

  来看一下这段代码中的向下转型相关内容。上面将IDoom3Token类型使用as操作符向下转型为Doom3Token,是因为_getNumber / _getSubstring / _getString这3个方法的输出参数类型是Doom3Token,而不是IDoom3Token,因此需要从IDoom3Token向下转型到Doom3Token。在TypeScript中也可以使用< >来进行类型转换。具体代码如下:

 

let  token : Doom3Token = < Doom3Token > tok ;


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。