Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
namespace Sabberworm\CSS\Value;
4
 
5
use Sabberworm\CSS\Parsing\ParserState;
6
use Sabberworm\CSS\Parsing\UnexpectedEOFException;
7
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
8
 
9
class CalcFunction extends CSSFunction
10
{
11
    /**
12
     * @var int
13
     */
14
    const T_OPERAND = 1;
15
 
16
    /**
17
     * @var int
18
     */
19
    const T_OPERATOR = 2;
20
 
21
    /**
22
     * @return CalcFunction
23
     *
24
     * @throws UnexpectedTokenException
25
     * @throws UnexpectedEOFException
26
     */
27
    public static function parse(ParserState $oParserState)
28
    {
29
        $aOperators = ['+', '-', '*', '/'];
30
        $sFunction = trim($oParserState->consumeUntil('(', false, true));
31
        $oCalcList = new CalcRuleValueList($oParserState->currentLine());
32
        $oList = new RuleValueList(',', $oParserState->currentLine());
33
        $iNestingLevel = 0;
34
        $iLastComponentType = null;
35
        while (!$oParserState->comes(')') || $iNestingLevel > 0) {
36
            $oParserState->consumeWhiteSpace();
37
            if ($oParserState->comes('(')) {
38
                $iNestingLevel++;
39
                $oCalcList->addListComponent($oParserState->consume(1));
40
                $oParserState->consumeWhiteSpace();
41
                continue;
42
            } elseif ($oParserState->comes(')')) {
43
                $iNestingLevel--;
44
                $oCalcList->addListComponent($oParserState->consume(1));
45
                $oParserState->consumeWhiteSpace();
46
                continue;
47
            }
48
            if ($iLastComponentType != CalcFunction::T_OPERAND) {
49
                $oVal = Value::parsePrimitiveValue($oParserState);
50
                $oCalcList->addListComponent($oVal);
51
                $iLastComponentType = CalcFunction::T_OPERAND;
52
            } else {
53
                if (in_array($oParserState->peek(), $aOperators)) {
54
                    if (($oParserState->comes('-') || $oParserState->comes('+'))) {
55
                        if (
56
                            $oParserState->peek(1, -1) != ' '
57
                            || !($oParserState->comes('- ')
58
                                || $oParserState->comes('+ '))
59
                        ) {
60
                            throw new UnexpectedTokenException(
61
                                " {$oParserState->peek()} ",
62
                                $oParserState->peek(1, -1) . $oParserState->peek(2),
63
                                'literal',
64
                                $oParserState->currentLine()
65
                            );
66
                        }
67
                    }
68
                    $oCalcList->addListComponent($oParserState->consume(1));
69
                    $iLastComponentType = CalcFunction::T_OPERATOR;
70
                } else {
71
                    throw new UnexpectedTokenException(
72
                        sprintf(
73
                            'Next token was expected to be an operand of type %s. Instead "%s" was found.',
74
                            implode(', ', $aOperators),
75
                            $oVal
76
                        ),
77
                        '',
78
                        'custom',
79
                        $oParserState->currentLine()
80
                    );
81
                }
82
            }
83
            $oParserState->consumeWhiteSpace();
84
        }
85
        $oList->addListComponent($oCalcList);
86
        $oParserState->consume(')');
87
        return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
88
    }
89
}