PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/lib/engines/simple_parser_engine.php

http://textmotion.googlecode.com/
PHP | 157 lines | 101 code | 31 blank | 25 comment | 42 complexity | 100e2a3e602928e7c283823b7bed463d MD5 | raw file
Possible License(s): MIT, CC0-1.0
  1. <?php
  2. /**
  3. * Simple Parser Engine
  4. * Finds text between given delimiters and evaluates the enclosed buffer.
  5. * ---
  6. * Written by Jose Carlos Nieto <xiam@menteslibres.org>
  7. * Copyright (c) 2007 Astrata Software S.A. de C.V.
  8. *
  9. * Licensed under The MIT License
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @author Jose Carlos Nieto <xiam@menteslibres.org>
  13. * @copyright Copyright (c) 2007-2008, Astrata Software S.A. de C.V.
  14. * @link http://opensource.astrata.com.mx Astrata Open Source Projects
  15. * @version $Revision: $
  16. * @modifiedby $LastChangedBy: $
  17. * @lastmodified $Date: $
  18. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  19. *
  20. */
  21. class simple_parser_engine extends tm_object {
  22. public $escape_char = null;
  23. public $delimiters = array();
  24. public $use_stack = false;
  25. public $recursive = true;
  26. public function set_delimiters($arr) {
  27. $this->delimiters = $arr;
  28. }
  29. public function eval_enclosed($buff, $delimiter) {
  30. return $buff;
  31. }
  32. public function parse(&$buff) {
  33. $stack = array();
  34. $search_for_index = -1;
  35. for ($i = 0; isset($buff[$i]); $i++) {
  36. foreach ($this->delimiters as $index => $delimiter) {
  37. if ($search_for_index == -1 || $search_for_index == $index) {
  38. // escape sequences
  39. if ($search_for_index == -1 && $this->escape_char) {
  40. if ($buff[$i] == $this->escape_char && isset($buff[$i+1])) {
  41. $break = false;
  42. // checking if this escape sequence is before a delimiting character
  43. for ($j = 0; $break == false && $j <= 1; $j++) {
  44. if ($buff[$i+1] == $delimiter[$j]{0}) {
  45. $buff = substr($buff, 0, $i).substr($buff, $i + 1);
  46. $break = true;
  47. }
  48. }
  49. if ($break) {
  50. break;
  51. }
  52. }
  53. }
  54. // lenght of start delimiter
  55. $len = strlen($delimiter[0]);
  56. $match = ($len > 0);
  57. if ($match && isset($buff[$i+$len-1])) {
  58. for ($j = 0; $match && $j < $len; $j++) {
  59. if ($buff[$i+$j] != $delimiter[0][$j]) {
  60. $match = false;
  61. }
  62. }
  63. if ($match) {
  64. if (!$stack) {
  65. $search_for_index = $index;
  66. }
  67. array_push($stack, $i);
  68. $i = $i + $len;
  69. $i = $i - 1;
  70. break;
  71. }
  72. }
  73. if ($stack) {
  74. // length of ending delimiter
  75. $len = strlen($delimiter[1]);
  76. $match = ($len > 0);
  77. if ($match && isset($buff[$i+$len-1])) {
  78. for ($j = 0; $match && $j < $len; $j++) {
  79. if ($buff[$i+$j] != $delimiter[1][$j]) {
  80. $match = false;
  81. }
  82. }
  83. if ($match) {
  84. // what did we close?
  85. $start = array_pop($stack);
  86. if (substr($buff, $start, strlen($delimiter[0])) == $delimiter[0]) {
  87. $i = $i + $len;
  88. $portion = substr($buff, $start, $i - $start);
  89. if ($this->recursive) {
  90. if ($stack) {
  91. // silently discarding this break point
  92. $i -= 1;
  93. break;
  94. } else {
  95. $portion = substr($portion, strlen($delimiter[0]), -1*strlen($delimiter[1]));
  96. if ($this->parse($portion)) {
  97. $portion = $delimiter[0].$portion.$delimiter[1];
  98. $search_for_index = -1;
  99. } else {
  100. debug('PANIC!');
  101. return false;
  102. }
  103. }
  104. }
  105. $portion = $this->eval_enclosed($portion, $delimiter);
  106. $search_for_index = -1;
  107. $buff = substr($buff, 0, $start).$portion.substr($buff, $i);
  108. $i = $start + strlen($portion);
  109. $i = $i - 1;
  110. } else {
  111. array_push($stack, $start);
  112. }
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. if ($stack) {
  120. debug("Filter syntax error near '".substr($buff, array_pop($stack), 60)."'");
  121. return false;
  122. }
  123. return true;
  124. }
  125. }
  126. ?>