public TokenRange GetMatchingRangeIn(TokenRange range) { Func <Token, bool> pred; int dir; switch (Value) { case "(": pred = t => t.Value != ")" || t.ParenDepth != ParenDepth; dir = +1; break; case ")": pred = t => t.Value != "(" || t.ParenDepth != ParenDepth; dir = -1; break; case "{": pred = t => t.Value != "}" || t.BraceDepth != BraceDepth; dir = +1; break; case "}": pred = t => t.Value != "{" || t.BraceDepth != BraceDepth; dir = -1; break; case "<": return (new TokenRange(range.GetAllTokens(), Position + 1, AngleBracketParser.NotInsideAngleBrackets( new TokenRange(range.GetAllTokens(), Position, range.End)) .Skip(1) // skip the "<", which is considered "outside" .First() // get the ">", which is likewise "outside" .Position)); default: throw new NotSupportedException("Can't match this token!"); } TokenRange r; if (dir == -1) { r = new TokenRange(range.GetAllTokens(), range.Begin, Position) .RevTakeWhile(pred); if (r.Begin == range.Begin) { throw new Error(SourceLine, "Syntax error: Unmatched " + Value); } } else { r = new TokenRange(range.GetAllTokens(), Position + 1, range.End) .TakeWhile(pred); if (r.End == range.End) { throw new Error(SourceLine, "Syntax error: Unmatched " + Value); } } return(r); }