TokenTranslationScheme::getToken()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UniLex\RegExp\Grammar;
6
7
use Remorhaz\UniLex\Exception;
8
use Remorhaz\UniLex\Parser\Symbol;
9
use Remorhaz\UniLex\Lexer\Token;
10
use Throwable;
11
12
class TokenTranslationScheme
13
{
14
    private $symbol;
15
16
    private $token;
17
18
    /**
19
     * @param Symbol $symbol
20
     * @param Token $token
21
     * @throws Exception
22
     */
23
    public function applyActions(Symbol $symbol, Token $token): void
24
    {
25
        $this->setContext($symbol, $token);
26
27
        switch ($symbol->getSymbolId()) {
28
            case SymbolType::T_DIGIT_ZERO:
29
            case SymbolType::T_DIGIT_OCT:
30
                $this
31
                    ->copyTokenAttribute('s.code', TokenAttribute::CODE)
32
                    ->copyTokenAttribute('s.oct_digit', TokenAttribute::DIGIT)
33
                    ->copyTokenAttribute('s.dec_digit', TokenAttribute::DIGIT)
34
                    ->copyTokenAttribute('s.hex_digit', TokenAttribute::DIGIT);
35
                break;
36
37
            case SymbolType::T_DIGIT_DEC:
38
                $this
39
                    ->copyTokenAttribute('s.code', TokenAttribute::CODE)
40
                    ->copyTokenAttribute('s.dec_digit', TokenAttribute::DIGIT)
41
                    ->copyTokenAttribute('s.hex_digit', TokenAttribute::DIGIT);
42
                break;
43
44
            case SymbolType::T_SMALL_C:
45
            case SymbolType::T_OTHER_HEX_LETTER:
46
                $this
47
                    ->copyTokenAttribute('s.code', TokenAttribute::CODE)
48
                    ->copyTokenAttribute('s.hex_digit', TokenAttribute::DIGIT);
49
                break;
50
51
            case SymbolType::T_COMMA:
52
            case SymbolType::T_HYPHEN:
53
            case SymbolType::T_CAPITAL_P:
54
            case SymbolType::T_RIGHT_SQUARE_BRACKET:
55
            case SymbolType::T_SMALL_O:
56
            case SymbolType::T_SMALL_P:
57
            case SymbolType::T_SMALL_U:
58
            case SymbolType::T_SMALL_X:
59
            case SymbolType::T_RIGHT_CURLY_BRACKET:
60
            case SymbolType::T_CTL_ASCII:
61
            case SymbolType::T_PRINTABLE_ASCII_OTHER:
62
            case SymbolType::T_NOT_ASCII:
63
            case SymbolType::T_DOLLAR:
64
            case SymbolType::T_LEFT_BRACKET:
65
            case SymbolType::T_RIGHT_BRACKET:
66
            case SymbolType::T_STAR:
67
            case SymbolType::T_PLUS:
68
            case SymbolType::T_QUESTION:
69
            case SymbolType::T_LEFT_SQUARE_BRACKET:
70
            case SymbolType::T_BACKSLASH:
71
            case SymbolType::T_CIRCUMFLEX:
72
            case SymbolType::T_LEFT_CURLY_BRACKET:
73
            case SymbolType::T_VERTICAL_LINE:
74
            case SymbolType::T_DOT:
75
            case SymbolType::T_OTHER_ASCII_LETTER:
76
                $this
77
                    ->copyTokenAttribute('s.code', TokenAttribute::CODE);
78
                break;
79
        }
80
    }
81
82
    /**
83
     * @param string $symbolAttr
84
     * @param string $tokenAttr
85
     * @return $this
86
     * @throws Exception
87
     */
88
    private function copyTokenAttribute(string $symbolAttr, string $tokenAttr)
89
    {
90
        try {
91
            $value = $this
92
                ->getToken()
93
                ->getAttribute($tokenAttr);
94
            $this
95
                ->getSymbol()
96
                ->setAttribute($symbolAttr, $value);
97
        } catch (Throwable $e) {
98
            $symbolText = "{$this->getSymbol()->getSymbolId()}.{$symbolAttr}";
99
            $tokenText = "{$this->getToken()->getType()}.{$tokenAttr}";
100
            throw new Exception("Failed to synthesize attribute {$symbolText} from token {$tokenText}", 0, $e);
101
        }
102
        return $this;
103
    }
104
105
106
    private function setContext(Symbol $symbol, Token $token): void
107
    {
108
        $this->symbol = $symbol;
109
        $this->token = $token;
110
    }
111
112
    /**
113
     * @return Symbol
114
     * @throws Exception
115
     */
116
    private function getSymbol(): Symbol
117
    {
118
        if (!isset($this->symbol)) {
119
            throw new Exception("No symbol defined in token translation scheme");
120
        }
121
        return $this->symbol;
122
    }
123
124
    /**
125
     * @return Token
126
     * @throws Exception
127
     */
128
    private function getToken(): Token
129
    {
130
        if (!isset($this->token)) {
131
            throw new Exception("No token defined in token translation scheme");
132
        }
133
        return $this->token;
134
    }
135
}
136