Skip to content

Commit a39f5f7

Browse files
committed
Added Boolean and Null argument types support
1 parent abd4d5b commit a39f5f7

File tree

4 files changed

+161
-71
lines changed

4 files changed

+161
-71
lines changed

src/Coduo/PHPMatcher/Lexer.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ class Lexer extends AbstractLexer
1212
const T_CLOSE_PARENTHESIS = 4;
1313
const T_STRING = 5;
1414
const T_NUMBER = 6;
15-
const T_COMMA = 7;
16-
const T_TYPE_PATTERN = 8;
15+
const T_BOOLEAN = 7;
16+
const T_NULL = 8;
17+
const T_COMMA = 9;
18+
const T_TYPE_PATTERN = 10;
1719

1820
/**
1921
* Lexical catchable patterns.
@@ -25,6 +27,8 @@ protected function getCatchablePatterns()
2527
return array(
2628
"\\.[a-zA-Z0-9_]+", // expander name
2729
"[a-zA-Z0-9_\\.]*", // value
30+
"(true|false)", // boolean
31+
"null", //
2832
"'(?:[^']|'')*'", // string between ' character
2933
"\"(?:[^\"]|\"\")*\"", // string between " character,
3034
"@[a-zA-Z0-9\\*]+@", // type pattern
@@ -73,6 +77,16 @@ protected function getType(&$value)
7377
return self::T_STRING;
7478
}
7579

80+
if ($this->isBooleanToken($value)) {
81+
$value = (strtolower($value) === 'true') ? true : false;
82+
return self::T_BOOLEAN;
83+
}
84+
85+
if ($this->isNullToken($value)) {
86+
$value = null;
87+
return self::T_NULL;
88+
}
89+
7690
if (is_numeric($value)) {
7791
if (is_string($value)) {
7892
$value = (strpos($value, '.') === false) ? (int) $value : (float) $value;
@@ -98,6 +112,24 @@ protected function isStringToken($value)
98112
return in_array(substr($value, 0, 1), array("\"", "'"));
99113
}
100114

115+
/**
116+
* @param string $value
117+
* @return bool
118+
*/
119+
protected function isBooleanToken($value)
120+
{
121+
return in_array(strtolower($value), array('true', 'false'), true);
122+
}
123+
124+
/**
125+
* @param string $value
126+
* @return bool
127+
*/
128+
protected function isNullToken($value)
129+
{
130+
return strtolower($value) === 'null';
131+
}
132+
101133
/**
102134
* @param $value
103135
* @return string

src/Coduo/PHPMatcher/Parser.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
class Parser
1313
{
14+
const NULL_VALUE = 'null';
15+
1416
/**
1517
* @var Lexer
1618
*/
@@ -21,6 +23,9 @@ class Parser
2123
*/
2224
private $AST;
2325

