📄 ruleparser.cs
字号:
{
//
// Extract single conditions
//
List<IExpression> expressions = ExtractSingleCondidtions(conditionExpression, input, lexems);
if (expressions.Count == 0)
{
throw new Exception("No valid conditions found in conditions part of the rule.");
}
ICondition cond = ParseConditionsRecurse(expressions, lexems);
//
// Return conditions
//
if (cond is Conditions)
{
return (Conditions)cond;
}
else
{
Conditions conditions = new Conditions();
return conditions;
}
}
static private int FindPairBracket(List<IExpression> expressions, Dictionary<string, Lexem> lexems)
{
//
// Assume that '(' stands at first place
//
int bracketsOpened = 1;
int closeBracket = -1;
for (int i = 1; i < expressions.Count; i++)
{
if (expressions[i] == lexems["("])
{
bracketsOpened++;
}
else if (expressions[i] == lexems[")"])
{
bracketsOpened--;
if (bracketsOpened == 0)
{
closeBracket = i;
break;
}
}
}
return closeBracket;
}
static private ICondition ParseConditionsRecurse(List<IExpression> expressions, Dictionary<string, Lexem> lexems)
{
if (expressions.Count < 1)
{
throw new Exception("Empty condition found.");
}
if (expressions[0] == lexems["("] && FindPairBracket(expressions, lexems) == expressions.Count)
{
//
// Remove extra brackets
//
return ParseConditionsRecurse(expressions.GetRange(1, expressions.Count - 2), lexems);
}
else if (expressions.Count == 1 && expressions[0] is ConditionExpression)
{
//
// Return single conditions
//
return ((ConditionExpression)expressions[0]).Condition;
}
else
{
//
// Parse list of one level conditions connected by or/and
//
List<IExpression> copyExpressions = expressions.GetRange(0, expressions.Count);
Conditions conds = new Conditions();
bool setOrAnd = false;
while (copyExpressions.Count > 0)
{
ICondition cond = null;
if (copyExpressions[0] == lexems["("])
{
//
// Find pair bracket
//
int closeBracket = FindPairBracket(copyExpressions, lexems);
if (closeBracket == -1)
{
throw new Exception("Parenthesis error.");
}
cond = ParseConditionsRecurse(copyExpressions.GetRange(1, closeBracket - 1), lexems);
copyExpressions.RemoveRange(0, closeBracket + 1);
}
else if (copyExpressions[0] is ConditionExpression)
{
cond = ((ConditionExpression)copyExpressions[0]).Condition;
copyExpressions.RemoveAt(0);
}
else
{
throw new ArgumentException(string.Format("Wrong expression in condition part at '{0}'"),copyExpressions[0].Text );
}
//
// And condition to the list
//
conds.Conditins.Add(cond);
if (copyExpressions.Count > 0)
{
if (copyExpressions[0] == lexems["and"] || copyExpressions[0] == lexems["or"])
{
if (copyExpressions.Count < 2)
{
throw new Exception(string.Format("Error at {0} in condition part.", copyExpressions[0].Text));
}
//
// Set and/or for conditions list
//
OperatorType newOp = (copyExpressions[0] == lexems["and"]) ? OperatorType.And : OperatorType.Or;
if (setOrAnd)
{
if (conds.Op != newOp)
{
throw new Exception("At the one nesting level cannot be mixed and/or operations.");
}
}
else
{
conds.Op = newOp;
setOrAnd = true;
}
copyExpressions.RemoveAt(0);
}
else
{
throw new Exception(string.Format("{1} cannot goes after {0}", copyExpressions[0].Text, copyExpressions[1].Text));
}
}
}
return conds;
}
}
static private SingleCondition ParseConclusion(List<IExpression> conditionExpression, List<FuzzyVariable> output, Dictionary<string, Lexem> lexems)
{
List<IExpression> copyExpression = conditionExpression.GetRange(0, conditionExpression.Count);
//
// Remove extra brackets
//
while (
copyExpression.Count >= 2 &&
(copyExpression[0] == lexems["("] && copyExpression[conditionExpression.Count - 1] == lexems[")"]))
{
copyExpression = copyExpression.GetRange(1, copyExpression.Count - 2);
}
if (copyExpression.Count != 3)
{
throw new Exception("Conclusion part of the rule should be in form: 'variable is term'");
}
//
// Parse variable
//
Lexem exprVariable = (Lexem)copyExpression[0];
if (!(exprVariable is VarLexem))
{
throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprVariable.Text));
}
VarLexem varLexem = (VarLexem)exprVariable;
if (varLexem.Input == true)
{
throw new Exception("The variable in conclusion part must be an output variable.");
}
//
// Parse 'is' lexem
//
Lexem exprIs = (Lexem)copyExpression[1];
if (exprIs != lexems["is"])
{
throw new Exception(string.Format("'is' keyword must go after {0} identifier.", varLexem.Text));
}
//
// Parse term
//
Lexem exprTerm = (Lexem)copyExpression[2];
if (!(exprTerm is TermLexem))
{
throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprTerm.Text));
}
TermLexem termLexem = (TermLexem)exprTerm;
if (!varLexem.Var.Terms.Contains(termLexem.Term))
{
throw new Exception(string.Format("The term ({0}) in conclusion part does not belong to the specified variable ({1}).", termLexem.Text, varLexem.Text));
}
//
// Return fuzzy rule's conclusion
//
return new SingleCondition(varLexem.Var, termLexem.Term, false);
}
static public FuzzyRule Parse(string rule, List<FuzzyVariable> input, List<FuzzyVariable> output)
{
if (rule.Length == 0)
{
throw new ArgumentException("Rule cannot be empty.");
}
//
// Surround brakes with spaces, remove double spaces
//
System.Text.StringBuilder sb = new StringBuilder();
foreach (char ch in rule)
{
if (ch == ')' || ch == '(')
{
if (sb.Length > 0 && sb[sb.Length - 1] == ' ')
{
// Do not duplicate spaces
}
else
{
sb.Append(' ');
}
sb.Append(ch);
sb.Append(' ');
}
else
{
if (ch == ' ' && sb.Length > 0 && sb[sb.Length - 1] == ' ')
{
// Do not duplicate spaces
}
else
{
sb.Append(ch);
}
}
}
//
// Remove spaces
//
string prepRule = sb.ToString().Trim();
//
// Build lexems dictionary
//
List<Lexem> lexems = BuildLexemsList(input, output);
Dictionary<string, Lexem> lexemsDict = new Dictionary<string, Lexem>();
foreach (Lexem lexem in lexems)
{
lexemsDict.Add(lexem.Text, lexem);
}
//
// At first we parse lexems
//
List<IExpression> expressions = ParseLexems(prepRule, lexemsDict);
if (expressions.Count == 0)
{
throw new System.Exception("No valid identifiers found.");
}
//
// Find condition & conclusion parts part
//
if (expressions[0] != lexemsDict["if"])
{
throw new System.Exception("'if' should be the first identifier.");
}
int thenIndex = -1;
for (int i = 1; i < expressions.Count; i++)
{
if (expressions[i] == lexemsDict["then"])
{
thenIndex = i;
break;
}
}
if (thenIndex == -1)
{
throw new System.Exception("'then' identifier not found.");
}
int conditionLen = thenIndex - 1;
if (conditionLen < 1)
{
throw new System.Exception("Condition part of the rule not found.");
}
int conclusionLen = expressions.Count - thenIndex - 1;
if (conclusionLen < 1)
{
throw new System.Exception("Conclusion part of the rule not found.");
}
List<IExpression> conditionExpressions = expressions.GetRange(1, conditionLen);
List<IExpression> conclusionExpressions = expressions.GetRange(thenIndex + 1, conclusionLen);
Conditions conditions = ParseConditions(conditionExpressions, input, lexemsDict);
SingleCondition conclusion = ParseConclusion(conclusionExpressions, output, lexemsDict);
FuzzyRule resultRule = new FuzzyRule(input, output);
resultRule.Condition = conditions;
resultRule.Conclusion = conclusion;
return resultRule;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -