Exemplo n.º 1
0
        /// <summary>
        /// ふるまい情報のインデックステーブルの行追加
        /// </summary>
        private void insertBehaviorTable(MethodVO mth, BehaviorChunk chk)
        {
            string sql = @"insert into t_parsed_behavior
			               (
                             chunkId, methodId, pos, parentId, previousId,
                             indLv, dottedNum, indent, behavior
				           ) values (
                             @chunkId, @methodId, @pos, @parentId, @previousId,
                             @indLv, @dottedNum, @indent, @behavior
			               ) "            ;

            using (SQLiteCommand command2 = conn.CreateCommand())
            {
                SQLiteParameter[] parameters = new SQLiteParameter[] {
                    new SQLiteParameter("@chunkId", (chk.chunkId))
                    , new SQLiteParameter("@methodId", chk.methodId)
                    , new SQLiteParameter("@pos", chk.pos)
                    , new SQLiteParameter("@parentId", chk.parentChunkId)
                    , new SQLiteParameter("@previousId", chk.previousChunkId)
                    , new SQLiteParameter("@indLv", chk.indLv)
                    , new SQLiteParameter("@dottedNum", chk.dottedNum)
                    , new SQLiteParameter("@indent", chk.indent)
                    , new SQLiteParameter("@behavior", chk.behavior)
                };

                command2.CommandText = sql;
                command2.Parameters.AddRange(parameters);
                command2.ExecuteNonQuery();
            }
        }
Exemplo n.º 2
0
 private void writeChunkLine(BehaviorChunk cnk, StreamWriter sw)
 {
     sw.WriteLine("{0}\t{{ \"chunkId\": {1}, \"methodId\": {2},  \"dottedNum\": \"{3}\",  \"behavior\": \"{4}\""
                  + ", \"pos\": {5}, \"parentId\": {6}, \"previousId\": {7} }}",
                  cnk.chunkId, cnk.chunkId, cnk.methodId, cnk.dottedNum, escapeJson(cnk.behavior),
                  cnk.pos, cnk.parentChunkId, cnk.previousChunkId);
     // chunkCount++;
 }
Exemplo n.º 3
0
        /// <summary>
        /// SQLiteのDBから属性、操作の値を取得
        /// </summary>
        /// <returns></returns>
        private List <BehaviorChunk> readBehaviorChunks(SQLiteConnection conn, int methodId)
        {
            List <BehaviorChunk> retList = new List <BehaviorChunk>();

            string fields    = @"chunkId, methodId, pos, parentId, previousId, indLv, dottedNum, indent, behavior";
            string whereCond = @" methodId = " + methodId;
            string sql       =
                @"select " + fields +
                " from t_parsed_behavior " +
                " where " + whereCond +
                " order by pos ";

            using (var command = conn.CreateCommand())
            {
                //クエリの実行
                command.CommandText = sql;
                using (var sdr = command.ExecuteReader())
                {
                    //
                    while (sdr.Read())
                    {
                        BehaviorChunk chk = new BehaviorChunk();

                        chk.chunkId         = sdr.GetInt32(0);
                        chk.methodId        = sdr.GetInt32(1);
                        chk.pos             = sdr.GetInt32(2);
                        chk.parentChunkId   = sdr.GetInt32(3);
                        chk.previousChunkId = sdr.GetInt32(4);
                        chk.indLv           = sdr.GetInt32(5);
                        chk.dottedNum       = sdr.GetString(6);
                        chk.indent          = sdr.GetString(7);
                        chk.behavior        = sdr.GetString(8);

                        retList.Add(chk);
                    }
                }
            }

            // 一件でも取得できたらtrueを返す
            return(retList);
        }
