第二人生的源码分析(106)脚本的词法分析(4)

 

前面介绍了flex文件的格式,那么flex程序又把这个文件生成怎么样的文件呢?下面就来仔细分析这个文件,由于flex程序生成C++的文件格式,那么就需要C++的编译器才可以编译了。它的代码如下:

#001  #line 2 "lex_yy.cpp"

这行是行号同步使用。

 

#002  /* A lexical scanner generated by flex */

#003 

#004  /* Scanner skeleton version:

#005   * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $

#006   */

上面这段说明这个文件是由词法分析程序flex生成的。

 

#007 

#008  #define FLEX_SCANNER

#009  #define YY_FLEX_MAJOR_VERSION 2

#010  #define YY_FLEX_MINOR_VERSION 5

 

上面这段说明flex的版本号。

 

#011 

#012  #include <stdio.h>

#013  #include <errno.h>

#014 

#015  /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */

#016  #ifdef c_plusplus

#017  #ifndef __cplusplus

#018  #define __cplusplus

#019  #endif

#020  #endif

#021 

#022 

#023  #ifdef __cplusplus

#024 

#025  #include <stdlib.h>

#026  #ifndef _WIN32

#027  #include <unistd.h>

#028  #endif

上面这段不同的flex程序和平台生成不一样,一定要小心了。

 

#029 

#030  /* Use prototypes in function declarations. */

#031  #define YY_USE_PROTOS

#032 

#033  /* The "const" storage-class-modifier is valid. */

#034  #define YY_USE_CONST

#035 

#036  #else  /* ! __cplusplus */

#037 

#038  #if __STDC__

#039 

#040  #define YY_USE_PROTOS

#041  #define YY_USE_CONST

#042 

#043  #endif /* __STDC__ */

#044  #endif /* ! __cplusplus */

#045 

 

 

 

下面再来分析下一段代码:

#001  #ifndef YY_DECL

#002  #define YY_DECL int yylex YY_PROTO(( void ))

#003  #endif

上面这行定义词法分析的函数。

 

#004 

#005  /* Code executed at the beginning of each rule, after yytext and yyleng

#006   * have been set up.

#007   */

#008  #ifndef YY_USER_ACTION

#009  #define YY_USER_ACTION

#010  #endif

#011 

#012  /* Code executed at the end of each rule. */

#013  #ifndef YY_BREAK

#014  #define YY_BREAK break;

#015  #endif

#016 

#017  #define YY_RULE_SETUP /

#018     YY_USER_ACTION

#019 

 

下面开始定义词法分析。

#020  YY_DECL

#021     {

#022     register yy_state_type yy_current_state;

#023     register char *yy_cp, *yy_bp;

#024     register int yy_act;

#025 

#026  #line 62 "indra.l"

#027 

#028  #line 2582 "lex_yy.cpp"

#029 

 

判断是否初始化。

#030     if ( yy_init )

#031         {

#032         yy_init = 0;

#033 

#034  #ifdef YY_USER_INIT

#035         YY_USER_INIT;

#036  #endif

#037 

#038         if ( ! yy_start )

#039             yy_start = 1;   /* first start state */

#040 

 

设置词法分析的文件输入。

#041         if ( ! yyin )

#042             yyin = stdin;

#043 

 

设置词法分析的文件输出。

#044         if ( ! yyout )

#045             yyout = stdout;

#046 

 

创建词法分析的缓冲区。

#047         if ( ! yy_current_buffer )

#048             yy_current_buffer =

#049                 yy_create_buffer( yyin, YY_BUF_SIZE );

#050 

#051         yy_load_buffer_state();

#052         }

#053 

 

 

下面一段是词法动作的分析:

#001  do_action: /* This label is used only to access EOF actions. */

#002 

#003 

 

根据动作的状态来响应。

#004         switch ( yy_act )

#005     { /* beginning of action switch */

#006             case 0: /* must back up */

#007             /* undo the effects of YY_DO_BEFORE_ACTION */

#008             *yy_cp = yy_hold_char;

#009             yy_cp = yy_last_accepting_cpos;

#010             yy_current_state = yy_last_accepting_state;

#011             goto yy_find_action;

#012 

 

不同的规则处理。

#013  case 1:

#014  YY_RULE_SETUP

#015  #line 63 "indra.l"

#016  { gInternalLine++; gInternalColumn = 0; comment(); }

#017     YY_BREAK

#018  case 2:

#019  YY_RULE_SETUP

#020  #line 65 "indra.l"

#021  { count(); return(INTEGER); }

#022     YY_BREAK

#023  case 3:

#024  YY_RULE_SETUP

#025  #line 66 "indra.l"

#026  { count(); return(FLOAT_TYPE); }

#027     YY_BREAK

 

接着下来就是不断地处理不同的规则,下一次再来通过调试来分析怎么样处理一个脚本的。

你可能感兴趣的:(源码分析)