26+
/**
27+
* @var array
28+
*/
2429
private $expanderDefinitions = array(
2530
"startsWith" => "Coduo\\PHPMatcher\\Matcher\\Pattern\\Expander\\StartsWith"
2631
);
@@ -159,6 +164,8 @@ private function getNextExpanderNode()
159164
private function addArgumentValues(AST\Expander $expander)
160165
{
161166
while(($argument = $this->getNextArgumentValue()) !== null) {
167+
$argument = ($argument === self::NULL_VALUE) ? null : $argument;
168+
162169
$expander->addArgument($argument);
163170
if (!$this->lexer->isNextToken(Lexer::T_COMMA)){
164171
break;
@@ -180,7 +187,9 @@ private function getNextArgumentValue()
180187
{
181188
$validArgumentTypes = array(
182189
Lexer::T_STRING,
183-
Lexer::T_NUMBER
190+
Lexer::T_NUMBER,
191+
Lexer::T_BOOLEAN,
192+
Lexer::T_NULL
184193
);
185194

186195
if ($this->lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) {
@@ -191,9 +200,14 @@ private function getNextArgumentValue()
191200
$this->unexpectedSyntaxError($this->lexer->lookahead, "string or number argument");
192201
}
193202

203+
$tokenType = $this->lexer->lookahead['type'];
194204
$argument = $this->lexer->lookahead['value'];
195205
$this->lexer->moveNext();
196206

207+
if ($tokenType === Lexer::T_NULL) {
208+
$argument = self::NULL_VALUE;
209+
}
210+
197211
return $argument;
198212
}
199213

@@ -258,11 +272,11 @@ private function endOfPattern()
258272
}
259273

260274
/**
261-
* @param $expander
275+
* @param AST\Expander $expander
262276
* @throws InvalidExpanderTypeException
263277
* @return Pattern\PatternExpander
264278
*/
265-
private function initializeExpander($expander)
279+
private function initializeExpander(AST\Expander $expander)
266280
{
267281
$reflection = new \ReflectionClass($this->expanderDefinitions[$expander->getName()]);
268282
$expander = !$expander->hasArguments()

tests/Coduo/PHPMatcher/LexerTest.php

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,73 @@ public static function validStringValuesProvider()
2626
);
2727
}
2828

29+
30+
/**
31+
* @dataProvider validNumberValuesProvider
32+
*/
33+
public function test_number_values($value, $expectedValue)
34+
{
35+
$lexer = new Lexer();
36+
$lexer->setInput($value);
37+
$lexer->moveNext();
38+
$this->assertEquals($lexer->lookahead['type'], Lexer::T_NUMBER);
39+
$this->assertEquals($lexer->lookahead['value'], $expectedValue);
40+
}
41+
42+
public static function validNumberValuesProvider()
43+
{
44+
return array(
45+
array(1, 1),
46+
array(1.25, 1.25),
47+
array(0, 0),
48+
array("125", 125),
49+
array("12.15", 12.15),
50+
);
51+
}
52+
53+
/**
54+
* @dataProvider validBooleanValuesProvider
55+
*/
56+
public function test_boolean_values($value, $expectedValue)
57+
{
58+
$lexer = new Lexer();
59+
$lexer->setInput($value);
60+
$lexer->moveNext();
61+
$this->assertEquals($lexer->lookahead['type'], Lexer::T_BOOLEAN);
62+
$this->assertEquals($lexer->lookahead['value'], $expectedValue);
63+
}
64+
65+
public static function validBooleanValuesProvider()
66+
{
67+
return array(
68+
array("true", true),
69+
array("false", false),
70+
array("TRUE", true),
71+
array("fAlSe", false)
72+
);
73+
}
74+
75+
/**
76+
* @dataProvider validNullValuesProvider
77+
*/
78+
public function test_null_values($value)
79+
{
80+
$lexer = new Lexer();
81+
$lexer->setInput($value);
82+
$lexer->moveNext();
83+
$this->assertEquals($lexer->lookahead['type'], Lexer::T_NULL);
84+
$this->assertNull($lexer->lookahead['value']);
85+
}
86+
87+
public static function validNullValuesProvider()
88+
{
89+
return array(
90+
array("null"),
91+
array("NULL"),
92+
array("NuLl"),
93+
);
94+
}
95+
2996
/**
3097
* @dataProvider validNonTokenValuesProvider
3198
*/
@@ -71,29 +138,6 @@ public function test_comma()
71138
$this->assertEquals($lexer->lookahead['type'], Lexer::T_COMMA);
72139
}
73140

74-
/**
75-
* @dataProvider validNumberValuesProvider
76-
*/
77-
public function test_number_values($value, $expectedValue)
78-
{
79-
$lexer = new Lexer();
80-
$lexer->setInput($value);
81-
$lexer->moveNext();
82-
$this->assertEquals($lexer->lookahead['type'], Lexer::T_NUMBER);
83-
$this->assertEquals($lexer->lookahead['value'], $expectedValue);
84-
}
85-
86-
public static function validNumberValuesProvider()
87-
{
88-
return array(
89-
array(1, 1),
90-
array(1.25, 1.25),
91-
array(0, 0),
92-
array("125", 125),
93-
array("12.15", 12.15),
94-
);
95-
}
96-
97141
/**
98142
* @dataProvider validMatcherTypePatterns
99143
*/

tests/Coduo/PHPMatcher/ParserTest.php

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,49 @@ public function test_simple_pattern_without_expanders()
1313
$this->assertFalse($parser->getAST()->hasExpanders());
1414
}
1515

