MediaWiki REL1_30
Expr.php
Go to the documentation of this file.
1<?php
2
3use UtfNormal\Validator;
4
5if ( !defined( 'MEDIAWIKI' ) ) {
6 die( 'This file is a MediaWiki extension, it is not a valid entry point' );
7}
8
9// Character classes
10define( 'EXPR_WHITE_CLASS', " \t\r\n" );
11define( 'EXPR_NUMBER_CLASS', '0123456789.' );
12
13// Token types
14define( 'EXPR_WHITE', 1 );
15define( 'EXPR_NUMBER', 2 );
16define( 'EXPR_NEGATIVE', 3 );
17define( 'EXPR_POSITIVE', 4 );
18define( 'EXPR_PLUS', 5 );
19define( 'EXPR_MINUS', 6 );
20define( 'EXPR_TIMES', 7 );
21define( 'EXPR_DIVIDE', 8 );
22define( 'EXPR_MOD', 9 );
23define( 'EXPR_OPEN', 10 );
24define( 'EXPR_CLOSE', 11 );
25define( 'EXPR_AND', 12 );
26define( 'EXPR_OR', 13 );
27define( 'EXPR_NOT', 14 );
28define( 'EXPR_EQUALITY', 15 );
29define( 'EXPR_LESS', 16 );
30define( 'EXPR_GREATER', 17 );
31define( 'EXPR_LESSEQ', 18 );
32define( 'EXPR_GREATEREQ', 19 );
33define( 'EXPR_NOTEQ', 20 );
34define( 'EXPR_ROUND', 21 );
35define( 'EXPR_EXPONENT', 22 );
36define( 'EXPR_SINE', 23 );
37define( 'EXPR_COSINE', 24 );
38define( 'EXPR_TANGENS', 25 );
39define( 'EXPR_ARCSINE', 26 );
40define( 'EXPR_ARCCOS', 27 );
41define( 'EXPR_ARCTAN', 28 );
42define( 'EXPR_EXP', 29 );
43define( 'EXPR_LN', 30 );
44define( 'EXPR_ABS', 31 );
45define( 'EXPR_FLOOR', 32 );
46define( 'EXPR_TRUNC', 33 );
47define( 'EXPR_CEIL', 34 );
48define( 'EXPR_POW', 35 );
49define( 'EXPR_PI', 36 );
50define( 'EXPR_FMOD', 37 );
51define( 'EXPR_SQRT', 38 );
52
53class ExprError extends Exception {
58 public function __construct( $msg, $parameter = '' ) {
59 // Give grep a chance to find the usages:
60 // pfunc_expr_stack_exhausted, pfunc_expr_unexpected_number, pfunc_expr_preg_match_failure,
61 // pfunc_expr_unrecognised_word, pfunc_expr_unexpected_operator, pfunc_expr_missing_operand,
62 // pfunc_expr_unexpected_closing_bracket, pfunc_expr_unrecognised_punctuation,
63 // pfunc_expr_unclosed_bracket, pfunc_expr_division_by_zero, pfunc_expr_invalid_argument,
64 // pfunc_expr_invalid_argument_ln, pfunc_expr_unknown_error, pfunc_expr_not_a_number
65 $this->message = wfMessage( "pfunc_expr_$msg", $parameter )->inContentLanguage()->text();
66 }
67}
68
70 public $maxStackSize = 100;
71
72 public $precedence = [
73 EXPR_NEGATIVE => 10,
74 EXPR_POSITIVE => 10,
75 EXPR_EXPONENT => 10,
76 EXPR_SINE => 9,
77 EXPR_COSINE => 9,
78 EXPR_TANGENS => 9,
79 EXPR_ARCSINE => 9,
80 EXPR_ARCCOS => 9,
81 EXPR_ARCTAN => 9,
82 EXPR_EXP => 9,
83 EXPR_LN => 9,
84 EXPR_ABS => 9,
85 EXPR_FLOOR => 9,
86 EXPR_TRUNC => 9,
87 EXPR_CEIL => 9,
88 EXPR_NOT => 9,
89 EXPR_SQRT => 9,
90 EXPR_POW => 8,
91 EXPR_TIMES => 7,
92 EXPR_DIVIDE => 7,
93 EXPR_MOD => 7,
94 EXPR_FMOD => 7,
95 EXPR_PLUS => 6,
96 EXPR_MINUS => 6,
97 EXPR_ROUND => 5,
98 EXPR_EQUALITY => 4,
99 EXPR_LESS => 4,
100 EXPR_GREATER => 4,
101 EXPR_LESSEQ => 4,
102 EXPR_GREATEREQ => 4,
103 EXPR_NOTEQ => 4,
104 EXPR_AND => 3,
105 EXPR_OR => 2,
106 EXPR_PI => 0,
107 EXPR_OPEN => -1,
108 EXPR_CLOSE => -1,
109 ];
110
111 public $names = [
112 EXPR_NEGATIVE => '-',
113 EXPR_POSITIVE => '+',
114 EXPR_NOT => 'not',
115 EXPR_TIMES => '*',
116 EXPR_DIVIDE => '/',
117 EXPR_MOD => 'mod',
118 EXPR_FMOD => 'fmod',
119 EXPR_PLUS => '+',
120 EXPR_MINUS => '-',
121 EXPR_ROUND => 'round',
122 EXPR_EQUALITY => '=',
123 EXPR_LESS => '<',
124 EXPR_GREATER => '>',
125 EXPR_LESSEQ => '<=',
126 EXPR_GREATEREQ => '>=',
127 EXPR_NOTEQ => '<>',
128 EXPR_AND => 'and',
129 EXPR_OR => 'or',
130 EXPR_EXPONENT => 'e',
131 EXPR_SINE => 'sin',
132 EXPR_COSINE => 'cos',
133 EXPR_TANGENS => 'tan',
134 EXPR_ARCSINE => 'asin',
135 EXPR_ARCCOS => 'acos',
136 EXPR_ARCTAN => 'atan',
137 EXPR_LN => 'ln',
138 EXPR_EXP => 'exp',
139 EXPR_ABS => 'abs',
140 EXPR_FLOOR => 'floor',
141 EXPR_TRUNC => 'trunc',
142 EXPR_CEIL => 'ceil',
143 EXPR_POW => '^',
144 EXPR_PI => 'pi',
145 EXPR_SQRT => 'sqrt',
146 ];
147
148 public $words = [
149 'mod' => EXPR_MOD,
150 'fmod' => EXPR_FMOD,
151 'and' => EXPR_AND,
152 'or' => EXPR_OR,
153 'not' => EXPR_NOT,
154 'round' => EXPR_ROUND,
155 'div' => EXPR_DIVIDE,
156 'e' => EXPR_EXPONENT,
157 'sin' => EXPR_SINE,
158 'cos' => EXPR_COSINE,
159 'tan' => EXPR_TANGENS,
160 'asin' => EXPR_ARCSINE,
161 'acos' => EXPR_ARCCOS,
162 'atan' => EXPR_ARCTAN,
163 'exp' => EXPR_EXP,
164 'ln' => EXPR_LN,
165 'abs' => EXPR_ABS,
166 'trunc' => EXPR_TRUNC,
167 'floor' => EXPR_FLOOR,
168 'ceil' => EXPR_CEIL,
169 'pi' => EXPR_PI,
170 'sqrt' => EXPR_SQRT,
171 ];
172
183 public function doExpression( $expr ) {
184 $operands = [];
185 $operators = [];
186
187 # Unescape inequality operators
188 $expr = strtr( $expr, [ '&lt;' => '<', '&gt;' => '>',
189 '&minus;' => '-', '−' => '-' ] );
190
191 $p = 0;
192 $end = strlen( $expr );
193 $expecting = 'expression';
194 $name = '';
195
196 while ( $p < $end ) {
197 if ( count( $operands ) > $this->maxStackSize || count( $operators ) > $this->maxStackSize ) {
198 throw new ExprError( 'stack_exhausted' );
199 }
200 $char = $expr[$p];
201 $char2 = substr( $expr, $p, 2 );
202
203 // Mega if-elseif-else construct
204 // Only binary operators fall through for processing at the bottom, the rest
205 // finish their processing and continue
206
207 // First the unlimited length classes
208
209 if ( false !== strpos( EXPR_WHITE_CLASS, $char ) ) {
210 // Whitespace
211 $p += strspn( $expr, EXPR_WHITE_CLASS, $p );
212 continue;
213 } elseif ( false !== strpos( EXPR_NUMBER_CLASS, $char ) ) {
214 // Number
215 if ( $expecting !== 'expression' ) {
216 throw new ExprError( 'unexpected_number' );
217 }
218
219 // Find the rest of it
220 $length = strspn( $expr, EXPR_NUMBER_CLASS, $p );
221 // Convert it to float, silently removing double decimal points
222 $operands[] = (float)substr( $expr, $p, $length );
223 $p += $length;
224 $expecting = 'operator';
225 continue;
226 } elseif ( ctype_alpha( $char ) ) {
227 // Word
228 // Find the rest of it
229 $remaining = substr( $expr, $p );
230 if ( !preg_match( '/^[A-Za-z]*/', $remaining, $matches ) ) {
231 // This should be unreachable
232 throw new ExprError( 'preg_match_failure' );
233 }
234 $word = strtolower( $matches[0] );
235 $p += strlen( $word );
236
237 // Interpret the word
238 if ( !isset( $this->words[$word] ) ) {
239 throw new ExprError( 'unrecognised_word', $word );
240 }
241 $op = $this->words[$word];
242 switch ( $op ) {
243 // constant
244 case EXPR_EXPONENT:
245 if ( $expecting !== 'expression' ) {
246 continue;
247 }
248 $operands[] = exp( 1 );
249 $expecting = 'operator';
250 continue 2;
251 case EXPR_PI:
252 if ( $expecting !== 'expression' ) {
253 throw new ExprError( 'unexpected_number' );
254 }
255 $operands[] = pi();
256 $expecting = 'operator';
257 continue 2;
258 // Unary operator
259 case EXPR_NOT:
260 case EXPR_SINE:
261 case EXPR_COSINE:
262 case EXPR_TANGENS:
263 case EXPR_ARCSINE:
264 case EXPR_ARCCOS:
265 case EXPR_ARCTAN:
266 case EXPR_EXP:
267 case EXPR_LN:
268 case EXPR_ABS:
269 case EXPR_FLOOR:
270 case EXPR_TRUNC:
271 case EXPR_CEIL:
272 case EXPR_SQRT:
273 if ( $expecting !== 'expression' ) {
274 throw new ExprError( 'unexpected_operator', $word );
275 }
276 $operators[] = $op;
277 continue 2;
278 }
279 // Binary operator, fall through
280 $name = $word;
281 }
282
283 // Next the two-character operators
284 elseif ( $char2 === '<=' ) {
285 $name = $char2;
286 $op = EXPR_LESSEQ;
287 $p += 2;
288 } elseif ( $char2 === '>=' ) {
289 $name = $char2;
290 $op = EXPR_GREATEREQ;
291 $p += 2;
292 } elseif ( $char2 === '<>' || $char2 === '!=' ) {
293 $name = $char2;
294 $op = EXPR_NOTEQ;
295 $p += 2;
296 }
297
298 // Finally the single-character operators
299 elseif ( $char === '+' ) {
300 ++$p;
301 if ( $expecting === 'expression' ) {
302 // Unary plus
303 $operators[] = EXPR_POSITIVE;
304 continue;
305 } else {
306 // Binary plus
307 $op = EXPR_PLUS;
308 }
309 } elseif ( $char === '-' ) {
310 ++$p;
311 if ( $expecting === 'expression' ) {
312 // Unary minus
313 $operators[] = EXPR_NEGATIVE;
314 continue;
315 } else {
316 // Binary minus
317 $op = EXPR_MINUS;
318 }
319 } elseif ( $char === '*' ) {
320 $name = $char;
321 $op = EXPR_TIMES;
322 ++$p;
323 } elseif ( $char === '/' ) {
324 $name = $char;
325 $op = EXPR_DIVIDE;
326 ++$p;
327 } elseif ( $char === '^' ) {
328 $name = $char;
329 $op = EXPR_POW;
330 ++$p;
331 } elseif ( $char === '(' ) {
332 if ( $expecting === 'operator' ) {
333 throw new ExprError( 'unexpected_operator', '(' );
334 }
335 $operators[] = EXPR_OPEN;
336 ++$p;
337 continue;
338 } elseif ( $char === ')' ) {
339 $lastOp = end( $operators );
340 while ( $lastOp && $lastOp != EXPR_OPEN ) {
341 $this->doOperation( $lastOp, $operands );
342 array_pop( $operators );
343 $lastOp = end( $operators );
344 }
345 if ( $lastOp ) {
346 array_pop( $operators );
347 } else {
348 throw new ExprError( 'unexpected_closing_bracket' );
349 }
350 $expecting = 'operator';
351 ++$p;
352 continue;
353 } elseif ( $char === '=' ) {
354 $name = $char;
355 $op = EXPR_EQUALITY;
356 ++$p;
357 } elseif ( $char === '<' ) {
358 $name = $char;
359 $op = EXPR_LESS;
360 ++$p;
361 } elseif ( $char === '>' ) {
362 $name = $char;
363 $op = EXPR_GREATER;
364 ++$p;
365 } else {
366 throw new ExprError( 'unrecognised_punctuation', Validator::cleanUp( $char ) );
367 }
368
369 // Binary operator processing
370 if ( $expecting === 'expression' ) {
371 throw new ExprError( 'unexpected_operator', $name );
372 }
373
374 // Shunting yard magic
375 $lastOp = end( $operators );
376 while ( $lastOp && $this->precedence[$op] <= $this->precedence[$lastOp] ) {
377 $this->doOperation( $lastOp, $operands );
378 array_pop( $operators );
379 $lastOp = end( $operators );
380 }
381 $operators[] = $op;
382 $expecting = 'expression';
383 }
384
385 // Finish off the operator array
386 // @codingStandardsIgnoreStart
387 while ( $op = array_pop( $operators ) ) {
388 // @codingStandardsIgnoreEnd
389 if ( $op == EXPR_OPEN ) {
390 throw new ExprError( 'unclosed_bracket' );
391 }
392 $this->doOperation( $op, $operands );
393 }
394
395 return implode( "<br />\n", $operands );
396 }
397
403 public function doOperation( $op, &$stack ) {
404 switch ( $op ) {
405 case EXPR_NEGATIVE:
406 if ( count( $stack ) < 1 ) {
407 throw new ExprError( 'missing_operand', $this->names[$op] );
408 }
409 $arg = array_pop( $stack );
410 $stack[] = -$arg;
411 break;
412 case EXPR_POSITIVE:
413 if ( count( $stack ) < 1 ) {
414 throw new ExprError( 'missing_operand', $this->names[$op] );
415 }
416 break;
417 case EXPR_TIMES:
418 if ( count( $stack ) < 2 ) {
419 throw new ExprError( 'missing_operand', $this->names[$op] );
420 }
421 $right = array_pop( $stack );
422 $left = array_pop( $stack );
423 $stack[] = $left * $right;
424 break;
425 case EXPR_DIVIDE:
426 if ( count( $stack ) < 2 ) {
427 throw new ExprError( 'missing_operand', $this->names[$op] );
428 }
429 $right = array_pop( $stack );
430 $left = array_pop( $stack );
431 if ( !$right ) {
432 throw new ExprError( 'division_by_zero', $this->names[$op] );
433 }
434 $stack[] = $left / $right;
435 break;
436 case EXPR_MOD:
437 if ( count( $stack ) < 2 ) {
438 throw new ExprError( 'missing_operand', $this->names[$op] );
439 }
440 $right = (int)array_pop( $stack );
441 $left = (int)array_pop( $stack );
442 if ( !$right ) {
443 throw new ExprError( 'division_by_zero', $this->names[$op] );
444 }
445 $stack[] = $left % $right;
446 break;
447 case EXPR_FMOD:
448 if ( count( $stack ) < 2 ) {
449 throw new ExprError( 'missing_operand', $this->names[$op] );
450 }
451 $right = (double)array_pop( $stack );
452 $left = (double)array_pop( $stack );
453 if ( !$right ) {
454 throw new ExprError( 'division_by_zero', $this->names[$op] );
455 }
456 $stack[] = fmod( $left, $right );
457 break;
458 case EXPR_PLUS:
459 if ( count( $stack ) < 2 ) {
460 throw new ExprError( 'missing_operand', $this->names[$op] );
461 }
462 $right = array_pop( $stack );
463 $left = array_pop( $stack );
464 $stack[] = $left + $right;
465 break;
466 case EXPR_MINUS:
467 if ( count( $stack ) < 2 ) {
468 throw new ExprError( 'missing_operand', $this->names[$op] );
469 }
470 $right = array_pop( $stack );
471 $left = array_pop( $stack );
472 $stack[] = $left - $right;
473 break;
474 case EXPR_AND:
475 if ( count( $stack ) < 2 ) {
476 throw new ExprError( 'missing_operand', $this->names[$op] );
477 }
478 $right = array_pop( $stack );
479 $left = array_pop( $stack );
480 $stack[] = ( $left && $right ) ? 1 : 0;
481 break;
482 case EXPR_OR:
483 if ( count( $stack ) < 2 ) {
484 throw new ExprError( 'missing_operand', $this->names[$op] );
485 }
486 $right = array_pop( $stack );
487 $left = array_pop( $stack );
488 $stack[] = ( $left || $right ) ? 1 : 0;
489 break;
490 case EXPR_EQUALITY:
491 if ( count( $stack ) < 2 ) {
492 throw new ExprError( 'missing_operand', $this->names[$op] );
493 }
494 $right = array_pop( $stack );
495 $left = array_pop( $stack );
496 $stack[] = ( $left == $right ) ? 1 : 0;
497 break;
498 case EXPR_NOT:
499 if ( count( $stack ) < 1 ) {
500 throw new ExprError( 'missing_operand', $this->names[$op] );
501 }
502 $arg = array_pop( $stack );
503 $stack[] = ( !$arg ) ? 1 : 0;
504 break;
505 case EXPR_ROUND:
506 if ( count( $stack ) < 2 ) {
507 throw new ExprError( 'missing_operand', $this->names[$op] );
508 }
509 $digits = (int)array_pop( $stack );
510 $value = array_pop( $stack );
511 $stack[] = round( $value, $digits );
512 break;
513 case EXPR_LESS:
514 if ( count( $stack ) < 2 ) {
515 throw new ExprError( 'missing_operand', $this->names[$op] );
516 }
517 $right = array_pop( $stack );
518 $left = array_pop( $stack );
519 $stack[] = ( $left < $right ) ? 1 : 0;
520 break;
521 case EXPR_GREATER:
522 if ( count( $stack ) < 2 ) {
523 throw new ExprError( 'missing_operand', $this->names[$op] );
524 }
525 $right = array_pop( $stack );
526 $left = array_pop( $stack );
527 $stack[] = ( $left > $right ) ? 1 : 0;
528 break;
529 case EXPR_LESSEQ:
530 if ( count( $stack ) < 2 ) {
531 throw new ExprError( 'missing_operand', $this->names[$op] );
532 }
533 $right = array_pop( $stack );
534 $left = array_pop( $stack );
535 $stack[] = ( $left <= $right ) ? 1 : 0;
536 break;
537 case EXPR_GREATEREQ:
538 if ( count( $stack ) < 2 ) {
539 throw new ExprError( 'missing_operand', $this->names[$op] );
540 }
541 $right = array_pop( $stack );
542 $left = array_pop( $stack );
543 $stack[] = ( $left >= $right ) ? 1 : 0;
544 break;
545 case EXPR_NOTEQ:
546 if ( count( $stack ) < 2 ) {
547 throw new ExprError( 'missing_operand', $this->names[$op] );
548 }
549 $right = array_pop( $stack );
550 $left = array_pop( $stack );
551 $stack[] = ( $left != $right ) ? 1 : 0;
552 break;
553 case EXPR_EXPONENT:
554 if ( count( $stack ) < 2 ) {
555 throw new ExprError( 'missing_operand', $this->names[$op] );
556 }
557 $right = array_pop( $stack );
558 $left = array_pop( $stack );
559 $stack[] = $left * pow( 10, $right );
560 break;
561 case EXPR_SINE:
562 if ( count( $stack ) < 1 ) {
563 throw new ExprError( 'missing_operand', $this->names[$op] );
564 }
565 $arg = array_pop( $stack );
566 $stack[] = sin( $arg );
567 break;
568 case EXPR_COSINE:
569 if ( count( $stack ) < 1 ) {
570 throw new ExprError( 'missing_operand', $this->names[$op] );
571 }
572 $arg = array_pop( $stack );
573 $stack[] = cos( $arg );
574 break;
575 case EXPR_TANGENS:
576 if ( count( $stack ) < 1 ) {
577 throw new ExprError( 'missing_operand', $this->names[$op] );
578 }
579 $arg = array_pop( $stack );
580 $stack[] = tan( $arg );
581 break;
582 case EXPR_ARCSINE:
583 if ( count( $stack ) < 1 ) {
584 throw new ExprError( 'missing_operand', $this->names[$op] );
585 }
586 $arg = array_pop( $stack );
587 if ( $arg < -1 || $arg > 1 ) {
588 throw new ExprError( 'invalid_argument', $this->names[$op] );
589 }
590 $stack[] = asin( $arg );
591 break;
592 case EXPR_ARCCOS:
593 if ( count( $stack ) < 1 ) {
594 throw new ExprError( 'missing_operand', $this->names[$op] );
595 }
596 $arg = array_pop( $stack );
597 if ( $arg < -1 || $arg > 1 ) {
598 throw new ExprError( 'invalid_argument', $this->names[$op] );
599 }
600 $stack[] = acos( $arg );
601 break;
602 case EXPR_ARCTAN:
603 if ( count( $stack ) < 1 ) {
604 throw new ExprError( 'missing_operand', $this->names[$op] );
605 }
606 $arg = array_pop( $stack );
607 $stack[] = atan( $arg );
608 break;
609 case EXPR_EXP:
610 if ( count( $stack ) < 1 ) {
611 throw new ExprError( 'missing_operand', $this->names[$op] );
612 }
613 $arg = array_pop( $stack );
614 $stack[] = exp( $arg );
615 break;
616 case EXPR_LN:
617 if ( count( $stack ) < 1 ) {
618 throw new ExprError( 'missing_operand', $this->names[$op] );
619 }
620 $arg = array_pop( $stack );
621 if ( $arg <= 0 ) {
622 throw new ExprError( 'invalid_argument_ln', $this->names[$op] );
623 }
624 $stack[] = log( $arg );
625 break;
626 case EXPR_ABS:
627 if ( count( $stack ) < 1 ) {
628 throw new ExprError( 'missing_operand', $this->names[$op] );
629 }
630 $arg = array_pop( $stack );
631 $stack[] = abs( $arg );
632 break;
633 case EXPR_FLOOR:
634 if ( count( $stack ) < 1 ) {
635 throw new ExprError( 'missing_operand', $this->names[$op] );
636 }
637 $arg = array_pop( $stack );
638 $stack[] = floor( $arg );
639 break;
640 case EXPR_TRUNC:
641 if ( count( $stack ) < 1 ) {
642 throw new ExprError( 'missing_operand', $this->names[$op] );
643 }
644 $arg = array_pop( $stack );
645 $stack[] = (int)$arg;
646 break;
647 case EXPR_CEIL:
648 if ( count( $stack ) < 1 ) {
649 throw new ExprError( 'missing_operand', $this->names[$op] );
650 }
651 $arg = array_pop( $stack );
652 $stack[] = ceil( $arg );
653 break;
654 case EXPR_POW:
655 if ( count( $stack ) < 2 ) {
656 throw new ExprError( 'missing_operand', $this->names[$op] );
657 }
658 $right = array_pop( $stack );
659 $left = array_pop( $stack );
660 $result = pow( $left, $right );
661 if ( $result === false ) {
662 throw new ExprError( 'division_by_zero', $this->names[$op] );
663 }
664 $stack[] = $result;
665 break;
666 case EXPR_SQRT:
667 if ( count( $stack ) < 1 ) {
668 throw new ExprError( 'missing_operand', $this->names[$op] );
669 }
670 $arg = array_pop( $stack );
671 $result = sqrt( $arg );
672 if ( is_nan( $result ) ) {
673 throw new ExprError( 'not_a_number', $this->names[$op] );
674 }
675 $stack[] = $result;
676 break;
677 default:
678 // Should be impossible to reach here.
679 throw new ExprError( 'unknown_error' );
680 }
681 }
682}
const EXPR_COSINE
Definition Expr.php:37
const EXPR_AND
Definition Expr.php:25
const EXPR_GREATER
Definition Expr.php:30
const EXPR_TANGENS
Definition Expr.php:38
const EXPR_EXP
Definition Expr.php:42
const EXPR_MINUS
Definition Expr.php:19
const EXPR_EQUALITY
Definition Expr.php:28
const EXPR_LESSEQ
Definition Expr.php:31
const EXPR_ARCSINE
Definition Expr.php:39
const EXPR_EXPONENT
Definition Expr.php:35
const EXPR_PI
Definition Expr.php:49
const EXPR_WHITE_CLASS(!defined( 'MEDIAWIKI'))
Definition Expr.php:10
const EXPR_NOTEQ
Definition Expr.php:33
const EXPR_DIVIDE
Definition Expr.php:21
const EXPR_ARCCOS
Definition Expr.php:40
const EXPR_OR
Definition Expr.php:26
const EXPR_ARCTAN
Definition Expr.php:41
const EXPR_LESS
Definition Expr.php:29
const EXPR_FLOOR
Definition Expr.php:45
const EXPR_SQRT
Definition Expr.php:51
const EXPR_CLOSE
Definition Expr.php:24
const EXPR_LN
Definition Expr.php:43
const EXPR_POSITIVE
Definition Expr.php:17
const EXPR_NEGATIVE
Definition Expr.php:16
const EXPR_SINE
Definition Expr.php:36
const EXPR_FMOD
Definition Expr.php:50
const EXPR_TRUNC
Definition Expr.php:46
const EXPR_ABS
Definition Expr.php:44
const EXPR_NOT
Definition Expr.php:27
const EXPR_MOD
Definition Expr.php:22
const EXPR_GREATEREQ
Definition Expr.php:32
const EXPR_TIMES
Definition Expr.php:20
const EXPR_NUMBER_CLASS
Definition Expr.php:11
const EXPR_PLUS
Definition Expr.php:18
const EXPR_POW
Definition Expr.php:48
const EXPR_ROUND
Definition Expr.php:34
const EXPR_OPEN
Definition Expr.php:23
const EXPR_CEIL
Definition Expr.php:47
__construct( $msg, $parameter='')
Definition Expr.php:58
$precedence
Definition Expr.php:72
doExpression( $expr)
Evaluate a mathematical expression.
Definition Expr.php:183
doOperation( $op, &$stack)
Definition Expr.php:403
$maxStackSize
Definition Expr.php:70
namespace being checked & $result
Definition hooks.txt:2293
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt;div ...>$1&lt;/div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services