Exemplo n.º 4
0
        /// <summary>
        /// トークナイズを試みる(tryを付けているのはインプットのふるまいの記述ルールに
        /// 揺れがあり実効性が不明なため)
        /// </summary>
        /// <param name="c">ふるまいチャンク</param>
        /// <returns>取得されたトークン</returns>
        private BehaviorToken tryTokenize(BehaviorChunk c)
        {
            string origStr    = c.behavior;
            string trimmedStr = getTrimmed(origStr);

            BehaviorToken tokenTop = new BehaviorToken();
            Match         matche;

            // 変数とかインスタンスを生成しつつ初期値をセットする
            matche = Regex.Match(trimmedStr, "(.*)を生成し、?(.*)を(セット|設定)する");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_DEFINE;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, "var", TokenType.TOKEN_DECLARE_LABEL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }

            // 型宣言と値代入を同時に行う場合
            // 例: OPEN用フライト情報にフライト情報を生成してセットする
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)を、?生成してセットする");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_DEFINE_WITH_TYPE;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_TYPE);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }


            // 変数とかインスタンスの生成(名前=型のやつ)
            matche = Regex.Match(trimmedStr, "(.*)を生成する");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_DECLARE;
                var g1 = matche.Groups[1];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ELEMENT_NAME);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }


            // メソッド呼び出しで戻り値を取らないパターン
            matche = Regex.Match(trimmedStr, "(.*)を呼び出す");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_CALL_METHOD;
                var g1 = matche.Groups[1];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_METHOD_NAME);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // メソッド呼び出しで戻り値を取るパターン
            matche = Regex.Match(trimmedStr, "(.*)を呼び?出し、?(.*)(に戻り値)?を(セット|取得)する");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_CALL_METHOD_TAKE_RETURN;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // メソッド呼び出しで戻り値を取るパターン(別バージョン)
            // 日付操作ユーティリティ.日付分割処理(空席照会条件入力・空席照会検索条件.往路搭乗日,\n定数クラス.日付セパレートキー(年))を呼び出し、取得した分割搭乗年を(変数)搭乗年 にセットする。
            matche = Regex.Match(trimmedStr, "(.*)を呼び?出し、?取得した(.*)を(.*)にセットする");
            if (matche.Success)
            {
                tokenTop.token = tokenTop.token = STMT_TYPE_CALL_METHOD_TAKE_RETURN;

                var g1 = matche.Groups[1];
                var g3 = matche.Groups[3];

                addToken(tokenTop, g3.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // リターン文
            // 例: 表示可能運賃存在フラグをリターンする。
            matche = Regex.Match(trimmedStr, "(.*)をリターンする");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_RETURN;
                var g1 = matche.Groups[1];

                addToken(tokenTop, "return ", TokenType.TOKEN_RETURN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // 型変換(Class Cast)を伴う代入式のパターン
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)に変換した(.*)を(セット|設定)(する|し)");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_LET_WITH_CAST;

                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];
                var g3 = matche.Groups[3];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);

                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ELEMENT_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                addToken(tokenTop, g3.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // 代入式のパターン
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)を(セット|設定)(する|し)");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_LET;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_EXPR_IDENTIFIER);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // 代入式のパターン(その2) ※ルール的にはダメなやつ
            matche = Regex.Match(trimmedStr, "(.*)を、?(.*)に(セット|設定)(する|し)");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_LET;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(evaluateAssignmentExpression(tokenTop));
            }


            // if文の条件式のパターン(「~の場合」で文が終わる)
            matche = Regex.Match(trimmedStr, "(.*)の場合[。、]?\\s*$");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_IF_COND;
                var g1 = matche.Groups[1];

                addToken(tokenTop, "if", TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // ループ
            // 例: フライト情報リストの要素数分ループし、以下の処理を繰り返す(ループカウンタ:i)
            matche = Regex.Match(trimmedStr, "(.*)の要素数分(ループし)?、*以下(の処理)?を繰り?返え?す。?\\(ループカウンタ[::](.*)\\)");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_FOREACH_COLLECTION_W_INDEX;
                Group g1 = matche.Groups[1];
                Group g2 = matche.Groups[4];

                addToken(tokenTop, "for", TokenType.TOKEN_FOREACH);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, "int", TokenType.TOKEN_INSTANCE_TYPE);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);
                addToken(tokenTop, "0", TokenType.TOKEN_LITERAL);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "<", TokenType.TOKEN_OPER_LESSTHAN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, ".", TokenType.TOKEN_OPER_DOT);
                addToken(tokenTop, "Count", TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "++", TokenType.TOKEN_OPER_INCREMENT);

                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // ループ
            // 例: フライト情報リストの要素数分ループし、以下の処理を繰り返す
            matche = Regex.Match(trimmedStr, "(.*)の要素数分(ループし)?、*以下の処理を繰り?返え?す");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_FOREACH_COLLECTION;
                var g1 = matche.Groups[1];

                addToken(tokenTop, "for", TokenType.TOKEN_FOREACH);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // コレクションをなめるループをしている中で、コレクションから1要素を取り出す記述
            // 合わせて、変数名などに「〇〇リスト」と名付けておくだけで
            // 「〇〇」という型のコレクションであるという宣言をしていることになるらしい。
            // 例: フライト情報リスト(i)をフライト情報として取得する。
            matche = Regex.Match(trimmedStr, "(.*)\\(([i-n])\\)を(.*)として取得する");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_FOREACH_PICKUP;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];
                var g3 = matche.Groups[3];

                addToken(tokenTop, g3.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_OPER_EQUAL);

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, "[", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, "]", TokenType.TOKEN_PARENTHESIS_END);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // break(ループを抜ける)
            // ループを抜ける。
            matche = Regex.Match(trimmedStr, "ループを抜ける");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_LOOP_BREAK;

                addToken(tokenTop, "break", TokenType.TOKEN_BREAK);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // continue(ループの先頭に戻る)
            // ループの先頭に戻る。
            matche = Regex.Match(trimmedStr, "ループの先頭に戻る");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_LOOP_CONTINUE;

                addToken(tokenTop, "continue", TokenType.TOKEN_CONTINUE);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // メソッド呼び出しで戻り値を取らないパターン(別パターン)
            // 単にメソッド名だけを書いた文章は、そのメソッドを呼び出し戻り値は無視する、という意味になるらしい。
            matche = Regex.Match(trimmedStr, "(.*)\\((.*)\\)$");
            if (matche.Success)
            {
                tokenTop.token = STMT_TYPE_CALL_METHOD;
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // それ以外はコメント扱いとしてそのまま出力
            tokenTop.token = STMT_TYPE_COMMENT;

            addToken(tokenTop, trimmedStr, TokenType.TOKEN_COMMENT);
            return(tokenTop);

            // return null;
        }
