private static ValueBase InstantiateUserValue(bool isRetweeter, TokenReader reader) { var selector = (Func<ValueBase, ValueBase, ValueBase>) ((user, retweeter) => isRetweeter ? retweeter : user); if (reader.IsRemainToken && reader.LookAhead().Type != TokenType.Period) { // user representation return selector(new User(), new Retweeter()); } reader.AssertGet(TokenType.Period); var literal = reader.AssertGet(TokenType.Literal); switch (literal.Value) { case "protected": case "isProtected": case "is_protected": return selector(new UserIsProtected(), new RetweeterIsProtected()); case "verified": case "isVerified": case "is_verified": return selector(new UserIsVerified(), new RetweeterIsVerified()); case "translator": case "isTranslator": case "is_translator": return selector(new UserIsTranslator(), new RetweeterIsTranslator()); case "contributorsEnabled": case "contributors_enabled": case "isContributorsEnabled": case "is_contributors_enabled": return selector(new UserIsContributorsEnabled(), new RetweeterIsContributorsEnabled()); case "geoEnabled": case "geo_enabled": case "isGeoEnabled": case "is_geo_enabled": return selector(new UserIsGeoEnabled(), new RetweeterIsGeoEnabled()); case "id": return selector(new UserId(), new RetweeterId()); case "status": case "statuses": case "statusCount": case "status_count": case "statusesCount": case "statuses_count": return selector(new UserStatuses(), new RetweeterStatuses()); case "friend": case "friends": case "following": case "followings": case "friendsCount": case "friends_count": case "followingsCount": case "followings_count": return selector(new UserFriends(), new RetweeterFriends()); case "follower": case "followers": case "followersCount": case "followers_count": return selector(new UserFollowers(), new RetweeterFollowers()); case "fav": case "favCount": case "favorite": case "favorites": case "fav_count": case "favoriteCount": case "favorite_count": case "favoritesCount": case "favorites_count": return selector(new UserFavroites(), new RetweeterFavroites()); case "list": case "listed": case "listCount": case "list_count": case "listedCount": case "listed_count": return selector(new UserListed(), new RetweeterListed()); case "screenName": case "screen_name": return selector(new UserScreenName(), new RetweeterScreenName()); case "name": return selector(new UserName(), new RetweeterName()); case "bio": case "desc": case "description": return selector(new UserDescription(), new RetweeterDescription()); case "loc": case "location": return selector(new UserLocation(), new RetweeterLocation()); case "lang": case "language": return selector(new UserLanguage(), new RetweeterLanguage()); default: throw new FilterQueryException("Unexpected token: " + literal.Value, "user." + literal.Value + " " + reader.RemainQuery); } }
private static ValueBase InstantiateValue(TokenReader reader) { var literal = reader.LookAhead(); if (literal.Type == TokenType.String) { // immediate string value return new StringValue(reader.AssertGet(TokenType.String).Value); } else if (literal.Type == TokenType.OperatorMultiple) { // for parsing asterisk user var _pseudo = reader.AssertGet(TokenType.OperatorMultiple); literal = new Token(TokenType.Literal, "*", _pseudo.DebugIndex); } else { literal = reader.AssertGet(TokenType.Literal); } // check first layers switch (literal.Value) { case "*": return InstantiateLocalUsers("*", reader); case "local": reader.AssertGet(TokenType.Period); return InstantiateLocalUsers(reader.AssertGet(TokenType.Literal).Value, reader); case "user": case "retweeter": return InstantiateUserValue(literal.Value == "retweeter", reader); default: long iv = 0; if (Int64.TryParse(literal.Value, out iv)) { return new NumericValue(iv); } else { return InstantiateStatusValue(literal.Value, reader); } } }
private static ValueBase InstantiateLocalUsers(string value, TokenReader reader) { var repl = GetRepresentation(value); if (reader.IsRemainToken && reader.LookAhead().Type == TokenType.Period) { reader.AssertGet(TokenType.Period); var literal = reader.AssertGet(TokenType.Literal); switch (literal.Value) { case "friend": case "friends": case "following": case "followings": return new LocalUserFollowings(repl); case "follower": case "followers": return new LocalUserFollowers(repl); default: throw new FilterQueryException("Unexpected token: " + literal.Value, repl.ToQuery() + "." + literal.Value + " " + reader.RemainQuery); } } else { return new LocalUser(repl); } }
private static FilterOperatorBase GenerateSink( TokenReader reader, FilterOperatorBase leftValue, TokenType type, FilterTwoValueOperator oper, Func<TokenReader, FilterOperatorBase> selfCall) { reader.AssertGet(type); var rightValue = selfCall(reader); oper.LeftValue = leftValue; oper.RightValue = rightValue; return oper; }
/// <summary> /// Instantiate sources from tokens. /// </summary> private static IEnumerable<FilterSourceBase> CompileSources(IEnumerable<Token> token) { // filter // filter: "argument" // filter: "argument1", "argument2", ... -> filter: "argument1", filter: "argument2", ... var reader = new TokenReader(token); while (reader.IsRemainToken) { var filter = reader.AssertGet(TokenType.Literal); Type fstype; if (!FilterSourceResolver.TryGetValue(filter.Value, out fstype)) throw new ArgumentException("Unexpected filter type: " + filter.Value); if (reader.IsRemainToken && reader.LookAhead().Type == TokenType.Collon) // with argument { reader.AssertGet(TokenType.Collon); do { var argument = reader.AssertGet(TokenType.String); yield return Activator.CreateInstance(fstype, argument.Value) as FilterSourceBase; // separated by comma if (reader.IsRemainToken) { reader.AssertGet(TokenType.Comma); } } while (reader.IsRemainToken && reader.LookAhead().Type == TokenType.String); } else { yield return Activator.CreateInstance(fstype) as FilterSourceBase; if (reader.IsRemainToken) { // filters are divided by comma reader.AssertGet(TokenType.Comma); } } } }
private static FilterOperatorBase CompileL8(TokenReader reader) { if (reader.LookAhead().Type == TokenType.OpenBracket) { // in bracket reader.AssertGet(TokenType.OpenBracket); var ret = CompileL0(reader); reader.AssertGet(TokenType.CloseBracket); return new FilterBracket(ret); } else { return InstantiateValue(reader); } }
private static FilterOperatorBase CompileL7(TokenReader reader) { // parse not if (reader.LookAhead().Type == TokenType.Exclamation) { reader.AssertGet(TokenType.Exclamation); return new FilterNegate() { Value = CompileL7(reader) }; } else { return CompileL8(reader); } }