16+
public function test_single_expander_without_args()
17+
{
18+
$parser = new Parser("@[email protected]()");
19+
$this->assertEquals("type", $parser->getAST()->getType());
20+
$expanders = $parser->getAST()->getExpanders();
21+
$this->assertEquals('expander', $expanders[0]->getName());
22+
$this->assertFalse($expanders[0]->hasArguments());
23+
}
24+
25+
public function test_single_expander_with_arguments()
26+
{
27+
$parser = new Parser("@[email protected]('arg1', 2, 2.24, \"arg3\")");
28+
$this->assertEquals("type", $parser->getAST()->getType());
29+
$expanders = $parser->getAST()->getExpanders();
30+
$expectedArguments = array(
31+
"arg1",
32+
2,
33+
2.24,
34+
"arg3"
35+
);
36+
$this->assertEquals($expectedArguments, $expanders[0]->getArguments());
37+
}
38+
39+
public function test_many_expanders()
40+
{
41+
$expanderArguments = array(
42+
array('arg1', 2, 2.24, 'arg3', null, false),
43+
array(),
44+
array(1, 2, 3, true, null)
45+
);
46+
47+
$parser = new Parser("@[email protected]('arg1', 2, 2.24, \"arg3\", null, false).expander1().expander(1,2,3, true, null)");
48+
$expanders = $parser->getAST()->getExpanders();
49+
$this->assertEquals("type", $parser->getAST()->getType());
50+
$this->assertEquals('expander', $expanders[0]->getName());
51+
$this->assertEquals('expander1', $expanders[1]->getName());
52+
$this->assertEquals('expander', $expanders[2]->getName());
53+
54+
$this->assertEquals($expanderArguments[0], $expanders[0]->getArguments());
55+
$this->assertEquals($expanderArguments[1], $expanders[1]->getArguments());
56+
$this->assertEquals($expanderArguments[2], $expanders[2]->getArguments());
57+
}
58+
1659
/**
1760
* @expectedException \Coduo\PHPMatcher\Exception\PatternException
1861
* @expectedExceptionMessage [Syntax Error] line 0, col 0: Error: Expected "@type@ pattern", got "not_valid_type"
@@ -63,15 +106,6 @@ public function test_not_argument_after_opening_parenthesis()
63106
$parser->getAST();
64107
}
65108

66-
public function test_single_expander_without_args()
67-
{
68-
$parser = new Parser("@[email protected]()");
69-
$this->assertEquals("type", $parser->getAST()->getType());
70-
$expanders = $parser->getAST()->getExpanders();
71-
$this->assertEquals('expander', $expanders[0]->getName());
72-
$this->assertFalse($expanders[0]->hasArguments());
73-
}
74-
75109
/**
76110
* @expectedException \Coduo\PHPMatcher\Exception\PatternException
77111
* @expectedExceptionMessage [Syntax Error] line 0, col 22: Error: Expected ")", got end of string.end of string
@@ -111,38 +145,4 @@ public function test_not_argument_after_comma()
111145
$parser = new Parser("@[email protected]('string',not_argument");
112146
$parser->getAST();
113147
}
114-
115-
public function test_single_expander_with_arguments()
116-
{
117-
$parser = new Parser("@[email protected]('arg1', 2, 2.24, \"arg3\")");
118-
$this->assertEquals("type", $parser->getAST()->getType());
119-
$expanders = $parser->getAST()->getExpanders();
120-
$expectedArguments = array(
121-
"arg1",
122-
2,
123-
2.24,
124-
"arg3"
125-
);
126-
$this->assertEquals($expectedArguments, $expanders[0]->getArguments());
127-
}
128-
129-
public function test_multiple_expanders()
130-
{
131-
$expanderArguments = array(
132-
array('arg1', 2, 2.24, 'arg3'),
133-
array(),
134-
array(1,2,3)
135-
);
136-
137-
$parser = new Parser("@[email protected]('arg1', 2, 2.24, \"arg3\").expander1().expander(1,2,3)");
138-
$expanders = $parser->getAST()->getExpanders();
139-
$this->assertEquals("type", $parser->getAST()->getType());
140-
$this->assertEquals('expander', $expanders[0]->getName());
141-
$this->assertEquals('expander1', $expanders[1]->getName());
142-
$this->assertEquals('expander', $expanders[2]->getName());
143-
144-
$this->assertEquals($expanderArguments[0], $expanders[0]->getArguments());
145-
$this->assertEquals($expanderArguments[1], $expanders[1]->getArguments());
146-
$this->assertEquals($expanderArguments[2], $expanders[2]->getArguments());
147-
}
148148
}

0 commit comments

Comments
 (0)