第二人生的源码分析(108)脚本的语法分析(1)

当玩家书写一个脚本时,如果写错了脚本,那么肯定运行不了。现在就来分析怎么样确保脚本是正确的问题,如果不正确就需要显示出来那里不正确。脚本是否正确,其实是根据脚本的语法来判断的。那么又怎么样来构造语法分析的程序呢?在第二人生里是通过使用程序bison.exe来创建的。

 

下面先来看看bison.exe是做什么东西的:

Yacc 代表 Yet Another Compiler Compiler Yacc GNU 版叫做 Bison。它是一种工具,将任何一种编程语言的所有语法翻译成针对此种语言的 Yacc 语 法解析器。它用巴科斯范式(BNF, Backus Naur Form)来书写。按照惯例,Yacc 文件有 .y 后缀。编译行如下调用 Yacc 编译器:

       $ yacc <options>   <filename ending with .y>

我们看到 Lex 从输入序列中识别标记。如果你在查看标记序列,你可能想在这一序列出现时执行某一动作。这种情况下有效序列的规范称为语法。Yacc 语法文件包括这一语法规范。它还包含了序列匹配时你想要做的事。

 

bison的语法文件,也是定义、规则和辅助代码部份。第二人生里的定义语法文件如下:

#001  %{

#002     #include "linden_common.h"

#003     #include "lscript_tree.h"

#004 

#005      #ifdef __cplusplus

#006      extern "C" {

#007      #endif

#008 

#009     int yylex(void);

#010     int yyparse( void );

#011     int yyerror(const char *fmt, ...);

#012 

#013      #if LL_LINUX

#014      // broken yacc codegen...  --ryan.

#015      #define getenv getenv_workaround

#016      #endif

#017 

#018      #ifdef LL_WINDOWS

#019     #pragma warning (disable : 4702) // warning C4702: unreachable code

#020     #pragma warning( disable : 4065 )   // warning: switch statement contains 'default' but no 'case' labels

#021     #endif

#022 

#023      #ifdef __cplusplus

#024      }

#025      #endif

#026  %}

#027 

#028  %union

#029  {

#030     S32                             ival;

#031     F32                             fval;

#032     char                            *sval;

#033     class LLScriptType              *type;

#034     class LLScriptConstant          *constant;

#035     class LLScriptIdentifier        *identifier;

#036     class LLScriptSimpleAssignable  *assignable;

#037     class LLScriptGlobalVariable    *global;

#038     class LLScriptEvent             *event;

#039     class LLScriptEventHandler      *handler;

#040     class LLScriptExpression        *expression;

#041     class LLScriptStatement         *statement;

#042     class LLScriptGlobalFunctions   *global_funcs;

#043     class LLScriptFunctionDec       *global_decl;

#044     class LLScriptState             *state;

#045     class LLScritpGlobalStorage     *global_store;

#046     class LLScriptScript            *script;

#047  };

posted @ 2008-07-21 00:22  ajuanabc  阅读(176)  评论(0编辑  收藏  举报