void FllImporter::processRuleBlock(const std::string& block, Engine* engine) const { std::istringstream reader(block); std::string line; RuleBlock* ruleBlock = new RuleBlock; engine->addRuleBlock(ruleBlock); while (std::getline(reader, line)) { std::pair<std::string, std::string> keyValue = parseKeyValue(line, ':'); if ("RuleBlock" == keyValue.first) { ruleBlock->setName(keyValue.second); } else if ("enabled" == keyValue.first) { ruleBlock->setEnabled(parseBoolean(keyValue.second)); } else if ("conjunction" == keyValue.first) { ruleBlock->setConjunction(parseTNorm(keyValue.second)); } else if ("disjunction" == keyValue.first) { ruleBlock->setDisjunction(parseSNorm(keyValue.second)); } else if ("activation" == keyValue.first) { ruleBlock->setActivation(parseTNorm(keyValue.second)); } else if ("rule" == keyValue.first) { ruleBlock->addRule(fl::Rule::parse(keyValue.second, engine)); } else { throw fl::Exception("[import error] key <" + keyValue.first + "> not " "recognized in pair <" + keyValue.first + ":" + keyValue.second + ">", FL_AT); } } }
void FllImporter::processOutputVariable(const std::string& block, Engine* engine) const { std::istringstream reader(block); std::string line; OutputVariable* outputVariable = new OutputVariable; engine->addOutputVariable(outputVariable); while (std::getline(reader, line)) { std::pair<std::string, std::string> keyValue = parseKeyValue(line, ':'); if ("OutputVariable" == keyValue.first) { outputVariable->setName(keyValue.second); } else if ("enabled" == keyValue.first) { outputVariable->setEnabled(parseBoolean(keyValue.second)); } else if ("range" == keyValue.first) { std::pair<scalar, scalar> range = parseRange(keyValue.second); outputVariable->setRange(range.first, range.second); } else if ("default" == keyValue.first) { outputVariable->setDefaultValue(Op::toScalar(keyValue.second)); } else if ("lock-valid" == keyValue.first) { outputVariable->setLockValidOutput(parseBoolean(keyValue.second)); } else if ("lock-range" == keyValue.first) { outputVariable->setLockOutputRange(parseBoolean(keyValue.second)); } else if ("defuzzifier" == keyValue.first) { outputVariable->setDefuzzifier(parseDefuzzifier(keyValue.second)); } else if ("accumulation" == keyValue.first) { outputVariable->fuzzyOutput()->setAccumulation(parseSNorm(keyValue.second)); } else if ("term" == keyValue.first) { outputVariable->addTerm(parseTerm(keyValue.second, engine)); } else { throw fl::Exception("[import error] key <" + keyValue.first + "> not " "recognized in pair <" + keyValue.first + ":" + keyValue.second + ">", FL_AT); } } }
void KVParser::process() { size_t available = m_readBuf.chainLength(); size_t avail = available; Cursor cursor(m_readBuf.front()); // if we can read a complete key/value then we are ready to be extracted if (parseKeyValue(cursor, avail)) { m_phase = Phase::READY; } m_readBuf.split(available - avail); }
void FllImporter::processRuleBlock(const std::string& block, Engine* engine) const { std::istringstream reader(block); std::string line; FL_unique_ptr<RuleBlock> ruleBlock(new RuleBlock); while (std::getline(reader, line)) { std::pair<std::string, std::string> keyValue = parseKeyValue(line, ':'); if ("RuleBlock" == keyValue.first) { ruleBlock->setName(keyValue.second); } else if ("enabled" == keyValue.first) { ruleBlock->setEnabled(parseBoolean(keyValue.second)); } else if ("conjunction" == keyValue.first) { ruleBlock->setConjunction(parseTNorm(keyValue.second)); } else if ("disjunction" == keyValue.first) { ruleBlock->setDisjunction(parseSNorm(keyValue.second)); } else if ("implication" == keyValue.first) { ruleBlock->setImplication(parseTNorm(keyValue.second)); } else if ("activation" == keyValue.first) { TNormFactory* tnorm = FactoryManager::instance()->tnorm(); //@todo remove backwards compatibility in version 7.0 if (tnorm->hasConstructor(keyValue.second)) { ruleBlock->setImplication(parseTNorm(keyValue.second)); FL_LOG("[warning] obsolete usage of identifier <activation: TNorm> " "in RuleBlock"); FL_LOG("[information] from version 6.0, the identifiers are " "<activation: Activation> for Activation methods " "and <implication: TNorm> for T-Norms"); FL_LOG("[backward compatibility] assumed " "<implication: " << keyValue.second << "> " "instead of <activation: " << keyValue.second << ">"); } else { ruleBlock->setActivation(parseActivation(keyValue.second)); } } else if ("rule" == keyValue.first) { Rule* rule = new Rule; rule->setText(keyValue.second); try { rule->load(engine); } catch (std::exception& ex) { FL_LOG(ex.what()); } ruleBlock->addRule(rule); } else { throw Exception("[import error] key <" + keyValue.first + "> not " "recognized in pair <" + keyValue.first + ":" + keyValue.second + ">", FL_AT); } } engine->addRuleBlock(ruleBlock.release()); }
void FllImporter::processInputVariable(const std::string& block, Engine* engine) const { std::istringstream reader(block); std::string line; InputVariable* inputVariable = new InputVariable; engine->addInputVariable(inputVariable); while (std::getline(reader, line)) { std::pair<std::string, std::string> keyValue = parseKeyValue(line, ':'); if ("InputVariable" == keyValue.first) { inputVariable->setName(keyValue.second); } else if ("enabled" == keyValue.first) { inputVariable->setEnabled(parseBoolean(keyValue.second)); } else if ("range" == keyValue.first) { std::pair<scalar, scalar> range = parseRange(keyValue.second); inputVariable->setRange(range.first, range.second); } else if ("term" == keyValue.first) { inputVariable->addTerm(parseTerm(keyValue.second, engine)); } else { throw fl::Exception("[import error] key <" + keyValue.first + "> not " "recognized in pair <" + keyValue.first + ":" + keyValue.second + ">", FL_AT); } } }
void FllImporter::processOutputVariable(const std::string& block, Engine* engine) const { std::istringstream reader(block); std::string line; FL_unique_ptr<OutputVariable> outputVariable(new OutputVariable); while (std::getline(reader, line)) { std::pair<std::string, std::string> keyValue = parseKeyValue(line, ':'); if ("OutputVariable" == keyValue.first) { outputVariable->setName(Op::validName(keyValue.second)); } else if ("enabled" == keyValue.first) { outputVariable->setEnabled(parseBoolean(keyValue.second)); } else if ("range" == keyValue.first) { std::pair<scalar, scalar> range = parseRange(keyValue.second); outputVariable->setRange(range.first, range.second); } else if ("default" == keyValue.first) { outputVariable->setDefaultValue(Op::toScalar(keyValue.second)); } else if ("lock-previous" == keyValue.first or "lock-valid" == keyValue.first) { outputVariable->setLockPreviousValue(parseBoolean(keyValue.second)); } else if ("lock-range" == keyValue.first) { outputVariable->setLockValueInRange(parseBoolean(keyValue.second)); } else if ("defuzzifier" == keyValue.first) { outputVariable->setDefuzzifier(parseDefuzzifier(keyValue.second)); } else if ("aggregation" == keyValue.first) { outputVariable->fuzzyOutput()->setAggregation(parseSNorm(keyValue.second)); } else if ("accumulation" == keyValue.first) { outputVariable->fuzzyOutput()->setAggregation(parseSNorm(keyValue.second)); FL_LOG("[warning] obsolete usage of identifier <accumulation: SNorm> in OutputVariable"); FL_LOG("[information] from version 6.0, the identifier <aggregation: SNorm> should be used"); FL_LOG("[backward compatibility] assumed " "<aggregation: " << keyValue.second << "> " "instead of <accumulation: " << keyValue.second << ">"); } else if ("term" == keyValue.first) { outputVariable->addTerm(parseTerm(keyValue.second, engine)); } else { throw Exception("[import error] key <" + keyValue.first + "> not " "recognized in pair <" + keyValue.first + ":" + keyValue.second + ">", FL_AT); } } engine->addOutputVariable(outputVariable.release()); }
bool XMLParser::parse() { if (_stream == 0) return parserError("XML stream not ready for reading."); if (_XMLkeys == 0) buildLayout(); while (!_activeKey.empty()) freeNode(_activeKey.pop()); cleanup(); bool activeClosure = false; bool activeHeader = false; bool selfClosure; _state = kParserNeedHeader; _activeKey.clear(); _char = _stream->readByte(); while (_char && _state != kParserError) { if (skipSpaces()) continue; if (skipComments()) continue; switch (_state) { case kParserNeedHeader: case kParserNeedKey: if (_char != '<') { parserError("Parser expecting key start."); break; } if ((_char = _stream->readByte()) == 0) { parserError("Unexpected end of file."); break; } if (_state == kParserNeedHeader) { if (_char != '?') { parserError("Expecting XML header."); break; } _char = _stream->readByte(); activeHeader = true; } else if (_char == '/') { _char = _stream->readByte(); activeClosure = true; } else if (_char == '?') { parserError("Unexpected header. There may only be one XML header per file."); break; } _state = kParserNeedKeyName; break; case kParserNeedKeyName: if (!parseToken()) { parserError("Invalid key name."); break; } if (activeClosure) { if (_activeKey.empty() || _token != _activeKey.top()->name) { parserError("Unexpected closure."); break; } } else { ParserNode *node = allocNode(); //new ParserNode; node->name = _token; node->ignore = false; node->header = activeHeader; node->depth = _activeKey.size(); node->layout = 0; _activeKey.push(node); } _state = kParserNeedPropertyName; break; case kParserNeedPropertyName: if (activeClosure) { if (!closeKey()) { parserError("Missing data when closing key '%s'.", _activeKey.top()->name.c_str()); break; } activeClosure = false; if (_char != '>') parserError("Invalid syntax in key closure."); else _state = kParserNeedKey; _char = _stream->readByte(); break; } selfClosure = false; if (_char == '/' || (_char == '?' && activeHeader)) { selfClosure = true; _char = _stream->readByte(); } if (_char == '>') { if (activeHeader && !selfClosure) { parserError("XML Header must be self-closed."); } else if (parseActiveKey(selfClosure)) { _char = _stream->readByte(); _state = kParserNeedKey; } activeHeader = false; break; } if (selfClosure) parserError("Expecting key closure after '/' symbol."); else if (!parseToken()) parserError("Error when parsing key value."); else _state = kParserNeedPropertyOperator; break; case kParserNeedPropertyOperator: if (_char != '=') parserError("Syntax error after key name."); else _state = kParserNeedPropertyValue; _char = _stream->readByte(); break; case kParserNeedPropertyValue: if (!parseKeyValue(_token)) parserError("Invalid key value."); else _state = kParserNeedPropertyName; break; default: break; } } if (_state == kParserError) return false; if (_state != kParserNeedKey || !_activeKey.empty()) return parserError("Unexpected end of file."); return true; }
std::pair<scalar, scalar> FllImporter::parseRange(const std::string& text) const { std::pair<std::string, std::string> range = parseKeyValue(text, ' '); return std::pair<scalar, scalar>(Op::toScalar(range.first), Op::toScalar(range.second)); }