前面介绍了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
接着下来就是不断地处理不同的规则,下一次再来通过调试来分析怎么样处理一个脚本的。