pcre2pire.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "pcre2pire.h"
  2. #include <util/generic/vector.h>
  3. #include <util/generic/yexception.h>
  4. TString Pcre2Pire(const TString& src) {
  5. TVector<char> result;
  6. result.reserve(src.size() + 1);
  7. enum EState {
  8. S_SIMPLE,
  9. S_SLASH,
  10. S_BRACE,
  11. S_EXPECT_Q,
  12. S_QUESTION,
  13. S_P,
  14. S_COMMA,
  15. S_IN,
  16. };
  17. EState state = S_SIMPLE;
  18. for (ui32 i = 0; i < src.size(); ++i) {
  19. const char c = src[i];
  20. switch (state) {
  21. case S_SIMPLE:
  22. if (c == '\\') {
  23. state = S_SLASH;
  24. } else if (c == '(') {
  25. state = S_BRACE;
  26. } else if (c == '*' || c == '?') {
  27. state = S_EXPECT_Q;
  28. result.push_back(c);
  29. } else {
  30. if (c == ')' && result.size() > 0 && result.back() == '(') {
  31. // eliminating "()"
  32. result.pop_back();
  33. } else {
  34. result.push_back(c);
  35. }
  36. }
  37. break;
  38. case S_SLASH:
  39. state = S_SIMPLE;
  40. if (c == ':' || c == '=' || c == '#' || c == '&') {
  41. result.push_back(c);
  42. } else {
  43. result.push_back('\\');
  44. --i;
  45. }
  46. break;
  47. case S_BRACE:
  48. if (c == '?') {
  49. state = S_QUESTION;
  50. } else {
  51. state = S_COMMA;
  52. --i;
  53. }
  54. break;
  55. case S_EXPECT_Q:
  56. state = S_SIMPLE;
  57. if (c != '?') {
  58. --i;
  59. }
  60. break;
  61. case S_QUESTION:
  62. if (c == 'P') {
  63. state = S_P;
  64. } else if (c == ':' || c == '=') {
  65. state = S_COMMA;
  66. } else {
  67. ythrow yexception() << "Pcre to pire convertaion failed: unexpected symbol '" << c << "' at posiotion " << i << "!";
  68. }
  69. break;
  70. case S_P:
  71. if (c == '<') {
  72. state = S_IN;
  73. } else {
  74. ythrow yexception() << "Pcre to pire convertaion failed: unexpected symbol '" << c << "' at posiotion " << i << "!";
  75. }
  76. break;
  77. case S_IN:
  78. if (c == '>') {
  79. state = S_COMMA;
  80. } else {
  81. // nothing to do
  82. }
  83. break;
  84. case S_COMMA:
  85. state = S_SIMPLE;
  86. if (c == ')') {
  87. // nothing to do
  88. } else {
  89. result.push_back('(');
  90. --i;
  91. }
  92. break;
  93. default:
  94. ythrow yexception() << "Pcre to pire convertaion failed: unexpected automata state!";
  95. }
  96. }
  97. if (state != S_SIMPLE && state != S_EXPECT_Q) {
  98. ythrow yexception() << "Pcre to pire convertaion failed: unexpected end of expression!";
  99. }
  100. result.push_back('\0');
  101. return &result[0];
  102. }