1: <?php
2:
3: namespace BN\Compiler\Parser;
4:
5: use BN\Compiler\Token\Token;
6: use BN\Compiler\Token\TokenType;
7: use BN\Compiler\Grammar\Operators;
8: use BN\Compiler\Parser\Token\ParseValue;
9: use BN\Compiler\Parser\Token\ParseOperator;
10: use BN\Compiler\Parser\Token\ParseOpeningBracket;
11: use BN\Compiler\Parser\Token\ParseClosingBracket;
12: use BN\Compiler\Parser\Token\ParseUnknownToken;
13:
14: class ShuntingYardParser
15: {
16: private $accumulator;
17: private $parsers;
18: private $postfix;
19: private $tokensArray;
20:
21: public function __construct(ParserErrorHandler $errorHandler, Operators $operators)
22: {
23: $this->accumulator = new QueueAccumulator($errorHandler);
24: $this->postfix = new StackCleaning($this->accumulator);
25: $parseValue = new ParseValue($this->accumulator);
26: $parseOperator = new ParseOperator($this->accumulator, $operators);
27: $this->parsers = array(
28: TokenType::NUMBER => $parseValue,
29: TokenType::VARIABLE => $parseValue,
30: TokenType::CONSTANT => $parseValue,
31: TokenType::ASSIGN => $parseOperator,
32: TokenType::OPERATOR => $parseOperator,
33: TokenType::BRACKET_OPENING => new ParseOpeningBracket($this->accumulator),
34: TokenType::BRACKET_CLOSING => new ParseClosingBracket($this->accumulator),
35: TokenType::UNKNOWN => new ParseUnknownToken($this->accumulator)
36: );
37: }
38:
39: public function parse(array $tokensInInfixNotation)
40: {
41: $this->prepareParser($tokensInInfixNotation);
42: while ($this->existsUnreadToken()) {
43: $this->readNextToken();
44: }
45: $this->pushOperatorsFromStack();
46: return $this->getTokensInPostfixNotation();
47: }
48:
49: private function prepareParser($tokens)
50: {
51: $this->tokensArray = $tokens;
52: $this->accumulator->init();
53: }
54:
55: private function existsUnreadToken()
56: {
57: return !empty($this->tokensArray);
58: }
59:
60: private function readNextToken()
61: {
62: $token = array_shift($this->tokensArray);
63: $parser = $this->getParser($token);
64: $parser->parse($token);
65: }
66:
67: private function getParser(Token $token)
68: {
69: if (array_key_exists($token->type, $this->parsers)) {
70: return $this->parsers[$token->type];
71: } else {
72: return $this->parsers[TokenType::UNKNOWN];
73: }
74: }
75:
76: private function pushOperatorsFromStack()
77: {
78: $this->postfix->pushOperatorsFromStack();
79: }
80:
81: private function getTokensInPostfixNotation()
82: {
83: return $this->accumulator->getResult();
84: }
85: }
86: