/* * INTEL CONFIDENTIAL * Copyright © 2011 Intel * Corporation All Rights Reserved. * * The source code contained or described herein and all documents related to * the source code ("Material") are owned by Intel Corporation or its suppliers * or licensors. Title to the Material remains with Intel Corporation or its * suppliers and licensors. The Material contains trade secrets and proprietary * and confidential information of Intel or its suppliers and licensors. The * Material is protected by worldwide copyright and trade secret laws and * treaty provisions. No part of the Material may be used, copied, reproduced, * modified, published, uploaded, posted, transmitted, distributed, or * disclosed in any way without Intel’s prior express written permission. * * No license under any patent, copyright, trade secret or other intellectual * property right is granted to or conferred upon you by disclosure or delivery * of the Materials, either expressly, by implication, inducement, estoppel or * otherwise. Any license under such intellectual property rights must be * express and approved by Intel in writing. * * CREATED: 2011-06-01 * UPDATED: 2011-07-27 */ #include "RuleParser.h" #include "CompoundRule.h" #include "SelectionCriterionRule.h" #include // Matches const char* CRuleParser::_acDelimiters[CRuleParser::ENbStatuses] = { "{", // EInit "{} ", // EBeginCompoundRule ",}", // EEndCompoundRule ",}", // ECriterionRule "{ ", // EContinue "" // EDone }; CRuleParser::CRuleParser(const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition) : _strApplicationRule(strApplicationRule), _pSelectionCriteriaDefinition(pSelectionCriteriaDefinition), _uiCurrentPos(0), _uiCurrentDeepness(0), _eStatus(CRuleParser::EInit), _pRootRule(NULL) { } CRuleParser::~CRuleParser() { delete _pRootRule; } // Parse bool CRuleParser::parse(CCompoundRule* pParentRule, string& strError) { while (true) { // Iterate till next relevant delimiter if (!iterate(strError)) { return false; } switch(_eStatus) { case EBeginCompoundRule: { // Create new compound rule CCompoundRule* pCompoundRule = new CCompoundRule; // Parse if (!pCompoundRule->parse(*this, strError)) { delete pCompoundRule; return false; } // Parent rule creation context? if (pParentRule) { // Chain pParentRule->addChild(pCompoundRule); } else { // Root rule delete _pRootRule; _pRootRule = pCompoundRule; } // Parse if (!parse(pCompoundRule, strError)) { return false; } // Go on break; } case EEndCompoundRule: return true; case EContinue: // Seek for new rule break; case ECriterionRule: { // Create new criterion rule CSelectionCriterionRule* pCriterionRule = new CSelectionCriterionRule; // Parse if (!pCriterionRule->parse(*this, strError)) { delete pCriterionRule; return false; } // Chain pParentRule->addChild(pCriterionRule); // Go on break; } case EDone: { // If the current state is EDone, check that at least one rule has been found. if (_pRootRule) { // At least one rule found return true; } else { strError = "Syntax error, no rule found"; return false; } } default: assert(0); return false; } } return true; } // Iterate bool CRuleParser::iterate(string& strError) { string::size_type iDelimiter; assert(_uiCurrentPos <= _strApplicationRule.length()); // Consume spaces if ((iDelimiter = _strApplicationRule.find_first_not_of(" ", _uiCurrentPos)) != string::npos) { // New pos _uiCurrentPos = iDelimiter; } // Parse if ((_uiCurrentPos != _strApplicationRule.length()) && ((iDelimiter = _strApplicationRule.find_first_of(_acDelimiters[_eStatus], _uiCurrentPos)) != string::npos)) { switch(_strApplicationRule[iDelimiter]) { case '{': _eStatus = EBeginCompoundRule; // Extract type _strRuleType = _strApplicationRule.substr(_uiCurrentPos, iDelimiter - _uiCurrentPos); _uiCurrentDeepness++; break; case '}': _eStatus = EEndCompoundRule; if (!_uiCurrentDeepness--) { strError = "Missing opening brace"; return false; } break; case ' ': _eStatus = ECriterionRule; // Extract type _strRuleType = _strApplicationRule.substr(_uiCurrentPos, iDelimiter - _uiCurrentPos); break; case ',': _eStatus = EContinue; break; } // New pos _uiCurrentPos = iDelimiter + 1; } else { if (_uiCurrentDeepness) { strError = "Missing closing brace"; return false; } // Remaining characters if (_uiCurrentPos != _strApplicationRule.length()) { strError = "Syntax error"; return false; } // Done _eStatus = EDone; } return true; } // Rule type const string& CRuleParser::getType() const { return _strRuleType; } // Criteria defintion const CSelectionCriteriaDefinition* CRuleParser::getSelectionCriteriaDefinition() const { return _pSelectionCriteriaDefinition; } // Root rule CCompoundRule* CRuleParser::grabRootRule() { CCompoundRule* pRootRule = _pRootRule; assert(pRootRule); _pRootRule = NULL; return pRootRule; } // Next word bool CRuleParser::next(string& strNext, string& strError) { string::size_type iDelimiter; // Consume spaces if ((iDelimiter = _strApplicationRule.find_first_not_of(" ", _uiCurrentPos)) != string::npos) { // New pos _uiCurrentPos = iDelimiter; } if ((iDelimiter = _strApplicationRule.find_first_of("{} ,", _uiCurrentPos)) == string::npos) { strError = "Syntax error"; return false; } strNext = _strApplicationRule.substr(_uiCurrentPos, iDelimiter - _uiCurrentPos); // New pos _uiCurrentPos = iDelimiter; return true; }