前面分析词法分析的代码生成,并且生成可编译的
C
++文件,那么它是怎么调用这个词法分析文件的呢?下面就来了解它的调用过程。
当你在第二人生里创建物体后,就可以编辑脚本了,当完成脚本编写之后就需要保存起来,这时就会触发脚本编译。它就如下调用:
#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
实现的。