Passed
Branch master (f3f280)
by Maciej
03:18
created

Perl::setupRules()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 76
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 47
nc 1
nop 0
dl 0
loc 76
ccs 0
cts 39
cp 0
crap 2
rs 9.1563
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Highlighter
5
 *
6
 * Copyright (C) 2016, Some right reserved.
7
 *
8
 * @author Kacper "Kadet" Donat <[email protected]>
9
 *
10
 * Contact with author:
11
 * Xmpp: [email protected]
12
 * E-mail: [email protected]
13
 *
14
 * From Kadet with love.
15
 */
16
17
namespace Kadet\Highlighter\Language;
18
19
use Kadet\Highlighter\Matcher\CommentMatcher;
20
use Kadet\Highlighter\Matcher\RegexMatcher;
21
use Kadet\Highlighter\Matcher\SubStringMatcher;
22
use Kadet\Highlighter\Matcher\WordMatcher;
23
use Kadet\Highlighter\Parser\CloseRule;
24
use Kadet\Highlighter\Parser\OpenRule;
25
use Kadet\Highlighter\Parser\Rule;
26
use Kadet\Highlighter\Parser\Token\ContextualToken;
27
use Kadet\Highlighter\Parser\Token\LanguageToken;
28
use Kadet\Highlighter\Parser\Token\Token;
29
use Kadet\Highlighter\Parser\TokenFactory;
30
use Kadet\Highlighter\Parser\Validator\Validator;
31
32
class Perl extends GreedyLanguage
33
{
34
    
35
    /**
36
     * Tokenization rules definition
37
     */
38
    public function setupRules()
39
    {
40
        $identifier = '\w+';
41
        $number = '[+-]?(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?';
42
43
        $this->rules->addMany([
44
            'string'  => CommonFeatures::strings(['single' => '\'', 'double' => '"'], [
45
                'context' => ['!keyword', '!comment', '!string', '!language', '!number'],
46
            ]),
47
48
            'comment' => new Rule(new CommentMatcher(['#'])),
49
50
            'keyword' => new Rule(new WordMatcher([
51
                'case', 'continue', 'do', 'else', 'elsif', 'for', 'foreach',
52
                'if', 'last', 'my', 'next', 'our', 'redo', 'reset', 'then',
53
                'unless', 'until', 'while', 'use', 'print', 'new', 'BEGIN',
54
                'sub', 'CHECK', 'INIT', 'END', 'return', 'exit'
55
            ])),
56
57
            'operator.escape' => new Rule(new RegexMatcher('/(\\\.)/'), [
58
                'context' => ['string']
59
            ]),
60
61
            'string.nowdoc'  => new Rule(
62
                new RegexMatcher('/<<\s*\'(\w+)\';(?P<string>.*?)\R\1/sm', [
63
                    'string' => Token::NAME,
64
                          0  => 'keyword.nowdoc'
65
                ]),
66
                ['context' => ['!comment']]
67
            ),
68
69
            'language.shell' => new Rule(new SubStringMatcher('`'), [
70
                'context' => ['!operator.escape', '!comment', '!string', '!keyword.nowdoc'],
71
                'factory' => new TokenFactory(ContextualToken::class),
72
            ]),
73
74
            'variable.scalar' => new Rule(new RegexMatcher("/(\\\$$identifier)/")),
75
            'variable.array'  => new Rule(new RegexMatcher("/(\\@$identifier)/")),
76
            'variable.hash'   => new Rule(new RegexMatcher("/(\\%$identifier)/")),
77
78
            'variable.property'   => new Rule(new RegexMatcher("/\\\$$identifier{($identifier)}/")),
79
80
            // Stupidly named var? Perl one, for sure.
81
            'variable.special'   => new Rule(new RegexMatcher('/([$@%][^\s\w]+[\w]*)/')),
82
83
            'operator' => [
84
                new Rule(new RegexMatcher('/(-[rwxoRWXOezsfdlpSbctugkTBMAC])/')),
85
                new Rule(new WordMatcher([
86
                    'not', 'and', 'or', 'xor', 'goto', 'last', 'next', 'redo', 'dump',
87
                    'eq', 'ne', 'cmp', 'not', 'and', 'or', 'xor'
88
                ], ['atomic' => true])),
89
            ],
90
91
            'call' => new Rule(new RegexMatcher('/([a-z]\w+)(?:\s*\(|\s+[$%@"\'`{])/i')),
92
93
            'number' => [
94
                new Rule(new RegexMatcher("/(\\b|\"|')$number\\1/", [
95
                    0 => Token::NAME
96
                ]), ['priority' => 5]),
97
            ],
98
99
            'string.regex' => [
100
                new OpenRule(new RegexMatcher('#~\s*[ms]?(/).*?/#m'), [
101
                    'context' => Validator::everywhere()
102
                ]),
103
                new OpenRule(new RegexMatcher('#~\s*(s/).*?/#m')),
104
105
                new Rule(new RegexMatcher('#(?=\/.*?(/[gimuy]{0,5}))#m'), [
106
                    'priority' => 1,
107
                    'factory'  => new TokenFactory(ContextualToken::class),
108
                    'context'  => ['!operator.escape', 'string.regex']
109
                ])
110
            ],
111
            
112
            'symbol.iterator' => [
113
                new Rule(new RegexMatcher('#(<\w+>)#s'))
114
            ]
115
        ]);
116
    }
117
118
    /**
119
     * Unique language identifier, for example 'php'
120
     *
121
     * @return string
122
     */
123
    public function getIdentifier()
124
    {
125
        return 'perl';
126
    }
127
128
    public function getEnds($embedded = false)
129
    {
130
        return [
131
            parent::getEnds($embedded),
132
            new CloseRule(new SubStringMatcher('__END__'), [
133
                'factory'  => new TokenFactory(LanguageToken::class),
134
                'language' => $this
135
            ])
136
        ];
137
    }
138
139
    public static function getMetadata()
140
    {
141
        return [
142
            'name'      => ['perl'],
143
            'mime'      => ['text/x-perl', 'application/x-perl'],
144
            'extension' => ['*.pl', '*.pm', '*.t']
145
        ];
146
    }
147
}
148