热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

前面介绍了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

#013  #include

#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

#026  #ifndef _WIN32

#027  #include

#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

 

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


推荐阅读
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • 本文探讨了如何利用 Android 的 Movie 类来展示 GIF 动画,并详细介绍了调整 GIF 尺寸以适应不同布局的方法。同时,提供了相关的代码示例和注意事项。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • 本文详细介绍了如何在 Ubuntu 14.04 系统上搭建仅使用 CPU 的 Caffe 深度学习框架,包括环境准备、依赖安装及编译过程。 ... [详细]
  • 本文详细介绍了在 Red Hat Linux 系统上安装 GCC 4.4.2 的步骤,包括必要的依赖库的安装及常见问题的解决方法。 ... [详细]
  • 想把一组chara[4096]的数组拷贝到shortb[6][256]中,尝试过用循环移位的方式,还用中间变量shortc[2048]的方式。得出的结论:1.移位方式效率最低2. ... [详细]
  • Vue CLI 基础入门指南
    本文详细介绍了 Vue CLI 的基础使用方法,包括环境搭建、项目创建、常见配置及路由管理等内容,适合初学者快速掌握 Vue 开发环境。 ... [详细]
  • 本文详细探讨了在Java中如何将图像对象转换为文件和字节数组(Byte[])的技术。虽然网络上存在大量相关资料,但实际操作时仍需注意细节。本文通过使用JMSL 4.0库中的图表对象作为示例,提供了一种实用的方法。 ... [详细]
  • 本文详细介绍了在 CentOS 系统中如何创建和管理 SWAP 分区,包括临时创建交换文件、永久性增加交换空间的方法,以及如何手动释放内存缓存。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 如何将955万数据表的17秒SQL查询优化至300毫秒
    本文详细介绍了通过优化SQL查询策略,成功将一张包含955万条记录的财务流水表的查询时间从17秒缩短至300毫秒的方法。文章不仅提供了具体的SQL优化技巧,还深入探讨了背后的数据库原理。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 本文详细介绍了如何正确设置Shadowsocks公共代理,包括调整超时设置、检查系统限制、防止滥用及遵守DMCA法规等关键步骤。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
author-avatar
amwaysuju
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有