protected abstract void OnOperator(LexemOperator op, LexemList left, LexemList right);
protected void Scan(LexemList lexems, LexemOperator.OperationType type, string[] operators, Action<LexemList> action, bool parseFromLeftToRight = false) { //обычный разбор выражения должен идти справа налево (<-) //например, попробуйте построить полиз для выражения: a-b+c или a/b*c //только разбирая одноуровневые операции справа налево получится корректный полиз!!! for (int i = parseFromLeftToRight ? 0 : lexems.Count - 1; 0 <= i && i < lexems.Count; i += (parseFromLeftToRight ? 1 : -1)) { var lexem = lexems[i]; if (lexem is LexemBracket) { i = this.SkipBrackets(lexems, i, parseFromLeftToRight); } else if (lexem is LexemOperator) { var op = lexem as LexemOperator; if (op.OperatorType == type && (operators == null || operators.Contains(op.Text))) { this.OnOperator(op, lexems.Range(0, i), lexems.Range(i + 1, lexems.Count - i - 1)); return; } } } if (action != null) action(lexems); }
protected override void OnOperator(LexemOperator op, LexemList left, LexemList right) { switch (op.OperatorType) { case LexemOperator.OperationType.Logical: { if (op.Text == "||") { this.AnalysLogicalOr(left); this.AnalysLogicalAnd(right); _lexems.Add(op); } else if (op.Text == "&&") { this.AnalysLogicalAnd(left); this.AnalysComparison(right); _lexems.Add(op); } return; } case LexemOperator.OperationType.Comparison: { this.AnalysArithmetic(left); this.AnalysArithmetic(right); _lexems.Add(op); return; } case LexemOperator.OperationType.Arithmetic: { if (op.Text == "+" || op.Text == "-") { this.AnalysArithmeticAddition(left); this.AnalysArithmeticMultiplication(right); _lexems.Add(op); } else if (op.Text == "*" || op.Text == "/") { this.AnalysArithmeticMultiplication(left); this.AnalysElement(right); _lexems.Add(op); } return; } case LexemOperator.OperationType.Code: { if (op.Text == "->" || op.Text == ".") { this.AnalysElement(left); this.AnalysElement(right); _lexems.Add(op); } return; } } }