public static ExpressionNode ResolveOperatorExpression <TSymbol>(IParseTree <TSymbol> parseTree, int opLevel) where TSymbol : ISymbol <TSymbol>
 {
     if (opLevel > OP_BOTTOM_LEVEL)
     {
         // these part proceeds op from level 15 to 5
         bool isLeft = ASTBuilder.IsLeftOperator(parseTree.Symbol);
         // get childrens connected by operators (one level lower)
         var childs = isLeft ?
                      ASTBuilder.Children(parseTree).Reverse().GetEnumerator() : // if left-to-right then reverse arguments
                      ASTBuilder.Children(parseTree).GetEnumerator();
         Debug.Assert(childs.MoveNext());                                        // set enumerator to the first element (must be present)
         return(ParseBinOperator(childs, opLevel - 1, isLeft));
     }
     else
     {
         // continue parsing lower level expressions
         Debug.Assert(opLevel == OP_BOTTOM_LEVEL);    // op level must be 4
         var node = ASTBuilder.FirstChild(parseTree); // Operator4Expression -> Operator3Expression
         // Operator3Expression -> (prefix_operator)* Operator2Expression
         var childs = ASTBuilder.Children(node).Reverse().GetEnumerator();
         Debug.Assert(childs.MoveNext());
         var op2       = childs.Current; // last child -> Operator2Expression
         var op2Childs = ASTBuilder.RevChildrenEnumerator(op2);
         Debug.Assert(op2Childs.MoveNext());
         return(AddPrefixOperators(3, ParseOperator2(op2Childs), childs));
     }
 }