Ejemplo n.º 1
0
        internal string DescribeInstruction(int opcodeOffset)
        {
            RegexOpcode opcode = (RegexOpcode)Codes[opcodeOffset];

            var sb = new StringBuilder();

            sb.Append($"{opcodeOffset:D6} ");
            sb.Append(OpcodeBacktracks(opcode & RegexOpcode.OperatorMask) ? '~' : ' ');
            sb.Append(opcode & RegexOpcode.OperatorMask);
            if ((opcode & RegexOpcode.CaseInsensitive) != 0)
            {
                sb.Append("-Ci");
            }
            if ((opcode & RegexOpcode.RightToLeft) != 0)
            {
                sb.Append("-Rtl");
            }
            if ((opcode & RegexOpcode.Backtracking) != 0)
            {
                sb.Append("-Back");
            }
            if ((opcode & RegexOpcode.BacktrackingSecond) != 0)
            {
                sb.Append("-Back2");
            }

            opcode &= RegexOpcode.OperatorMask;

            switch (opcode)
            {
            case RegexOpcode.One:
            case RegexOpcode.Onerep:
            case RegexOpcode.Oneloop:
            case RegexOpcode.Oneloopatomic:
            case RegexOpcode.Onelazy:
            case RegexOpcode.Notone:
            case RegexOpcode.Notonerep:
            case RegexOpcode.Notoneloop:
            case RegexOpcode.Notoneloopatomic:
            case RegexOpcode.Notonelazy:
                sb.Append(Indent()).Append('\'').Append(RegexCharClass.DescribeChar((char)Codes[opcodeOffset + 1])).Append('\'');
                break;

            case RegexOpcode.Set:
            case RegexOpcode.Setrep:
            case RegexOpcode.Setloop:
            case RegexOpcode.Setloopatomic:
            case RegexOpcode.Setlazy:
                sb.Append(Indent()).Append(RegexCharClass.DescribeSet(Strings[Codes[opcodeOffset + 1]]));
                break;

            case RegexOpcode.Multi:
                sb.Append(Indent()).Append('"').Append(Strings[Codes[opcodeOffset + 1]]).Append('"');
                break;

            case RegexOpcode.Backreference:
            case RegexOpcode.TestBackreference:
                sb.Append(Indent()).Append("index = ").Append(Codes[opcodeOffset + 1]);
                break;

            case RegexOpcode.Capturemark:
                sb.Append(Indent()).Append("index = ").Append(Codes[opcodeOffset + 1]);
                if (Codes[opcodeOffset + 2] != -1)
                {
                    sb.Append(", unindex = ").Append(Codes[opcodeOffset + 2]);
                }
                break;

            case RegexOpcode.Nullcount:
            case RegexOpcode.Setcount:
                sb.Append(Indent()).Append("value = ").Append(Codes[opcodeOffset + 1]);
                break;

            case RegexOpcode.Goto:
            case RegexOpcode.Lazybranch:
            case RegexOpcode.Branchmark:
            case RegexOpcode.Lazybranchmark:
            case RegexOpcode.Branchcount:
            case RegexOpcode.Lazybranchcount:
                sb.Append(Indent()).Append("addr = ").Append(Codes[opcodeOffset + 1]);
                break;
            }

            switch (opcode)
            {
            case RegexOpcode.Onerep:
            case RegexOpcode.Oneloop:
            case RegexOpcode.Oneloopatomic:
            case RegexOpcode.Onelazy:
            case RegexOpcode.Notonerep:
            case RegexOpcode.Notoneloop:
            case RegexOpcode.Notoneloopatomic:
            case RegexOpcode.Notonelazy:
            case RegexOpcode.Setrep:
            case RegexOpcode.Setloop:
            case RegexOpcode.Setloopatomic:
            case RegexOpcode.Setlazy:
                sb.Append(", rep = ").Append(Codes[opcodeOffset + 2] == int.MaxValue ? "inf" : Codes[opcodeOffset + 2]);
                break;

            case RegexOpcode.Branchcount:
            case RegexOpcode.Lazybranchcount:
                sb.Append(", limit = ").Append(Codes[opcodeOffset + 2] == int.MaxValue ? "inf" : Codes[opcodeOffset + 2]);
                break;
            }

            return(sb.ToString());

            string Indent() => new string(' ', Math.Max(1, 25 - sb.Length));
        }