前面分析词法分析的代码生成,并且生成可编译的C++文件,那么它是怎么调用这个词法分析文件的呢?下面就来了解它的调用过程。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
当你在第二人生里创建物体后,就可以编辑脚本了,当完成脚本编写之后就需要保存起来,这时就会触发脚本编译。它就如下调用:
#001 void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
#002 LLViewerObject*
#003 object,
#004 const
#005 LLTransactionID& tid,
#006 BOOL
#007 is_running)
#008 {
创建一个对象来保存脚本数据。
#009 LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID,
#010
#011 mItem,
#012
#013 is_running);
保存脚本到磁盘文件。
#014 gAssetStorage->storeAssetData(filename.c_str(), tid,
#015 LLAssetType::AT_LSL_TEXT,
#016 &onSaveTextComplete,
#017 (void*)data,
#018 FALSE);
#019
#020 LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
#021 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString());
下面开始创建两个输出的文件名称。
#022 std::string dst_filename = llformat("%s.lso", filepath.c_str());
#023 std::string err_filename = llformat("%s.out", filepath.c_str());
#024
#025 FILE *fp;
下面调用函数lscript_compile来进行脚本编译。
#026 if(!lscript_compile(filename.c_str(),
#027 dst_filename.c_str(),
#028 err_filename.c_str(),
#029 gAgent.isGodlike()))
#030 {
#031 // load the error file into the error scrolllist
#032 llinfos << "Compile failed!" << llendl;
#033 if(NULL != (fp = LLFile::fopen(err_filename.c_str(), "r")))
#034 {
#035 char buffer[MAX_STRING]; /*Flawfinder: ignore*/
#036 LLString line;
#037 while(!feof(fp))
而函数lscript_compile在flex脚本文件里已经定义了,那么这里就是调用它。如果不了解就要查看前面的文章。
下面再来看看下面一段代码:
#001 BOOL lscript_compile(const char* src_filename, const char* dst_filename,
#002 const char* err_filename, BOOL is_god_like)
#003 {
......
打开脚本文件输入。
#018 yyin = LLFile::fopen(src_filename, "r");
#019 if (yyin)
#020 {
打开出错文件输出。
#021 yyout = LLFile::fopen(err_filename, "w");
#022
#023 // Reset the lexer's internal buffering.
#024
词法分析输入复位。
#025 yyrestart(yyin);
#026
这里进行语法分析。
#027 b_parse_ok = !yyparse();
#028
#029 if (b_parse_ok)
#030 {
下一次,我们就需要去分析怎么样判断脚本是合法的了,它就是在函数yyparse实现的。