Blame view

framework/core/manifest/TokenisedRegularExpression.php 3.2 KB
0084d336   Administrator   Importers CRUD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  <?php
  
  /**
   * A tokenised regular expression is a parser, similar to a regular expression, that acts on tokens rather than
   * characters.  This is a crucial component of the ManifestBuilder.
   * 
   * @package framework
   * @subpackage core
   */ 
  class TokenisedRegularExpression {
  	/**
  	 * The regular expression definition
  	 */
  	protected $expression;
  	
  	public function __construct($expression) {
  		$this->expression = $expression;
  	}
  	
  	public function findAll($tokens) {
  		$tokenTypes = array();
  		foreach($tokens as $i => $token) {
  			if(is_array($token)) {
  				$tokenTypes[$i] = $token[0];
  			} else {
  				$tokenTypes[$i] = $token;
  				// Pre-process string tokens for matchFrom()
  				$tokens[$i] = array($token, $token);
  			}
  		}
  
  		$startKeys = array_keys($tokenTypes, is_array($this->expression[0]) 
  			? $this->expression[0][0] : $this->expression[0]);
  		$allMatches = array();
  		
  		foreach($startKeys as $startKey) {
  			$matches = array();
  			if($this->matchFrom($startKey, 0, $tokens, $matches)) {
  				$allMatches[] = $matches;
  			}
  		}
  		return $allMatches;
  	}
  	
  	public function matchFrom($tokenPos, $expressionPos, &$tokens, &$matches) {
  		$expressionRule = $this->expression[$expressionPos];
  		$expectation = is_array($expressionRule) ? $expressionRule[0] : $expressionRule;
  		if(!is_array($expressionRule)) $expressionRule = array();
  		
  		if($expectation == $tokens[$tokenPos][0]) {
  			if(isset($expressionRule['save_to'])) {
  				// Append to an array
  				if(substr($expressionRule['save_to'],-2) == '[]') {
  					$matches[substr($expressionRule['save_to'],0,-2)][] = $tokens[$tokenPos][1];
  				}
  				// Regular variable setting
  				else $matches[$expressionRule['save_to']] = $tokens[$tokenPos][1];
  			}
  			
  			// End of the expression
  			if(!isset($this->expression[$expressionPos+1])) {
  				return true;
  			
  			// Process next step as normal
  			} else if($this->matchFrom($tokenPos+1, $expressionPos+1, $tokens, $matches)) {
  				return true;
  
  			// This step is optional
  			} else if(isset($expressionRule['optional']) 
  					&& $this->matchFrom($tokenPos, $expressionPos+1, $tokens, $matches)) {
  				return true;
  
  			// Process jumps
  			} else if(isset($expressionRule['can_jump_to'])) {
  				if(is_array($expressionRule['can_jump_to'])) foreach($expressionRule['can_jump_to'] as $canJumpTo) {
  					// can_jump_to & optional both set
  					if(isset($expressionRule['optional']) 
  							&& $this->matchFrom($tokenPos, $canJumpTo, $tokens, $matches)) {
  						return true;
  					}
  					// can_jump_to set (optional may or may not be set)
  					if($this->matchFrom($tokenPos+1, $canJumpTo, $tokens, $matches)) {
  						return true;
  					}
  
  				} else {
  					// can_jump_to & optional both set
  					if(isset($expressionRule['optional'])
  							&& $this->matchFrom($tokenPos, $expressionRule['can_jump_to'], $tokens, $matches)) {
  						return true;
  					}
  					// can_jump_to set (optional may or may not be set)
  					if($this->matchFrom($tokenPos+1, $expressionRule['can_jump_to'], $tokens, $matches)) {
  						return true;
  					}
  				}
  			}
  
  		} else if(isset($expressionRule['optional'])) {
  			if(isset($this->expression[$expressionPos+1])) {
  				return $this->matchFrom($tokenPos, $expressionPos+1, $tokens, $matches);
  			}
  			else return true;
  		}
  
  		return false;
  		
  	}
  }