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); }
/// <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))); }
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); }