Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <scriptable_monitor/PredicatesScript.h>
00009
00010 PredicatesScript::PredicatesScript(string script, set<string>& internalFunctions)
00011 {
00012 _internalFunctions = internalFunctions;
00013 _sourceScript = script;
00014 _translatedScript = script;
00015
00016 try {
00017 processParameters(_translatedScript);
00018
00019 if (getParameter("type") == "predicate") {
00020 processTopics(_translatedScript);
00021 processInternalFunctions(_translatedScript);
00022 processPredicates(_translatedScript);
00023 }
00024 } catch(...) {
00025
00026 }
00027 }
00028
00029 bool PredicatesScript::addParameter(
00030 const boost::match_results<std::string::const_iterator>& paramMatch)
00031 {
00032 string paramName = paramMatch[1].str();
00033 string paramValue = paramMatch[2].str();
00034
00035 if (paramName == "name")
00036 _name = paramValue;
00037 else {
00038 _parameters[paramName] = paramValue;
00039 }
00040
00041 return true;
00042 }
00043
00044 void PredicatesScript::processParameters(string& script)
00045 {
00046 boost::regex regex("\\#\\!\\s([a-zA-Z_]+)\\s([^\\n]+)", boost::regbase::normal | boost::regbase::icase);
00047 boost::sregex_iterator m1(script.begin(), script.end(), regex);
00048 boost::sregex_iterator m2;
00049 std::for_each(m1, m2, boost::bind(&PredicatesScript::addParameter, this, _1));
00050 }
00051
00052 void PredicatesScript::processTopics(string& script)
00053 {
00054 boost::regex regex("\\{(([a-zA-Z0-9_/]+(\\[[0-9\\:]+\\])?)+)\\}", boost::regbase::normal | boost::regbase::icase);
00055 script = boost::regex_replace(script, regex, "topic(\"\\1\")");
00056 }
00057
00058 void PredicatesScript::processPredicates(string& script)
00059 {
00060 using namespace boost::algorithm;
00061
00062 vector<string> lines;
00063 vector<string> processedLines;
00064 split(lines, script, is_any_of("\n"));
00065
00066 foreach(string line, lines) {
00067 if (contains(line, ">") || contains(line, "<") || contains(line, "==") || contains(line, "!=")) {
00068 string escapedLine = line;
00069 boost::replace_all(escapedLine, "\"", "'");
00070 string newLine = "validate.is_true(" + line + ", \"" + escapedLine + "\")";
00071 processedLines.push_back(newLine);
00072 } else
00073 processedLines.push_back(line);
00074 }
00075
00076 script = join(processedLines, "\n");
00077 }
00078
00079 void PredicatesScript::processInternalFunctions(string& script)
00080 {
00081 using namespace boost::algorithm;
00082
00083 vector<string> lines;
00084 vector<string> processedLines;
00085 split(lines, script, is_any_of("\n"));
00086
00087 foreach(string line, lines) {
00088 int bracketDepth = 0;
00089 bool func = false;
00090 bool withinQuotes = false;
00091 int funcStart = 0;
00092 int funcEnd = 0;
00093 string funcName = "";
00094
00095 for (int i = 0; i < line.size() + 1; i++) {
00096
00097 char currentChar;
00098
00099 if (i < line.size())
00100 currentChar = line[i];
00101 else
00102 currentChar = ' ';
00103
00104
00105
00106 if (!withinQuotes && (currentChar == '"' || currentChar == '\'')) {
00107 withinQuotes = true;
00108 continue;
00109 } else if (withinQuotes && (currentChar == '"' || currentChar == '\'')) {
00110 withinQuotes = false;
00111 continue;
00112 }
00113
00114
00115 if (currentChar == '(') {
00116
00117 if (bracketDepth == 0 && funcName.size() > 0) {
00118 func = true;
00119 funcStart = i - funcName.length();
00120 }
00121
00122 bracketDepth++;
00123 continue;
00124 } else if (currentChar == ')') {
00125 bracketDepth--;
00126
00127 if (func && bracketDepth == 0) {
00128 funcEnd = i;
00129 break;
00130 }
00131 continue;
00132 }
00133
00134
00135 if (bracketDepth == 0) {
00136 if (isalnum(currentChar) || currentChar == '_') {
00137 funcName += currentChar;
00138 continue;
00139 } else {
00140 funcName = "";
00141 }
00142 }
00143
00144 }
00145
00146 if (_internalFunctions.count(funcName) > 0) {
00147 string parameters = line.substr(funcStart + funcName.length() + 1, funcEnd - funcStart - 1 - funcName.length() );
00148 string newLine = line.substr(0, funcStart) + "robil_lib.invoke('" + funcName + "'" + ( parameters.size() > 0 ? ", " + parameters : "") + ")";
00149 processedLines.push_back(newLine);
00150 } else {
00151 processedLines.push_back(line);
00152 }
00153
00154
00155 }
00156
00157 script = join(processedLines, "\n");
00158 }
00159