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