Exemplo n.º 5
0
        /// <summary>
        /// ふるまいの各行を解析し、各行の処理内容を評価する前段階として1行ないし複数行の
        /// 命令に分ける。
        /// </summary>
        /// <param name="tlin"></param>
        /// <param name="idx"></param>
        /// <returns></returns>
        private List <BehaviorChunk> parseBehaviorLines(string[] tlin)
        {
            //Console.WriteLine("start parsedBehavior()");

            List <BehaviorChunk> chunkList = new List <BehaviorChunk>();

            for (int idx = 0; idx < tlin.Length; idx++)
            {
                string l = tlin[idx];

                // ハイフンだけの行は出力外
                Match matche = Regex.Match(l, "^-----*");
                if (matche.Success)
                {
                    continue;
                }

                // 全角・半角空白のtrim()結果が空文字列なら出力外
                string trm = l.Trim(' ', ' ');
                if (trm == "")
                {
                    continue;
                }

                // "1.2.3"の部分のあるふるまい行は、行番号部分を抽出する
                matche = Regex.Match(trm, "^[0-9][0-9.]*");
                if (matche.Success)
                {
                    string bodyText = trm.Substring(matche.Value.Length, trm.Length - matche.Value.Length);

                    BehaviorChunk chunk = new BehaviorChunk();
                    chunk.pos       = idx + 1;
                    chunk.behavior  = bodyText.Trim(' ', ' ');
                    chunk.dottedNum = matche.Value;
                    chunk.indent    = "";
                    if (parsingMethod != null)
                    {
                        chunk.methodId = parsingMethod.methodId;
                    }

                    chunkList.Add(chunk);
                }
                else
                {
                    // そうでないふるまい行は先頭の空白をインデントとして保持し、
                    // 項番はNULLにする
                    matche = Regex.Match(l, "^[  ]*");

                    BehaviorChunk chunk = new BehaviorChunk();
                    chunk.pos       = idx + 1;
                    chunk.behavior  = trm;
                    chunk.dottedNum = "";
                    chunk.indent    = matche.Value;

                    if (parsingMethod != null)
                    {
                        chunk.methodId = parsingMethod.methodId;
                    }

                    chunkList.Add(chunk);
                }
            }

            // 1パスで作成されたふるまいチャンクリストを再度解析(2パス)
            for (int i = 0; i < chunkList.Count; i++)
            {
                bool dottedFlg = false;

                // 1.1のようなドットでつながれた番号を持つ行かを判断
                var chunk = chunkList[i];
                if (chunk.dottedNum != null && chunk.dottedNum != "")
                {
                    dottedFlg = true;
                }

                if (dottedFlg)
                {
                    // 全角ドットの数を数え、インデントレベルを取得
                    chunk.indLv = countChar(chunk.dottedNum, ".") + 1;

                    for (int j = i + 1; j < chunkList.Count; j++)
                    {
                        BehaviorChunk nextChunk = chunkList[j];

                        if (nextChunk.dottedNum == "")
                        {
                            chunk.hasFollower     = true;
                            nextChunk.followeeIdx = i;
                        }
                        else
                        {
                            // ループを抜ける
                            break;
                        }
                    }
                }
                else
                {
                    // 空白の数を数え、インデントレベルを取得
                    chunk.indLv = countChar(chunk.indent, " ") * 2 + countChar(chunk.indent, " ");
                }
            }


            // ふるまいチャンクリストを再度解析し、返却用リストに詰める(3パス)
            List <BehaviorChunk> retList = new List <BehaviorChunk>();
            int saveIndLv = 0;

            for (int i = 0; i < chunkList.Count; i++)
            {
                var chunk = chunkList[i];

                // 後続チャンクが存在したら
                if (chunk.hasFollower)
                {
                    // 後続チャンクが続く限り、ふるまいの内容を自チャンクに付加する(仮想改行文字付き)
                    for (int j = i + 1; j < chunkList.Count; j++)
                    {
                        BehaviorChunk nextChunk = chunkList[j];
                        if (i == nextChunk.followeeIdx)
                        {
                            // 続く処理でインデントレベルがぶつからないように後続チャンクには大きな数をセット
                            nextChunk.indLv = 999;
                            chunk.behavior  = chunk.behavior + "\\n" + nextChunk.behavior;
                        }
                        else
                        {
                            // forを抜ける
                            break;
                        }
                    }
                }

                if (chunk.followeeIdx < 0)
                {
                    chunk.chunkId = chunkCount++;
                    retList.Add(chunk);
                }
            }

            for (int i = 0; i < retList.Count; i++)
            {
                var chunk = retList[i];

                // 2行目以降: 親チャンク、兄弟(インデントレベルが同じ)をセット
                if (i > 0)
                {
                    // 1つ前のインデントレベルと比較し同じだったら
                    if (chunk.indLv == saveIndLv)
                    {
                        // 自分のインデントレベルより小さい最後のチャンクを探し、それを親とみなす
                        chunk.parentChunkId = searchParentChunkId(chunkList, chunk.indLv, i);

                        // 前チャンクID=1つ前の行のチャンクIDをセット
                        chunk.previousChunkId = chunkList[i - 1].chunkId;
                    }
                    // 1つ前のインデントレベルと比較し自分が大きい、もしくは小さい場合で、
                    // かつインデントレベルが0より大きい場合(何かの子になるはず)
                    else if (chunk.indLv > 0)
                    {
                        // 自分のインデントレベルより小さい最後のチャンクを探し、それを親とみなす
                        chunk.parentChunkId = searchParentChunkId(chunkList, chunk.indLv, i);

                        // 自分のインデントレベルと等しい最後のチャンクを探す。かつ小さくなる前にマッチしたものを返す
                        chunk.previousChunkId = searchPreviousChunkId(chunkList, chunk.indLv, i);
                    }
                    // 1つ前のインデントレベルと比較し自分が大きい、もしくは小さい場合で、
                    // かつインデントレベルが0の場合
                    else
                    {
                        // 親の検索は不要で親無しになる
                        chunk.parentChunkId = 0;
                        // 自分のインデントレベルと等しい最後のチャンクを探す。かつ小さくなる前にマッチしたものを返す
                        chunk.previousChunkId = searchPreviousChunkId(chunkList, chunk.indLv, i);
                    }
                }
                // 1行目は親も兄弟もなし
                else
                {
                    chunk.parentChunkId   = 0;
                    chunk.previousChunkId = 0;
                }

                saveIndLv = chunk.indLv;
            }


            return(retList);
        }
