/// <summary> /// 次の一つのトークンがどれかに合致するか確認します。 /// </summary> /// <param name="reader">リーダートークン</param> /// <param name="isEnd">文末を受け入れるか</param> /// <param name="tokens">可能なトークン集合</param> private static void AssertNextAny(ref TokenReader reader, bool isEnd, params Token.TokenType[] tokens) { var descstr = ""; if (tokens.Count() == 1) { descstr = "ここには " + tokens.First().ToString() + " が存在しなければなりません。"; } else { descstr = "ここには " + String.Join(", ", tokens.Select(s => s.ToString())) + " のうちいずれかが存在しなければなりません。"; } if (!reader.IsRemainToken) { if (isEnd) { return; } reader.PushError("クエリが解析の途中で終了しました。" + descstr); } if (tokens == null) { return; } var lat = reader.LookAhead().Type; if (!tokens.Any(f => f == lat)) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + descstr); } }
private static ArgBodyTuple MakeArgBody(ref TokenReader reader) { System.Diagnostics.Debug.WriteLine("MakeArgBody"); var token = reader.Get(); if (token.Type != Token.TokenType.String && token.Type != Token.TokenType.Literal) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + "フィルタ引数は、単純な文字列かダブルクオートで括られた文字列のみが指定できます。"); } var ret = new ArgBodyTuple() { Arg = token }; AssertNextAny(ref reader, false, Token.TokenType.Comma, Token.TokenType.CloseBracket, Token.TokenType.ConcatenatorAnd, Token.TokenType.ConcatenatorOr); return(ret); }
/// <summary> /// 次に出現するトークンが特定の種類であることを確認し、読みます。<para /> /// 読めなかった場合はリワインドします。 /// </summary> /// <param name="reader">トークン リーダー</param> /// <param name="type">トークンの種類</param> private static Token AssertNext(ref TokenReader reader, Token.TokenType type) { if (!reader.IsRemainToken) { reader.PushError("クエリが解析の途中で終了しました。" + "ここには " + type.ToString() + " が存在しなければなりません。"); } var ntoken = reader.Get(); if (ntoken.Type != type) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + "ここには " + type.ToString() + " が存在しなければなりません。"); return(new Token() { Type = type, Value = null, DebugIndex = -1 }); } return(ntoken); }
private static RootTuple MakeRoot(ref TokenReader reader) { System.Diagnostics.Debug.WriteLine("MakeRoot"); var ret = new RootTuple(); if (reader.IsRemainToken) { ret.Cluster = MakeCluster(ref reader); } if (reader.IsRemainToken) { throw new ArgumentException("クエリが途中で終了しています。閉じ括弧が多すぎる可能性があります。(次のクエリ:" + reader.LookAhead().ToString() + ", インデックス:" + reader.LookAhead().DebugIndex.ToString()); } return(ret); }
/// <summary> /// 次のトークンを先読みし、指定した型であるかを判定します。 /// </summary> /// <param name="reader">トークン リーダー</param> /// <param name="type">先読みするトークンの種類</param> /// <param name="trim">読み込みが合致した時にトークンを読み飛ばす</param> /// <returns>合致すればtrue</returns> private static bool TryLookAhead(ref TokenReader reader, Token.TokenType type, bool trim = true) { if (!reader.IsRemainToken) { return(false); } if (reader.LookAhead().Type == type) { if (trim) { reader.Get(); } return(true); } else { return(false); } }
/// <summary> /// 次のトークンを先読みし、指定した型であるかを判定します。 /// </summary> /// <param name="reader">トークン リーダー</param> /// <param name="type">先読みするトークンの種類</param> /// <param name="trim">読み込みが合致した時にトークンを読み飛ばす</param> /// <returns>合致すればtrue</returns> private static bool TryLookAhead(ref TokenReader reader, Token.TokenType type, bool trim = true) { if (!reader.IsRemainToken) return false; if (reader.LookAhead().Type == type) { if (trim) reader.Get(); return true; } else { return false; } }
private static RootTuple MakeRoot(ref TokenReader reader) { System.Diagnostics.Debug.WriteLine("MakeRoot"); var ret = new RootTuple(); if (reader.IsRemainToken) { ret.Cluster = MakeCluster(ref reader); } if (reader.IsRemainToken) throw new ArgumentException("クエリが途中で終了しています。閉じ括弧が多すぎる可能性があります。(次のクエリ:" + reader.LookAhead().ToString() + ", インデックス:" + reader.LookAhead().DebugIndex.ToString()); return ret; }
private static ArgBodyTuple MakeArgBody(ref TokenReader reader) { System.Diagnostics.Debug.WriteLine("MakeArgBody"); var token = reader.Get(); if (token.Type != Token.TokenType.String && token.Type != Token.TokenType.Literal) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + "フィルタ引数は、単純な文字列かダブルクオートで括られた文字列のみが指定できます。"); } var ret = new ArgBodyTuple() { Arg = token }; AssertNextAny(ref reader, false, Token.TokenType.Comma, Token.TokenType.CloseBracket, Token.TokenType.ConcatenatorAnd, Token.TokenType.ConcatenatorOr); return ret; }
/// <summary> /// 次の一つのトークンがどれかに合致するか確認します。 /// </summary> /// <param name="reader">リーダートークン</param> /// <param name="isEnd">文末を受け入れるか</param> /// <param name="tokens">可能なトークン集合</param> private static void AssertNextAny(ref TokenReader reader, bool isEnd, params Token.TokenType[] tokens) { var descstr = ""; if (tokens.Count() == 1) descstr = "ここには " + tokens.First().ToString() + " が存在しなければなりません。"; else descstr = "ここには " + String.Join(", ", tokens.Select(s => s.ToString())) + " のうちいずれかが存在しなければなりません。"; if (!reader.IsRemainToken) { if (isEnd) return; reader.PushError("クエリが解析の途中で終了しました。" + descstr); } if (tokens == null) return; var lat = reader.LookAhead().Type; if (!tokens.Any(f => f == lat)) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + descstr); } }
/// <summary> /// 次に出現するトークンが特定の種類であることを確認し、読みます。<para /> /// 読めなかった場合はリワインドします。 /// </summary> /// <param name="reader">トークン リーダー</param> /// <param name="type">トークンの種類</param> private static Token AssertNext(ref TokenReader reader, Token.TokenType type) { if (!reader.IsRemainToken) reader.PushError("クエリが解析の途中で終了しました。" + "ここには " + type.ToString() + " が存在しなければなりません。"); var ntoken = reader.Get(); if (ntoken.Type != type) { reader.PushError("不明な文字です: " + reader.LookAhead() + " (インデックス:" + reader.LookAhead().DebugIndex + ")" + "ここには " + type.ToString() + " が存在しなければなりません。"); return new Token() { Type = type, Value = null, DebugIndex = -1 }; } return ntoken; }
private static ExpressionTuple MakeExpression(ref TokenReader reader) { var extuple = new ExpressionTuple() { ExpressionBody = MakeExpressionBody(ref reader) }; if (reader.IsRemainToken) { var ntoken = reader.LookAhead(); switch (ntoken.Type) { case Token.TokenType.ConcatenatorAnd: reader.Get(); extuple.ConcatOr = false; extuple.Expression = MakeExpression(ref reader); break; case Token.TokenType.ConcatenatorOr: reader.Get(); extuple.ConcatOr = true; extuple.Expression = MakeExpression(ref reader); break; case Token.TokenType.CloseBracket: break; default: throw new ArgumentException("トークン " + ntoken.ToString() + " はここに置くことはできません。(@" + ntoken.DebugIndex + ")"); } } return extuple; }