PageRenderTime 34ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/view/SSTemplateParser.php

http://github.com/silverstripe/sapphire
PHP | 4793 lines | 4258 code | 256 blank | 279 comment | 755 complexity | 8fc7ab4185d38da482a6c4e135d64fa7 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. WARNING: This file has been machine generated. Do not edit it, or your changes will be overwritten next time it is compiled.
  4. */
  5. // We want this to work when run by hand too
  6. if (defined(THIRDPARTY_PATH)) {
  7. require_once(THIRDPARTY_PATH . '/php-peg/Parser.php');
  8. }
  9. else {
  10. $base = dirname(__FILE__);
  11. require_once($base.'/../thirdparty/php-peg/Parser.php');
  12. }
  13. /**
  14. * This is the exception raised when failing to parse a template. Note that we don't currently do any static analysis,
  15. * so we can't know if the template will run, just if it's malformed. It also won't catch mistakes that still look
  16. * valid.
  17. *
  18. * @package framework
  19. * @subpackage view
  20. */
  21. class SSTemplateParseException extends Exception {
  22. function __construct($message, $parser) {
  23. $prior = substr($parser->string, 0, $parser->pos);
  24. preg_match_all('/\r\n|\r|\n/', $prior, $matches);
  25. $line = count($matches[0])+1;
  26. parent::__construct("Parse error in template on line $line. Error was: $message");
  27. }
  28. }
  29. /**
  30. * This is the parser for the SilverStripe template language. It gets called on a string and uses a php-peg parser
  31. * to match that string against the language structure, building up the PHP code to execute that structure as it
  32. * parses
  33. *
  34. * The $result array that is built up as part of the parsing (see thirdparty/php-peg/README.md for more on how
  35. * parsers build results) has one special member, 'php', which contains the php equivalent of that part of the
  36. * template tree.
  37. *
  38. * Some match rules generate alternate php, or other variations, so check the per-match documentation too.
  39. *
  40. * Terms used:
  41. *
  42. * Marked: A string or lookup in the template that has been explictly marked as such - lookups by prepending with
  43. * "$" (like $Foo.Bar), strings by wrapping with single or double quotes ('Foo' or "Foo")
  44. *
  45. * Bare: The opposite of marked. An argument that has to has it's type inferred by usage and 2.4 defaults.
  46. *
  47. * Example of using a bare argument for a loop block: <% loop Foo %>
  48. *
  49. * Block: One of two SS template structures. The special characters "<%" and "%>" are used to wrap the opening and
  50. * (required or forbidden depending on which block exactly) closing block marks.
  51. *
  52. * Open Block: An SS template block that doesn't wrap any content or have a closing end tag (in fact, a closing end
  53. * tag is forbidden)
  54. *
  55. * Closed Block: An SS template block that wraps content, and requires a counterpart <% end_blockname %> tag
  56. *
  57. * Angle Bracket: angle brackets "<" and ">" are used to eat whitespace between template elements
  58. * N: eats white space including newlines (using in legacy _t support)
  59. *
  60. * @package framework
  61. * @subpackage view
  62. */
  63. class SSTemplateParser extends Parser implements TemplateParser {
  64. /**
  65. * @var bool - Set true by SSTemplateParser::compileString if the template should include comments intended
  66. * for debugging (template source, included files, etc)
  67. */
  68. protected $includeDebuggingComments = false;
  69. /**
  70. * Stores the user-supplied closed block extension rules in the form:
  71. * array(
  72. * 'name' => function (&$res) {}
  73. * )
  74. * See SSTemplateParser::ClosedBlock_Handle_Loop for an example of what the callable should look like
  75. * @var array
  76. */
  77. protected $closedBlocks = array();
  78. /**
  79. * Stores the user-supplied open block extension rules in the form:
  80. * array(
  81. * 'name' => function (&$res) {}
  82. * )
  83. * See SSTemplateParser::OpenBlock_Handle_Base_tag for an example of what the callable should look like
  84. * @var array
  85. */
  86. protected $openBlocks = array();
  87. /**
  88. * Allow the injection of new closed & open block callables
  89. * @param array $closedBlocks
  90. * @param array $openBlocks
  91. */
  92. public function __construct($closedBlocks = array(), $openBlocks = array()) {
  93. $this->setClosedBlocks($closedBlocks);
  94. $this->setOpenBlocks($openBlocks);
  95. }
  96. /**
  97. * Override the function that constructs the result arrays to also prepare a 'php' item in the array
  98. */
  99. function construct($matchrule, $name, $arguments = null) {
  100. $res = parent::construct($matchrule, $name, $arguments);
  101. if (!isset($res['php'])) $res['php'] = '';
  102. return $res;
  103. }
  104. /**
  105. * Set the closed blocks that the template parser should use
  106. *
  107. * This method will delete any existing closed blocks, please use addClosedBlock if you don't
  108. * want to overwrite
  109. * @param array $closedBlocks
  110. * @throws InvalidArgumentException
  111. */
  112. public function setClosedBlocks($closedBlocks) {
  113. $this->closedBlocks = array();
  114. foreach ((array) $closedBlocks as $name => $callable) {
  115. $this->addClosedBlock($name, $callable);
  116. }
  117. }
  118. /**
  119. * Set the open blocks that the template parser should use
  120. *
  121. * This method will delete any existing open blocks, please use addOpenBlock if you don't
  122. * want to overwrite
  123. * @param array $openBlocks
  124. * @throws InvalidArgumentException
  125. */
  126. public function setOpenBlocks($openBlocks) {
  127. $this->openBlocks = array();
  128. foreach ((array) $openBlocks as $name => $callable) {
  129. $this->addOpenBlock($name, $callable);
  130. }
  131. }
  132. /**
  133. * Add a closed block callable to allow <% name %><% end_name %> syntax
  134. * @param string $name The name of the token to be used in the syntax <% name %><% end_name %>
  135. * @param callable $callable The function that modifies the generation of template code
  136. * @throws InvalidArgumentException
  137. */
  138. public function addClosedBlock($name, $callable) {
  139. $this->validateExtensionBlock($name, $callable, 'Closed block');
  140. $this->closedBlocks[$name] = $callable;
  141. }
  142. /**
  143. * Add a closed block callable to allow <% name %> syntax
  144. * @param string $name The name of the token to be used in the syntax <% name %>
  145. * @param callable $callable The function that modifies the generation of template code
  146. * @throws InvalidArgumentException
  147. */
  148. public function addOpenBlock($name, $callable) {
  149. $this->validateExtensionBlock($name, $callable, 'Open block');
  150. $this->openBlocks[$name] = $callable;
  151. }
  152. /**
  153. * Ensures that the arguments to addOpenBlock and addClosedBlock are valid
  154. * @param $name
  155. * @param $callable
  156. * @param $type
  157. * @throws InvalidArgumentException
  158. */
  159. protected function validateExtensionBlock($name, $callable, $type) {
  160. if (!is_string($name)) {
  161. throw new InvalidArgumentException(
  162. sprintf(
  163. "Name argument for %s must be a string",
  164. $type
  165. )
  166. );
  167. } elseif (!is_callable($callable)) {
  168. throw new InvalidArgumentException(
  169. sprintf(
  170. "Callable %s argument named '%s' is not callable",
  171. $type,
  172. $name
  173. )
  174. );
  175. }
  176. }
  177. /* Template: (Comment | Translate | If | Require | CacheBlock | UncachedBlock | OldI18NTag | Include | ClosedBlock |
  178. OpenBlock | MalformedBlock | Injection | Text)+ */
  179. protected $match_Template_typestack = array('Template');
  180. function match_Template ($stack = array()) {
  181. $matchrule = "Template"; $result = $this->construct($matchrule, $matchrule, null);
  182. $count = 0;
  183. while (true) {
  184. $res_50 = $result;
  185. $pos_50 = $this->pos;
  186. $_49 = NULL;
  187. do {
  188. $_47 = NULL;
  189. do {
  190. $res_0 = $result;
  191. $pos_0 = $this->pos;
  192. $matcher = 'match_'.'Comment'; $key = $matcher; $pos = $this->pos;
  193. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  194. if ($subres !== FALSE) {
  195. $this->store( $result, $subres );
  196. $_47 = TRUE; break;
  197. }
  198. $result = $res_0;
  199. $this->pos = $pos_0;
  200. $_45 = NULL;
  201. do {
  202. $res_2 = $result;
  203. $pos_2 = $this->pos;
  204. $matcher = 'match_'.'Translate'; $key = $matcher; $pos = $this->pos;
  205. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  206. if ($subres !== FALSE) {
  207. $this->store( $result, $subres );
  208. $_45 = TRUE; break;
  209. }
  210. $result = $res_2;
  211. $this->pos = $pos_2;
  212. $_43 = NULL;
  213. do {
  214. $res_4 = $result;
  215. $pos_4 = $this->pos;
  216. $matcher = 'match_'.'If'; $key = $matcher; $pos = $this->pos;
  217. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  218. if ($subres !== FALSE) {
  219. $this->store( $result, $subres );
  220. $_43 = TRUE; break;
  221. }
  222. $result = $res_4;
  223. $this->pos = $pos_4;
  224. $_41 = NULL;
  225. do {
  226. $res_6 = $result;
  227. $pos_6 = $this->pos;
  228. $matcher = 'match_'.'Require'; $key = $matcher; $pos = $this->pos;
  229. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  230. if ($subres !== FALSE) {
  231. $this->store( $result, $subres );
  232. $_41 = TRUE; break;
  233. }
  234. $result = $res_6;
  235. $this->pos = $pos_6;
  236. $_39 = NULL;
  237. do {
  238. $res_8 = $result;
  239. $pos_8 = $this->pos;
  240. $matcher = 'match_'.'CacheBlock'; $key = $matcher; $pos = $this->pos;
  241. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  242. if ($subres !== FALSE) {
  243. $this->store( $result, $subres );
  244. $_39 = TRUE; break;
  245. }
  246. $result = $res_8;
  247. $this->pos = $pos_8;
  248. $_37 = NULL;
  249. do {
  250. $res_10 = $result;
  251. $pos_10 = $this->pos;
  252. $matcher = 'match_'.'UncachedBlock'; $key = $matcher; $pos = $this->pos;
  253. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  254. if ($subres !== FALSE) {
  255. $this->store( $result, $subres );
  256. $_37 = TRUE; break;
  257. }
  258. $result = $res_10;
  259. $this->pos = $pos_10;
  260. $_35 = NULL;
  261. do {
  262. $res_12 = $result;
  263. $pos_12 = $this->pos;
  264. $matcher = 'match_'.'OldI18NTag'; $key = $matcher; $pos = $this->pos;
  265. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  266. if ($subres !== FALSE) {
  267. $this->store( $result, $subres );
  268. $_35 = TRUE; break;
  269. }
  270. $result = $res_12;
  271. $this->pos = $pos_12;
  272. $_33 = NULL;
  273. do {
  274. $res_14 = $result;
  275. $pos_14 = $this->pos;
  276. $matcher = 'match_'.'Include'; $key = $matcher; $pos = $this->pos;
  277. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  278. if ($subres !== FALSE) {
  279. $this->store( $result, $subres );
  280. $_33 = TRUE; break;
  281. }
  282. $result = $res_14;
  283. $this->pos = $pos_14;
  284. $_31 = NULL;
  285. do {
  286. $res_16 = $result;
  287. $pos_16 = $this->pos;
  288. $matcher = 'match_'.'ClosedBlock'; $key = $matcher; $pos = $this->pos;
  289. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  290. if ($subres !== FALSE) {
  291. $this->store( $result, $subres );
  292. $_31 = TRUE; break;
  293. }
  294. $result = $res_16;
  295. $this->pos = $pos_16;
  296. $_29 = NULL;
  297. do {
  298. $res_18 = $result;
  299. $pos_18 = $this->pos;
  300. $matcher = 'match_'.'OpenBlock'; $key = $matcher; $pos = $this->pos;
  301. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  302. if ($subres !== FALSE) {
  303. $this->store( $result, $subres );
  304. $_29 = TRUE; break;
  305. }
  306. $result = $res_18;
  307. $this->pos = $pos_18;
  308. $_27 = NULL;
  309. do {
  310. $res_20 = $result;
  311. $pos_20 = $this->pos;
  312. $matcher = 'match_'.'MalformedBlock'; $key = $matcher; $pos = $this->pos;
  313. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  314. if ($subres !== FALSE) {
  315. $this->store( $result, $subres );
  316. $_27 = TRUE; break;
  317. }
  318. $result = $res_20;
  319. $this->pos = $pos_20;
  320. $_25 = NULL;
  321. do {
  322. $res_22 = $result;
  323. $pos_22 = $this->pos;
  324. $matcher = 'match_'.'Injection'; $key = $matcher; $pos = $this->pos;
  325. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  326. if ($subres !== FALSE) {
  327. $this->store( $result, $subres );
  328. $_25 = TRUE; break;
  329. }
  330. $result = $res_22;
  331. $this->pos = $pos_22;
  332. $matcher = 'match_'.'Text'; $key = $matcher; $pos = $this->pos;
  333. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  334. if ($subres !== FALSE) {
  335. $this->store( $result, $subres );
  336. $_25 = TRUE; break;
  337. }
  338. $result = $res_22;
  339. $this->pos = $pos_22;
  340. $_25 = FALSE; break;
  341. }
  342. while(0);
  343. if( $_25 === TRUE ) { $_27 = TRUE; break; }
  344. $result = $res_20;
  345. $this->pos = $pos_20;
  346. $_27 = FALSE; break;
  347. }
  348. while(0);
  349. if( $_27 === TRUE ) { $_29 = TRUE; break; }
  350. $result = $res_18;
  351. $this->pos = $pos_18;
  352. $_29 = FALSE; break;
  353. }
  354. while(0);
  355. if( $_29 === TRUE ) { $_31 = TRUE; break; }
  356. $result = $res_16;
  357. $this->pos = $pos_16;
  358. $_31 = FALSE; break;
  359. }
  360. while(0);
  361. if( $_31 === TRUE ) { $_33 = TRUE; break; }
  362. $result = $res_14;
  363. $this->pos = $pos_14;
  364. $_33 = FALSE; break;
  365. }
  366. while(0);
  367. if( $_33 === TRUE ) { $_35 = TRUE; break; }
  368. $result = $res_12;
  369. $this->pos = $pos_12;
  370. $_35 = FALSE; break;
  371. }
  372. while(0);
  373. if( $_35 === TRUE ) { $_37 = TRUE; break; }
  374. $result = $res_10;
  375. $this->pos = $pos_10;
  376. $_37 = FALSE; break;
  377. }
  378. while(0);
  379. if( $_37 === TRUE ) { $_39 = TRUE; break; }
  380. $result = $res_8;
  381. $this->pos = $pos_8;
  382. $_39 = FALSE; break;
  383. }
  384. while(0);
  385. if( $_39 === TRUE ) { $_41 = TRUE; break; }
  386. $result = $res_6;
  387. $this->pos = $pos_6;
  388. $_41 = FALSE; break;
  389. }
  390. while(0);
  391. if( $_41 === TRUE ) { $_43 = TRUE; break; }
  392. $result = $res_4;
  393. $this->pos = $pos_4;
  394. $_43 = FALSE; break;
  395. }
  396. while(0);
  397. if( $_43 === TRUE ) { $_45 = TRUE; break; }
  398. $result = $res_2;
  399. $this->pos = $pos_2;
  400. $_45 = FALSE; break;
  401. }
  402. while(0);
  403. if( $_45 === TRUE ) { $_47 = TRUE; break; }
  404. $result = $res_0;
  405. $this->pos = $pos_0;
  406. $_47 = FALSE; break;
  407. }
  408. while(0);
  409. if( $_47 === FALSE) { $_49 = FALSE; break; }
  410. $_49 = TRUE; break;
  411. }
  412. while(0);
  413. if( $_49 === FALSE) {
  414. $result = $res_50;
  415. $this->pos = $pos_50;
  416. unset( $res_50 );
  417. unset( $pos_50 );
  418. break;
  419. }
  420. $count += 1;
  421. }
  422. if ($count > 0) { return $this->finalise($result); }
  423. else { return FALSE; }
  424. }
  425. function Template_STR(&$res, $sub) {
  426. $res['php'] .= $sub['php'] . PHP_EOL ;
  427. }
  428. /* Word: / [A-Za-z_] [A-Za-z0-9_]* / */
  429. protected $match_Word_typestack = array('Word');
  430. function match_Word ($stack = array()) {
  431. $matchrule = "Word"; $result = $this->construct($matchrule, $matchrule, null);
  432. if (( $subres = $this->rx( '/ [A-Za-z_] [A-Za-z0-9_]* /' ) ) !== FALSE) {
  433. $result["text"] .= $subres;
  434. return $this->finalise($result);
  435. }
  436. else { return FALSE; }
  437. }
  438. /* NamespacedWord: / [A-Za-z_\/\\] [A-Za-z0-9_\/\\]* / */
  439. protected $match_NamespacedWord_typestack = array('NamespacedWord');
  440. function match_NamespacedWord ($stack = array()) {
  441. $matchrule = "NamespacedWord"; $result = $this->construct($matchrule, $matchrule, null);
  442. if (( $subres = $this->rx( '/ [A-Za-z_\/\\\\] [A-Za-z0-9_\/\\\\]* /' ) ) !== FALSE) {
  443. $result["text"] .= $subres;
  444. return $this->finalise($result);
  445. }
  446. else { return FALSE; }
  447. }
  448. /* Number: / [0-9]+ / */
  449. protected $match_Number_typestack = array('Number');
  450. function match_Number ($stack = array()) {
  451. $matchrule = "Number"; $result = $this->construct($matchrule, $matchrule, null);
  452. if (( $subres = $this->rx( '/ [0-9]+ /' ) ) !== FALSE) {
  453. $result["text"] .= $subres;
  454. return $this->finalise($result);
  455. }
  456. else { return FALSE; }
  457. }
  458. /* Value: / [A-Za-z0-9_]+ / */
  459. protected $match_Value_typestack = array('Value');
  460. function match_Value ($stack = array()) {
  461. $matchrule = "Value"; $result = $this->construct($matchrule, $matchrule, null);
  462. if (( $subres = $this->rx( '/ [A-Za-z0-9_]+ /' ) ) !== FALSE) {
  463. $result["text"] .= $subres;
  464. return $this->finalise($result);
  465. }
  466. else { return FALSE; }
  467. }
  468. /* CallArguments: :Argument ( < "," < :Argument )* */
  469. protected $match_CallArguments_typestack = array('CallArguments');
  470. function match_CallArguments ($stack = array()) {
  471. $matchrule = "CallArguments"; $result = $this->construct($matchrule, $matchrule, null);
  472. $_62 = NULL;
  473. do {
  474. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  475. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  476. if ($subres !== FALSE) {
  477. $this->store( $result, $subres, "Argument" );
  478. }
  479. else { $_62 = FALSE; break; }
  480. while (true) {
  481. $res_61 = $result;
  482. $pos_61 = $this->pos;
  483. $_60 = NULL;
  484. do {
  485. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  486. if (substr($this->string,$this->pos,1) == ',') {
  487. $this->pos += 1;
  488. $result["text"] .= ',';
  489. }
  490. else { $_60 = FALSE; break; }
  491. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  492. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  493. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  494. if ($subres !== FALSE) {
  495. $this->store( $result, $subres, "Argument" );
  496. }
  497. else { $_60 = FALSE; break; }
  498. $_60 = TRUE; break;
  499. }
  500. while(0);
  501. if( $_60 === FALSE) {
  502. $result = $res_61;
  503. $this->pos = $pos_61;
  504. unset( $res_61 );
  505. unset( $pos_61 );
  506. break;
  507. }
  508. }
  509. $_62 = TRUE; break;
  510. }
  511. while(0);
  512. if( $_62 === TRUE ) { return $this->finalise($result); }
  513. if( $_62 === FALSE) { return FALSE; }
  514. }
  515. /**
  516. * Values are bare words in templates, but strings in PHP. We rely on PHP's type conversion to back-convert
  517. * strings to numbers when needed.
  518. */
  519. function CallArguments_Argument(&$res, $sub) {
  520. if (!empty($res['php'])) $res['php'] .= ', ';
  521. $res['php'] .= ($sub['ArgumentMode'] == 'default') ? $sub['string_php'] :
  522. str_replace('$$FINAL', 'XML_val', $sub['php']);
  523. }
  524. /* Call: Method:Word ( "(" < :CallArguments? > ")" )? */
  525. protected $match_Call_typestack = array('Call');
  526. function match_Call ($stack = array()) {
  527. $matchrule = "Call"; $result = $this->construct($matchrule, $matchrule, null);
  528. $_72 = NULL;
  529. do {
  530. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  531. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  532. if ($subres !== FALSE) {
  533. $this->store( $result, $subres, "Method" );
  534. }
  535. else { $_72 = FALSE; break; }
  536. $res_71 = $result;
  537. $pos_71 = $this->pos;
  538. $_70 = NULL;
  539. do {
  540. if (substr($this->string,$this->pos,1) == '(') {
  541. $this->pos += 1;
  542. $result["text"] .= '(';
  543. }
  544. else { $_70 = FALSE; break; }
  545. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  546. $res_67 = $result;
  547. $pos_67 = $this->pos;
  548. $matcher = 'match_'.'CallArguments'; $key = $matcher; $pos = $this->pos;
  549. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  550. if ($subres !== FALSE) {
  551. $this->store( $result, $subres, "CallArguments" );
  552. }
  553. else {
  554. $result = $res_67;
  555. $this->pos = $pos_67;
  556. unset( $res_67 );
  557. unset( $pos_67 );
  558. }
  559. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  560. if (substr($this->string,$this->pos,1) == ')') {
  561. $this->pos += 1;
  562. $result["text"] .= ')';
  563. }
  564. else { $_70 = FALSE; break; }
  565. $_70 = TRUE; break;
  566. }
  567. while(0);
  568. if( $_70 === FALSE) {
  569. $result = $res_71;
  570. $this->pos = $pos_71;
  571. unset( $res_71 );
  572. unset( $pos_71 );
  573. }
  574. $_72 = TRUE; break;
  575. }
  576. while(0);
  577. if( $_72 === TRUE ) { return $this->finalise($result); }
  578. if( $_72 === FALSE) { return FALSE; }
  579. }
  580. /* LookupStep: :Call &"." */
  581. protected $match_LookupStep_typestack = array('LookupStep');
  582. function match_LookupStep ($stack = array()) {
  583. $matchrule = "LookupStep"; $result = $this->construct($matchrule, $matchrule, null);
  584. $_76 = NULL;
  585. do {
  586. $matcher = 'match_'.'Call'; $key = $matcher; $pos = $this->pos;
  587. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  588. if ($subres !== FALSE) {
  589. $this->store( $result, $subres, "Call" );
  590. }
  591. else { $_76 = FALSE; break; }
  592. $res_75 = $result;
  593. $pos_75 = $this->pos;
  594. if (substr($this->string,$this->pos,1) == '.') {
  595. $this->pos += 1;
  596. $result["text"] .= '.';
  597. $result = $res_75;
  598. $this->pos = $pos_75;
  599. }
  600. else {
  601. $result = $res_75;
  602. $this->pos = $pos_75;
  603. $_76 = FALSE; break;
  604. }
  605. $_76 = TRUE; break;
  606. }
  607. while(0);
  608. if( $_76 === TRUE ) { return $this->finalise($result); }
  609. if( $_76 === FALSE) { return FALSE; }
  610. }
  611. /* LastLookupStep: :Call */
  612. protected $match_LastLookupStep_typestack = array('LastLookupStep');
  613. function match_LastLookupStep ($stack = array()) {
  614. $matchrule = "LastLookupStep"; $result = $this->construct($matchrule, $matchrule, null);
  615. $matcher = 'match_'.'Call'; $key = $matcher; $pos = $this->pos;
  616. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  617. if ($subres !== FALSE) {
  618. $this->store( $result, $subres, "Call" );
  619. return $this->finalise($result);
  620. }
  621. else { return FALSE; }
  622. }
  623. /* Lookup: LookupStep ("." LookupStep)* "." LastLookupStep | LastLookupStep */
  624. protected $match_Lookup_typestack = array('Lookup');
  625. function match_Lookup ($stack = array()) {
  626. $matchrule = "Lookup"; $result = $this->construct($matchrule, $matchrule, null);
  627. $_90 = NULL;
  628. do {
  629. $res_79 = $result;
  630. $pos_79 = $this->pos;
  631. $_87 = NULL;
  632. do {
  633. $matcher = 'match_'.'LookupStep'; $key = $matcher; $pos = $this->pos;
  634. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  635. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  636. else { $_87 = FALSE; break; }
  637. while (true) {
  638. $res_84 = $result;
  639. $pos_84 = $this->pos;
  640. $_83 = NULL;
  641. do {
  642. if (substr($this->string,$this->pos,1) == '.') {
  643. $this->pos += 1;
  644. $result["text"] .= '.';
  645. }
  646. else { $_83 = FALSE; break; }
  647. $matcher = 'match_'.'LookupStep'; $key = $matcher; $pos = $this->pos;
  648. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  649. if ($subres !== FALSE) {
  650. $this->store( $result, $subres );
  651. }
  652. else { $_83 = FALSE; break; }
  653. $_83 = TRUE; break;
  654. }
  655. while(0);
  656. if( $_83 === FALSE) {
  657. $result = $res_84;
  658. $this->pos = $pos_84;
  659. unset( $res_84 );
  660. unset( $pos_84 );
  661. break;
  662. }
  663. }
  664. if (substr($this->string,$this->pos,1) == '.') {
  665. $this->pos += 1;
  666. $result["text"] .= '.';
  667. }
  668. else { $_87 = FALSE; break; }
  669. $matcher = 'match_'.'LastLookupStep'; $key = $matcher; $pos = $this->pos;
  670. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  671. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  672. else { $_87 = FALSE; break; }
  673. $_87 = TRUE; break;
  674. }
  675. while(0);
  676. if( $_87 === TRUE ) { $_90 = TRUE; break; }
  677. $result = $res_79;
  678. $this->pos = $pos_79;
  679. $matcher = 'match_'.'LastLookupStep'; $key = $matcher; $pos = $this->pos;
  680. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  681. if ($subres !== FALSE) {
  682. $this->store( $result, $subres );
  683. $_90 = TRUE; break;
  684. }
  685. $result = $res_79;
  686. $this->pos = $pos_79;
  687. $_90 = FALSE; break;
  688. }
  689. while(0);
  690. if( $_90 === TRUE ) { return $this->finalise($result); }
  691. if( $_90 === FALSE) { return FALSE; }
  692. }
  693. function Lookup__construct(&$res) {
  694. $res['php'] = '$scope->locally()';
  695. $res['LookupSteps'] = array();
  696. }
  697. /**
  698. * The basic generated PHP of LookupStep and LastLookupStep is the same, except that LookupStep calls 'obj' to
  699. * get the next ViewableData in the sequence, and LastLookupStep calls different methods (XML_val, hasValue, obj)
  700. * depending on the context the lookup is used in.
  701. */
  702. function Lookup_AddLookupStep(&$res, $sub, $method) {
  703. $res['LookupSteps'][] = $sub;
  704. $property = $sub['Call']['Method']['text'];
  705. if (isset($sub['Call']['CallArguments']) && $arguments = $sub['Call']['CallArguments']['php']) {
  706. $res['php'] .= "->$method('$property', array($arguments), true)";
  707. }
  708. else {
  709. $res['php'] .= "->$method('$property', null, true)";
  710. }
  711. }
  712. function Lookup_LookupStep(&$res, $sub) {
  713. $this->Lookup_AddLookupStep($res, $sub, 'obj');
  714. }
  715. function Lookup_LastLookupStep(&$res, $sub) {
  716. $this->Lookup_AddLookupStep($res, $sub, '$$FINAL');
  717. }
  718. /* Translate: "<%t" < Entity < (Default:QuotedString)? < (!("is" "=") < "is" < Context:QuotedString)? <
  719. (InjectionVariables)? > "%>" */
  720. protected $match_Translate_typestack = array('Translate');
  721. function match_Translate ($stack = array()) {
  722. $matchrule = "Translate"; $result = $this->construct($matchrule, $matchrule, null);
  723. $_116 = NULL;
  724. do {
  725. if (( $subres = $this->literal( '<%t' ) ) !== FALSE) { $result["text"] .= $subres; }
  726. else { $_116 = FALSE; break; }
  727. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  728. $matcher = 'match_'.'Entity'; $key = $matcher; $pos = $this->pos;
  729. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  730. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  731. else { $_116 = FALSE; break; }
  732. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  733. $res_98 = $result;
  734. $pos_98 = $this->pos;
  735. $_97 = NULL;
  736. do {
  737. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  738. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  739. if ($subres !== FALSE) {
  740. $this->store( $result, $subres, "Default" );
  741. }
  742. else { $_97 = FALSE; break; }
  743. $_97 = TRUE; break;
  744. }
  745. while(0);
  746. if( $_97 === FALSE) {
  747. $result = $res_98;
  748. $this->pos = $pos_98;
  749. unset( $res_98 );
  750. unset( $pos_98 );
  751. }
  752. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  753. $res_109 = $result;
  754. $pos_109 = $this->pos;
  755. $_108 = NULL;
  756. do {
  757. $res_103 = $result;
  758. $pos_103 = $this->pos;
  759. $_102 = NULL;
  760. do {
  761. if (( $subres = $this->literal( 'is' ) ) !== FALSE) { $result["text"] .= $subres; }
  762. else { $_102 = FALSE; break; }
  763. if (substr($this->string,$this->pos,1) == '=') {
  764. $this->pos += 1;
  765. $result["text"] .= '=';
  766. }
  767. else { $_102 = FALSE; break; }
  768. $_102 = TRUE; break;
  769. }
  770. while(0);
  771. if( $_102 === TRUE ) {
  772. $result = $res_103;
  773. $this->pos = $pos_103;
  774. $_108 = FALSE; break;
  775. }
  776. if( $_102 === FALSE) {
  777. $result = $res_103;
  778. $this->pos = $pos_103;
  779. }
  780. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  781. if (( $subres = $this->literal( 'is' ) ) !== FALSE) { $result["text"] .= $subres; }
  782. else { $_108 = FALSE; break; }
  783. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  784. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  785. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  786. if ($subres !== FALSE) {
  787. $this->store( $result, $subres, "Context" );
  788. }
  789. else { $_108 = FALSE; break; }
  790. $_108 = TRUE; break;
  791. }
  792. while(0);
  793. if( $_108 === FALSE) {
  794. $result = $res_109;
  795. $this->pos = $pos_109;
  796. unset( $res_109 );
  797. unset( $pos_109 );
  798. }
  799. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  800. $res_113 = $result;
  801. $pos_113 = $this->pos;
  802. $_112 = NULL;
  803. do {
  804. $matcher = 'match_'.'InjectionVariables'; $key = $matcher; $pos = $this->pos;
  805. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  806. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  807. else { $_112 = FALSE; break; }
  808. $_112 = TRUE; break;
  809. }
  810. while(0);
  811. if( $_112 === FALSE) {
  812. $result = $res_113;
  813. $this->pos = $pos_113;
  814. unset( $res_113 );
  815. unset( $pos_113 );
  816. }
  817. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  818. if (( $subres = $this->literal( '%>' ) ) !== FALSE) { $result["text"] .= $subres; }
  819. else { $_116 = FALSE; break; }
  820. $_116 = TRUE; break;
  821. }
  822. while(0);
  823. if( $_116 === TRUE ) { return $this->finalise($result); }
  824. if( $_116 === FALSE) { return FALSE; }
  825. }
  826. /* InjectionVariables: (< InjectionName:Word "=" Argument)+ */
  827. protected $match_InjectionVariables_typestack = array('InjectionVariables');
  828. function match_InjectionVariables ($stack = array()) {
  829. $matchrule = "InjectionVariables"; $result = $this->construct($matchrule, $matchrule, null);
  830. $count = 0;
  831. while (true) {
  832. $res_123 = $result;
  833. $pos_123 = $this->pos;
  834. $_122 = NULL;
  835. do {
  836. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  837. $matcher = 'match_'.'Word'; $key = $matcher; $pos = $this->pos;
  838. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  839. if ($subres !== FALSE) {
  840. $this->store( $result, $subres, "InjectionName" );
  841. }
  842. else { $_122 = FALSE; break; }
  843. if (substr($this->string,$this->pos,1) == '=') {
  844. $this->pos += 1;
  845. $result["text"] .= '=';
  846. }
  847. else { $_122 = FALSE; break; }
  848. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  849. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  850. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  851. else { $_122 = FALSE; break; }
  852. $_122 = TRUE; break;
  853. }
  854. while(0);
  855. if( $_122 === FALSE) {
  856. $result = $res_123;
  857. $this->pos = $pos_123;
  858. unset( $res_123 );
  859. unset( $pos_123 );
  860. break;
  861. }
  862. $count += 1;
  863. }
  864. if ($count > 0) { return $this->finalise($result); }
  865. else { return FALSE; }
  866. }
  867. /* Entity: / [A-Za-z_] [\w\.]* / */
  868. protected $match_Entity_typestack = array('Entity');
  869. function match_Entity ($stack = array()) {
  870. $matchrule = "Entity"; $result = $this->construct($matchrule, $matchrule, null);
  871. if (( $subres = $this->rx( '/ [A-Za-z_] [\w\.]* /' ) ) !== FALSE) {
  872. $result["text"] .= $subres;
  873. return $this->finalise($result);
  874. }
  875. else { return FALSE; }
  876. }
  877. function Translate__construct(&$res) {
  878. $res['php'] = '$val .= _t(';
  879. }
  880. function Translate_Entity(&$res, $sub) {
  881. $res['php'] .= "'$sub[text]'";
  882. }
  883. function Translate_Default(&$res, $sub) {
  884. $res['php'] .= ",$sub[text]";
  885. }
  886. function Translate_Context(&$res, $sub) {
  887. $res['php'] .= ",$sub[text]";
  888. }
  889. function Translate_InjectionVariables(&$res, $sub) {
  890. $res['php'] .= ",$sub[php]";
  891. }
  892. function Translate__finalise(&$res) {
  893. $res['php'] .= ');';
  894. }
  895. function InjectionVariables__construct(&$res) {
  896. $res['php'] = "array(";
  897. }
  898. function InjectionVariables_InjectionName(&$res, $sub) {
  899. $res['php'] .= "'$sub[text]'=>";
  900. }
  901. function InjectionVariables_Argument(&$res, $sub) {
  902. $res['php'] .= str_replace('$$FINAL', 'XML_val', $sub['php']) . ',';
  903. }
  904. function InjectionVariables__finalise(&$res) {
  905. if (substr($res['php'], -1) == ',') $res['php'] = substr($res['php'], 0, -1); //remove last comma in the array
  906. $res['php'] .= ')';
  907. }
  908. /* SimpleInjection: '$' :Lookup */
  909. protected $match_SimpleInjection_typestack = array('SimpleInjection');
  910. function match_SimpleInjection ($stack = array()) {
  911. $matchrule = "SimpleInjection"; $result = $this->construct($matchrule, $matchrule, null);
  912. $_127 = NULL;
  913. do {
  914. if (substr($this->string,$this->pos,1) == '$') {
  915. $this->pos += 1;
  916. $result["text"] .= '$';
  917. }
  918. else { $_127 = FALSE; break; }
  919. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  920. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  921. if ($subres !== FALSE) {
  922. $this->store( $result, $subres, "Lookup" );
  923. }
  924. else { $_127 = FALSE; break; }
  925. $_127 = TRUE; break;
  926. }
  927. while(0);
  928. if( $_127 === TRUE ) { return $this->finalise($result); }
  929. if( $_127 === FALSE) { return FALSE; }
  930. }
  931. /* BracketInjection: '{$' :Lookup "}" */
  932. protected $match_BracketInjection_typestack = array('BracketInjection');
  933. function match_BracketInjection ($stack = array()) {
  934. $matchrule = "BracketInjection"; $result = $this->construct($matchrule, $matchrule, null);
  935. $_132 = NULL;
  936. do {
  937. if (( $subres = $this->literal( '{$' ) ) !== FALSE) { $result["text"] .= $subres; }
  938. else { $_132 = FALSE; break; }
  939. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  940. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  941. if ($subres !== FALSE) {
  942. $this->store( $result, $subres, "Lookup" );
  943. }
  944. else { $_132 = FALSE; break; }
  945. if (substr($this->string,$this->pos,1) == '}') {
  946. $this->pos += 1;
  947. $result["text"] .= '}';
  948. }
  949. else { $_132 = FALSE; break; }
  950. $_132 = TRUE; break;
  951. }
  952. while(0);
  953. if( $_132 === TRUE ) { return $this->finalise($result); }
  954. if( $_132 === FALSE) { return FALSE; }
  955. }
  956. /* Injection: BracketInjection | SimpleInjection */
  957. protected $match_Injection_typestack = array('Injection');
  958. function match_Injection ($stack = array()) {
  959. $matchrule = "Injection"; $result = $this->construct($matchrule, $matchrule, null);
  960. $_137 = NULL;
  961. do {
  962. $res_134 = $result;
  963. $pos_134 = $this->pos;
  964. $matcher = 'match_'.'BracketInjection'; $key = $matcher; $pos = $this->pos;
  965. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  966. if ($subres !== FALSE) {
  967. $this->store( $result, $subres );
  968. $_137 = TRUE; break;
  969. }
  970. $result = $res_134;
  971. $this->pos = $pos_134;
  972. $matcher = 'match_'.'SimpleInjection'; $key = $matcher; $pos = $this->pos;
  973. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  974. if ($subres !== FALSE) {
  975. $this->store( $result, $subres );
  976. $_137 = TRUE; break;
  977. }
  978. $result = $res_134;
  979. $this->pos = $pos_134;
  980. $_137 = FALSE; break;
  981. }
  982. while(0);
  983. if( $_137 === TRUE ) { return $this->finalise($result); }
  984. if( $_137 === FALSE) { return FALSE; }
  985. }
  986. function Injection_STR(&$res, $sub) {
  987. $res['php'] = '$val .= '. str_replace('$$FINAL', 'XML_val', $sub['Lookup']['php']) . ';';
  988. }
  989. /* DollarMarkedLookup: SimpleInjection */
  990. protected $match_DollarMarkedLookup_typestack = array('DollarMarkedLookup');
  991. function match_DollarMarkedLookup ($stack = array()) {
  992. $matchrule = "DollarMarkedLookup"; $result = $this->construct($matchrule, $matchrule, null);
  993. $matcher = 'match_'.'SimpleInjection'; $key = $matcher; $pos = $this->pos;
  994. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  995. if ($subres !== FALSE) {
  996. $this->store( $result, $subres );
  997. return $this->finalise($result);
  998. }
  999. else { return FALSE; }
  1000. }
  1001. function DollarMarkedLookup_STR(&$res, $sub) {
  1002. $res['Lookup'] = $sub['Lookup'];
  1003. }
  1004. /* QuotedString: q:/['"]/ String:/ (\\\\ | \\. | [^$q\\])* / '$q' */
  1005. protected $match_QuotedString_typestack = array('QuotedString');
  1006. function match_QuotedString ($stack = array()) {
  1007. $matchrule = "QuotedString"; $result = $this->construct($matchrule, $matchrule, null);
  1008. $_143 = NULL;
  1009. do {
  1010. $stack[] = $result; $result = $this->construct( $matchrule, "q" );
  1011. if (( $subres = $this->rx( '/[\'"]/' ) ) !== FALSE) {
  1012. $result["text"] .= $subres;
  1013. $subres = $result; $result = array_pop($stack);
  1014. $this->store( $result, $subres, 'q' );
  1015. }
  1016. else {
  1017. $result = array_pop($stack);
  1018. $_143 = FALSE; break;
  1019. }
  1020. $stack[] = $result; $result = $this->construct( $matchrule, "String" );
  1021. if (( $subres = $this->rx( '/ (\\\\\\\\ | \\\\. | [^'.$this->expression($result, $stack, 'q').'\\\\])* /' ) ) !== FALSE) {
  1022. $result["text"] .= $subres;
  1023. $subres = $result; $result = array_pop($stack);
  1024. $this->store( $result, $subres, 'String' );
  1025. }
  1026. else {
  1027. $result = array_pop($stack);
  1028. $_143 = FALSE; break;
  1029. }
  1030. if (( $subres = $this->literal( ''.$this->expression($result, $stack, 'q').'' ) ) !== FALSE) { $result["text"] .= $subres; }
  1031. else { $_143 = FALSE; break; }
  1032. $_143 = TRUE; break;
  1033. }
  1034. while(0);
  1035. if( $_143 === TRUE ) { return $this->finalise($result); }
  1036. if( $_143 === FALSE) { return FALSE; }
  1037. }
  1038. /* FreeString: /[^,)%!=><|&]+/ */
  1039. protected $match_FreeString_typestack = array('FreeString');
  1040. function match_FreeString ($stack = array()) {
  1041. $matchrule = "FreeString"; $result = $this->construct($matchrule, $matchrule, null);
  1042. if (( $subres = $this->rx( '/[^,)%!=><|&]+/' ) ) !== FALSE) {
  1043. $result["text"] .= $subres;
  1044. return $this->finalise($result);
  1045. }
  1046. else { return FALSE; }
  1047. }
  1048. /* Argument:
  1049. :DollarMarkedLookup |
  1050. :QuotedString |
  1051. :Lookup !(< FreeString)|
  1052. :FreeString */
  1053. protected $match_Argument_typestack = array('Argument');
  1054. function match_Argument ($stack = array()) {
  1055. $matchrule = "Argument"; $result = $this->construct($matchrule, $matchrule, null);
  1056. $_163 = NULL;
  1057. do {
  1058. $res_146 = $result;
  1059. $pos_146 = $this->pos;
  1060. $matcher = 'match_'.'DollarMarkedLookup'; $key = $matcher; $pos = $this->pos;
  1061. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1062. if ($subres !== FALSE) {
  1063. $this->store( $result, $subres, "DollarMarkedLookup" );
  1064. $_163 = TRUE; break;
  1065. }
  1066. $result = $res_146;
  1067. $this->pos = $pos_146;
  1068. $_161 = NULL;
  1069. do {
  1070. $res_148 = $result;
  1071. $pos_148 = $this->pos;
  1072. $matcher = 'match_'.'QuotedString'; $key = $matcher; $pos = $this->pos;
  1073. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1074. if ($subres !== FALSE) {
  1075. $this->store( $result, $subres, "QuotedString" );
  1076. $_161 = TRUE; break;
  1077. }
  1078. $result = $res_148;
  1079. $this->pos = $pos_148;
  1080. $_159 = NULL;
  1081. do {
  1082. $res_150 = $result;
  1083. $pos_150 = $this->pos;
  1084. $_156 = NULL;
  1085. do {
  1086. $matcher = 'match_'.'Lookup'; $key = $matcher; $pos = $this->pos;
  1087. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1088. if ($subres !== FALSE) {
  1089. $this->store( $result, $subres, "Lookup" );
  1090. }
  1091. else { $_156 = FALSE; break; }
  1092. $res_155 = $result;
  1093. $pos_155 = $this->pos;
  1094. $_154 = NULL;
  1095. do {
  1096. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1097. $matcher = 'match_'.'FreeString'; $key = $matcher; $pos = $this->pos;
  1098. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1099. if ($subres !== FALSE) {
  1100. $this->store( $result, $subres );
  1101. }
  1102. else { $_154 = FALSE; break; }
  1103. $_154 = TRUE; break;
  1104. }
  1105. while(0);
  1106. if( $_154 === TRUE ) {
  1107. $result = $res_155;
  1108. $this->pos = $pos_155;
  1109. $_156 = FALSE; break;
  1110. }
  1111. if( $_154 === FALSE) {
  1112. $result = $res_155;
  1113. $this->pos = $pos_155;
  1114. }
  1115. $_156 = TRUE; break;
  1116. }
  1117. while(0);
  1118. if( $_156 === TRUE ) { $_159 = TRUE; break; }
  1119. $result = $res_150;
  1120. $this->pos = $pos_150;
  1121. $matcher = 'match_'.'FreeString'; $key = $matcher; $pos = $this->pos;
  1122. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1123. if ($subres !== FALSE) {
  1124. $this->store( $result, $subres, "FreeString" );
  1125. $_159 = TRUE; break;
  1126. }
  1127. $result = $res_150;
  1128. $this->pos = $pos_150;
  1129. $_159 = FALSE; break;
  1130. }
  1131. while(0);
  1132. if( $_159 === TRUE ) { $_161 = TRUE; break; }
  1133. $result = $res_148;
  1134. $this->pos = $pos_148;
  1135. $_161 = FALSE; break;
  1136. }
  1137. while(0);
  1138. if( $_161 === TRUE ) { $_163 = TRUE; break; }
  1139. $result = $res_146;
  1140. $this->pos = $pos_146;
  1141. $_163 = FALSE; break;
  1142. }
  1143. while(0);
  1144. if( $_163 === TRUE ) { return $this->finalise($result); }
  1145. if( $_163 === FALSE) { return FALSE; }
  1146. }
  1147. /**
  1148. * If we get a bare value, we don't know enough to determine exactly what php would be the translation, because
  1149. * we don't know if the position of use indicates a lookup or a string argument.
  1150. *
  1151. * Instead, we record 'ArgumentMode' as a member of this matches results node, which can be:
  1152. * - lookup if this argument was unambiguously a lookup (marked as such)
  1153. * - string is this argument was unambiguously a string (marked as such, or impossible to parse as lookup)
  1154. * - default if this argument needs to be handled as per 2.4
  1155. *
  1156. * In the case of 'default', there is no php member of the results node, but instead 'lookup_php', which
  1157. * should be used by the parent if the context indicates a lookup, and 'string_php' which should be used
  1158. * if the context indicates a string
  1159. */
  1160. function Argument_DollarMarkedLookup(&$res, $sub) {
  1161. $res['ArgumentMode'] = 'lookup';
  1162. $res['php'] = $sub['Lookup']['php'];
  1163. }
  1164. function Argument_QuotedString(&$res, $sub) {
  1165. $res['ArgumentMode'] = 'string';
  1166. $res['php'] = "'" . str_replace("'", "\\'", $sub['String']['text']) . "'";
  1167. }
  1168. function Argument_Lookup(&$res, $sub) {
  1169. if (count($sub['LookupSteps']) == 1 && !isset($sub['LookupSteps'][0]['Call']['Arguments'])) {
  1170. $res['ArgumentMode'] = 'default';
  1171. $res['lookup_php'] = $sub['php'];
  1172. $res['string_php'] = "'".$sub['LookupSteps'][0]['Call']['Method']['text']."'";
  1173. }
  1174. else {
  1175. $res['ArgumentMode'] = 'lookup';
  1176. $res['php'] = $sub['php'];
  1177. }
  1178. }
  1179. function Argument_FreeString(&$res, $sub) {
  1180. $res['ArgumentMode'] = 'string';
  1181. $res['php'] = "'" . str_replace("'", "\\'", trim($sub['text'])) . "'";
  1182. }
  1183. /* ComparisonOperator: "!=" | "==" | ">=" | ">" | "<=" | "<" | "=" */
  1184. protected $match_ComparisonOperator_typestack = array('ComparisonOperator');
  1185. function match_ComparisonOperator ($stack = array()) {
  1186. $matchrule = "ComparisonOperator"; $result = $this->construct($matchrule, $matchrule, null);
  1187. $_188 = NULL;
  1188. do {
  1189. $res_165 = $result;
  1190. $pos_165 = $this->pos;
  1191. if (( $subres = $this->literal( '!=' ) ) !== FALSE) {
  1192. $result["text"] .= $subres;
  1193. $_188 = TRUE; break;
  1194. }
  1195. $result = $res_165;
  1196. $this->pos = $pos_165;
  1197. $_186 = NULL;
  1198. do {
  1199. $res_167 = $result;
  1200. $pos_167 = $this->pos;
  1201. if (( $subres = $this->literal( '==' ) ) !== FALSE) {
  1202. $result["text"] .= $subres;
  1203. $_186 = TRUE; break;
  1204. }
  1205. $result = $res_167;
  1206. $this->pos = $pos_167;
  1207. $_184 = NULL;
  1208. do {
  1209. $res_169 = $result;
  1210. $pos_169 = $this->pos;
  1211. if (( $subres = $this->literal( '>=' ) ) !== FALSE) {
  1212. $result["text"] .= $subres;
  1213. $_184 = TRUE; break;
  1214. }
  1215. $result = $res_169;
  1216. $this->pos = $pos_169;
  1217. $_182 = NULL;
  1218. do {
  1219. $res_171 = $result;
  1220. $pos_171 = $this->pos;
  1221. if (substr($this->string,$this->pos,1) == '>') {
  1222. $this->pos += 1;
  1223. $result["text"] .= '>';
  1224. $_182 = TRUE; break;
  1225. }
  1226. $result = $res_171;
  1227. $this->pos = $pos_171;
  1228. $_180 = NULL;
  1229. do {
  1230. $res_173 = $result;
  1231. $pos_173 = $this->pos;
  1232. if (( $subres = $this->literal( '<=' ) ) !== FALSE) {
  1233. $result["text"] .= $subres;
  1234. $_180 = TRUE; break;
  1235. }
  1236. $result = $res_173;
  1237. $this->pos = $pos_173;
  1238. $_178 = NULL;
  1239. do {
  1240. $res_175 = $result;
  1241. $pos_175 = $this->pos;
  1242. if (substr($this->string,$this->pos,1) == '<') {
  1243. $this->pos += 1;
  1244. $result["text"] .= '<';
  1245. $_178 = TRUE; break;
  1246. }
  1247. $result = $res_175;
  1248. $this->pos = $pos_175;
  1249. if (substr($this->string,$this->pos,1) == '=') {
  1250. $this->pos += 1;
  1251. $result["text"] .= '=';
  1252. $_178 = TRUE; break;
  1253. }
  1254. $result = $res_175;
  1255. $this->pos = $pos_175;
  1256. $_178 = FALSE; break;
  1257. }
  1258. while(0);
  1259. if( $_178 === TRUE ) { $_180 = TRUE; break; }
  1260. $result = $res_173;
  1261. $this->pos = $pos_173;
  1262. $_180 = FALSE; break;
  1263. }
  1264. while(0);
  1265. if( $_180 === TRUE ) { $_182 = TRUE; break; }
  1266. $result = $res_171;
  1267. $this->pos = $pos_171;
  1268. $_182 = FALSE; break;
  1269. }
  1270. while(0);
  1271. if( $_182 === TRUE ) { $_184 = TRUE; break; }
  1272. $result = $res_169;
  1273. $this->pos = $pos_169;
  1274. $_184 = FALSE; break;
  1275. }
  1276. while(0);
  1277. if( $_184 === TRUE ) { $_186 = TRUE; break; }
  1278. $result = $res_167;
  1279. $this->pos = $pos_167;
  1280. $_186 = FALSE; break;
  1281. }
  1282. while(0);
  1283. if( $_186 === TRUE ) { $_188 = TRUE; break; }
  1284. $result = $res_165;
  1285. $this->pos = $pos_165;
  1286. $_188 = FALSE; break;
  1287. }
  1288. while(0);
  1289. if( $_188 === TRUE ) { return $this->finalise($result); }
  1290. if( $_188 === FALSE) { return FALSE; }
  1291. }
  1292. /* Comparison: Argument < ComparisonOperator > Argument */
  1293. protected $match_Comparison_typestack = array('Comparison');
  1294. function match_Comparison ($stack = array()) {
  1295. $matchrule = "Comparison"; $result = $this->construct($matchrule, $matchrule, null);
  1296. $_195 = NULL;
  1297. do {
  1298. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  1299. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1300. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1301. else { $_195 = FALSE; break; }
  1302. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1303. $matcher = 'match_'.'ComparisonOperator'; $key = $matcher; $pos = $this->pos;
  1304. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1305. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1306. else { $_195 = FALSE; break; }
  1307. if (( $subres = $this->whitespace( ) ) !== FALSE) { $result["text"] .= $subres; }
  1308. $matcher = 'match_'.'Argument'; $key = $matcher; $pos = $this->pos;
  1309. $subres = ( $this->packhas( $key, $pos ) ? $this->packread( $key, $pos ) : $this->packwrite( $key, $pos, $this->$matcher(array_merge($stack, array($result))) ) );
  1310. if ($subres !== FALSE) { $this->store( $result, $subres ); }
  1311. else { $_195 =

Large files files are truncated, but you can click here to view the full file