Exemplo n.º 6
0
        private BehaviorToken tryTokenize(BehaviorChunk c)
        {
            string origStr    = c.behavior;
            string trimmedStr = getTrimmed(origStr);

            BehaviorToken tokenTop = new BehaviorToken();
            Match         matche;

            // 変数とかインスタンスを生成しつつ初期値をセットする
            matche = Regex.Match(trimmedStr, "(.*)を生成し、?(.*)を(セット|設定)する");
            if (matche.Success)
            {
                tokenTop.token = "[define]";
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, "var", TokenType.TOKEN_DECLARE_LABEL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "=", TokenType.TOKEN_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }

            // 型宣言と値代入を同時に行う場合
            // 例: OPEN用フライト情報にフライト情報を生成してセットする
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)を、?生成してセットする");
            if (matche.Success)
            {
                tokenTop.token = "[define-with-type]";
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_INSTANCE_TYPE);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, "=", TokenType.TOKEN_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }


            // 変数とかインスタンスの生成(名前=型のやつ)
            matche = Regex.Match(trimmedStr, "(.*)を生成する");
            if (matche.Success)
            {
                tokenTop.token = "[declare]";
                var g1 = matche.Groups[1];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ELEMENT_NAME);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_INSTANCE_LABEL);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);

                return(tokenTop);
            }


            // メソッド呼び出しで戻り値を取らないパターン
            matche = Regex.Match(trimmedStr, "(.*)を呼び出す");
            if (matche.Success)
            {
                tokenTop.token = "[call]";
                var g1 = matche.Groups[1];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_METHOD_NAME);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // メソッド呼び出しで戻り値を取るパターン
            matche = Regex.Match(trimmedStr, "(.*)を呼び?出し、?(.*)(に戻り値)?を(セット|取得)する");
            if (matche.Success)
            {
                tokenTop.token = "[receive_response]";
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_EQUAL);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // リターン文
            // 例: 表示可能運賃存在フラグをリターンする。
            matche = Regex.Match(trimmedStr, "(.*)をリターンする");
            if (matche.Success)
            {
                tokenTop.token = "[return]";
                var g1 = matche.Groups[1];

                addToken(tokenTop, "return ", TokenType.TOKEN_RETURN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // 型変換を伴う代入式のパターン
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)に変換した(.*)を(セット|設定)(する|し)");
            if (matche.Success)
            {
                tokenTop.token = "[let_with_conv]";

                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];
                var g3 = matche.Groups[3];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_EQUAL);

                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                addToken(tokenTop, g3.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // 代入式のパターン
            matche = Regex.Match(trimmedStr, "(.*)に、?(.*)を(セット|設定)(する|し)");
            if (matche.Success)
            {
                tokenTop.token = "[let]";
                var g1 = matche.Groups[1];
                var g2 = matche.Groups[2];

                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "=", TokenType.TOKEN_EQUAL);
                addToken(tokenTop, g2.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);

                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            // if文の条件式のパターン(「~の場合」で文が終わる)
            matche = Regex.Match(trimmedStr, "(.*)の場合[。、]?\\s*$");
            if (matche.Success)
            {
                tokenTop.token = "[if-cond]";
                var g1 = matche.Groups[1];

                addToken(tokenTop, "if", TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_ATTRIBUTE_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // ループ
            // 例: フライト情報リストの要素数分ループし、以下の処理を繰り返す(ループカウンタ:i)
            matche = Regex.Match(trimmedStr, "(.*)の要素数分(ループし)?、*以下の処理を繰り?返え?す。?\\(ループカウンタ:(.*)\\)");
            if (matche.Success)
            {
                tokenTop.token = "[foreach-collection]";
                Group g1 = matche.Groups[1];

                Group g2;
                if (matche.Groups[2].ToString() == "ループし")
                {
                    g2 = matche.Groups[3];
                }
                else
                {
                    g2 = matche.Groups[2];
                }

                addToken(tokenTop, "for", TokenType.TOKEN_FOREACH);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // ループ
            // 例: フライト情報リストの要素数分ループし、以下の処理を繰り返す
            matche = Regex.Match(trimmedStr, "(.*)の要素数分(ループし)?、*以下の処理を繰り?返え?す");
            if (matche.Success)
            {
                tokenTop.token = "[foreach-collection]";
                var g1 = matche.Groups[1];

                addToken(tokenTop, "for", TokenType.TOKEN_FOREACH);
                addToken(tokenTop, "(", TokenType.TOKEN_PARENTHESIS_BEGIN);
                addToken(tokenTop, g1.ToString(), TokenType.TOKEN_COLLECTION_NAME);
                addToken(tokenTop, ")", TokenType.TOKEN_PARENTHESIS_END);

                return(tokenTop);
            }

            // break(ループを抜ける)
            // ループを抜ける。
            matche = Regex.Match(trimmedStr, "ループを抜ける");
            if (matche.Success)
            {
                tokenTop.token = "[loop-break]";

                addToken(tokenTop, "break", TokenType.TOKEN_BREAK);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }


            // continue(ループの先頭に戻る)
            // ループの先頭に戻る。
            matche = Regex.Match(trimmedStr, "ループの先頭に戻る");
            if (matche.Success)
            {
                tokenTop.token = "[loop-continue]";

                addToken(tokenTop, "continue", TokenType.TOKEN_CONTINUE);
                addToken(tokenTop, ";", TokenType.TOKEN_SEMICOLON);
                return(tokenTop);
            }

            return(null);
        }