研究 JLex(6) (最后)

2.7)输出lexer程序

   在构造好DFA之后,产生出相应的lexer程序本身并不复杂,我们所谓的研究是要看看
产生的各个数据结构在最终产生的lexer程序(也称driver)中是什么。尤其指表格部分。

   这一任务由CEmit.emit()中实现,其被CLexGen.generate()所调用。以下假定输出的
lexer的类名字是缺省的Yylex,其它也都用缺省设置(如yylex(), Yytoken等)。

(1)lex state相关数据

   Yylex.yy_state_dtrans[] 为从 lex_state 到 dfa_state 的入口表。如果有多个lex state,
则每个lex state都有一个DFA入口状态,该入口状态索引存放在此表中。

   Yylex.yybegin(int state)实际上就是设置yy_lexical_state为指定的state即可。在yylex()中会
设置起始状态yy_state = yy_state_dtrans[yy_lexical_state]的(DFA机器入口)。

   另外为每个lex state的名字建立一个Yylex类的常量,如YYINITIAL=0,COMMENT=1等。

(2)接受状态表,状态转换表,以及其辅助的字符输入映射,行压缩映射表。

    在函数CEmit.emit_driver() =>调用 emit_table() 中输出这些表格。

    yy_acpt[]为接受状态表,内部对应为CSpec.m_accept_vector,索引i的项表示该索引的
dfa状态及相应的anchor。

    yy_cmap[]为字符输入映射,从输入的字符int值映射为状态转换表dtrans[row][col]的col值。
       在内部实际为双层映射CSpec.m_col_map[m_ccls_map[ch]],m_col_map是压缩col时候
       产生的,m_ccls_map是简化字符输入时候生成的。

    yy_rmap[]为行映射表,在压缩row的时候产生的,主要为减少dtrans[][]表大小用。

    yy_nxt[][] 即是状态转换表,内部为CSpec.m_dtrans_vector. 
       对于yy_nxt[row][col],其中row为DFA状态索引,col表示输入字符的映射,值为下一个
       状态,即迁移的状态。

    原来的JLex程序将yy_cmap,yy_rmap,yy_nxt都压缩为一个字符串,然后在lexer程序中展开,
为了调试方便,我修改了一点程序直接输出表格。

    为了方便,我在这里上传了修改过的JLex程序,主要是加了些中文注释,或者强迫症爆发
修改了一些代码,庶几能方便一点看明白代码的意图么?

代码地址: http://vdisk.weibo.com/s/2p-6j/1328753277

里面也有一个Sample2.java,里面为研究driver做了些注释,就当写了一个driver研究的blog吧。

你可能感兴趣的:(研究 JLex(6) (最后))