private IObservableParser <char, IObservable <XObject> > Content(
            out IObservableParser <char, IObservable <XAttribute> > attributes,
            IEnumerable <IObservableParser <char, XObject> > content)
        {
            Contract.Requires(content != null);
            Contract.Ensures(Contract.ValueAtReturn(out attributes) != null);
            Contract.Ensures(Contract.Result <IObservableParser <char, IObservable <XObject> > >() != null);

            var contentList = content.ToList();

            var attributeList = contentList.OfType <IObservableParser <char, XAttribute> >().ToList();

            var anyAttribute = attribute(_ => true);

            Contract.Assume(anyAttribute != null);

            attributes = (attributeList.Count == 0)
        ? anyAttribute.None()
        : attributeList.AllUnordered();

            foreach (var a in attributeList)
            {
                contentList.Remove(a);
            }

            var contentWithComments = new List <IObservableParser <char, IObservable <XObject> > >(contentList.Count);

            foreach (var item in contentList)
            {
                Contract.Assume(item != null);

                contentWithComments.Add(Comment.Maybe().And(item));
            }

            /* The original code here used a conditional instead of a full if block to return the result.  At runtime,
             * when targeting Silverlight, it threw an exception: "Operation could destabilize the runtime".  I'm not
             * sure if it was the C# compiler or the Code Contracts rewriter that caused the problem, but expanding it
             * to a full if block has fixed it.
             */
            IObservableParser <char, IObservable <XObject> > result;

            if (contentWithComments.Count == 0)
            {
                result =
                    from noContent in Content(
                        text => text.Where(node => node.Value.Trim().Length > 0),
                        includeComments: false) // excluding comments actually allows them because of .None()
                    .None()
                    from _ in InsignificantWhiteSpace
                    from comments in comment.NoneOrMore()
                    from __ in InsignificantWhiteSpace
                    select comments;
            }
            else
            {
                result = contentWithComments.All();
            }

            return(result);
        }
예제 #2
0
        public MiniMLObservableParser()
        {
            anyId = from _ in InsignificantWhiteSpace
                    from first in Character(char.IsLetter)
                    from remainder in Character(char.IsLetterOrDigit).NoneOrMore().Join()
                    select first + remainder;

            letId    = anyId.Where(id => id == "let");
            inId     = anyId.Where(id => id == "in");
            keyword  = letId.Or(inId);
            identity = anyId.Not(keyword);

            term1 = (from id in identity
                     select(Term) new VarTerm(id))
                    .Or(
                from _ in WsChr('(')
                from t in term
                from __ in WsChr(')')
                select t);

            term = (from _ in WsChr('\\')
                    from id in identity
                    from __ in WsChr('.')
                    from t in term
                    select(Term) new LambdaTerm(id, t))
                   .Or(
                from _ in letId
                from id in identity
                from __ in WsChr('=')
                from rhs in term
                from ___ in inId
                from body in term
                select(Term) new LetTerm(id, rhs, body))
                   .Or(
                from t in term1
                from remainder in term1.NoneOrMore()
                from list in remainder.ToList()
                select(Term) new AppTerm(t, list));
        }
        private IObservableParser <char, XObject> Content(
            Func <IObservableParser <char, XText>, IObservableParser <char, XText> > textSelector,
            bool includeComments = true)
        {
            Contract.Requires(textSelector != null);
            Contract.Ensures(Contract.Result <IObservableParser <char, XObject> >() != null);

            return(ObservableParser.Defer(() =>
            {
                var content = new List <IObservableParser <char, XObject> >(4)
                {
                    element(_ => true, AnyAttribute.NoneOrMore(), Content(textSelector, includeComments).NoneOrMore()),
                    textSelector(text),
                    cData
                };

                if (includeComments)
                {
                    content.Add(comment);
                }

                return content.Any();
            }));
        }