예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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);
        }
예제 #5
0
 /// <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);
     }
 }
예제 #6
0
 /// <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;
     }
 }
예제 #7
0
 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;
 }
예제 #8
0
 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;
 }
예제 #9
0
        /// <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);
            }
        }
예제 #10
0
 /// <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;
 }
예제 #11
0
 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;
 }