private YSection ParseInternal(IReadOnlyList <Token> tokens)
        {
            // 戻り値用変数の準備
            var result = new YSection();

            for (int i = 0; i < tokens.Count;)
            {
                switch (tokens[i].Type)
                {
                case TokenType.Name:                         // 名前なら
                    // 名前を保持
                    string name = tokens[i].SourceText;
                    // カウンタを進める
                    ++i;
                    // 等号じゃなかったらエラー
                    if (tokens[i].Type != TokenType.Equal)
                    {
                        throw new InvalidSyntaxException(tokens[i]);
                    }
                    // カウンタを進める
                    ++i;
                    // 型指定子を使って型を特定する
                    YNode node;
                    switch (tokens[i].Type)
                    {
                    case TokenType.NullOrEmpty:                                     // 空値なら
                        // カウンタを進める
                        ++i;
                        // インスタンスの生成
                        node = new YNullOrEmpty();
                        break;

                    case TokenType.CommentChar:                                     // コメントなら
                        // カウンタを進める
                        ++i;
                        // インスタンスの生成
                        var com = new YComment();
                        com.HasName = true;                                         // 名前あり
                        // コメント文字列があるなら
                        if (tokens[i].Type == TokenType.CommentText)
                        {
                            com.SetValue(tokens[i].SourceText);
                            ++i;
                        }
                        node = com;
                        break;

                    case TokenType.SectionStart:                                     // セクションなら
                        // カウンタを進める
                        ++i;
                        // 新しいリストにセクションの終わりまでの字句を追加する
                        var list = new List <Token>();
                        int j    = 1;
                        while (j > 0)
                        {
                            if (tokens[i].Type == TokenType.SectionStart)
                            {
                                ++j;
                            }
                            if (tokens[i].Type == TokenType.SectionEnd)
                            {
                                --j;
                            }
                            // リストに追加する
                            list.Add(tokens[i]);
                            // カウンタを進める
                            ++i;
                        }
                        // 終端の SectionEnd を削除
                        list.RemoveAt(list.Count - 1);
                        // 右の処理は必要ない? //// カウンタを進める //++i;
                        // インスタンスの生成
                        node = this.ParseInternal(list);
                        break;

                    case TokenType.String:                                     // 文字列なら
                        // インスタンスの生成
                        var str = new YString();
                        str.SetEscapedText(tokens[i].SourceText);
                        // カウンタを進める
                        ++i;
                        node = str;
                        break;

                    case TokenType.Number:                                     // 数値なら
                        // インスタンスの生成
                        var num = new YNumber();
                        num.UInt64Value = ulong.Parse(tokens[i].SourceText);
                        // カウンタを進める
                        ++i;
                        node = num;
                        break;

                    case TokenType.Boolean:                                     // 論理値なら
                        // インスタンスの生成
                        var flg = new YBoolean();
                        flg.Flag = tokens[i].SourceText == "T";
                        // カウンタを進める
                        ++i;
                        node = flg;
                        break;

                    default:                                     // それ以外、例外を発生させる
                        throw new InvalidSyntaxException(tokens[i]);
                    }
                    node.Name = name;
                    result.Add(node);
                    break;

                case TokenType.CommentChar:                         // コメントなら
                    // カウンタを進める
                    ++i;
                    // インスタンスの生成
                    var obj = new YComment();
                    // プロパティの設定
                    obj.Name    = Guid.NewGuid().ToString().Replace("{", "").Replace("}", "").Replace("-", "_");
                    obj.HasName = false;
                    // もしコメント文字列があるなら設定
                    if (tokens[i].Type == TokenType.CommentText)
                    {
                        obj.SetValue(tokens[i].SourceText);
                        ++i;
                    }
                    // 結果に追加
                    result.Add(obj);
                    break;

                default:                         // それ以外、例外を発生させる
                    throw new InvalidSyntaxException(tokens[i]);
                }
            }

            // 結果を返す
            return(result);
        }
Exemple #2
0
        private YSection ReadSection(BinaryReader br)
        {
            var result = new YSection();

            // キーの数を取得
            uint kc = br.ReadUInt32();

            // キーの数だけ繰り返す
            for (uint i = 0; i < kc; ++i)
            {
                // 名前の文字列長を取得
                ulong nmsz;
                switch (Header.KeyNameSize)
                {
                // 8ビット
                case KeyNameSize.HWord:
                    nmsz = br.ReadByte();
                    break;

                // 16ビット
                case KeyNameSize.Word:
                    nmsz = br.ReadUInt16();
                    break;

                // 32ビット
                case KeyNameSize.DWord:
                    nmsz = br.ReadUInt32();
                    break;

#if false
                // 64ビット
                case KeyNameSize.QWord:
                    nmsz = br.ReadUInt64();
                    break;
#endif
                default:
                    // ここには来ない筈
                    nmsz = 0;
                    break;
                }
                // 文字列値分のバイト配列を取得
                byte[] bName = br.ReadBytes(unchecked ((int)(nmsz)));
                // バイト配列をデコードして名前に変換
                string name = Header.GetEncoding().GetString(bName);
                // 型識別子の取得
                byte t = br.ReadByte();
                // 値の取得
                YNode node;
                switch (t)
                {
                // セクション
                case 0x01:
                    node = ReadSection(br);
                    break;

                // 文字列
                case 0x02:
                    var    str  = new YString();
                    int    sz   = br.ReadInt32();
                    byte[] bStr = br.ReadBytes(sz);
                    string val  = Encoding.Unicode.GetString(bStr);
                    str.SetEscapedText(val);
                    node = str;
                    break;

                // 整数値
                case 0x03:
                    node = new YNumber()
                    {
                        UInt64Value = br.ReadUInt64()
                    };
                    break;

                // 真理値
                case 0x04:
                    node = new YBoolean()
                    {
                        Flag = true
                    };
                    break;

                // 偽理値
                case 0x05:
                    node = new YBoolean()
                    {
                        Flag = false
                    };
                    break;

                // NULL値 | 空値
                default:                         // case 0x00:
                    node = new YNullOrEmpty();
                    break;
                }
                // 名前を設定して現在のセクションに追加
                node.Name = name;
                result.Add(node);
            }

            // 作成したセクションを呼び出し元に返す
            return(result);
        }