1: <?php
2: namespace Pharborist;
3:
4: use Pharborist\Operators\BinaryOperationNode;
5: use Pharborist\Operators\PostDecrementNode;
6: use Pharborist\Operators\PostIncrementNode;
7: use Pharborist\Operators\TernaryOperationNode;
8: use Pharborist\Operators\UnaryOperationNode;
9:
10: 11: 12: 13: 14: 15:
16: class OperatorFactory {
17: 18: 19: 20:
21: private static $operators = [
22: T_LOGICAL_OR => [Operator::ASSOC_LEFT, 1, TRUE, '\Pharborist\Operators\LogicalOrNode', NULL],
23: T_LOGICAL_XOR => [Operator::ASSOC_LEFT, 2, TRUE, '\Pharborist\Operators\LogicalXorNode', NULL],
24: T_LOGICAL_AND => [Operator::ASSOC_LEFT, 3, TRUE, '\Pharborist\Operators\LogicalAndNode', NULL],
25: '=' => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\AssignNode', NULL],
26: T_AND_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\BitwiseAndAssignNode', NULL],
27: T_CONCAT_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\ConcatAssignNode', NULL],
28: T_DIV_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\DivideAssignNode', NULL],
29: T_MINUS_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\SubtractAssignNode', NULL],
30: T_MOD_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\ModulusAssignNode', NULL],
31: T_MUL_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\MultiplyAssignNode', NULL],
32: T_OR_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\BitwiseOrAssignNode', NULL],
33: T_PLUS_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\AddAssignNode', NULL],
34: T_SL_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\BitwiseShiftLeftAssignNode', NULL],
35: T_SR_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\BitwiseShiftRightAssignNode', NULL],
36: T_XOR_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\BitwiseXorAssignNode', NULL],
37: T_POW_EQUAL => [Operator::ASSOC_RIGHT, 4, FALSE, '\Pharborist\Operators\PowerAssignNode', NULL],
38: '?' => [Operator::ASSOC_LEFT, 5, TRUE, NULL, NULL],
39: T_BOOLEAN_OR => [Operator::ASSOC_LEFT, 6, TRUE, '\Pharborist\Operators\BooleanOrNode', NULL],
40: T_BOOLEAN_AND => [Operator::ASSOC_LEFT, 7, TRUE, '\Pharborist\Operators\BooleanAndNode', NULL],
41: '|' => [Operator::ASSOC_LEFT, 8, TRUE, '\Pharborist\Operators\BitwiseOrNode', NULL],
42: '^' => [Operator::ASSOC_LEFT, 9, TRUE, '\Pharborist\Operators\BitwiseXorNode', NULL],
43: '&' => [Operator::ASSOC_LEFT, 10, TRUE, '\Pharborist\Operators\BitwiseAndNode', NULL],
44: T_IS_EQUAL => [Operator::ASSOC_NONE, 11, TRUE, '\Pharborist\Operators\EqualNode', NULL],
45: T_IS_IDENTICAL => [Operator::ASSOC_NONE, 11, TRUE, '\Pharborist\Operators\IdenticalNode', NULL],
46: T_IS_NOT_EQUAL => [Operator::ASSOC_NONE, 11, TRUE, '\Pharborist\Operators\NotEqualNode', NULL],
47: T_IS_NOT_IDENTICAL => [Operator::ASSOC_NONE, 11, TRUE, '\Pharborist\Operators\NotIdenticalNode', NULL],
48: '<' => [Operator::ASSOC_NONE, 12, TRUE, '\Pharborist\Operators\LessThanNode', NULL],
49: T_IS_SMALLER_OR_EQUAL => [Operator::ASSOC_NONE, 12, TRUE, '\Pharborist\Operators\LessThanOrEqualToNode', NULL],
50: T_IS_GREATER_OR_EQUAL => [Operator::ASSOC_NONE, 12, TRUE, '\Pharborist\Operators\GreaterThanOrEqualToNode', NULL],
51: '>' => [Operator::ASSOC_NONE, 12, TRUE, '\Pharborist\Operators\GreaterThanNode', NULL],
52: T_SL => [Operator::ASSOC_LEFT, 13, TRUE, '\Pharborist\Operators\BitwiseShiftLeftNode', NULL],
53: T_SR => [Operator::ASSOC_LEFT, 13, TRUE, '\Pharborist\Operators\BitwiseShiftRightNode', NULL],
54: '+' => [Operator::ASSOC_LEFT, 14, TRUE, '\Pharborist\Operators\AddNode', '\Pharborist\Operators\PlusNode'],
55: '-' => [Operator::ASSOC_LEFT, 14, TRUE, '\Pharborist\Operators\SubtractNode', '\Pharborist\Operators\NegateNode'],
56: '.' => [Operator::ASSOC_LEFT, 14, TRUE, '\Pharborist\Operators\ConcatNode', NULL],
57: '*' => [Operator::ASSOC_LEFT, 15, TRUE, '\Pharborist\Operators\MultiplyNode', NULL],
58: '/' => [Operator::ASSOC_LEFT, 15, TRUE, '\Pharborist\Operators\DivideNode', NULL],
59: '%' => [Operator::ASSOC_LEFT, 15, TRUE, '\Pharborist\Operators\ModulusNode', NULL],
60: '!' => [Operator::ASSOC_RIGHT, 16, TRUE, NULL, '\Pharborist\Operators\BooleanNotNode'],
61: T_INSTANCEOF => [Operator::ASSOC_NONE, 17, FALSE, '\Pharborist\Operators\InstanceOfNode', NULL],
62: T_INC => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\PreIncrementNode'],
63: T_DEC => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\PreDecrementNode'],
64: T_BOOL_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\BooleanCastNode'],
65: T_INT_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\IntegerCastNode'],
66: T_DOUBLE_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\FloatCastNode'],
67: T_STRING_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\StringCastNode'],
68: T_ARRAY_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\ArrayCastNode'],
69: T_OBJECT_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\ObjectCastNode'],
70: T_UNSET_CAST => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\UnsetCastNode'],
71: '@' => [Operator::ASSOC_RIGHT, 18, FALSE, NULL, '\Pharborist\Operators\SuppressWarningNode'],
72: '~' => [Operator::ASSOC_RIGHT, 18, TRUE, NULL, '\Pharborist\Operators\BitwiseNotNode'],
73: T_POW => [Operator::ASSOC_RIGHT, 19, TRUE, '\Pharborist\Operators\PowerNode', NULL],
74: T_CLONE => [Operator::ASSOC_RIGHT, 20, FALSE, NULL, '\Pharborist\Operators\CloneNode'],
75: T_PRINT => [Operator::ASSOC_RIGHT, 21, FALSE, NULL, '\Pharborist\Operators\PrintNode'],
76: ];
77:
78: 79: 80: 81: 82: 83:
84: public static function createOperator($token_type, $static_only = FALSE) {
85: if (array_key_exists($token_type, self::$operators)) {
86: list($assoc, $precedence, $static, $binary_class_name, $unary_class_name) = self::$operators[$token_type];
87: if ($static_only && !$static) {
88: return NULL;
89: }
90: $operator = new Operator();
91: $operator->type = $token_type;
92: $operator->associativity = $assoc;
93: $operator->precedence = $precedence;
94: $operator->hasBinaryMode = $binary_class_name !== NULL;
95: $operator->hasUnaryMode = $unary_class_name !== NULL;
96: $operator->binaryClassName = $binary_class_name;
97: $operator->unaryClassName = $unary_class_name;
98: return $operator;
99: }
100: return NULL;
101: }
102:
103: 104: 105: 106: 107:
108: public static function createElvisOperator(Operator $question_operator, PartialNode $colon_node) {
109: $operator = new Operator();
110: $operator->mergeNode($question_operator);
111: $operator->mergeNode($colon_node);
112: $operator->type = '?:';
113: $operator->associativity = Operator::ASSOC_LEFT;
114: $operator->precedence = 5;
115: $operator->hasBinaryMode = TRUE;
116: $operator->hasUnaryMode = FALSE;
117: $operator->binaryClassName = '\Pharborist\Operators\ElvisNode';
118: return $operator;
119: }
120:
121: 122: 123: 124: 125:
126: public static function createAssignReferenceOperator(Operator $assign_operator, PartialNode $by_ref_node) {
127: $operator = new Operator();
128: $operator->mergeNode($assign_operator);
129: $operator->mergeNode($by_ref_node);
130: $operator->associativity = Operator::ASSOC_RIGHT;
131: $operator->precedence = 4;
132: $operator->hasBinaryMode = TRUE;
133: $operator->hasUnaryMode = FALSE;
134: $operator->binaryClassName = '\Pharborist\Operators\AssignReferenceNode';
135: return $operator;
136: }
137:
138: 139: 140: 141: 142:
143: public static function createUnaryOperatorNode(Operator $operator, Node $operand) {
144: $class_name = $operator->unaryClassName;
145:
146: $node = new $class_name();
147: $node->mergeNode($operator);
148: $node->addChild($operand, 'operand');
149: return $node;
150: }
151:
152: 153: 154: 155: 156: 157:
158: public static function createBinaryOperatorNode(Node $left, Operator $operator, Node $right) {
159: $class_name = $operator->binaryClassName;
160:
161: $node = new $class_name();
162: $node->addChild($left, 'left');
163: $node->mergeNode($operator);
164: $node->addChild($right, 'right');
165: return $node;
166: }
167:
168: 169: 170: 171: 172: 173:
174: public static function createPostfixOperatorNode(Node $operand, Operator $operator) {
175: if ($operator->type === T_DEC) {
176: $node = new PostDecrementNode();
177: }
178: elseif ($operator->type === T_INC) {
179: $node = new PostIncrementNode();
180: }
181: else {
182: throw new ParserException($operator->getOperator()->getSourcePosition(), "Invalid postfix operator!");
183: }
184: $node->addChild($operand, 'operand');
185: $node->mergeNode($operator);
186: return $node;
187: }
188:
189: 190: 191: 192: 193: 194: 195: 196:
197: public static function createTernaryOperatorNode(
198: Node $condition,
199: Operator $operator,
200: Node $then,
201: ParentNode $colon,
202: Node $else
203: ) {
204: $node = new TernaryOperationNode();
205: $node->addChild($condition, 'condition');
206: $node->mergeNode($operator);
207: $node->addChild($then, 'then');
208: $node->mergeNode($colon);
209: $node->addChild($else, 'else');
210: return $node;
211: }
212: }
213: