Esempio n. 1
0
 private void RegisteringExpressionsThatNeedParentheses(NonTerminal nonTerminal)
 {
     foreach (BnfTermList childBnfTerms in Unparser.GetChildBnfTermListsLeftToRight(nonTerminal))
     {
         Unparse(
             new UnparsableAst(nonTerminal, astValue: null),
             childBnfTerms.Select(childBnfTerm => new UnparsableAst(childBnfTerm, astValue: null)),
             initialization: true
             );
     }
 }
Esempio n. 2
0
        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);
        }