debug.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. //
  2. // assembly: System
  3. // namespace: System.Text.RegularExpressions
  4. // file: debug.cs
  5. //
  6. // author: Dan Lewis ([email protected])
  7. // (c) 2002
  8. using System;
  9. using System.Collections;
  10. namespace System.Text.RegularExpressions {
  11. class Disassembler {
  12. public static void DisassemblePattern (ushort[] image) {
  13. DisassembleBlock (image, 0, 0);
  14. }
  15. public static void DisassembleBlock (ushort[] image, int pc, int depth) {
  16. OpCode op;
  17. OpFlags flags;
  18. for (;;) {
  19. if (pc >= image.Length)
  20. return;
  21. PatternCompiler.DecodeOp (image[pc], out op, out flags);
  22. Console.Write (FormatAddress (pc) + ": "); // address
  23. Console.Write (new string (' ', depth * 2)); // indent
  24. Console.Write (DisassembleOp (image, pc)); // instruction
  25. Console.WriteLine ();
  26. int skip;
  27. switch (op) {
  28. case OpCode.False: case OpCode.True: case OpCode.Until:
  29. skip = 1;
  30. break;
  31. case OpCode.Character: case OpCode.Category: case OpCode.Position:
  32. case OpCode.Open: case OpCode.Close: case OpCode.Reference:
  33. case OpCode.Sub: case OpCode.Branch: case OpCode.Jump: case OpCode.In:
  34. skip = 2;
  35. break;
  36. case OpCode.Balance: case OpCode.IfDefined: case OpCode.Range:
  37. case OpCode.Test: case OpCode.Anchor:
  38. skip = 3;
  39. break;
  40. case OpCode.Repeat: case OpCode.FastRepeat: case OpCode.Info:
  41. skip = 4;
  42. break;
  43. case OpCode.String: skip = image[pc + 1] + 2; break;
  44. case OpCode.Set: skip = image[pc + 2] + 3; break;
  45. default:
  46. skip = 1;
  47. break;
  48. }
  49. pc += skip;
  50. }
  51. }
  52. public static string DisassembleOp (ushort[] image, int pc) {
  53. OpCode op;
  54. OpFlags flags;
  55. PatternCompiler.DecodeOp (image[pc], out op, out flags);
  56. string str = op.ToString ();
  57. if (flags != 0)
  58. str += "[" + flags.ToString ("f") + "]";
  59. switch (op) {
  60. case OpCode.False: case OpCode.True: case OpCode.Until:
  61. default:
  62. break;
  63. case OpCode.Info:
  64. str += " " + image[pc + 1];
  65. str += " (" + image[pc + 2] + ", " + image[pc + 3] + ")";
  66. break;
  67. case OpCode.Character:
  68. str += " '" + FormatChar ((char)image[pc + 1]) + "'";
  69. break;
  70. case OpCode.Category:
  71. str += " /" + (Category)image[pc + 1];
  72. break;
  73. case OpCode.Range:
  74. str += " '" + FormatChar ((char)image[pc + 1]) + "', ";
  75. str += " '" + FormatChar ((char)image[pc + 2]) + "'";
  76. break;
  77. case OpCode.Set:
  78. str += " " + FormatSet (image, pc + 1);
  79. break;
  80. case OpCode.String:
  81. str += " '" + ReadString (image, pc + 1) + "'";
  82. break;
  83. case OpCode.Position:
  84. str += " /" + (Position)image[pc + 1];
  85. break;
  86. case OpCode.Open: case OpCode.Close: case OpCode.Reference:
  87. str += " " + image[pc + 1];
  88. break;
  89. case OpCode.Balance:
  90. str += " " + image[pc + 1] + " " + image[pc + 2];
  91. break;
  92. case OpCode.IfDefined: case OpCode.Anchor:
  93. str += " :" + FormatAddress (pc + image[pc + 1]);
  94. str += " " + image[pc + 2];
  95. break;
  96. case OpCode.Sub: case OpCode.Branch: case OpCode.Jump:
  97. case OpCode.In:
  98. str += " :" + FormatAddress (pc + image[pc + 1]);
  99. break;
  100. case OpCode.Test:
  101. str += " :" + FormatAddress (pc + image[pc + 1]);
  102. str += ", :" + FormatAddress (pc + image[pc + 2]);
  103. break;
  104. case OpCode.Repeat: case OpCode.FastRepeat:
  105. str += " :" + FormatAddress (pc + image[pc + 1]);
  106. str += " (" + image[pc + 2] + ", ";
  107. if (image[pc + 3] == 0xffff)
  108. str += "Inf";
  109. else
  110. str += image[pc + 3];
  111. str += ")";
  112. break;
  113. }
  114. return str;
  115. }
  116. // private static members
  117. private static string ReadString (ushort[] image, int pc) {
  118. int len = image[pc];
  119. char[] chars = new char[len];
  120. for (int i = 0; i < len; ++ i)
  121. chars[i] = (char)image[pc + i + 1];
  122. return new string (chars);
  123. }
  124. private static string FormatAddress (int pc) {
  125. return pc.ToString ("x4");
  126. }
  127. private static string FormatSet (ushort[] image, int pc) {
  128. int lo = image[pc ++];
  129. int hi = (image[pc ++] << 4) - 1;
  130. string str = "[";
  131. bool hot = false;
  132. char a = (char)0, b;
  133. for (int i = 0; i <= hi; ++ i) {
  134. bool m = (image[pc + (i >> 4)] & (1 << (i & 0xf))) != 0;
  135. if (m & !hot) { // start of range
  136. a = (char)(lo + i);
  137. hot = true;
  138. }
  139. else if (hot & (!m || i == hi)) { // end of range
  140. b = (char)(lo + i - 1);
  141. str += FormatChar (a);
  142. if (b != a)
  143. str += "-" + FormatChar (b);
  144. hot = false;
  145. }
  146. }
  147. str += "]";
  148. return str;
  149. }
  150. private static string FormatChar (char c) {
  151. if (c == '-' || c == ']')
  152. return "\\" + c;
  153. if (Char.IsLetterOrDigit (c) || Char.IsSymbol (c))
  154. return c.ToString ();
  155. if (Char.IsControl (c)) {
  156. return "^" + (char)('@' + c);
  157. }
  158. return "\\u" + ((int)c).ToString ("x4");
  159. }
  160. }
  161. }