本文主要是介绍专题:一个自制代码生成器(嵌入式脚本语言)之辅助逻辑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
初级代码游戏的专栏介绍与文章目录-CSDN博客
我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
专题:一个自制代码生成器(嵌入式脚本语言)之总述-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之对象模型-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之堆栈结构和总入口-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之核心逻辑-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之辅助逻辑-CSDN博客(本篇)
专题:一个自制代码生成器(嵌入式脚本语言)之应用实例-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之模型开发-CSDN博客
专题:一个自制代码生成器(嵌入式脚本语言)之代码模板详解-CSDN博客
目录
一、处理变量替换
二、处理表达式
三、寻找块结束
四、查找对象
一、处理变量替换
变量替换使用“${”和“}”包裹。
//处理没有控制块的纯替换bool _ProcessNoBlock(string const& _source, long start, long end, stringstream& ss, CCTObject& O, CCTStack& S){string source = _source.substr(start, end - start);DEBUG_LOG << "---------------------------------- " << start << " " << end << endl << source << endi;size_t pos = 0;//标记开始处size_t pos2 = 0;//指向未处理部分while (string::npos != (pos = source.find("${", pos2))){ss << source.substr(pos2, pos - pos2);pos2 = source.find("}", pos + 2);if (source.npos == pos2){thelog << "没找到匹配的 } :" << source.substr(pos) << ende;return false;}string objname = source.substr(pos, pos2 + 1 - pos);bool INCafterUsed = false;//带有后++objname = _makeobjname(objname);//脱壳if (objname.size() > 2 && "++" == objname.substr(objname.size() - 2)){INCafterUsed = true;objname.erase(objname.size() - 2);}if ("__LOG__" == objname){ss << "thelog << " << _getLineNumber(_source.c_str(), start + pos) << " << \" \"";}else if ("__DEBUG_LOG__" == objname){ss << "DEBUG_LOG << " << _getLineNumber(_source.c_str(), start + pos) << " << \" \"";}else{CCTObject* p = _FindObject(objname, O, S);if (NULL == p){thelog << "对象不存在 [" << objname << "] line : " << _getLineNumber(_source.c_str(), pos + start) << ende;return false;}DEBUG_LOG << "line : " << _getLineNumber(_source.c_str(), pos + start) << " " << objname << " " << p->GetDefaultValue() << endi;ss << p->GetDefaultValue();if (INCafterUsed){char buf[64];sprintf(buf, "%ld", atol(p->GetDefaultValue().c_str()) + 1);p->SetDefaultValue(buf);}}pos2 = pos2 + 1;}ss << source.substr(pos2);DEBUG_LOG << "-------------------" << endi;return true;}
二、处理表达式
//处理表达式,双引号引导为纯文本,单引号引导为脚本,没有引号先判断是不是对象再当作脚本,如果是对象则p有效string _ProcessExpression(CCTObject& O, CCTStack& S, string const& expression, CCTObject*& p){//thelog << expression << endi;p = nullptr;if (expression.size() >= 2 && '\"' == expression[0] && '\"' == expression[expression.size() - 1]){//thelog << varname<<" "<< objname.substr(1, objname.size() - 2) <<endi;return expression.substr(1, expression.size() - 2);}stringstream tmp_ss;if (expression.size() >= 2 && '\'' == expression[0] && '\'' == expression[expression.size() - 1]){//thelog << expression << endi;if (_ProcessBlock(expression.substr(1, expression.size() - 2), 0, expression.size() - 2, tmp_ss, O, S)){//thelog << tmp_ss.str() << endi;return tmp_ss.str();}else{return expression + " 对象不存在或脚本出错 ";}}else{p = _tryFindObject(expression, O, S);if (NULL != p){return "";}if (_ProcessBlock(expression, 0, expression.size(), tmp_ss, O, S)){return tmp_ss.str();}else{return expression + " 对象不存在或脚本出错 ";}}}
处理表达式只在dim和set中使用。
三、寻找块结束
//寻找块结束,end1 end2返回扩展后的结束标签bool _findBlockEnd(string const& source, size_t start, size_t end, size_t& end1, size_t& end2, char const* labelBegin, char const* labelEnd){return __findBlockEnd(source, start, end, end1, end2, labelBegin, labelEnd, false);}bool _TryFindBlockEnd(string const& source, size_t start, size_t end, size_t& end1, size_t& end2, char const* labelBegin, char const* labelEnd){return __findBlockEnd(source, start, end, end1, end2, labelBegin, labelEnd, true);}bool __findBlockEnd(string const& source, size_t start, size_t end, size_t& end1, size_t& end2, char const* labelBegin, char const* labelEnd, bool isTry){long level = 1;string matchlable;end1 = start;end2 = start;while (level > 0){end1 = source.find("<%", end2);if (string::npos == end1 || end1 >= end){if (!isTry)thelog << "控制块不匹配 level " << level << " " << labelBegin << " " << labelEnd << " 行 " << _getLineNumber(source.c_str(), start) << ende;//exit(0);return false;}end2 = source.find("%>", end1 + 2);if (string::npos == end2 || end2 >= end){thelog << "没找到匹配的 %> : " << source.substr(end1) << ende;return false;}string blockcode = source.substr(end1 + 2, end2 - (end1 + 2));StringTokenizer st(blockcode, " ");DEBUG_LOG << "level " << level << " " << st[0] << " 行:" << _getLineNumber(source.c_str(), end1) << endi;if (st.size() > 0){if ((string)"else" == labelEnd){if ((string)"else" == st[0] && 1 == level){//找else只能在最后一层时降级DEBUG_LOG << "level=1时找到else" << endi;matchlable = st[0];--level;}if ((string)"endif" == st[0]){DEBUG_LOG << "找else时遇到endif" << endi;matchlable = st[0];--level;}}else if (labelEnd == st[0]){DEBUG_LOG << "找到结束标记" << endi;matchlable = st[0];--level;}if (labelBegin == st[0]){DEBUG_LOG << "找到开始标记" << endi;matchlable = st[0];++level;}}end2 += 2;}if (0 == level && labelEnd == matchlable){_extendToLine(source.c_str(), end1, end2);DEBUG_LOG << "找到块 " << labelBegin << " " << labelEnd << " 行 " << _getLineNumber(source.c_str(), end1) << " " << source.substr(end1, end2 - end1) << endi;return true;}else{if (labelEnd != (string)"else")thelog << "控制块不匹配" << labelBegin << " " << labelEnd << " 行 " << _getLineNumber(source.c_str(), start) << ende;return false;}}
四、查找对象
CCTObject* _FindObject(string _objname, CCTObject& O, CCTStack& S){return __FindObject(_objname, O, S, false);}CCTObject* _tryFindObject(string _objname, CCTObject& O, CCTStack& S){return __FindObject(_objname, O, S, true);}CCTObject* __FindObject(string _objname, CCTObject& O, CCTStack& S, bool isTry){//G_IS_DEBUG = true;string objname = _makeobjname(_objname);//脱壳CCTObject* ret = NULL;DEBUG_LOG << "查找 " << objname << " " << S.size() << endi;for (long i = S.size() - 1; i >= 0; --i){DEBUG_LOG << "S... " << endi;ret = S[i].FindObject(objname);if (ret != NULL){DEBUG_LOG << "找到 " << endi;return ret;}}DEBUG_LOG << "O... " << endi;ret = O.FindObject(objname);if (NULL == ret){if (!isTry)thelog << "对象不存在 " << objname << endw;//string str;//thelog << endl << O.toString(str) << endi;//for (CCTStack::reverse_iterator it = S.rbegin(); it != S.rend(); ++it)//{// thelog << endl << it->toString(str) << endi;//}}return ret;}
(这里是结束但不是整个系列的结束)
这篇关于专题:一个自制代码生成器(嵌入式脚本语言)之辅助逻辑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!