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);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Matches all results from the specified <paramref name="parser"/> that equal the specified
        /// <paramref name="value"/> using the specified <paramref name="comparer"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the source elements.</typeparam>
        /// <typeparam name="TResult">The type of the elements that are generated from parsing the source elements.</typeparam>
        /// <param name="parser">The parser from which matches equivalent to the specified <paramref name="value"/> will be yielded.</param>
        /// <param name="value">The value to be compared to matches for equality.</param>
        /// <param name="comparer">The object that compares matches to the specified <paramref name="value"/> for equality.</param>
        /// <returns>A parser that matches only those results from the specified <paramref name="parser"/> that equal
        /// the specified <paramref name="value"/> using the specified <paramref name="comparer"/>.</returns>
        public static IObservableParser <TSource, TResult> Of <TSource, TResult>(
            this IObservableParser <TSource, TResult> parser,
            TResult value,
            IEqualityComparer <TResult> comparer)
        {
            Contract.Requires(parser != null);
            Contract.Requires(comparer != null);
            Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null);

            return(parser.Where(v => comparer.Equals(v, value)));
        }
Exemplo n.º 3
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));
        }
        protected XmlObservableParser(bool caseSensitive)
        {
            comparer = caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;

            id = Character(char.IsLetter)
                 .And(
                Character(char.IsLetterOrDigit).NoneOrMore())
                 .Join();

            const char tagStartChar = '<';
            const char tagEndChar   = '>';

            tagStart = Character(tagStartChar);
            tagEnd   = Character(tagEndChar);

            tagName = id;

            openTag = (namePredicate, attributes) =>
                      from _ in tagStart
                      from name in tagName.Where(namePredicate)
                      from attrs in attributes
                      from __ in InsignificantWhiteSpace
                      from empty in Character('/').Maybe()
                      from ___ in tagEnd
                      select Tuple.Create(name, attrs, empty.Any());

            attributeDelimiter = Character('\'').Or(Character('"'));

            attributeName = id;

            attributeValue = from delimeter in attributeDelimiter
                             from value in AnyCharacterUntil(delimeter)
                             from _ in Character(delimeter)
                             select value;

            attribute = predicate => from _ in InsignificantWhiteSpace
                        from name in attributeName.Where(predicate)
                        from __ in InsignificantWhiteSpace
                        from ___ in Character('=')
                        from ____ in InsignificantWhiteSpace
                        from value in attributeValue
                        select new XAttribute(name, value);

            closeTag = from _ in tagStart.And(Character('/'))
                       from name in tagName
                       from __ in InsignificantWhiteSpace
                       from ___ in tagEnd
                       select name;

            text = AnyCharacterUntil(tagStartChar).Select(t => new XText(t));

            comment = from _ in Word(tagStartChar + "!--")
                      from value in AnyCharacterUntil("--")
                      from __ in Word("--" + tagEndChar)
                      select new XComment(value);

            string startCData = tagStartChar + "![CDATA[";
            string endCData   = "]]" + tagEndChar;

            cData = from _ in Word(startCData)
                    from value in AnyCharacterUntil(endCData)
                    from __ in Word(endCData)
                    select new XCData(value);

            element = (namePredicate, attributes, elementContent) =>
                      from _ in InsignificantWhiteSpace
                      let open = openTag(namePredicate, attributes)
                                 from tag in open
                                 from isEmpty in tag.Item3
                                 from children in isEmpty
          ? open.Success(Observable.Empty <XObject>())
          : elementContent.IgnoreTrailing(
                InsignificantWhiteSpace.IgnoreBefore(
                    closeTag))
                                 from array in tag.Item2.Concat(children).ToArray()
                                 select new XElement(tag.Item1, array);
        }