private void OverrideBnfTermKindInCaseOfSpecificInfo(BnfTerm current, ref BnfTermKind currentKind) { if (IsFlaggedOperator(current)) { currentKind = BnfTermKind.Operator; _flaggedOrDerivedOperatorToMultiOperatorInfo[current] = new MultiOperatorInfo(current, current); } else if (current.IsOpenBrace()) { currentKind = BnfTermKind.LeftParenthesis; } else if (current.IsCloseBrace()) { currentKind = BnfTermKind.RightParenthesis; } else if (current is GrammarHint) { currentKind = BnfTermKind.GrammarHint; } }
private BnfTermKind CalculateBnfTermKindForNonTerminal(NonTerminal current) { BnfTermKind?currentKind = null; var childOperators = new List <BnfTerm>(); foreach (BnfTermList children in Unparser.GetChildBnfTermListsLeftToRight(current)) { int operatorCount = 0; int leftParenthesisCount = 0; int rightParenthesisCount = 0; int otherCount = 0; /* * NOTE: we should not read bnfTermToBnfTermKind in this method (because of recursive definitions in grammar), * that's why we store BnfTermKind as well * */ BnfTerm prevChild = null; BnfTermKind? prevChildKind = null; ParenthesizedExpression parentheses = null; BnfTerm childExpression = null; if (children.Count == 0) { continue; } BnfTerm childOperator = null; foreach (BnfTerm child in children) { BnfTermKind childKind = CalculateBnfTermKind(child); Debug.Assert(childKind != BnfTermKind.Undetermined); #region Handle childKind switch (childKind) { case BnfTermKind.Operator: operatorCount++; childOperator = child; childExpression = null; parentheses = null; break; case BnfTermKind.LeftParenthesis: leftParenthesisCount++; parentheses = new ParenthesizedExpression() { LeftParenthesis = child }; childExpression = null; break; case BnfTermKind.RightParenthesis: rightParenthesisCount++; if (prevChildKind == BnfTermKind.Other && childExpression == prevChild) { Debug.Assert(parentheses != null && parentheses.LeftParenthesis != null && parentheses.Expression != null); parentheses.RightParenthesis = child; ParenthesizedExpression registeredParentheses; if (_expressionToParentheses.TryGetValue(childExpression, out registeredParentheses)) { if (parentheses != registeredParentheses) { _expressionToParentheses[childExpression] = null; // ambiguous parentheses -> set to null, and check later (we might not need the parentheses at all) } } else { _expressionToParentheses.Add(childExpression, parentheses); } } childExpression = null; parentheses = null; break; case BnfTermKind.Other: otherCount++; if (prevChildKind == BnfTermKind.LeftParenthesis) { Debug.Assert(parentheses != null && parentheses.LeftParenthesis != null); childExpression = child; parentheses.Expression = childExpression; } else { childExpression = null; parentheses = null; } break; } #endregion if (childKind != BnfTermKind.GrammarHint) { prevChild = child; prevChildKind = childKind; } } #region Determine childListLooksLike BnfTermKind?childListLooksLike; if (operatorCount == 1 && leftParenthesisCount == 0 && rightParenthesisCount == 0 && otherCount == 0) { childListLooksLike = BnfTermKind.Operator; } else if (leftParenthesisCount == 1 && operatorCount == 0 && rightParenthesisCount == 0 && otherCount == 0) { childListLooksLike = BnfTermKind.LeftParenthesis; } else if (rightParenthesisCount == 1 && operatorCount == 0 && leftParenthesisCount == 0 && otherCount == 0) { childListLooksLike = BnfTermKind.RightParenthesis; } else { childListLooksLike = BnfTermKind.Other; } #endregion if (childListLooksLike == BnfTermKind.Operator) { childOperators.Add(childOperator); } #region Determine currentKind if ((currentKind == null || currentKind == BnfTermKind.Operator) && childListLooksLike == BnfTermKind.Operator) { currentKind = BnfTermKind.Operator; } else if ((currentKind == null || currentKind == BnfTermKind.LeftParenthesis) && childListLooksLike == BnfTermKind.LeftParenthesis) { currentKind = BnfTermKind.LeftParenthesis; } else if ((currentKind == null || currentKind == BnfTermKind.RightParenthesis) && childListLooksLike == BnfTermKind.RightParenthesis) { currentKind = BnfTermKind.RightParenthesis; } else { currentKind = BnfTermKind.Other; } #endregion } if (currentKind == BnfTermKind.Operator) { HandleOperators(current, childOperators); } return(currentKind ?? BnfTermKind.Other); }