From 0daf00a42968e7285fd4286cb54157032084cdf4 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Fri, 27 Nov 2020 13:28:09 +1000 Subject: [PATCH 01/12] fix: Propagate the call to mt_rand() by assigning it to $seed (Fixes #6) --- src/ReverseRegex/Random/SimpleRandom.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ReverseRegex/Random/SimpleRandom.php b/src/ReverseRegex/Random/SimpleRandom.php index 9fd0c97..b2399cc 100644 --- a/src/ReverseRegex/Random/SimpleRandom.php +++ b/src/ReverseRegex/Random/SimpleRandom.php @@ -37,7 +37,8 @@ class SimpleRandom implements GeneratorInterface public function __construct($seed = null) { if ($seed === null || $seed === 0) { - $this->seed(mt_rand()); + ## 6 - Propagate the call to mt_rand() by assigning it to $seed + $seed = mt_rand(); } $this->seed($seed); @@ -117,4 +118,4 @@ public function generate($min = 0, $max = null) } } -/* End of File */ \ No newline at end of file +/* End of File */ From e0d84889d906e46403f9b54ad333dc69ace1be8b Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Fri, 27 Nov 2020 13:37:55 +1000 Subject: [PATCH 02/12] fix: Update Lexer to extend AbstractLexer --- src/ReverseRegex/Lexer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ReverseRegex/Lexer.php b/src/ReverseRegex/Lexer.php index f5b6940..67431f1 100644 --- a/src/ReverseRegex/Lexer.php +++ b/src/ReverseRegex/Lexer.php @@ -1,7 +1,7 @@ * @since 0.0.1 */ -class Lexer extends BaseLexer +class Lexer extends AbstractLexer { // ---------------------------------------------------------------------------- @@ -370,4 +370,4 @@ protected function scan($input) } } -/* End of File */ \ No newline at end of file +/* End of File */ From bc000da2c9dd68e6c2b945770fd71e6f0c4b2d66 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 13:24:56 +1000 Subject: [PATCH 03/12] chore: Add .phpunit.result.cache to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f775f95..68c598c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor composer.lock *.komodoproject manifest +.phpunit.result.cache \ No newline at end of file From e746e81a8604126ec01aa0fe27c9283eb7759936 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 13:25:58 +1000 Subject: [PATCH 04/12] chore: Add PHP 7.4 and 8.0 to .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 85178ee..48b4edd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ language: php php: - 7.2 - 7.3 + - 7.4 + - 8.0 before_script: - composer install From 23ac8ce93a7e69fbda1f62cc1b36740b84318173 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 13:26:41 +1000 Subject: [PATCH 05/12] fix: Incorrect namespace for Doctrine Lexer base class --- src/ReverseRegex/Test/LexerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReverseRegex/Test/LexerTest.php b/src/ReverseRegex/Test/LexerTest.php index 635f9a9..655847a 100644 --- a/src/ReverseRegex/Test/LexerTest.php +++ b/src/ReverseRegex/Test/LexerTest.php @@ -9,7 +9,7 @@ class LexerTest extends Basic public function testInheritsDoctrineLexer() { $lexer = new Lexer('[a-z]'); - $this->assertInstanceOf('\Doctrine\Common\Lexer',$lexer); + $this->assertInstanceOf('\Doctrine\Common\Lexer\AbstractLexer',$lexer); } From 16e3fed413f3c1ebaced77b8a4c41666f4954449 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 17:35:08 +1000 Subject: [PATCH 06/12] chore: Update composer library versions and use psr-4 autoloader --- composer.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index e76b022..3ec28e0 100644 --- a/composer.json +++ b/composer.json @@ -12,19 +12,19 @@ "homepage": "http://www.icomefromthenet.com" } ], - "require-dev": { - "phpunit/phpunit": "^8" - }, "require": { - "php" : "^7.2", - "doctrine/lexer" : "1.2.1", - "doctrine/collections" : "1.6.5", - "patchwork/utf8" : ">=1.3" + "php": ">=7.2", + "doctrine/lexer": "^1.2", + "doctrine/collections": "^1.6", + "patchwork/utf8": ">=1.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" }, "autoload": { - "psr-0": { - "ReverseRegex": "src/", - "PHPStats" : "src/" + "psr-4": { + "ReverseRegex\\": "src/ReverseRegex", + "PHPStats\\" : "src/PHPStats" } } } From e777e6185d9e9901562a004d831ad00ea4f5c96a Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 13:27:37 +1000 Subject: [PATCH 07/12] refactor: Update tests to use assertMatchesRegularExpression() instead of deprecated assertRegExp() --- src/ReverseRegex/Test/ParserTest.php | 12 ++++++------ src/ReverseRegex/Test/ScopeTest.php | 2 +- src/ReverseRegex/Test/ShortTest.php | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ReverseRegex/Test/ParserTest.php b/src/ReverseRegex/Test/ParserTest.php index 5b00d44..2c528ea 100644 --- a/src/ReverseRegex/Test/ParserTest.php +++ b/src/ReverseRegex/Test/ParserTest.php @@ -75,7 +75,7 @@ public function testExampleD() $random = new MersenneRandom(100); $generator->generate($result,$random); - $this->assertRegExp('/\d\d\d/',$result); + $this->assertMatchesRegularExpression('/\d\d\d/',$result); } @@ -91,7 +91,7 @@ public function testExampleE() $random = new MersenneRandom(10034343); $generator->generate($result,$random); - $this->assertRegExp('/\d\d\d([a-zA-Z])\w./',$result); + $this->assertMatchesRegularExpression('/\d\d\d([a-zA-Z])\w./',$result); } @@ -139,7 +139,7 @@ public function testParserExamplePostCode() for($i = 100; $i > 0; $i--) { $result =''; $generator->generate($result,$random); - $this->assertRegExp('/^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$/',$result); + $this->assertMatchesRegularExpression('/^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$/',$result); } # Generate Postcode for ACT only @@ -192,7 +192,7 @@ public function testHellowWorld() for($i = 10; $i > 0; $i--) { $result =''; $generator->generate($result,$random); - $this->assertRegExp('/^Hello|World|Is|Good$/',$result); + $this->assertMatchesRegularExpression('/^Hello|World|Is|Good$/',$result); } } @@ -212,7 +212,7 @@ public function testLimitingQuantifer() for($i = 10; $i > 0; $i--) { $result =''; $generator->generate($result,$random); - $this->assertRegExp('/(Hello){5,9}/',$result); + $this->assertMatchesRegularExpression('/(Hello){5,9}/',$result); } $lexer = new Lexer("(Hello)?"); @@ -226,7 +226,7 @@ public function testLimitingQuantifer() $result =''; $generator->generate($result,$random); - $this->assertRegExp('/(Hello)?/',$result); + $this->assertMatchesRegularExpression('/(Hello)?/',$result); } diff --git a/src/ReverseRegex/Test/ScopeTest.php b/src/ReverseRegex/Test/ScopeTest.php index c4d9f7c..a8ca6ec 100644 --- a/src/ReverseRegex/Test/ScopeTest.php +++ b/src/ReverseRegex/Test/ScopeTest.php @@ -173,7 +173,7 @@ public function testGenerateWithAlternatingStrategy() $scope->useAlternatingStrategy(); $scope->generate($result,$gen); - $this->assertRegExp('/[1-6]{7}/',$result); + $this->assertMatchesRegularExpression('/[1-6]{7}/',$result); } diff --git a/src/ReverseRegex/Test/ShortTest.php b/src/ReverseRegex/Test/ShortTest.php index bd7beac..d34edea 100644 --- a/src/ReverseRegex/Test/ShortTest.php +++ b/src/ReverseRegex/Test/ShortTest.php @@ -25,7 +25,7 @@ public function testDigit() $result = $head->getLiterals(); foreach($result as $value) { - $this->assertRegExp('/\d/',$value); + $this->assertMatchesRegularExpression('/\d/',$value); } } @@ -45,7 +45,7 @@ public function testNotDigit() $result = $head->getLiterals(); foreach($result as $value) { - $this->assertRegExp('/\D/',$value); + $this->assertMatchesRegularExpression('/\D/',$value); } } @@ -103,7 +103,7 @@ public function testWord() $result = $head->getLiterals(); foreach($result as $value) { - $this->assertRegExp('/\w/',$value); + $this->assertMatchesRegularExpression('/\w/',$value); } } @@ -124,7 +124,7 @@ public function testNonWord() $result = $head->getLiterals(); foreach($result as $value) { - $this->assertRegExp('/\W/',$value); + $this->assertMatchesRegularExpression('/\W/',$value); } From f1f0da71645e4d857e1e4b0394856dcc05193704 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 17:36:10 +1000 Subject: [PATCH 08/12] refactor: Remove use of abandoned patchwork/utf8 library. --- composer.json | 2 +- src/ReverseRegex/Parser/CharacterClass.php | 9 ++++----- src/ReverseRegex/Parser/Unicode.php | 5 ++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 3ec28e0..69c5015 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php": ">=7.2", "doctrine/lexer": "^1.2", "doctrine/collections": "^1.6", - "patchwork/utf8": ">=1.3" + "symfony/polyfill-mbstring": "^1.23" }, "require-dev": { "phpunit/phpunit": "^9.5" diff --git a/src/ReverseRegex/Parser/CharacterClass.php b/src/ReverseRegex/Parser/CharacterClass.php index 57f3dc0..5618ffa 100644 --- a/src/ReverseRegex/Parser/CharacterClass.php +++ b/src/ReverseRegex/Parser/CharacterClass.php @@ -5,7 +5,6 @@ use ReverseRegex\Generator\LiteralScope; use ReverseRegex\Lexer; use ReverseRegex\Exception as ParserException; -use Patchwork\Utf8; /** * Parse a character class [0-9][a-z] @@ -108,7 +107,7 @@ public function parse(Scope $head, Scope $set, Lexer $lexer) break; case($normal_lexer->isNextToken(Lexer::T_LITERAL_NUMERIC) || $normal_lexer->isNextToken(Lexer::T_LITERAL_CHAR)) : - $index = (integer)Utf8::ord($normal_lexer->lookahead['value']); + $index = (integer)mb_ord($normal_lexer->lookahead['value']); $head->setLiteral($index,$normal_lexer->lookahead['value']); break; default: @@ -131,15 +130,15 @@ public function parse(Scope $head, Scope $set, Lexer $lexer) public function fillRange(Scope $head,$start,$end) { - $start_index = Utf8::ord($start); - $ending_index = Utf8::ord($end); + $start_index = mb_ord($start); + $ending_index = mb_ord($end); if($ending_index < $start_index ) { throw new ParserException(sprintf('Character class range %s - %s is out of order',$start,$end)); } for($i = $start_index; $i <= $ending_index; $i++) { - $head->setLiteral($i,Utf8::chr($i)); + $head->setLiteral($i,mb_chr($i)); } } diff --git a/src/ReverseRegex/Parser/Unicode.php b/src/ReverseRegex/Parser/Unicode.php index 84445e4..64bfd89 100644 --- a/src/ReverseRegex/Parser/Unicode.php +++ b/src/ReverseRegex/Parser/Unicode.php @@ -4,7 +4,6 @@ use ReverseRegex\Generator\Scope; use ReverseRegex\Lexer; use ReverseRegex\Exception as ParserException; -use Patchwork\Utf8; /** * Parse a unicode sequence e.g \x54 \X{4444} @@ -74,7 +73,7 @@ public function evaluate(Lexer $lexer) $number = trim(implode('',$tokens)); - return Utf8::chr(hexdec($number)); + return mb_chr(hexdec($number)); break; case ($lexer->isNextToken(Lexer::T_SHORT_X)) : @@ -92,7 +91,7 @@ public function evaluate(Lexer $lexer) } $value = trim(implode('',$tokens)); - return Utf8::chr(hexdec($value)); + return mb_chr(hexdec($value)); break; default : throw new ParserException('No Unicode expression to evaluate'); From c163a7954293ed14026c66d9410a34bb8bc9f0ed Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 17:56:22 +1000 Subject: [PATCH 09/12] chore: Updated copyright information and package name --- LICENCE | 18 +++++++++++++----- composer.json | 25 ++++++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/LICENCE b/LICENCE index 329b5b6..01eda5e 100644 --- a/LICENCE +++ b/LICENCE @@ -1,14 +1,20 @@ +All source code included in the "ReverseRegex" archive is, +unless otherwise specified, released under the MIT licence as follows: + +----- begin license block ----- + Copyright (c) 2012 Lewis Dyer +Copyright 2020-2021 Alannah Kearney Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -16,4 +22,6 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. + +----- end license block ----- diff --git a/composer.json b/composer.json index 69c5015..55a7eb6 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,26 @@ { - "name": "icomefromthenet/reverse-regex", + "name": "pointybeard/reverse-regex", "description": "Convert Regular Expressions into text, for testing", - "keywords": ["regex","testing","test data","generator"], - "homepage": "http://github.com/icomefromthenet/ReverseRegex", + "keywords": [ + "regex", + "testing", + "test data", + "generator" + ], + "homepage": "http://github.com/pointybeard-forks/ReverseRegex", "type": "library", "license": "MIT", + "support": { + "issues": "https://github.com/pointybeard-forks/ReverseRegex/issues", + "wiki": "https://github.com/pointybeard-forks/ReverseRegex/wiki" + }, + "minimum-stability": "stable", "authors": [ + { + "name": "Alannah Kearney", + "email": "hi@alannahkearney.com", + "homepage": "https://github.com/pointybeard" + }, { "name": "Lewis Dyer", "email": "getintouch@icomefromthenet.com", @@ -19,12 +34,12 @@ "symfony/polyfill-mbstring": "^1.23" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5", }, "autoload": { "psr-4": { "ReverseRegex\\": "src/ReverseRegex", - "PHPStats\\" : "src/PHPStats" + "PHPStats\\": "src/PHPStats" } } } From 932db8fe802d4ff54ae3ec1f79b6200287a49ab5 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 17:57:29 +1000 Subject: [PATCH 10/12] chore: Add php-cs-fixer, php-commitizen, and php-parallel-lint dev libraries --- .php-commitizen.php | 41 +++++++++++++++++++++++++++++++++++ .php-cs-fixer.dist.php | 49 ++++++++++++++++++++++++++++++++++++++++++ composer.json | 12 +++++++++++ 3 files changed, 102 insertions(+) create mode 100644 .php-commitizen.php create mode 100644 .php-cs-fixer.dist.php diff --git a/.php-commitizen.php b/.php-commitizen.php new file mode 100644 index 0000000..8c77023 --- /dev/null +++ b/.php-commitizen.php @@ -0,0 +1,41 @@ + [ + 'lengthMin' => 3, + 'lengthMax' => 8, + 'acceptExtra' => false, + 'values' => [ + 'feat', + 'fix', + 'docs', + 'chore', + 'test', + 'refactor', + 'revert', + 'ci', + ] + ], + 'scope' => [ + 'lengthMin' => 0, + 'lengthMax' => 10, + 'acceptExtra' => true, + 'values' => [], + ], + 'description' => [ + 'lengthMin' => 1, + 'lengthMax' => 47, + ], + 'subject' => [ + 'lengthMin' => 1, + 'lengthMax' => 69, + ], + 'body' => [ + 'wrap' => 72, + ], + 'footer' => [ + 'wrap' => 72, + ], +]; diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..0b43b0e --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,49 @@ +setUsingCache(true) + ->setRiskyAllowed(true) + ->setFinder( + (new PhpCsFixer\Finder()) + ->files() + ->name('*.php') + ->in(__DIR__.'/src') + ->exclude(__DIR__.'/vendor') + ) + ->setRules([ + '@PSR2' => true, + '@Symfony' => true, + 'is_null' => true, + 'blank_line_before_statement' => ['statements' => ['continue', 'declare', 'return', 'throw', 'try']], + 'cast_spaces' => ['space' => 'single'], + 'include' => true, + 'class_attributes_separation' => ['elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one']], + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + 'object_operator_without_whitespace' => true, + 'phpdoc_align' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'psr_autoloading' => true, + 'array_syntax' => ['syntax' => 'short'], + 'declare_strict_types' => true, + 'single_blank_line_before_namespace' => true, + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline' => true, + ]) +; diff --git a/composer.json b/composer.json index 55a7eb6..fccbbb4 100644 --- a/composer.json +++ b/composer.json @@ -35,11 +35,23 @@ }, "require-dev": { "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.0", + "friendsofphp/php-cs-fixer": "^3.0", + "damianopetrungaro/php-commitizen": "^0.1.2", + "php-parallel-lint/php-parallel-lint": "^1.2" }, "autoload": { "psr-4": { "ReverseRegex\\": "src/ReverseRegex", "PHPStats\\": "src/PHPStats" } + }, + "scripts": { + "tidy": "php-cs-fixer fix -v --using-cache=no", + "tidy-dry": "@tidy --dry-run", + "test": [ + "parallel-lint . --exclude vendor", + "phpunit" + ] } } From f2581fb4c5c9aa60b4f2880474636f344553eb5a Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 18:13:31 +1000 Subject: [PATCH 11/12] chore: Updated README with additional author information --- README.md | 179 +++++++++++++++++++++--------------------------------- 1 file changed, 68 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index a300ae2..a1daf1e 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,54 @@ -ReverseRegex -============ +# ReverseRegex -[![Build Status](https://travis-ci.org/icomefromthenet/ReverseRegex.png)](https://travis-ci.org/icomefromthenet/ReverseRegex) +[![Build Status](https://api.travis-ci.com/pointybeard-forks/ReverseRegex.svg)](https://app.travis-ci.com/github/pointybeard-forks/ReverseRegex) -Use Regular Expressions to generate text strings can be used in the following situations: +Use Regular Expressions to generate strings. -1. Wrting test data for web forms. -2. Writing test data for databases. -3. Generating test data for regular expressions. +- [Installation](#installation) +- [Usage](#usage) +- [About](#about) + - [Requirements](#dependencies) +- [Support](#support) +- [Contributing](#contributing) +- [License](#license) +## Installation -##Example +This library is installed via [Composer](http://getcomposer.org/). To install, use `composer require pointybeard/reverse-regex` in your application. + +## Usage ```php +parse()->getResult()->generate($result,$gen); +$lexer = new Lexer($pattern); +$random = new SimpleRandom(); +$parser = new Parser($lexer, new Scope(), new Scope()); +$generator = $parser->parse()->getResult(); -echo $result; +$result = ''; -``` +$parser = new Parser($lexer,new Scope(),new Scope()); -***Produces*** +var_dump($generator->generate($result, $random)); +// string(10) "j2ydisgoks" ``` -jmceohykoa -aclohnotga -jqegzuklcv -ixdbpbgpkl -kcyrxqqfyw -jcxsjrtrqb -kvaczmawlz -itwrowxfxh -auinmymonl -dujyzuhoag -vaygybwkfm -``` -#### Other examples - -1. [Australian phone numbers](https://github.com/icomefromthenet/ReverseRegex/blob/master/examples/ausphone.php) -2. [Australian postcodes](https://github.com/icomefromthenet/ReverseRegex/blob/master/examples/auspostcode.php) -3. [Mobile numbers](https://github.com/icomefromthenet/ReverseRegex/blob/master/examples/mobilenumbers.php) - -##Installing +See for more examples. -To install use composer - -```json -{ - "require" : { - "icomefromthenet/reverse-regex" : "dev-master" - } -} -``` -## Writing a Regex +### Notes When Writing Regular Expressions 1. Escape all meta-characters i.e. if you need to escape the character in a regex you will need to escape here. 2. Not all meta-characters are suppported see list below. @@ -75,71 +57,46 @@ To install use composer 5. Quantifiers are applied to left most group, literal or character class. 6. Beware of the `+` and `*` quantifers they apply a possible maxium number of occurances up to `PHP_INT_MAX`. -### Regex Support - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Example - - Description - - Resulting String -
(abcf) Support literals this would generate string `abcf`
\((abcf)\) Escape meta characters as you normally would in a regex `(abcf)`
[a-z] Character Classes are supported `a`
a{5} Quantifiers supported always last group or literal or character class `aaaaa`
a{1,5} Range Quantifiers supported `aa`
a|b|c Alternation supported pick one of three at random `b`
a|(y|d){5} Groups supported with alternation and quantifiers `ddddd` or `a` or `yyyyy`
\d Digit shorthand equ [0-9] `1`
\w word character shorthand equ [a-zA-Z0-9_] `j`
\W Non word character shorthand equ [^a-zA-Z0-9_] `j`
\s White space shorthand ASCII only ` `
\S Non White space shorthand ASCII only `i`
. Dot all ASCII characters `$`
* + ? Short hand quantifiers, recommend not use them
\X{00FF}[\X{00FF}-\X{00FF}] Unicode ranges
\xFF[\xFF-\xFF] Hex ranges
+### Supported Syntax + +| Example | Description | Resulting String | +| ------------- | ------------- | ------------- | +| `(abcf)` | Support literals this would generate string | 'abcf' | +| `\((abcf)\)` | Escape meta characters as you normally would in a regex | '(abcf)' | +| `[a-z]` | Character Classes are supported | 'a' | +| `a{5}` | Quantifiers supported always last group or literal or character class | 'aaaaa' | +| `a{1,5}` | Range Quantifiers supported | 'aa' | +| `a\|b\|c` | Alternation supported pick one of three at random | 'b' | +| `a\|(y\|d){5}` | Groups supported with alternation and quantifiers | 'ddddd', 'a', or 'yyyyy' | +| `\d` | Digit shorthand equ [0-9] | '1' | +| `\w` | word character shorthand equ [a-zA-Z0-9_] | 'j' | +| `\W` | Non word character shorthand equ [^a-zA-Z0-9_] | 'j' | +| `\s` | White space shorthand ASCII only | ' ' | +| `\S` | Non White space shorthand ASCII only | 'i' | +| `.` | Dot all ASCII characters | '\$' | +| `* + ?` | Short hand quantifiers, recommend not use them | | +| `\X{00FF}[\X{00FF}-\X{00FF}]` | Unicode ranges | | +| `\xFF[\xFF-\xFF]` | Hex ranges | | + +## About + +### Requirements + +- This library works with PHP 7.2 or above. + +## Support + +If you believe you have found a bug, please report it using the [GitHub issue tracker][ext-issues]. + +## Author +- Lewis Dyer (, ) - Original author +- Alannah Kearney () - Fixed a few things after library was abandoned +- See also the list of [contributors][ext-contributor] who participated in this project +## License +"ReverseRegex" is released under the MIT License. See [LICENCE][doc-LICENCE] for details. +[doc-LICENCE]: http://www.opensource.org/licenses/MIT +[ext-issues]: https://github.com/pointybeard/ReverseRegex/issues +[ext-contributor]: https://github.com/pointybeard/ReverseRegex/contributors From 1490bb5e711b39505b42b543a4f6a186ab1f1aa4 Mon Sep 17 00:00:00 2001 From: Alannah Kearney Date: Sun, 14 Nov 2021 18:17:38 +1000 Subject: [PATCH 12/12] chore: Run PHP CS Fixer code tidy --- src/PHPStats/Generator/GeneratorInterface.php | 46 +- src/ReverseRegex/ArrayCollection.php | 51 +- src/ReverseRegex/Exception.php | 16 +- .../Generator/AlternateInterface.php | 36 +- .../Generator/ContextInterface.php | 30 +- src/ReverseRegex/Generator/LiteralScope.php | 116 +-- src/ReverseRegex/Generator/Node.php | 133 +-- .../Generator/RepeatInterface.php | 70 +- src/ReverseRegex/Generator/Scope.php | 238 ++--- src/ReverseRegex/Lexer.php | 410 ++++---- src/ReverseRegex/Parser.php | 279 +++-- src/ReverseRegex/Parser/CharacterClass.php | 174 ++-- src/ReverseRegex/Parser/Quantifier.php | 231 ++-- src/ReverseRegex/Parser/Short.php | 195 ++-- src/ReverseRegex/Parser/StrategyInterface.php | 34 +- src/ReverseRegex/Parser/Unicode.php | 111 +- src/ReverseRegex/Random/GeneratorFactory.php | 88 +- .../Random/GeneratorInterface.php | 46 +- src/ReverseRegex/Random/MersenneRandom.php | 175 ++-- src/ReverseRegex/Random/SimpleRandom.php | 134 ++- src/ReverseRegex/Random/SrandRandom.php | 106 +- src/ReverseRegex/Test/Basic.php | 12 +- src/ReverseRegex/Test/CharacterClassTest.php | 196 ++-- src/ReverseRegex/Test/LexerTest.php | 982 +++++++++--------- src/ReverseRegex/Test/LiteralScopeTest.php | 111 +- src/ReverseRegex/Test/ParserTest.php | 292 +++--- .../Test/QuantifierParserTest.php | 232 ++--- src/ReverseRegex/Test/ScopeTest.php | 155 ++- src/ReverseRegex/Test/ShortTest.php | 141 ++- src/ReverseRegex/Test/UnicodeTest.php | 116 +-- 30 files changed, 2317 insertions(+), 2639 deletions(-) diff --git a/src/PHPStats/Generator/GeneratorInterface.php b/src/PHPStats/Generator/GeneratorInterface.php index 5c15e53..9f374ef 100644 --- a/src/PHPStats/Generator/GeneratorInterface.php +++ b/src/PHPStats/Generator/GeneratorInterface.php @@ -1,37 +1,33 @@ - */ + * Interface that all generators should implement. + */ interface GeneratorInterface { - /** - * Generate a value between $min - $max - * - * @param integer $max - * @param integer $max - */ - public function generate($min = 0,$max = null); - + * Generate a value between $min - $max. + * + * @param int $max + * @param int $max + */ + public function generate($min = 0, $max = null); + /** - * Set the seed to use - * - * @param $seed integer the seed to use - * @access public - */ + * Set the seed to use. + * + * @param $seed integer the seed to use + */ public function seed($seed = null); - + /** - * Return the hights possible random value - * - * @access public - * @return double - */ + * Return the hights possible random value. + * + * @return float + */ public function max(); - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/ArrayCollection.php b/src/ReverseRegex/ArrayCollection.php index 4515664..b20ea63 100644 --- a/src/ReverseRegex/ArrayCollection.php +++ b/src/ReverseRegex/ArrayCollection.php @@ -1,56 +1,53 @@ toArray(); ksort($values); - + $this->clear(); - - foreach($values as $index => $value) { - $this->set($index,$value); + + foreach ($values as $index => $value) { + $this->set($index, $value); } - + return $this; } - + /** - * Fetch a value using ones based position - * - * @access public - * @param integer $position - * @return mixed | null if bad position - */ + * Fetch a value using ones based position. + * + * @param int $position + * + * @return mixed|null if bad position + */ public function getAt($position) { - if($position < $this->count() && $position < 0) { + if ($position < $this->count() && $position < 0) { return null; } - + $this->first(); - - while($position > 1) { + + while ($position > 1) { $this->next(); --$position; } - + return $this->current(); } - - } /* End of Class */ - - diff --git a/src/ReverseRegex/Exception.php b/src/ReverseRegex/Exception.php index 1726c13..20e84df 100644 --- a/src/ReverseRegex/Exception.php +++ b/src/ReverseRegex/Exception.php @@ -1,14 +1,16 @@ - * @since 0.0.1 - */ + * Base class for exceptions. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Exception extends \Exception { - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Generator/AlternateInterface.php b/src/ReverseRegex/Generator/AlternateInterface.php index 811effd..5d08f4a 100644 --- a/src/ReverseRegex/Generator/AlternateInterface.php +++ b/src/ReverseRegex/Generator/AlternateInterface.php @@ -1,29 +1,29 @@ - * @since 0.0.1 - */ + * Allows a scope to select children using alternating strategy. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ interface AlternateInterface { /** - * Tell the scope to select childing use alternating strategy - * - * @access public - * @return void - */ + * Tell the scope to select childing use alternating strategy. + * + * @return void + */ public function useAlternatingStrategy(); - + /** - * Return true if setting been activated - * - * @access public - * @return boolean true - */ + * Return true if setting been activated. + * + * @return bool true + */ public function usingAlternatingStrategy(); - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Generator/ContextInterface.php b/src/ReverseRegex/Generator/ContextInterface.php index f684124..875633d 100644 --- a/src/ReverseRegex/Generator/ContextInterface.php +++ b/src/ReverseRegex/Generator/ContextInterface.php @@ -1,26 +1,24 @@ - * @since 0.0.1 - */ + * Conext interface for Generator. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ interface ContextInterface { /** - * Generate a text string appending to result arguments - * - * @access public - * @param string $result - * @param GeneratorInterface $generator - */ - public function generate(&$result,GeneratorInterface $generator); - + * Generate a text string appending to result arguments. + * + * @param string $result + */ + public function generate(&$result, GeneratorInterface $generator); } - -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Generator/LiteralScope.php b/src/ReverseRegex/Generator/LiteralScope.php index f67a69c..54f9f80 100644 --- a/src/ReverseRegex/Generator/LiteralScope.php +++ b/src/ReverseRegex/Generator/LiteralScope.php @@ -1,104 +1,96 @@ - * @since 0.0.1 - */ + * Scope for Literal Values. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class LiteralScope extends Scope { /** - * @var ReverseRegex\ArrayCollection container for literals values - */ + * @var ReverseRegex\ArrayCollection container for literals values + */ protected $literals; - /** - * Class Constructor - * - * @access public - * @param string $label - * @param Node $parent - */ + * Class Constructor. + * + * @param string $label + * @param Node $parent + */ public function __construct($label = 'label') { parent::__construct($label); - + $this->literals = new ArrayCollection(); } /** - * Adds a literal value to internal collection - * - * @access public - * @param mixed $literal - */ + * Adds a literal value to internal collection. + * + * @param mixed $literal + */ public function addLiteral($literal) { $this->literals->add($literal); } /** - * Sets a value on the internal collection using a key - * - * @access public - * @param string $hex a hexidecimal number - * @param string $literal the literal to store - */ - public function setLiteral($hex,$literal) + * Sets a value on the internal collection using a key. + * + * @param string $hex a hexidecimal number + * @param string $literal the literal to store + */ + public function setLiteral($hex, $literal) { - $this->literals->set($hex,$literal); + $this->literals->set($hex, $literal); } - + /** - * Return the literal ArrayCollection - * - * @access public - * @return Doctrine\Common\Collections\ArrayCollection - */ + * Return the literal ArrayCollection. + * + * @return Doctrine\Common\Collections\ArrayCollection + */ public function getLiterals() { return $this->literals; } - - + /** - * Generate a text string appending to the result argument - * - * @access public - * @param string $result - * @param GeneratorInterface $generator - */ - public function generate(&$result,GeneratorInterface $generator) + * Generate a text string appending to the result argument. + * + * @param string $result + */ + public function generate(&$result, GeneratorInterface $generator) { - if($this->literals->count() === 0) { + if (0 === $this->literals->count()) { throw new GeneratorException('There are no literals to choose from'); } - - $repeat_x = $this->calculateRepeatQuota($generator); - - while($repeat_x > 0) { - $randomIndex = 0; - - if($this->literals->count() > 1) { - $randomIndex = \round($generator->generate(1,($this->literals->count()))); - } - - $result .= $this->literals->getAt($randomIndex); - - --$repeat_x; + + $repeat_x = $this->calculateRepeatQuota($generator); + + while ($repeat_x > 0) { + $randomIndex = 0; + + if ($this->literals->count() > 1) { + $randomIndex = \round($generator->generate(1, ($this->literals->count()))); + } + + $result .= $this->literals->getAt($randomIndex); + + --$repeat_x; } - + return $result; - } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Generator/Node.php b/src/ReverseRegex/Generator/Node.php index f8d8f48..ca8c327 100644 --- a/src/ReverseRegex/Generator/Node.php +++ b/src/ReverseRegex/Generator/Node.php @@ -1,41 +1,44 @@ - * @since 0.0.1 - */ + * Base to all Generator Scopes. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Node implements ArrayAccess, Countable, Iterator { /** - * @var string name of the node - */ + * @var string name of the node + */ protected $label; - + /** - * @var ArrayObject container for node metadata - */ + * @var ArrayObject container for node metadata + */ protected $attrs; - + /** - * @var SplObjectStorage container for node relationships - */ + * @var SplObjectStorage container for node relationships + */ protected $links; /** - * Class Constructor - * - * @access public - * @param string $label - */ + * Class Constructor. + * + * @param string $label + */ public function __construct($label = 'node') { $this->attrs = new ArrayObject(); @@ -45,39 +48,36 @@ public function __construct($label = 'node') } /** - * Fetch the nodes label - * - * @access public - * @return string the nodes label - */ + * Fetch the nodes label. + * + * @return string the nodes label + */ public function getLabel() { return $this->label; } /** - * Sets the node label - * - * @access public - * @param string $label the nodes label - */ + * Sets the node label. + * + * @param string $label the nodes label + */ public function setLabel($label) { - if (!(is_scalar($label) || is_null($label))) { + if (!(is_scalar($label) || null === $label)) { return false; } $this->label = $label; } - /** - * Attach a node - * - * @access public - * @param Node $node the node to attach - * @return Node - */ + * Attach a node. + * + * @param Node $node the node to attach + * + * @return Node + */ public function &attach(Node $node) { $this->links->attach($node); @@ -86,12 +86,12 @@ public function &attach(Node $node) } /** - * Detach a node - * - * @access public - * @return Node - * @param Node $node the node to remove - */ + * Detach a node. + * + * @param Node $node the node to remove + * + * @return Node + */ public function &detach(Node $node) { foreach ($this->links as $linked_node) { @@ -104,12 +104,12 @@ public function &detach(Node $node) } /** - * Search for node in its relations - * - * @access public - * @return boolean true if found - * @param Node $node the node to search for - */ + * Search for node in its relations. + * + * @param Node $node the node to search for + * + * @return bool true if found + */ public function contains(Node $node) { foreach ($this->links as $linked_node) { @@ -120,11 +120,10 @@ public function contains(Node $node) return false; } - - /** - * Apply a closure to all relations + + /** + * Apply a closure to all relations. * - * @access public * @param Closer the function to apply */ public function map(Closure $function) @@ -133,41 +132,45 @@ public function map(Closure $function) $function($node); } } - + //------------------------------------------------------------------ - # Countable - + // Countable + public function count() { return count($this->links); } - + //------------------------------------------------------------------ - # Iterator + // Iterator public function current() { return $this->links->current(); } + public function key() { return $this->links->key(); } + public function next() { return $this->links->next(); } + public function rewind() { return $this->links->rewind(); } + public function valid() { return $this->links->valid(); } - + //------------------------------------------------------------------ - # ArrayAccess Implementation + // ArrayAccess Implementation public function offsetGet($key) { @@ -190,4 +193,4 @@ public function offsetUnset($key) } } -/* End of Class */ \ No newline at end of file +/* End of Class */ diff --git a/src/ReverseRegex/Generator/RepeatInterface.php b/src/ReverseRegex/Generator/RepeatInterface.php index 4a8283a..c8b1193 100644 --- a/src/ReverseRegex/Generator/RepeatInterface.php +++ b/src/ReverseRegex/Generator/RepeatInterface.php @@ -1,54 +1,50 @@ - * @since 0.0.1 - */ + * Represent a group has max and min number of occurances. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ interface RepeatInterface { /** - * Fetches the max re-occurances - * - * @access public - * @return integer the maximum number of occurances - */ + * Fetches the max re-occurances. + * + * @return int the maximum number of occurances + */ public function getMaxOccurances(); - + /** - * Sets the maximum re-occurances - * - * @access public - * @param integer $num - */ + * Sets the maximum re-occurances. + * + * @param int $num + */ public function setMaxOccurances($num); - - + /** - * Fetch the Minimum re-occurances - * - * @access public - * @return integer - */ + * Fetch the Minimum re-occurances. + * + * @return int + */ public function getMinOccurances(); - + /** - * Sets the Minimum number of re-occurances - * - * @access public - * @param integer $num - */ + * Sets the Minimum number of re-occurances. + * + * @param int $num + */ public function setMinOccurances($num); - + /** - * Return the occurance range - * - * @access public - * @return integer the range - */ + * Return the occurance range. + * + * @return int the range + */ public function getOccuranceRange(); - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Generator/Scope.php b/src/ReverseRegex/Generator/Scope.php index 6a9d08e..48f03f1 100644 --- a/src/ReverseRegex/Generator/Scope.php +++ b/src/ReverseRegex/Generator/Scope.php @@ -1,28 +1,30 @@ - * @since 0.0.1 - */ + * Base Class for Scopes. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Scope extends Node implements ContextInterface, RepeatInterface, AlternateInterface { - - const REPEAT_MIN_INDEX = 'repeat_min'; - - const REPEAT_MAX_INDEX = 'repeat_max'; - - const USE_ALTERNATING_INDEX = 'use_alternating'; - - + public const REPEAT_MIN_INDEX = 'repeat_min'; + + public const REPEAT_MAX_INDEX = 'repeat_max'; + + public const USE_ALTERNATING_INDEX = 'use_alternating'; + /** - * Class Constructor - */ + * Class Constructor. + */ public function __construct($label = 'node') { parent::__construct($label); @@ -32,186 +34,158 @@ public function __construct($label = 'node') $this->setMinOccurances(1); $this->setMaxOccurances(1); } - - + // ---------------------------------------------------------------------------- - # Conext Interface - - + // Conext Interface + /** - * Generate a text string appending to result arguments - * - * @access public - * @param string $result - * @param GeneratorInterface $generator - */ - public function generate(&$result,GeneratorInterface $generator) + * Generate a text string appending to result arguments. + * + * @param string $result + */ + public function generate(&$result, GeneratorInterface $generator) { - if($this->count() === 0) { + if (0 === $this->count()) { throw new GeneratorException('No child scopes to call must be atleast 1'); } - + $repeat_x = $this->calculateRepeatQuota($generator); - - # rewind the current item + + // rewind the current item $this->rewind(); - while($repeat_x > 0) { - - if($this->usingAlternatingStrategy()) { - $randomIndex = \round($generator->generate(1,($this->count()))); - $this->get($randomIndex)->generate($result,$generator); - + while ($repeat_x > 0) { + if ($this->usingAlternatingStrategy()) { + $randomIndex = \round($generator->generate(1, ($this->count()))); + $this->get($randomIndex)->generate($result, $generator); } else { - - foreach($this as $current) { - $current->generate($result,$generator); - } - + foreach ($this as $current) { + $current->generate($result, $generator); + } } - - $repeat_x = $repeat_x -1; + + $repeat_x = $repeat_x - 1; } - - + return $result; } - - + /** - * Fetch a node given an `one-based index` - * - * @access public - * @return Scope | null if none found - */ + * Fetch a node given an `one-based index`. + * + * @return Scope|null if none found + */ public function get($index) { - if($index > $this->count() || $index <= 0) { + if ($index > $this->count() || $index <= 0) { return null; } - + $this->rewind(); - while(($index - 1) > 0) { + while (($index - 1) > 0) { $this->next(); $index = $index - 1; } - + return $this->current(); - } - - + // ---------------------------------------------------------------------------- - # Repeat Interface - - /** - * Fetches the max occurances - * - * @access public - * @return integer the maximum number of occurances - */ + // Repeat Interface + + /** + * Fetches the max occurances. + * + * @return int the maximum number of occurances + */ public function getMaxOccurances() { return $this[self::REPEAT_MAX_INDEX]; } - - /** - * Sets the maximum re-occurances - * - * @access public - * @param integer $num - */ + + /** + * Sets the maximum re-occurances. + * + * @param int $num + */ public function setMaxOccurances($num) { - if(is_integer($num) === false){ + if (false === is_integer($num)) { throw new GeneratorException('Number must be an integer'); } - + $this[self::REPEAT_MAX_INDEX] = $num; - } - + /** - * Fetch the Minimum Occurances - * - * @access public - * @return integer - */ + * Fetch the Minimum Occurances. + * + * @return int + */ public function getMinOccurances() { return $this[self::REPEAT_MIN_INDEX]; } - + /** - * Sets the Minimum number of re-occurances - * - * @access public - * @param integer $num - */ + * Sets the Minimum number of re-occurances. + * + * @param int $num + */ public function setMinOccurances($num) { - if(is_integer($num) === false){ + if (false === is_integer($num)) { throw new GeneratorException('Number must be an integer'); } - + $this[self::REPEAT_MIN_INDEX] = $num; } - - - /** - * Return the occurance range - * - * @access public - * @return integer the range - */ + + /** + * Return the occurance range. + * + * @return int the range + */ public function getOccuranceRange() { - return (integer)($this->getMaxOccurances() - $this->getMinOccurances()); + return (int) ($this->getMaxOccurances() - $this->getMinOccurances()); } - - + /** - * Calculate a random numer of repeats given the current min-max range - * - * @access public - * @param GeneratorInterface $generator - * @return Integer - */ + * Calculate a random numer of repeats given the current min-max range. + * + * @return int + */ public function calculateRepeatQuota(GeneratorInterface $generator) { $repeat_x = $this->getMinOccurances(); - - if($this->getOccuranceRange() > 0) { - $repeat_x = (integer) \round($generator->generate($this->getMinOccurances(),$this->getMaxOccurances())); - } - + + if ($this->getOccuranceRange() > 0) { + $repeat_x = (int) \round($generator->generate($this->getMinOccurances(), $this->getMaxOccurances())); + } + return $repeat_x; } - + //------------------------------------------------------------------ - # AlternateInterface - - + // AlternateInterface + /** - * Tell the scope to select childing use alternating strategy - * - * @access public - * @return void - */ + * Tell the scope to select childing use alternating strategy. + * + * @return void + */ public function useAlternatingStrategy() { $this[self::USE_ALTERNATING_INDEX] = true; } - + /** - * Return true if setting been activated - * - * @access public - * @return boolean true - */ + * Return true if setting been activated. + * + * @return bool true + */ public function usingAlternatingStrategy() { - return (boolean) $this[self::USE_ALTERNATING_INDEX]; + return (bool) $this[self::USE_ALTERNATING_INDEX]; } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Lexer.php b/src/ReverseRegex/Lexer.php index 67431f1..c209af0 100644 --- a/src/ReverseRegex/Lexer.php +++ b/src/ReverseRegex/Lexer.php @@ -1,169 +1,172 @@ - * @since 0.0.1 - */ + * Lexer to split expression syntax. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Lexer extends AbstractLexer { - // ---------------------------------------------------------------------------- - # Char Constants + // Char Constants /** - * @integer an escape character - */ - const T_ESCAPE_CHAR = -1; - + * @integer an escape character + */ + public const T_ESCAPE_CHAR = -1; + /** - * The literal type ie a=a ^=^ - */ - const T_LITERAL_CHAR = 0; + * The literal type ie a=a ^=^. + */ + public const T_LITERAL_CHAR = 0; /** - * Numeric literal 1=1 100=100 - */ - const T_LITERAL_NUMERIC = 1; - + * Numeric literal 1=1 100=100. + */ + public const T_LITERAL_NUMERIC = 1; + /** - * The opening character for group. [(] - */ - const T_GROUP_OPEN = 2; - + * The opening character for group. [(]. + */ + public const T_GROUP_OPEN = 2; + /** - * The closing character for group [)] - */ - const T_GROUP_CLOSE = 3; - + * The closing character for group [)]. + */ + public const T_GROUP_CLOSE = 3; + /** - * Opening character for Quantifier ({) - */ - const T_QUANTIFIER_OPEN = 4; - + * Opening character for Quantifier ({). + */ + public const T_QUANTIFIER_OPEN = 4; + /** - * Closing character for Quantifier (}) - */ - const T_QUANTIFIER_CLOSE = 5; - + * Closing character for Quantifier (}). + */ + public const T_QUANTIFIER_CLOSE = 5; + /** - * Star quantifier character (*) - */ - const T_QUANTIFIER_STAR = 6; - + * Star quantifier character (*). + */ + public const T_QUANTIFIER_STAR = 6; + /** - * Pluse quantifier character (+) - */ - const T_QUANTIFIER_PLUS = 7; - + * Pluse quantifier character (+). + */ + public const T_QUANTIFIER_PLUS = 7; + /** - * The one but optonal character (?) - */ - const T_QUANTIFIER_QUESTION = 8; - + * The one but optonal character (?). + */ + public const T_QUANTIFIER_QUESTION = 8; + /** - * Start of string character (^) - */ - const T_START_CARET = 9; - + * Start of string character (^). + */ + public const T_START_CARET = 9; + /** - * End of string character ($) - */ - const T_END_DOLLAR = 10; - + * End of string character ($). + */ + public const T_END_DOLLAR = 10; + /** - * Range character inside set ([) - */ - const T_SET_OPEN = 11; - + * Range character inside set ([). + */ + public const T_SET_OPEN = 11; + /** - * Range character inside set (]) - */ - const T_SET_CLOSE = 12; - + * Range character inside set (]). + */ + public const T_SET_CLOSE = 12; + /** - * Range character inside set (-) - */ - const T_SET_RANGE = 13; - + * Range character inside set (-). + */ + public const T_SET_RANGE = 13; + /** - * Negated Character in set ([^) - */ - const T_SET_NEGATED = 14; - + * Negated Character in set ([^). + */ + public const T_SET_NEGATED = 14; + /** - * The either character (|) - */ - const T_CHOICE_BAR = 15; - + * The either character (|). + */ + public const T_CHOICE_BAR = 15; + /** - * The dot character (.) - */ - const T_DOT = 16; - - + * The dot character (.). + */ + public const T_DOT = 16; + // ---------------------------------------------------------------------------- - # Shorthand constants - + // Shorthand constants + /** - * One Word boundry - */ - const T_SHORT_W = 100; - const T_SHORT_NOT_W = 101; - - const T_SHORT_D = 102; - const T_SHORT_NOT_D = 103; - - const T_SHORT_S = 104; - const T_SHORT_NOT_S = 105; - + * One Word boundry. + */ + public const T_SHORT_W = 100; + + public const T_SHORT_NOT_W = 101; + + public const T_SHORT_D = 102; + + public const T_SHORT_NOT_D = 103; + + public const T_SHORT_S = 104; + + public const T_SHORT_NOT_S = 105; + /** - * Unicode sequences /p{} /pNum - */ - const T_SHORT_P = 106; - - + * Unicode sequences /p{} /pNum. + */ + public const T_SHORT_P = 106; + /** - * Hex Sequences /x{} /xNum - */ - const T_SHORT_X = 108; - + * Hex Sequences /x{} /xNum. + */ + public const T_SHORT_X = 108; + /** - * Unicode hex sequence /X{} /XNum - */ - const T_SHORT_UNICODE_X = 109; - + * Unicode hex sequence /X{} /XNum. + */ + public const T_SHORT_UNICODE_X = 109; + // ---------------------------------------------------------------------------- - # Lexer Modes + // Lexer Modes /** - * @var boolean The lexer has detected escape character - */ + * @var bool The lexer has detected escape character + */ protected $escape_mode = false; /** - * @var boolean The lexer is parsing a char set - */ + * @var bool The lexer is parsing a char set + */ protected $set_mode = false; /** - * @var integer the number of groups open - */ + * @var int the number of groups open + */ protected $group_set = 0; - + /** - * @var number of characters parsed inside the set - */ + * @var number of characters parsed inside the set + */ protected $set_internal_counter = 0; - - + // ---------------------------------------------------------------------------- - # Doctrine\Common\Lexer Methods + // Doctrine\Common\Lexer Methods /** * Creates a new query scanner object. @@ -176,163 +179,162 @@ public function __construct($input) } /** - * @inheritdoc + * {@inheritdoc} */ protected function getCatchablePatterns() { - return array( - '.' - ); + return [ + '.', + ]; } /** - * @inheritdoc + * {@inheritdoc} */ protected function getNonCatchablePatterns() { - return array('\s+'); + return ['\s+']; } /** - * @inheritdoc + * {@inheritdoc} */ protected function getType(&$value) { $type = null; switch (true) { - case ($value === '\\' && $this->escape_mode === false) : + case '\\' === $value && false === $this->escape_mode: $this->escape_mode = true; $type = self::T_ESCAPE_CHAR; - - if($this->set_mode === true) { - $this->set_internal_counter++; + + if (true === $this->set_mode) { + ++$this->set_internal_counter; } - - break; - + + break; + // Groups - case ($value === '(' && $this->escape_mode === false && $this->set_mode === false) : + case '(' === $value && false === $this->escape_mode && false === $this->set_mode: $type = self::T_GROUP_OPEN; - $this->group_set++; + ++$this->group_set; break; - case ($value === ')' && $this->escape_mode === false && $this->set_mode === false) : + case ')' === $value && false === $this->escape_mode && false === $this->set_mode: $type = self::T_GROUP_CLOSE; - $this->group_set--; + --$this->group_set; break; - - // Charset - case ($value === '[' && $this->escape_mode === false && $this->set_mode === true) : + + // Charset + case '[' === $value && false === $this->escape_mode && true === $this->set_mode: throw new LexerException("Can't have a second character class while first remains open"); break; - case ($value === ']' && $this->escape_mode === false && $this->set_mode === false) : + case ']' === $value && false === $this->escape_mode && false === $this->set_mode: throw new LexerException("Can't close a character class while none is open"); break; - case ($value === '[' && $this->escape_mode === false && $this->set_mode === false) : + case '[' === $value && false === $this->escape_mode && false === $this->set_mode: $this->set_mode = true; $type = self::T_SET_OPEN; $this->set_internal_counter = 1; break; - case ($value === ']' && $this->escape_mode === false && $this->set_mode === true) : + case ']' === $value && false === $this->escape_mode && true === $this->set_mode: $this->set_mode = false; $type = self::T_SET_CLOSE; $this->set_internal_counter = 0; break; - case ($value === '-' && $this->escape_mode === false && $this->set_mode === true) : + case '-' === $value && false === $this->escape_mode && true === $this->set_mode: $this->set_internal_counter++; + return self::T_SET_RANGE; break; - case ($value === '^' && $this->escape_mode === false && $this->set_mode === true && $this->set_internal_counter === 1) : + case '^' === $value && false === $this->escape_mode && true === $this->set_mode && 1 === $this->set_internal_counter: $this->set_internal_counter++; - return self::T_SET_NEGATED; + + return self::T_SET_NEGATED; break; // Quantifers - case ($value === '{' && $this->escape_mode === false && $this->set_mode === false) : return self::T_QUANTIFIER_OPEN; - case ($value === '}' && $this->escape_mode === false && $this->set_mode === false) : return self::T_QUANTIFIER_CLOSE; - case ($value === '*' && $this->escape_mode === false && $this->set_mode === false) : return self::T_QUANTIFIER_STAR; - case ($value === '+' && $this->escape_mode === false && $this->set_mode === false) : return self::T_QUANTIFIER_PLUS; - case ($value === '?' && $this->escape_mode === false && $this->set_mode === false) : return self::T_QUANTIFIER_QUESTION; - + case '{' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_QUANTIFIER_OPEN; + case '}' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_QUANTIFIER_CLOSE; + case '*' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_QUANTIFIER_STAR; + case '+' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_QUANTIFIER_PLUS; + case '?' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_QUANTIFIER_QUESTION; + // Recognize symbols - case ($value === '.' && $this->escape_mode === false && $this->set_mode === false) : return self::T_DOT; - case ($value === '|' && $this->escape_mode === false && $this->set_mode === false) : return self::T_CHOICE_BAR; - case ($value === '^' && $this->escape_mode === false && $this->set_mode === false) : return self::T_START_CARET; - case ($value === '$' && $this->escape_mode === false && $this->set_mode === false) : return self::T_END_DOLLAR; - - + case '.' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_DOT; + case '|' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_CHOICE_BAR; + case '^' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_START_CARET; + case '$' === $value && false === $this->escape_mode && false === $this->set_mode: return self::T_END_DOLLAR; + // ShortCodes - case ($value === 'd' && $this->escape_mode === true) : + case 'd' === $value && true === $this->escape_mode: $type = self::T_SHORT_D; $this->escape_mode = false; break; - case ($value === 'D' && $this->escape_mode === true) : + case 'D' === $value && true === $this->escape_mode: $type = self::T_SHORT_NOT_D; $this->escape_mode = false; break; - case ($value === 'w' && $this->escape_mode === true) : + case 'w' === $value && true === $this->escape_mode: $type = self::T_SHORT_W; $this->escape_mode = false; break; - case ($value === 'W' && $this->escape_mode === true) : + case 'W' === $value && true === $this->escape_mode: $type = self::T_SHORT_NOT_W; $this->escape_mode = false; break; - case ($value === 's' && $this->escape_mode === true) : + case 's' === $value && true === $this->escape_mode: $type = self::T_SHORT_S; $this->escape_mode = false; break; - case ($value === 'S' && $this->escape_mode === true) : + case 'S' === $value && true === $this->escape_mode: $type = self::T_SHORT_NOT_S; $this->escape_mode = false; break; - case ($value === 'x' && $this->escape_mode === true) : + case 'x' === $value && true === $this->escape_mode: $type = self::T_SHORT_X; $this->escape_mode = false; - - if($this->set_mode === true) { - $this->set_internal_counter++; + + if (true === $this->set_mode) { + ++$this->set_internal_counter; } - + break; - case ($value === 'X' && $this->escape_mode === true) : + case 'X' === $value && true === $this->escape_mode: $type = self::T_SHORT_UNICODE_X; $this->escape_mode = false; - - if($this->set_mode === true) { - $this->set_internal_counter++; + + if (true === $this->set_mode) { + ++$this->set_internal_counter; } - + break; - case (($value === 'p' || $value === 'P') && $this->escape_mode === true) : + case ('p' === $value || 'P' === $value) && true === $this->escape_mode: $type = self::T_SHORT_P; $this->escape_mode = false; - - if($this->set_mode === true) { - $this->set_internal_counter++; + + if (true === $this->set_mode) { + ++$this->set_internal_counter; } - + break; - - // Default - default : - if(is_numeric($value) === true) { + + // Default + default: + if (true === is_numeric($value)) { $type = self::T_LITERAL_NUMERIC; } else { - $type = self::T_LITERAL_CHAR; + $type = self::T_LITERAL_CHAR; } - - if($this->set_mode === true) { - $this->set_internal_counter++; + + if (true === $this->set_mode) { + ++$this->set_internal_counter; } - - + $this->escape_mode = false; } return $type; } - - + /** * Scans the input string for tokens. * @@ -340,34 +342,30 @@ protected function getType(&$value) */ protected function scan($input) { - # reset default for scan - $this->group_set = 0; + // reset default for scan + $this->group_set = 0; $this->escape_mode = false; - $this->set_mode = false; - + $this->set_mode = false; + static $regex; - if ( ! isset($regex)) { - $regex = '/(' . implode(')|(', $this->getCatchablePatterns()) . ')|' - . implode('|', $this->getNonCatchablePatterns()) . '/ui'; + if (!isset($regex)) { + $regex = '/('.implode(')|(', $this->getCatchablePatterns()).')|' + .implode('|', $this->getNonCatchablePatterns()).'/ui'; } parent::scan($input); - - if($this->group_set > 0) { + if ($this->group_set > 0) { throw new LexerException('Opening group char "(" has no matching closing character'); } - - if($this->group_set < 0) { + + if ($this->group_set < 0) { throw new LexerException('Closing group char "(" has no matching opening character'); } - - if($this->set_mode === true) { + + if (true === $this->set_mode) { throw new LexerException('Character Class that been closed'); } - } - } -/* End of File */ diff --git a/src/ReverseRegex/Parser.php b/src/ReverseRegex/Parser.php index 4006f13..47356c4 100644 --- a/src/ReverseRegex/Parser.php +++ b/src/ReverseRegex/Parser.php @@ -1,255 +1,234 @@ - * @since 0.0.1 - */ + * Parser to convert regex into Group. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Parser { /** - * @var Lexer - */ + * @var Lexer + */ protected $lexer; - + /** - * @var ReverseRegex\Generator\Scope - */ + * @var ReverseRegex\Generator\Scope + */ protected $result; - + /** - * @var ReverseRegex\Generator\Scope the current head - */ + * @var ReverseRegex\Generator\Scope the current head + */ protected $head; - + /** - * @var ReverseRegex\Generator\Scope Last attached scope - */ + * @var ReverseRegex\Generator\Scope Last attached scope + */ protected $left; - + /** - * Class Constructor - * - * @access public - * @param Lexer $lexer - */ + * Class Constructor. + */ public function __construct(Lexer $lexer, Scope $result, Scope $head = null) { - $this->lexer = $lexer; + $this->lexer = $lexer; $this->result = $result; - - if($head === null) { + + if (null === $head) { $this->head = new Scope(); } else { - $this->head = $head; + $this->head = $head; } - + $this->result->attach($head); - + $this->left = $head; } - - + /** - * Fetch the regex lexer - * - * @access public - * @return Lexer - */ + * Fetch the regex lexer. + * + * @return Lexer + */ public function getLexer() { return $this->lexer; } - - + /** - * Will parse the regex into generator - * - * @access public - * @return - */ + * Will parse the regex into generator. + * + * @return + */ public function parse($sub = false) { - try { - - while($this->lexer->moveNext()) { - + while ($this->lexer->moveNext()) { $result = null; - $scope = null; + $scope = null; $parser = null; - - switch(true) { - case($this->lexer->isNextToken(Lexer::T_GROUP_OPEN)) : - - # is the group character the first token? is the regex wrapped in brackets. + + switch (true) { + case $this->lexer->isNextToken(Lexer::T_GROUP_OPEN) : + + // is the group character the first token? is the regex wrapped in brackets. //if($this->lexer->token === null) { // continue; //} - - # note this is a new group create new parser instance. - $parser = new Parser($this->lexer,new Scope(),new Scope()); - + + // note this is a new group create new parser instance. + $parser = new Parser($this->lexer, new Scope(), new Scope()); + $this->left = $parser->parse(true)->getResult(); - $this->head->attach($this->left); - + $this->head->attach($this->left); + break; - case($this->lexer->isNextToken(Lexer::T_GROUP_CLOSE)) : - - # group is finished don't want to contine this loop break = 2 + case $this->lexer->isNextToken(Lexer::T_GROUP_CLOSE) : + + // group is finished don't want to contine this loop break = 2 break 2; break; - case ($this->lexer->isNextTokenAny(array(Lexer::T_LITERAL_CHAR,Lexer::T_LITERAL_NUMERIC))): - - # test for literal characters (abcd) + case $this->lexer->isNextTokenAny([Lexer::T_LITERAL_CHAR, Lexer::T_LITERAL_NUMERIC]): + + // test for literal characters (abcd) $this->left = new LiteralScope(); $this->left->addLiteral($this->lexer->lookahead['value']); $this->head->attach($this->left); - + break; - case($this->lexer->isNextToken(Lexer::T_SET_OPEN)) : - - # character classes [a-z] + case $this->lexer->isNextToken(Lexer::T_SET_OPEN) : + + // character classes [a-z] $this->left = new LiteralScope(); - self::createSubParser('character')->parse($this->left,$this->head,$this->lexer); + self::createSubParser('character')->parse($this->left, $this->head, $this->lexer); $this->head->attach($this->left); - - + break; - case ($this->lexer->isNextTokenAny(array( + case $this->lexer->isNextTokenAny([ Lexer::T_DOT, Lexer::T_SHORT_D, Lexer::T_SHORT_NOT_D, Lexer::T_SHORT_W, Lexer::T_SHORT_NOT_W, Lexer::T_SHORT_S, - Lexer::T_SHORT_NOT_S))): - - # match short (. \d \D \w \W \s \S) + Lexer::T_SHORT_NOT_S, ]): + + // match short (. \d \D \w \W \s \S) $this->left = new LiteralScope(); - self::createSubParser('short')->parse($this->left,$this->head,$this->lexer); + self::createSubParser('short')->parse($this->left, $this->head, $this->lexer); $this->head->attach($this->left); - - + break; - case ($this->lexer->isNextTokenAny(array( + case $this->lexer->isNextTokenAny([ Lexer::T_SHORT_P, Lexer::T_SHORT_UNICODE_X, - Lexer::T_SHORT_X))): - - # match short (\p{L} \x \X ) + Lexer::T_SHORT_X, ]): + + // match short (\p{L} \x \X ) $this->left = new LiteralScope(); - self::createSubParser('unicode')->parse($this->left,$this->head,$this->lexer); + self::createSubParser('unicode')->parse($this->left, $this->head, $this->lexer); $this->head->attach($this->left); - - + break; - case ($this->lexer->isNextTokenAny(array( + case $this->lexer->isNextTokenAny([ Lexer::T_QUANTIFIER_OPEN, Lexer::T_QUANTIFIER_PLUS, Lexer::T_QUANTIFIER_QUESTION, Lexer::T_QUANTIFIER_STAR, - Lexer::T_QUANTIFIER_OPEN - ))): - - # match quantifiers - self::createSubParser('quantifer')->parse($this->left,$this->head,$this->lexer); - + Lexer::T_QUANTIFIER_OPEN, + ]): + + // match quantifiers + self::createSubParser('quantifer')->parse($this->left, $this->head, $this->lexer); + break; - case ($this->lexer->isNextToken(Lexer::T_CHOICE_BAR)): - - # match alternations + case $this->lexer->isNextToken(Lexer::T_CHOICE_BAR): + + // match alternations $this->left = $this->head; - + $this->head = new Scope(); $this->result->useAlternatingStrategy(); $this->result->attach($this->head); - - - break; + + break; default: - # ignore character - } - - + // ignore character + } } - - } - catch(ParserException $e) - { + } catch (ParserException $e) { $pos = $this->lexer->lookahead['position']; $compressed = $this->compress(); - throw new ParserException(sprintf('Error found STARTING at position %s after `%s` with msg %s ',$pos,$compressed,$e->getMessage())); + + throw new ParserException(sprintf('Error found STARTING at position %s after `%s` with msg %s ', $pos, $compressed, $e->getMessage())); } - - return $this; + + return $this; } - + /** - * Compress the lexer into value string until current lookahead - * - * @access public - * @return string the compressed value string - */ + * Compress the lexer into value string until current lookahead. + * + * @return string the compressed value string + */ public function compress() { - $current = $this->lexer->lookahead['position']; + $current = $this->lexer->lookahead['position']; $this->lexer->reset(); $string = ''; - - while($this->lexer->moveNext() && $this->lexer->lookahead['position'] <= $current) { + + while ($this->lexer->moveNext() && $this->lexer->lookahead['position'] <= $current) { $string .= $this->lexer->lookahead['value']; } - + return $string; } - - + /** - * Return the result of the parse - */ + * Return the result of the parse. + */ public function getResult() { return $this->result; } - - - public static $sub_parsers = array( - 'character' => '\\ReverseRegex\\Parser\\CharacterClass', - 'unicode' => '\\ReverseRegex\\Parser\\Unicode', + + public static $sub_parsers = [ + 'character' => '\\ReverseRegex\\Parser\\CharacterClass', + 'unicode' => '\\ReverseRegex\\Parser\\Unicode', 'quantifer' => '\\ReverseRegex\\Parser\\Quantifier', - 'short' => '\\ReverseRegex\\Parser\\Short' - ); - + 'short' => '\\ReverseRegex\\Parser\\Short', + ]; + /** - * Return an instance os subparser - * - * @access public - * @static - * @return ReverseRegex\Parser\StrategyInterface - * @param string $name the short name - */ - static function createSubParser($name) + * Return an instance os subparser. + * + * @static + * + * @param string $name the short name + * + * @return ReverseRegex\Parser\StrategyInterface + */ + public static function createSubParser($name) { - - if(isset(self::$sub_parsers[$name]) === false) { + if (false === isset(self::$sub_parsers[$name])) { throw new ParserException('Unknown subparser at '.$name); } - - if(is_object(self::$sub_parsers[$name]) === false) { + + if (false === is_object(self::$sub_parsers[$name])) { self::$sub_parsers[$name] = new self::$sub_parsers[$name](); } - + return self::$sub_parsers[$name]; } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Parser/CharacterClass.php b/src/ReverseRegex/Parser/CharacterClass.php index 5618ffa..5c72a03 100644 --- a/src/ReverseRegex/Parser/CharacterClass.php +++ b/src/ReverseRegex/Parser/CharacterClass.php @@ -1,150 +1,138 @@ - * @since 0.0.1 - */ + * Parse a character class [0-9][a-z]. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class CharacterClass implements StrategyInterface { - - /** - * Will return a normalized ie unicode sequences been evaluated. - * - * @return string a normalized character class string - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $set - * @param Lexer $lexer the lexer to normalize - */ + * Will return a normalized ie unicode sequences been evaluated. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $set + * @param Lexer $lexer the lexer to normalize + * + * @return string a normalized character class string + */ public function normalize(Scope $head, Scope $set, Lexer $lexer) { - $collection = array(); + $collection = []; $unicode = new Unicode(); - - while($lexer->moveNext() && !$lexer->isNextToken(Lexer::T_SET_CLOSE)) { - + + while ($lexer->moveNext() && !$lexer->isNextToken(Lexer::T_SET_CLOSE)) { $value = null; - - switch(true) { - case($lexer->isNextTokenAny(array(Lexer::T_SHORT_UNICODE_X, Lexer::T_SHORT_P,Lexer::T_SHORT_X))): + + switch (true) { + case $lexer->isNextTokenAny([Lexer::T_SHORT_UNICODE_X, Lexer::T_SHORT_P, Lexer::T_SHORT_X]): $collection[] = $unicode->evaluate($lexer); break; - case($lexer->isNextTokenAny(array(Lexer::T_LITERAL_CHAR, Lexer::T_LITERAL_NUMERIC))): + case $lexer->isNextTokenAny([Lexer::T_LITERAL_CHAR, Lexer::T_LITERAL_NUMERIC]): $collection[] = $lexer->lookahead['value']; break; - case($lexer->isNextToken(Lexer::T_SET_RANGE)): + case $lexer->isNextToken(Lexer::T_SET_RANGE): $collection[] = '-'; break; - case($lexer->isNextToken(Lexer::T_ESCAPE_CHAR)): + case $lexer->isNextToken(Lexer::T_ESCAPE_CHAR): $collection[] = '\\'; break; - default : + default: throw new ParserException('Illegal meta character detected in character class'); } - } - + /* if($lexer->lookahead['type'] === null) { throw new ParserException('Closing character set token not found'); } */ - - return '['. implode('',$collection) .']'; - + + return '['.implode('', $collection).']'; } - - - + /** - * Parse the current token for new Quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $set - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for new Quantifiers. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $set + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function parse(Scope $head, Scope $set, Lexer $lexer) { - if($lexer->lookahead['type'] !== Lexer::T_SET_OPEN) { + if (Lexer::T_SET_OPEN !== $lexer->lookahead['type']) { throw new ParserException('Opening character set token not found'); } - + $peek = $lexer->glimpse(); - if($peek['type'] === Lexer::T_SET_NEGATED) { - throw new ParserException('Negated Character Set ranges not supported at this time'); + if (Lexer::T_SET_NEGATED === $peek['type']) { + throw new ParserException('Negated Character Set ranges not supported at this time'); } - - $normal_lexer = new Lexer($this->normalize($head,$set,$lexer)); - - while( $normal_lexer->moveNext() && !$normal_lexer->isNextToken(Lexer::T_SET_CLOSE)) { + + $normal_lexer = new Lexer($this->normalize($head, $set, $lexer)); + + while ($normal_lexer->moveNext() && !$normal_lexer->isNextToken(Lexer::T_SET_CLOSE)) { $glimpse = $normal_lexer->glimpse(); - - if($glimpse['type'] === Lexer::T_SET_RANGE) { + + if (Lexer::T_SET_RANGE === $glimpse['type']) { continue; //value be included in range when `-` character is passed } - - switch(true) { - case($normal_lexer->isNextToken(Lexer::T_SET_RANGE)) : + + switch (true) { + case $normal_lexer->isNextToken(Lexer::T_SET_RANGE) : $range_start = $normal_lexer->token['value']; - + $normal_lexer->moveNext(); - - if($normal_lexer->isNextToken(Lexer::T_ESCAPE_CHAR)) { + + if ($normal_lexer->isNextToken(Lexer::T_ESCAPE_CHAR)) { $normal_lexer->moveNext(); } - - $range_end = $normal_lexer->lookahead['value']; - $this->fillRange($head,$range_start,$range_end); - - break; - case($normal_lexer->isNextToken(Lexer::T_LITERAL_NUMERIC) || $normal_lexer->isNextToken(Lexer::T_LITERAL_CHAR)) : - $index = (integer)mb_ord($normal_lexer->lookahead['value']); - $head->setLiteral($index,$normal_lexer->lookahead['value']); + + $range_end = $normal_lexer->lookahead['value']; + $this->fillRange($head, $range_start, $range_end); + + break; + case $normal_lexer->isNextToken(Lexer::T_LITERAL_NUMERIC) || $normal_lexer->isNextToken(Lexer::T_LITERAL_CHAR) : + $index = (int) mb_ord($normal_lexer->lookahead['value']); + $head->setLiteral($index, $normal_lexer->lookahead['value']); break; default: - # ignore + // ignore } } - - + $head->getLiterals()->sort(); - + return $head; } - + /** - * Fill a range given starting and ending character - * - * @return void - * @access public - */ - public function fillRange(Scope $head,$start,$end) + * Fill a range given starting and ending character. + * + * @return void + */ + public function fillRange(Scope $head, $start, $end) { - - $start_index = mb_ord($start); + $start_index = mb_ord($start); $ending_index = mb_ord($end); - - if($ending_index < $start_index ) { - throw new ParserException(sprintf('Character class range %s - %s is out of order',$start,$end)); + + if ($ending_index < $start_index) { + throw new ParserException(sprintf('Character class range %s - %s is out of order', $start, $end)); + } + + for ($i = $start_index; $i <= $ending_index; ++$i) { + $head->setLiteral($i, mb_chr($i)); } - - for($i = $start_index; $i <= $ending_index; $i++) { - $head->setLiteral($i,mb_chr($i)); - } } - - - } - - -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Parser/Quantifier.php b/src/ReverseRegex/Parser/Quantifier.php index 49f0dcd..a790232 100644 --- a/src/ReverseRegex/Parser/Quantifier.php +++ b/src/ReverseRegex/Parser/Quantifier.php @@ -1,200 +1,193 @@ - * @since 0.0.1 - */ + * Parse a group quantifer e.g (abghb){1,5} , (abghb){5} , (abghb)* , (abghb)? , (abghb)+. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Quantifier implements StrategyInterface { - /** - * Parse the current token for new Quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $set - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for new Quantifiers. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $set + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function parse(Scope $head, Scope $set, Lexer $lexer) { - switch(true) { - case ($lexer->isNextToken(Lexer::T_QUANTIFIER_PLUS)) : - $head = $this->quantifyPlus($head,$set,$lexer); + switch (true) { + case $lexer->isNextToken(Lexer::T_QUANTIFIER_PLUS): + $head = $this->quantifyPlus($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_QUANTIFIER_QUESTION)) : - $head = $this->quantifyQuestion($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_QUANTIFIER_QUESTION): + $head = $this->quantifyQuestion($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_QUANTIFIER_STAR)) : - $head = $this->quantifyStar($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_QUANTIFIER_STAR): + $head = $this->quantifyStar($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN)) : - $head = $this->quantifyClosure($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN): + $head = $this->quantifyClosure($head, $set, $lexer); break; - default : + default: //do nothing no token matches found } - + return $head; - } - - + /** - * Parse the current token for + quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $result - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for + quantifiers. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $result + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function quantifyPlus(Scope $head, Scope $result, Lexer $lexer) { $min = 1; $max = PHP_INT_MAX; - + $head->setMaxOccurances($max); $head->setMinOccurances($min); - + return $head; } - + /** - * Parse the current token for * quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $result - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for * quantifiers. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $result + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function quantifyStar(Scope $head, Scope $result, Lexer $lexer) { $min = 0; $max = PHP_INT_MAX; - + $head->setMaxOccurances($max); $head->setMinOccurances($min); - + return $head; } - + /** - * Parse the current token for ? quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $result - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for ? quantifiers. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $result + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function quantifyQuestion(Scope $head, Scope $result, Lexer $lexer) { $min = 0; $max = 1; - + $head->setMaxOccurances($max); $head->setMinOccurances($min); - + return $head; } - - + /** - * Parse the current token for closers : {###} { ## } {##,##} - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $result - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for closers : {###} { ## } {##,##}. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $result + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function quantifyClosure(Scope $head, Scope $result, Lexer $lexer) { - $tokens = array(); + $tokens = []; $min = $head->getMinOccurances(); $max = $head->getMaxOccurances(); - - # move to the first token inside the quantifer. - # parse for the minimum , move lookahead until read end of the closure or the `,` - while($lexer->moveNext() === true && !$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE) && $lexer->lookahead['value'] !== ',' ) { - if($lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN)) { + // move to the first token inside the quantifer. + // parse for the minimum , move lookahead until read end of the closure or the `,` + while (true === $lexer->moveNext() && !$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE) && ',' !== $lexer->lookahead['value']) { + if ($lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN)) { throw new ParserException('Nesting Quantifiers is not allowed'); } $tokens[] = $lexer->lookahead; } - + $min = $this->convertInteger($tokens); - - # do we have a maximum after the comma? - if($lexer->lookahead['value'] === ',' ) { - - # make sure we have values to gather ie not {778,} - $tokens = array(); - - # move to the first token after the `,` character - # grab the remaining numbers - while($lexer->moveNext() && !$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE)) { - - if($lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN)) { + + // do we have a maximum after the comma? + if (',' === $lexer->lookahead['value']) { + + // make sure we have values to gather ie not {778,} + $tokens = []; + + // move to the first token after the `,` character + // grab the remaining numbers + while ($lexer->moveNext() && !$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE)) { + if ($lexer->isNextToken(Lexer::T_QUANTIFIER_OPEN)) { throw new ParserException('Nesting Quantifiers is not allowed'); } - + $tokens[] = $lexer->lookahead; } - + $max = $this->convertInteger($tokens); - - } - else { + } else { $max = $min; } - + $head->setMaxOccurances($max); $head->setMinOccurances($min); - - # skip the lexer to the closing token + + // skip the lexer to the closing token $lexer->skipUntil(Lexer::T_QUANTIFIER_CLOSE); - - # check if the last matched token was the closing bracket - # not going to stop errors like {#####,###{[a-z]} {#####{[a-z]} - if(!$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE)) { - throw new ParserException('Closing quantifier token `}` not found'); + + // check if the last matched token was the closing bracket + // not going to stop errors like {#####,###{[a-z]} {#####{[a-z]} + if (!$lexer->isNextToken(Lexer::T_QUANTIFIER_CLOSE)) { + throw new ParserException('Closing quantifier token `}` not found'); } - + return $head; } - - + /** - * Convert a collection of Lexer::T_LITERAL_NUMERIC tokens into integer - * - * @access public - * @return integer the size - * @param array $tokens collection of tokens from lexer - */ + * Convert a collection of Lexer::T_LITERAL_NUMERIC tokens into integer. + * + * @param array $tokens collection of tokens from lexer + * + * @return int the size + */ protected function convertInteger(array $tokens) { - $number_string = array_map(function($item) { return $item['value']; }, $tokens); - $number_string = trim(implode('',$number_string)); - + $number_string = array_map(function ($item) { return $item['value']; }, $tokens); + $number_string = trim(implode('', $number_string)); + $value = preg_match('/^(0|(-{0,1}[1-9]\d*))$/', $number_string); - if ($value == 0) { + if (0 == $value) { throw new ParserException('Quantifier expects and integer compitable string'); } - + return intval($number_string); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Parser/Short.php b/src/ReverseRegex/Parser/Short.php index f83b6c4..7b2be3b 100644 --- a/src/ReverseRegex/Parser/Short.php +++ b/src/ReverseRegex/Parser/Short.php @@ -1,174 +1,163 @@ - * @since 0.0.1 - */ + * Parse a following Shorts (\d, \w, \D, \W, \s, \S, dot). + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Short implements StrategyInterface { - - /** - * Parse the current token for Short Codes `.` `\d` `\w` - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $set - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for Short Codes `.` `\d` `\w`. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $set + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function parse(Scope $head, Scope $set, Lexer $lexer) { - switch(true) { - case ($lexer->isNextToken(Lexer::T_DOT)) : - $this->convertDotToRange($head,$set,$lexer); + switch (true) { + case $lexer->isNextToken(Lexer::T_DOT): + $this->convertDotToRange($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_SHORT_D)) : - case ($lexer->isNextToken(Lexer::T_SHORT_NOT_D)) : - $this->convertDigitToRange($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_SHORT_D): + case $lexer->isNextToken(Lexer::T_SHORT_NOT_D): + $this->convertDigitToRange($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_SHORT_W)) : - case ($lexer->isNextToken(Lexer::T_SHORT_NOT_W)) : - $this->convertWordToRange($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_SHORT_W): + case $lexer->isNextToken(Lexer::T_SHORT_NOT_W): + $this->convertWordToRange($head, $set, $lexer); break; - case ($lexer->isNextToken(Lexer::T_SHORT_S)) : - case ($lexer->isNextToken(Lexer::T_SHORT_NOT_S)) : - $this->convertWhiteSpaceToRange($head,$set,$lexer); + case $lexer->isNextToken(Lexer::T_SHORT_S): + case $lexer->isNextToken(Lexer::T_SHORT_NOT_S): + $this->convertWhiteSpaceToRange($head, $set, $lexer); break; - default : + default: //do nothing no token matches found } - } - - + public function convertDotToRange(Scope $head, Scope $result, Lexer $lexer) { - for($i = 0; $i <= 127; $i++) { + for ($i = 0; $i <= 127; ++$i) { $head->addLiteral(chr($i)); } } - + public function convertDigitToRange(Scope $head, Scope $result, Lexer $lexer) { - if($lexer->isNextToken(Lexer::T_SHORT_D)) { - # digits only (0048 - 0057) digits + if ($lexer->isNextToken(Lexer::T_SHORT_D)) { + // digits only (0048 - 0057) digits $min = 48; $max = 57; - while($min <= $max) { + while ($min <= $max) { $head->addLiteral(chr($min)); - $min++; + ++$min; } - } - else { - - # not digits every assci character expect (0048 - 0057) digits + } else { + + // not digits every assci character expect (0048 - 0057) digits $min = 0; $max = 47; - while($min <= $max) { + while ($min <= $max) { $head->addLiteral(chr($min)); - $min++; + ++$min; } - + $min = 58; $max = 127; - while($min <= $max) { + while ($min <= $max) { $head->addLiteral(chr($min)); - $min++; + ++$min; } - } - } - - + public function convertWordToRange(Scope $head, Scope $result, Lexer $lexer) { - if($lexer->isNextToken(Lexer::T_SHORT_W)) { - # `[a-zA-Z0-9_]` - - # 48 - 57 - for($i = 48; $i <= 57; $i++) { + if ($lexer->isNextToken(Lexer::T_SHORT_W)) { + // `[a-zA-Z0-9_]` + + // 48 - 57 + for ($i = 48; $i <= 57; ++$i) { $head->addLiteral(chr($i)); } - - # 65 - 90 - for($i = 65; $i <= 90; $i++) { + + // 65 - 90 + for ($i = 65; $i <= 90; ++$i) { $head->addLiteral(chr($i)); } - - # 95 + + // 95 $head->addLiteral(chr(95)); - - # 97 - 122 - for($i = 97; $i <= 122; $i++) { + + // 97 - 122 + for ($i = 97; $i <= 122; ++$i) { $head->addLiteral(chr($i)); } - } else { - # `![a-zA-Z0-9_]` - - # 0 - 47 - for($i = 0; $i <= 47; $i++) { + // `![a-zA-Z0-9_]` + + // 0 - 47 + for ($i = 0; $i <= 47; ++$i) { $head->addLiteral(chr($i)); - } - - # 58 - 64 - for($i = 58; $i <= 64; $i++) { + } + + // 58 - 64 + for ($i = 58; $i <= 64; ++$i) { $head->addLiteral(chr($i)); - } - - # 91 - 94 - for($i = 91; $i <= 94; $i++) { + } + + // 91 - 94 + for ($i = 91; $i <= 94; ++$i) { + $head->addLiteral(chr($i)); + } + + // 96 + $head->addLiteral(chr(96)); + + // 123 - 127 + for ($i = 123; $i <= 127; ++$i) { $head->addLiteral(chr($i)); - } - - # 96 - $head->addLiteral(chr(96)); - - # 123 - 127 - for($i = 123; $i <= 127; $i++) { - $head->addLiteral(chr($i)); - } - + } } } - + public function convertWhiteSpaceToRange(Scope $head, Scope $result, Lexer $lexer) { - if($lexer->isNextToken(Lexer::T_SHORT_S)) { - # spaces, tabs, and line breaks - #0009 #0010 #0012 #0013 #0032 - + if ($lexer->isNextToken(Lexer::T_SHORT_S)) { + // spaces, tabs, and line breaks + //0009 #0010 #0012 #0013 #0032 + $head->addLiteral(chr(9)); $head->addLiteral(chr(10)); $head->addLiteral(chr(12)); $head->addLiteral(chr(13)); $head->addLiteral(chr(32)); - } else { - # not spaces, tabs, and line breaks - #0000-0008 #0011 #0014 - #0031 - - for($i=0; $i <= 8; $i++) { + // not spaces, tabs, and line breaks + //0000-0008 #0011 #0014 - #0031 + + for ($i = 0; $i <= 8; ++$i) { $head->addLiteral(chr($i)); } - + $head->addLiteral(chr(11)); - - for($i=14; $i <= 31; $i++) { + + for ($i = 14; $i <= 31; ++$i) { $head->addLiteral(chr($i)); } } } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Parser/StrategyInterface.php b/src/ReverseRegex/Parser/StrategyInterface.php index c778f5c..6e779ca 100644 --- a/src/ReverseRegex/Parser/StrategyInterface.php +++ b/src/ReverseRegex/Parser/StrategyInterface.php @@ -1,29 +1,29 @@ - * @since 0.0.1 - */ + * Interface for all parser strategy object. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ interface StrategyInterface { - /** - * Parse the current token and return a new head - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\Scope $head - * @param ReverseRegex\Generator\Scope $set - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token and return a new head. + * + * @param ReverseRegex\Generator\Scope $head + * @param ReverseRegex\Generator\Scope $set + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function parse(Scope $head, Scope $set, Lexer $lexer); - - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Parser/Unicode.php b/src/ReverseRegex/Parser/Unicode.php index 64bfd89..231e738 100644 --- a/src/ReverseRegex/Parser/Unicode.php +++ b/src/ReverseRegex/Parser/Unicode.php @@ -1,103 +1,104 @@ - * @since 0.0.1 - */ + * Parse a unicode sequence e.g \x54 \X{4444}. + * + * @author Lewis Dyer + * + * @since 0.0.1 + */ class Unicode implements StrategyInterface { - /** - * Parse the current token for new Quantifiers - * - * @access public - * @return ReverseRegex\Generator\Scope a new head - * @param ReverseRegex\Generator\LiteralScope $head - * @param ReverseRegex\Generator\Scope $set - * @param ReverseRegex\Lexer $lexer - */ + * Parse the current token for new Quantifiers. + * + * @param ReverseRegex\Generator\LiteralScope $head + * @param ReverseRegex\Generator\Scope $set + * @param ReverseRegex\Lexer $lexer + * + * @return ReverseRegex\Generator\Scope a new head + */ public function parse(Scope $head, Scope $set, Lexer $lexer) { $character = $this->evaluate($lexer); $head->addLiteral($character); + return $head; } - - + /** - * Parse a reference - */ + * Parse a reference. + */ public function evaluate(Lexer $lexer) { - switch(true) { - case ($lexer->isNextToken(Lexer::T_SHORT_P)) : + switch (true) { + case $lexer->isNextToken(Lexer::T_SHORT_P): throw new ParserException('Property \p (Unicode Property) not supported use \x to specify unicode character or range'); break; - case ($lexer->isNextToken(Lexer::T_SHORT_UNICODE_X)) : - + case $lexer->isNextToken(Lexer::T_SHORT_UNICODE_X): + $lexer->moveNext(); - if($lexer->lookahead['value'] !== '{' ) { - throw new ParserException('Expecting character { after \X none found'); + if ('{' !== $lexer->lookahead['value']) { + throw new ParserException('Expecting character { after \X none found'); } - - $tokens = array(); - while($lexer->moveNext() && $lexer->lookahead !== null && $lexer->lookahead['value'] !== '}') { - - # check if we nested eg.{ddd{d} - if($lexer->lookahead['value'] === '{') { + + $tokens = []; + while ($lexer->moveNext() && null !== $lexer->lookahead && '}' !== $lexer->lookahead['value']) { + + // check if we nested eg.{ddd{d} + if ('{' === $lexer->lookahead['value']) { throw new ParserException('Nesting hex value ranges is not allowed'); } - - if($lexer->lookahead['value'] !== " " && ctype_xdigit($lexer->lookahead['value']) === false) { - throw new ParserException(sprintf('Character %s is not a hexdeciaml digit',$lexer->lookahead['value'])); + + if (' ' !== $lexer->lookahead['value'] && false === ctype_xdigit($lexer->lookahead['value'])) { + throw new ParserException(sprintf('Character %s is not a hexdeciaml digit', $lexer->lookahead['value'])); } - + $tokens[] = $lexer->lookahead['value']; } - # check that current lookahead is a closing character as it's possible to iterate to end of string (i.e. lookahead === null) - if($lexer->lookahead === null || $lexer->lookahead['value'] !== '}') { - throw new ParserException('Closing quantifier token `}` not found'); + // check that current lookahead is a closing character as it's possible to iterate to end of string (i.e. lookahead === null) + if (null === $lexer->lookahead || '}' !== $lexer->lookahead['value']) { + throw new ParserException('Closing quantifier token `}` not found'); } - - if(count($tokens) === 0) { + + if (0 === count($tokens)) { throw new ParserException('No hex number found inside the range'); } - - $number = trim(implode('',$tokens)); - + + $number = trim(implode('', $tokens)); + return mb_chr(hexdec($number)); - + break; - case ($lexer->isNextToken(Lexer::T_SHORT_X)) : + case $lexer->isNextToken(Lexer::T_SHORT_X): // only allow another 2 hex characters $glimpse = $lexer->glimpse(); - if($glimpse['value'] === '{') { + if ('{' === $glimpse['value']) { throw new ParserException('Braces not supported here'); } - - $tokens = array(); + + $tokens = []; $count = 2; - while($count > 0 && $lexer->moveNext()) { + while ($count > 0 && $lexer->moveNext()) { $tokens[] = $lexer->lookahead['value']; --$count; } - - $value = trim(implode('',$tokens)); + + $value = trim(implode('', $tokens)); + return mb_chr(hexdec($value)); break; - default : + default: throw new ParserException('No Unicode expression to evaluate'); } - } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Random/GeneratorFactory.php b/src/ReverseRegex/Random/GeneratorFactory.php index eefd931..caae934 100644 --- a/src/ReverseRegex/Random/GeneratorFactory.php +++ b/src/ReverseRegex/Random/GeneratorFactory.php @@ -1,71 +1,71 @@ - */ -class GeneratorFactory + * Generator Factory. + * + * @author Lewis Dyer + */ +class GeneratorFactory { - - /** - * @var string[] list of Generators - * - * Each Generator must implement the ReverseRegex\RandomInterface - */ - protected static $types = array( - 'srand' => '\\ReverseRegex\\Random\\SrandRandom', - 'mersenne' => '\\ReverseRegex\\Random\\MersenneRandom', - 'simple' => '\\ReverseRegex\\Random\\SimpleRandom', - ); - - public static function registerExtension($index,$namespace) + * @var string[] list of Generators + * + * Each Generator must implement the ReverseRegex\RandomInterface + */ + protected static $types = [ + 'srand' => '\\ReverseRegex\\Random\\SrandRandom', + 'mersenne' => '\\ReverseRegex\\Random\\MersenneRandom', + 'simple' => '\\ReverseRegex\\Random\\SimpleRandom', + ]; + + public static function registerExtension($index, $namespace) { $index = strtolower($index); + return self::$types[$index] = $namespace; } - + public static function registerExtensions(array $extension) { - foreach($extension as $key => $ns) { - self::registerExtension($key,$ns); + foreach ($extension as $key => $ns) { + self::registerExtension($key, $ns); } } - + // ---------------------------------------------------------------------------- - - /** - * Resolve a Dcotrine DataType Class - * - * @param string the random generator type name - * @access public - * @return ReverseRegex\RandomInterface - * @throws PHPStats\Exception - */ - public function create($type,$seed = null) + + /** + * Resolve a Dcotrine DataType Class. + * + * @param string the random generator type name + * + * @throws PHPStats\Exception + * + * @return ReverseRegex\RandomInterface + */ + public function create($type, $seed = null) { $type = strtolower($type); - - # check extension list - - if(isset(self::$types[$type]) === true) { - # assign platform the full namespace - if(class_exists(self::$types[$type]) === false) { - throw new ReverseRegexException('Unknown Generator at::'.$type); + + // check extension list + + if (true === isset(self::$types[$type])) { + // assign platform the full namespace + if (false === class_exists(self::$types[$type])) { + throw new ReverseRegexException('Unknown Generator at::'.$type); } - + $type = self::$types[$type]; - } else { throw new ReverseRegexException('Unknown Generator at::'.$type); } - + return new $type($seed); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Random/GeneratorInterface.php b/src/ReverseRegex/Random/GeneratorInterface.php index 61139a2..8deb827 100644 --- a/src/ReverseRegex/Random/GeneratorInterface.php +++ b/src/ReverseRegex/Random/GeneratorInterface.php @@ -1,39 +1,35 @@ - */ + * Interface that all generators should implement. + */ interface GeneratorInterface extends CommonInterface { - /** - * Generate a value between $min - $max - * - * @param integer $max - * @param integer $max - */ - public function generate($min = 0,$max = null); - + * Generate a value between $min - $max. + * + * @param int $max + * @param int $max + */ + public function generate($min = 0, $max = null); + /** - * Set the seed to use - * - * @param $seed integer the seed to use - * @access public - */ + * Set the seed to use. + * + * @param $seed integer the seed to use + */ public function seed($seed = null); - + /** - * Return the hights possible random value - * - * @access public - * @return double - */ + * Return the hights possible random value. + * + * @return float + */ public function max(); - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Random/MersenneRandom.php b/src/ReverseRegex/Random/MersenneRandom.php index 0293f01..858a31e 100644 --- a/src/ReverseRegex/Random/MersenneRandom.php +++ b/src/ReverseRegex/Random/MersenneRandom.php @@ -1,138 +1,135 @@ - * @link http://boxrefuge.com/?tag=random-number - */ + * Mersenne Twiseter Implementation. + * + * @author Lewis Dyer + * + * @see http://boxrefuge.com/?tag=random-number + */ class MersenneRandom implements GeneratorInterface { /** - * @var integer a seed use count - */ + * @var int a seed use count + */ protected $index; - + /** - * @var integer the seed value to use - */ + * @var int the seed value to use + */ protected $seed; - + /** - * @var integer previous seed value used - */ + * @var int previous seed value used + */ protected $ps; - + /** - * @var integer the max - */ + * @var int the max + */ protected $max; - + /** - * @var integer the min - */ + * @var int the min + */ protected $min; - + public function __construct($seed = null) { - $this->seed($seed); $this->index = -1; $this->ps = null; $this->max = null; $this->min = null; } - - + public function max($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $max = 2147483647; - } - elseif($value === null) { + } elseif (null === $value) { $max = $this->max; - } - else { + } else { $max = $this->max = $value; } - + return $max; } - - + public function min($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $min = 0; - } - elseif($value === null) { + } elseif (null === $value) { $min = $this->min; - } - else { + } else { $min = $this->min = $value; } - + return $min; } - - public function generate($min = 0,$max = null) + + public function generate($min = 0, $max = null) { - if($max === null) { + if (null === $max) { $max = $this->max; } - - if($min === null) { + + if (null === $min) { $min = $this->min; } - - return abs($this->mt(++$this->index,$min,$max)); + + return abs($this->mt(++$this->index, $min, $max)); } - - + public function seed($seed = null) { - if($seed === null){ - $seed = mt_rand(0,PHP_INT_MAX); + if (null === $seed) { + $seed = mt_rand(0, PHP_INT_MAX); } - + $this->seed = $seed; } - + /** - * Mersenne Twister Random Number Generator - * Returns a random number. Depending on the application, you likely don't have to reseed every time as you can simply select a different index - * from the last seed and get a different number. - * - * Note: This has been tweaked for performance. It still generates the same numbers as the original algorithm but it's slightly more complicated - * because it maintains both speed and elegance. Though not a crucial difference under normal use, on 1 million iterations, - * re-seeding each time, it will save 5 minutes of time from the orginal algorithm - at least on my system. - * - * @param $index An index indicating the index of the internal array to select the number to generate the random number from - * @param $min The minimum number to return - * @param $max The maximum number to return - * @return float the random number - * @link http://boxrefuge.com/?tag=random-number - * @author Justin unknown - * - **/ + * Mersenne Twister Random Number Generator + * Returns a random number. Depending on the application, you likely don't have to reseed every time as you can simply select a different index + * from the last seed and get a different number. + * + * Note: This has been tweaked for performance. It still generates the same numbers as the original algorithm but it's slightly more complicated + * because it maintains both speed and elegance. Though not a crucial difference under normal use, on 1 million iterations, + * re-seeding each time, it will save 5 minutes of time from the orginal algorithm - at least on my system. + * + * @param $index An index indicating the index of the internal array to select the number to generate the random number from + * @param $min The minimum number to return + * @param $max The maximum number to return + * + * @return float the random number + * + * @see http://boxrefuge.com/?tag=random-number + * + * @author Justin unknown + * + **/ public function mt($index = null, $min = 0, $max = 1000) { - static $op = array(0x0, 0x9908b0df); // Used for efficiency below to eliminate if statement - static $mt = array(); // 624 element array used to get random numbers - + static $op = [0x0, 0x9908B0DF]; // Used for efficiency below to eliminate if statement + static $mt = []; // 624 element array used to get random numbers + // Regenerate when reseeding or seeding initially - if($this->seed !== $this->ps) - { - $s = $this->seed & 0xffffffff; - $mt = array(&$s, 624 => &$s); + if ($this->seed !== $this->ps) { + $s = $this->seed & 0xFFFFFFFF; + $mt = [&$s, 624 => &$s]; $this->ps = $this->seed; - - for($i = 1; $i < 624; ++$i) - $mt[$i] = (0x6c078965 * ($mt[$i - 1] ^ ($mt[$i - 1] >> 30)) + $i) & 0xffffffff; - + + for ($i = 1; $i < 624; ++$i) { + $mt[$i] = (0x6C078965 * ($mt[$i - 1] ^ ($mt[$i - 1] >> 30)) + $i) & 0xFFFFFFFF; + } + // This has been tweaked for maximum speed and elegance // Explanation of possibly confusing variables: // $p = previous index @@ -140,27 +137,21 @@ public function mt($index = null, $min = 0, $max = 1000) // $n = number to iterate to - we loop up to 227 adding 397 after which we finish looping up to 624 subtracting 227 to continue getting out 397 indices ahead reference // $m = 397 or -227 to add to $i to keep our 397 index difference // $i = the previous element in $sp, our starting index in this iteration - for($j = 1, $sp = array(0, 227, 397); $j < count($sp); ++$j) - { - for($p = $j - 1, $i = $sp[$p], $m = ((624 - $sp[$j]) * ($p ? -1 : 1)), $n = ($sp[$j] + $sp[$p]); $i < $n; ++$i) - { - $y = ($mt[$i] & 0x80000000) | ($mt[$i + 1] & 0x7fffffff); + for ($j = 1, $sp = [0, 227, 397]; $j < count($sp); ++$j) { + for ($p = $j - 1, $i = $sp[$p], $m = ((624 - $sp[$j]) * ($p ? -1 : 1)), $n = ($sp[$j] + $sp[$p]); $i < $n; ++$i) { + $y = ($mt[$i] & 0x80000000) | ($mt[$i + 1] & 0x7FFFFFFF); $mt[$i] = $mt[$i + $m] ^ ($y >> 1) ^ $op[$y & 0x1]; } } } - + // Select a number from the array and randomize it $y = $mt[$this->index = $this->index % 624]; $y ^= $y >> 11; - $y ^= ($y << 7) & 0x9d2c5680; - $y ^= ($y << 15) & 0xefc60000; + $y ^= ($y << 7) & 0x9D2C5680; + $y ^= ($y << 15) & 0xEFC60000; $y ^= $y >> 18; - + return $y % ($max - $min + 1) + $min; } - - - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Random/SimpleRandom.php b/src/ReverseRegex/Random/SimpleRandom.php index b2399cc..58c3363 100644 --- a/src/ReverseRegex/Random/SimpleRandom.php +++ b/src/ReverseRegex/Random/SimpleRandom.php @@ -1,121 +1,115 @@ seed($seed); } - + public function max($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $max = 2147483647; - } - elseif($value === null) { + } elseif (null === $value) { $max = $this->max; - } - else { + } else { $max = $this->max = $value; } - + return $max; } - - + public function min($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $min = 0; - } - elseif($value === null) { + } elseif (null === $value) { $min = $this->min; - } - else { + } else { $min = $this->min = $value; } - + return $min; } - - + /** - * Set the seed to use for generator - * - * @param integer $seed the seed to use - * @access public - */ + * Set the seed to use for generator. + * + * @param int $seed the seed to use + */ public function seed($seed = null) - { - if($seed === null) { + { + if (null === $seed) { $seed = 0; } - - return $this->seed = abs(intval($seed)) % 9999999 + 1; - } - + + return $this->seed = abs(intval($seed)) % 9999999 + 1; + } + /** - * Generate a random numer - * - * @param integer $max - * @param integer $max 2,796,203 largest possible max - */ + * Generate a random numer. + * + * @param int $max + * @param int $max 2,796,203 largest possible max + */ public function generate($min = 0, $max = null) - { - if($max === null) { + { + if (null === $max) { $max = 2796203; } - - if($max > 2796203) { + + if ($max > 2796203) { throw new ReverseRegexException('Max param has exceeded the maxium 2796203'); } - - if ($this->seed == 0) { + + if (0 == $this->seed) { $this->seed(mt_rand()); } - - $this->seed = ($this->seed * 125) % 2796203; - - - return $this->seed % ($max - $min + 1) + $min; - } - + + $this->seed = ($this->seed * 125) % 2796203; + + return $this->seed % ($max - $min + 1) + $min; + } } /* End of File */ diff --git a/src/ReverseRegex/Random/SrandRandom.php b/src/ReverseRegex/Random/SrandRandom.php index 3287011..d9462d6 100644 --- a/src/ReverseRegex/Random/SrandRandom.php +++ b/src/ReverseRegex/Random/SrandRandom.php @@ -1,7 +1,8 @@ - * + * */ class SrandRandom implements GeneratorInterface { - /** - * @var integer the seed to use on each pass - */ + * @var int the seed to use on each pass + */ protected $seed; - - - /** - * @var integer the max - */ + + /** + * @var int the max + */ protected $max; - + /** - * @var integer the min - */ + * @var int the min + */ protected $min; - - + /* * __construct() * @@ -45,77 +43,67 @@ public function __construct($seed = 0) { $this->seed($seed); } - + /** - * Return the maxium random number - * - * @access public - * @return double - */ + * Return the maxium random number. + * + * @return float + */ public function max($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $max = getrandmax(); - } - elseif($value === null) { + } elseif (null === $value) { $max = $this->max; - } - else { + } else { $max = $this->max = $value; } - + return $max; } - - + public function min($value = null) { - if($value === null && $this->max === null) { + if (null === $value && null === $this->max) { $min = 0; - } - elseif($value === null) { + } elseif (null === $value) { $min = $this->min; - } - else { + } else { $min = $this->min = $value; } - + return $min; } - + /** - * Generate a value between $min - $max - * - * @param integer $max - * @param integer $max - */ - public function generate($min = 0,$max = null) + * Generate a value between $min - $max. + * + * @param int $max + * @param int $max + */ + public function generate($min = 0, $max = null) { - if($max === null) { + if (null === $max) { $max = $this->max; } - - if($min === null) { + + if (null === $min) { $min = $this->min; } - - - return rand($min,$max); + + return rand($min, $max); } - + /** - * Set the seed to use - * - * @param $seed integer the seed to use - * @access public - */ + * Set the seed to use. + * + * @param $seed integer the seed to use + */ public function seed($seed = null) { $this->seed = $seed; srand($this->seed); - + return $this; } - } -/* End of File */ diff --git a/src/ReverseRegex/Test/Basic.php b/src/ReverseRegex/Test/Basic.php index f1545f8..fba9486 100644 --- a/src/ReverseRegex/Test/Basic.php +++ b/src/ReverseRegex/Test/Basic.php @@ -1,18 +1,20 @@ boot(new Pimple()); + $boot = new PimpleBootstrap(); + $pimple = $boot->boot(new Pimple()); + return $pimple; } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/CharacterClassTest.php b/src/ReverseRegex/Test/CharacterClassTest.php index 23b22c4..497e3ec 100644 --- a/src/ReverseRegex/Test/CharacterClassTest.php +++ b/src/ReverseRegex/Test/CharacterClassTest.php @@ -1,224 +1,192 @@ moveNext(); - $result = $parser->normalize($scope,$scope,$lexer); - - $this->assertEquals('[a-mnop]',$result); - + $result = $parser->normalize($scope, $scope, $lexer); + + $this->assertEquals('[a-mnop]', $result); } - + public function testNormalizeWithUnicodeValue() { - $lexer = new Lexer('[\X{00ff}nop]'); $scope = new Scope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $result = $parser->normalize($scope,$scope,$lexer); - - $this->assertEquals('[\\ÿnop]',$result); - + $result = $parser->normalize($scope, $scope, $lexer); + + $this->assertEquals('[\\ÿnop]', $result); } - + public function testNormalizeWithUnicodeRange() { - $lexer = new Lexer('[\X{00FF}-\X{00FF}mnop]'); $scope = new Scope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $result = $parser->normalize($scope,$scope,$lexer); - - $this->assertEquals('[\\ÿ-\\ÿmnop]',$result); - + $result = $parser->normalize($scope, $scope, $lexer); + + $this->assertEquals('[\\ÿ-\\ÿmnop]', $result); } - - + public function testFillRangeAscii() { $start = '!'; - $end = '&'; + $end = '&'; $range = '!"#$%&'; $scope = new LiteralScope(); $parser = new CharacterClass(); - - $parser->fillRange($scope,$start,$end); - - $this->assertEquals($range,implode('',$scope->getLiterals()->toArray())); + + $parser->fillRange($scope, $start, $end); + + $this->assertEquals($range, implode('', $scope->getLiterals()->toArray())); } - + public function testFillRangeUnicode() { - $start = 'Ꭰ'; - $end = 'Ꭵ'; + $start = 'Ꭰ'; + $end = 'Ꭵ'; $range = 'ᎠᎡᎢᎣᎤᎥ'; $scope = new LiteralScope(); $parser = new CharacterClass(); - - $parser->fillRange($scope,$start,$end); - - $this->assertEquals($range,implode('',$scope->getLiterals()->toArray())); - + + $parser->fillRange($scope, $start, $end); + + $this->assertEquals($range, implode('', $scope->getLiterals()->toArray())); } - - + public function testFillRangeOutofOrder() { $start = 'z'; - $end = 'a'; + $end = 'a'; $scope = new LiteralScope(); $parser = new CharacterClass(); $this->expectException(RegexException::class); $this->expectExceptionMessage('Character class range z - a is out of order'); - - $parser->fillRange($scope,$start,$end); - + + $parser->fillRange($scope, $start, $end); } - - - + public function testParseNoRanges() { - $lexer = new Lexer('[amnop]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->toArray(); - - $this->assertEquals(array('a','m','n','o','p'),array_values($values)); + + $this->assertEquals(['a', 'm', 'n', 'o', 'p'], array_values($values)); } - - + public function testParseNoUnicodeShorts() { $lexer = new Lexer('[a-k]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->toArray(); - - $this->assertEquals(array('a','b','c','d','e','f','g','h','i','j','k'),array_values($values)); - + + $this->assertEquals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], array_values($values)); } - + public function testParseNoUnicodeShortsMultiRange() { $lexer = new Lexer('[a-k-n]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->toArray(); - - $this->assertEquals(array('a','b','c','d','e','f','g','h','i','j','k','l','m','n'),array_values($values)); - + + $this->assertEquals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'], array_values($values)); } - + public function testParseUnicodeShort() { $lexer = new Lexer('[\X{0061}-\X{006B}]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->toArray(); - - $this->assertEquals(array('a','b','c','d','e','f','g','h','i','j','k'),array_values($values)); + + $this->assertEquals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], array_values($values)); } - + public function testParseHexShort() { $lexer = new Lexer('[\x61-\x6B]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->toArray(); - - $this->assertEquals(array('a','b','c','d','e','f','g','h','i','j','k'),array_values($values)); - - + + $this->assertEquals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], array_values($values)); } - + public function testParseHexShortMultirange() { - $lexer = new Lexer('[z\x61-\x6B-\x6E]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - - + $parser->parse($head, $scope, $lexer); + $values = $head->getLiterals()->getValues(); - $this->assertEquals(array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','z'),$values); - + $this->assertEquals(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'z'], $values); } - - + public function testParseHexShortBraceError() { $lexer = new Lexer('[\x{61}-\x6B-\x6E]'); $scope = new Scope(); - $head = new LiteralScope(); + $head = new LiteralScope(); $parser = new CharacterClass(); - + $this->expectException(RegexException::class); $this->expectExceptionMessage('Braces not supported here'); - + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/LexerTest.php b/src/ReverseRegex/Test/LexerTest.php index 655847a..6649160 100644 --- a/src/ReverseRegex/Test/LexerTest.php +++ b/src/ReverseRegex/Test/LexerTest.php @@ -1,4 +1,7 @@ assertInstanceOf('\Doctrine\Common\Lexer\AbstractLexer',$lexer); - + $this->assertInstanceOf('\Doctrine\Common\Lexer\AbstractLexer', $lexer); } - + public function testLexerPatternA() { $lexer = new Lexer('[a-z]'); - - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('a',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('a', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('-',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_RANGE,$lexer->lookahead['type']); - + $this->assertEquals('-', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_RANGE, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('z',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('z', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); + //$lexer->moveNext(); //$this->assertEquals(null,$lexer->lookahead['value']); - } - - + public function testLexerPatternB() { $lexer = new Lexer('\[a-z\]'); - - + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('a',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('a', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('-',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('-', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('z',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('z', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + //$lexer->moveNext(); //$this->assertEquals(null,$lexer->lookahead['value']); - } - + public function testLexerPatternC() { $lexer = new Lexer('[1-9]'); - - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('1',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('1', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('-',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_RANGE,$lexer->lookahead['type']); - + $this->assertEquals('-', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_RANGE, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('9',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('9', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); + //$lexer->moveNext(); //$this->assertEquals(null,$lexer->lookahead['value']); - } - + public function testLexerPatternD() { $lexer = new Lexer('[1-9\x{56}]'); - - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('1',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('1', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('-',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_RANGE,$lexer->lookahead['type']); - + $this->assertEquals('-', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_RANGE, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('9',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('9', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('x',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_X,$lexer->lookahead['type']); - + $this->assertEquals('x', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_X, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('{',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('5',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('5', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('6',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('6', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('}',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); + //$lexer->moveNext(); //$this->assertEquals(null,$lexer->lookahead['value']); - } - - + public function testLexerPatternE() { $lexer = new Lexer('([^1-8\[]){0,9}*?+'); - - $lexer->moveNext(); - $this->assertEquals('(',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_OPEN,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('^',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_NEGATED,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('1',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('-',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_RANGE,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('8',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals(')',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_CLOSE,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('{',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_OPEN,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('0',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals(',',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('9',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('}',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_CLOSE,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('*',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_STAR,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('?',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_QUESTION,$lexer->lookahead['type']); - - $lexer->moveNext(); - $this->assertEquals('+',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_PLUS,$lexer->lookahead['type']); - + + $lexer->moveNext(); + $this->assertEquals('(', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_OPEN, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('^', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_NEGATED, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('1', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('-', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_RANGE, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('8', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals(')', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_CLOSE, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_OPEN, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('0', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals(',', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('9', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_CLOSE, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('*', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_STAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('?', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_QUESTION, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('+', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_PLUS, $lexer->lookahead['type']); + //$lexer->moveNext(); //$this->assertEquals(null,$lexer->lookahead['value']); - } - - + public function testParrentShortCodes() { $lexer = new Lexer('\W'); - + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('W',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_NOT_W,$lexer->lookahead['type']); - + $this->assertEquals('W', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_NOT_W, $lexer->lookahead['type']); + $lexer = new Lexer('\w'); - + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('w',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_W,$lexer->lookahead['type']); - + $this->assertEquals('w', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_W, $lexer->lookahead['type']); + $lexer = new Lexer('\S'); - - $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - - $lexer->moveNext(); - $this->assertEquals('S',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_NOT_S,$lexer->lookahead['type']); - - $lexer = new Lexer('\s'); - - $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - - $lexer->moveNext(); - $this->assertEquals('s',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_S,$lexer->lookahead['type']); - + + $lexer->moveNext(); + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('S', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_NOT_S, $lexer->lookahead['type']); + + $lexer = new Lexer('\s'); + + $lexer->moveNext(); + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('s', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_S, $lexer->lookahead['type']); + $lexer = new Lexer('\D'); - - $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - - $lexer->moveNext(); - $this->assertEquals('D',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_NOT_D,$lexer->lookahead['type']); - - $lexer = new Lexer('\d'); - - $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - - - $lexer->moveNext(); - $this->assertEquals('d',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_D,$lexer->lookahead['type']); - - - + + $lexer->moveNext(); + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('D', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_NOT_D, $lexer->lookahead['type']); + + $lexer = new Lexer('\d'); + + $lexer->moveNext(); + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + + $lexer->moveNext(); + $this->assertEquals('d', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_D, $lexer->lookahead['type']); } - + public function testLexerPatternF() { $lexer = new Lexer('[\']'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - - # in the above expression using php metasequence \' to escape a single quote - # the reg only see the expression ['] and NOT [\'] + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + + // in the above expression using php metasequence \' to escape a single quote + // the reg only see the expression ['] and NOT [\'] $lexer->moveNext(); - $this->assertEquals("'",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals("'", $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - - + public function testLexerEscapedBlackslash() { $lexer = new Lexer('\\\\'); - + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); } - - + public function testLexerBrackets() { $lexer = new Lexer('[\p{}]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("\\",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("p",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_P,$lexer->lookahead['type']); - + $this->assertEquals('p', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_P, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("{",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("}",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); + $lexer = new Lexer('\p{}'); - + $lexer->moveNext(); - $this->assertEquals("\\",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("p",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_P,$lexer->lookahead['type']); - + $this->assertEquals('p', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_P, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("{",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals("}",$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_QUANTIFIER_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_QUANTIFIER_CLOSE, $lexer->lookahead['type']); } - - + public function testAlternation() { $lexer = new Lexer('A|a'); - + $lexer->moveNext(); - $this->assertEquals('A',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('A', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('|',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_CHOICE_BAR,$lexer->lookahead['type']); - + $this->assertEquals('|', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_CHOICE_BAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('a',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - # no alternation in char classes - + $this->assertEquals('a', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + + // no alternation in char classes + $lexer = new Lexer('[A|a]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('A',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('A', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('|',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('|', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('a',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('a', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - - + public function testDotCharacter() { - $lexer = new Lexer('.'); - + $lexer->moveNext(); - $this->assertEquals('.',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_DOT,$lexer->lookahead['type']); - + $this->assertEquals('.', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_DOT, $lexer->lookahead['type']); + $lexer = new Lexer('\.'); - + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('.',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - # normal char in a char class + $this->assertEquals('.', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + + // normal char in a char class $lexer = new Lexer('[.]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('.',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('.', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - + public function testLexerPatternG() { $lexer = new Lexer('abcd&\*\(\)'); - + $lexer->moveNext(); - $this->assertEquals('a',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('a', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('b',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('b', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('c',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('c', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('d',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('d', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('&',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('&', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('*',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('*', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('(',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('(', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(')',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); + $this->assertEquals(')', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); } - - + public function testUnicodePropertyinCharacterClass() { $lexer = new Lexer('[np\p{L}]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); $lexer->moveNext(); - $this->assertEquals('n',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('n', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('p',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('p', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('p',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_P,$lexer->lookahead['type']); - + $this->assertEquals('p', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_P, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('{',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('L',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('L', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('}',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - - + public function testUnicodeReferencePropertyinCharacterClass() { - $lexer = new Lexer('[no\X{00FF}]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); $lexer->moveNext(); - $this->assertEquals('n',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('n', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('o',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('o', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('X',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SHORT_UNICODE_X,$lexer->lookahead['type']); - + $this->assertEquals('X', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SHORT_UNICODE_X, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('{',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('{', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('0',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('0', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('0',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_NUMERIC,$lexer->lookahead['type']); - + $this->assertEquals('0', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_NUMERIC, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('F',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('F', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('F',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('F', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('}',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - - + $this->assertEquals('}', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - - + public function testCarretAndDollar() { $lexer = new Lexer('^$'); - + $lexer->moveNext(); - $this->assertEquals('^',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_START_CARET,$lexer->lookahead['type']); - + $this->assertEquals('^', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_START_CARET, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('$',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_END_DOLLAR,$lexer->lookahead['type']); - + $this->assertEquals('$', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_END_DOLLAR, $lexer->lookahead['type']); + $lexer = new Lexer('[\^$]'); - + $lexer->moveNext(); - $this->assertEquals('[',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('[', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('\\',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_ESCAPE_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('\\', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_ESCAPE_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('^',$lexer->lookahead['value']); + $this->assertEquals('^', $lexer->lookahead['value']); $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); - + $lexer->moveNext(); - $this->assertEquals('$',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_LITERAL_CHAR,$lexer->lookahead['type']); - + $this->assertEquals('$', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_LITERAL_CHAR, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(']',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_SET_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(']', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_SET_CLOSE, $lexer->lookahead['type']); } - + public function testLexerPatternHGroupNesting() { $lexer = new Lexer('(())'); - + $lexer->moveNext(); - $this->assertEquals('(',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('(', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals('(',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_OPEN,$lexer->lookahead['type']); - + $this->assertEquals('(', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_OPEN, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(')',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(')', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_CLOSE, $lexer->lookahead['type']); + $lexer->moveNext(); - $this->assertEquals(')',$lexer->lookahead['value']); - $this->assertEquals(Lexer::T_GROUP_CLOSE,$lexer->lookahead['type']); - + $this->assertEquals(')', $lexer->lookahead['value']); + $this->assertEquals(Lexer::T_GROUP_CLOSE, $lexer->lookahead['type']); } - - + public function testGroupNestingErrorStillOpen() { - $this->expectException(RegexException::class); + $this->expectException(RegexException::class); $this->expectExceptionMessage('Opening group char "(" has no matching closing character'); $lexer = new Lexer('(()'); - } - - + public function testGroupNestingErrorClosedNotOpened() { - $this->expectException(RegexException::class); + $this->expectException(RegexException::class); $this->expectExceptionMessage('Closing group char "(" has no matching opening character'); - $lexer = new Lexer('())'); - } - - + public function testCharSetNestingError() { - $this->expectException(RegexException::class); + $this->expectException(RegexException::class); $this->expectExceptionMessage("Can't have a second character class while first remains open"); $lexer = new Lexer('[[]]'); } - - + public function testCharSetOpenError() { - $this->expectException(RegexException::class); + $this->expectException(RegexException::class); $this->expectExceptionMessage("Can't close a character class while none is open"); - $lexer = new Lexer(']'); } - - + public function testCharSetOpenNotClosed() { - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Character Class that been closed"); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Character Class that been closed'); - $lexer = new Lexer('['); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/LiteralScopeTest.php b/src/ReverseRegex/Test/LiteralScopeTest.php index 9ff4c40..c2c795e 100644 --- a/src/ReverseRegex/Test/LiteralScopeTest.php +++ b/src/ReverseRegex/Test/LiteralScopeTest.php @@ -1,58 +1,54 @@ assertInstanceOf('ReverseRegex\Generator\Scope',$literal); + $literal = new LiteralScope('scope1'); + $this->assertInstanceOf('ReverseRegex\Generator\Scope', $literal); } - public function testAddLiteral() { $literal = new LiteralScope('scope1'); - + $literal->addLiteral('a'); $literal->addLiteral('b'); $literal->addLiteral('c'); - + $collection = $literal->getLiterals(); - - $this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection',$collection); - - $this->assertEquals('a',$collection->get(0)); - $this->assertEquals('b',$collection->get(1)); - $this->assertEquals('c',$collection->get(2)); - + + $this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $collection); + + $this->assertEquals('a', $collection->get(0)); + $this->assertEquals('b', $collection->get(1)); + $this->assertEquals('c', $collection->get(2)); } - public function testGenerateNoRepeats() { $literal = new LiteralScope('scope1'); $literal->addLiteral('a'); $literal->setMinOccurances(1); $literal->setMaxOccurances(1); - - $generator_mock = $this->createMock('ReverseRegex\Random\GeneratorInterface', array('generate','seed','max')); - + + $generator_mock = $this->createMock('ReverseRegex\Random\GeneratorInterface', ['generate', 'seed', 'max']); + $generator_mock->expects($this->exactly(0)) ->method('generate'); - + $result = ''; - $literal->generate($result,$generator_mock); - - $this->assertEquals('a',$result); + $literal->generate($result, $generator_mock); + + $this->assertEquals('a', $result); } - - + public function testGenerateRepeatsTwice() { $literal = new LiteralScope('scope1'); @@ -60,40 +56,37 @@ public function testGenerateRepeatsTwice() $literal->addLiteral('b'); $literal->setMinOccurances(2); $literal->setMaxOccurances(2); - - $generator_mock = $this->createMock('ReverseRegex\Random\GeneratorInterface', array('generate','seed','max')); - + + $generator_mock = $this->createMock('ReverseRegex\Random\GeneratorInterface', ['generate', 'seed', 'max']); + $generator_mock->expects($this->exactly(2)) ->method('generate') - ->with($this->equalTo(1),$this->equalTo(2)) + ->with($this->equalTo(1), $this->equalTo(2)) ->will($this->returnValue(0)); - + $result = ''; - - $literal->generate($result,$generator_mock); - - $this->assertEquals('aa',$result); + + $literal->generate($result, $generator_mock); + + $this->assertEquals('aa', $result); } - - + public function testGenerateWithSmallRange() { $literal = new LiteralScope('scope1'); $literal->addLiteral('a'); $literal->setMinOccurances(1); $literal->setMaxOccurances(2); - + $gen = new \ReverseRegex\Random\SrandRandom(0); - + $result = ''; - $literal->generate($result,$gen); - + $literal->generate($result, $gen); + $this->assertLessThanOrEqual(2, strlen($result)); $this->assertGreaterThanOrEqual(1, strlen($result)); - } - - + public function testGenerateWithMulipleLiterals() { $literal = new LiteralScope('scope1'); @@ -101,33 +94,31 @@ public function testGenerateWithMulipleLiterals() $literal->addLiteral('b'); $literal->addLiteral('c'); $literal->addLiteral('d'); - + $literal->setMinOccurances(1); $literal->setMaxOccurances(4); - + $gen = new \ReverseRegex\Random\SrandRandom(0); - - $result = ''; - $literal->generate($result,$gen); + + $result = ''; + $literal->generate($result, $gen); $this->assertLessThanOrEqual(4, strlen($result)); $this->assertGreaterThanOrEqual(1, strlen($result)); } - + public function testSetLiteral() { $literal = new LiteralScope('scope1'); - $literal->setLiteral('0001','a'); - $literal->setLiteral('0002','b'); - $literal->setLiteral('0003','c'); - $literal->setLiteral('0004','d'); - + $literal->setLiteral('0001', 'a'); + $literal->setLiteral('0002', 'b'); + $literal->setLiteral('0003', 'c'); + $literal->setLiteral('0004', 'd'); + $result = $literal->getLiterals()->toArray(); - - $this->assertArrayHasKey('0001',$result); - $this->assertArrayHasKey('0002',$result); - $this->assertArrayHasKey('0003',$result); - $this->assertArrayHasKey('0004',$result); + + $this->assertArrayHasKey('0001', $result); + $this->assertArrayHasKey('0002', $result); + $this->assertArrayHasKey('0003', $result); + $this->assertArrayHasKey('0004', $result); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/ParserTest.php b/src/ReverseRegex/Test/ParserTest.php index 2c528ea..5243420 100644 --- a/src/ReverseRegex/Test/ParserTest.php +++ b/src/ReverseRegex/Test/ParserTest.php @@ -1,269 +1,243 @@ parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - $generator->generate($result,$random); - - $this->assertEquals('ex11111',$result); - + $generator->generate($result, $random); + + $this->assertEquals('ex11111', $result); } - - + public function testParserExampleB() { //$lexer = new Lexer('\(0[23478]\)-[0-9]{4} [0-9]{4}'); - + $lexer = new Lexer('(\(0[23478]\)){4}'); - + $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - $generator->generate($result,$random); - - $this->assertEquals('(02)(04)(02)(08)',$result); - + $generator->generate($result, $random); + + $this->assertEquals('(02)(04)(02)(08)', $result); } - + public function testExampleC() { $lexer = new Lexer('509[0-9][A-K]'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - - $generator->generate($result,$random); - $this->assertEquals('5090J',$result); - + + $generator->generate($result, $random); + $this->assertEquals('5090J', $result); } - - + public function testExampleD() { $lexer = new Lexer('\d\d\d'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/\d\d\d/',$result); - + + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/\d\d\d/', $result); } - + public function testExampleE() { $lexer = new Lexer('\d\d\d([a-zA-Z])\w.'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(10034343); - - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/\d\d\d([a-zA-Z])\w./',$result); - + + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/\d\d\d([a-zA-Z])\w./', $result); } - + public function testParserExamplePhoneNumber() { $lexer = new Lexer('\(0[23478]\)[0-9]{4}-[0-9]{4}'); - + $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - $generator->generate($result,$random); - - $this->assertEquals('(02)2595-1288',$result); - - + $generator->generate($result, $random); + + $this->assertEquals('(02)2595-1288', $result); } - - + public function testParserExamplePostCode() { - # Australian Post Codes. - - # ACT: 0200-0299 and 2600-2639. - # NSW: 1000-1999, 2000-2599 and 2640-2914. - # NT: 0900-0999 and 0800-0899. - # QLD: 9000-9999 and 4000-4999. - # SA: 5000-5999. - # TAS: 7800-7999 and 7000-7499. - # VIC: 8000-8999 and 3000-3999. - # WA: 6800-6999 and 6000-6799 - - - $lexer = new Lexer("(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})"); + // Australian Post Codes. + + // ACT: 0200-0299 and 2600-2639. + // NSW: 1000-1999, 2000-2599 and 2640-2914. + // NT: 0900-0999 and 0800-0899. + // QLD: 9000-9999 and 4000-4999. + // SA: 5000-5999. + // TAS: 7800-7999 and 7000-7499. + // VIC: 8000-8999 and 3000-3999. + // WA: 6800-6999 and 6000-6799 + + $lexer = new Lexer('(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - + $random = new MersenneRandom(10789); - - for($i = 100; $i > 0; $i--) { - $result =''; - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$/',$result); + + for ($i = 100; $i > 0; --$i) { + $result = ''; + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$/', $result); } - - # Generate Postcode for ACT only - + + // Generate Postcode for ACT only + $lexer = new Lexer('02[0-9]{2}|26[0-3][0-9]'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - - $result =''; + + $result = ''; $random = new MersenneRandom(100); - - $generator->generate($result,$random); - $this->assertEquals('0225',$result); - - $result =''; - $generator->generate($result,$random); - $this->assertEquals('2631',$result); - - $result =''; - $generator->generate($result,$random); - $this->assertEquals('0288',$result); - - $result =''; - $generator->generate($result,$random); - $this->assertEquals('0243',$result); - - $result =''; - $generator->generate($result,$random); - $this->assertEquals('0284',$result); - - $result =''; - $generator->generate($result,$random); - $this->assertEquals('0210',$result); + + $generator->generate($result, $random); + $this->assertEquals('0225', $result); + + $result = ''; + $generator->generate($result, $random); + $this->assertEquals('2631', $result); + + $result = ''; + $generator->generate($result, $random); + $this->assertEquals('0288', $result); + + $result = ''; + $generator->generate($result, $random); + $this->assertEquals('0243', $result); + + $result = ''; + $generator->generate($result, $random); + $this->assertEquals('0284', $result); + + $result = ''; + $generator->generate($result, $random); + $this->assertEquals('0210', $result); } - - - + public function testHellowWorld() { - $lexer = new Lexer("Hello|World|Is|Good"); + $lexer = new Lexer('Hello|World|Is|Good'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - + $random = new MersenneRandom(10789); - - for($i = 10; $i > 0; $i--) { - $result =''; - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/^Hello|World|Is|Good$/',$result); + + for ($i = 10; $i > 0; --$i) { + $result = ''; + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/^Hello|World|Is|Good$/', $result); } - } - - + public function testLimitingQuantifer() { - - $lexer = new Lexer("(Hello){5,9}"); + $lexer = new Lexer('(Hello){5,9}'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - + $random = new MersenneRandom(10789); - - for($i = 10; $i > 0; $i--) { - $result =''; - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/(Hello){5,9}/',$result); + + for ($i = 10; $i > 0; --$i) { + $result = ''; + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/(Hello){5,9}/', $result); } - - $lexer = new Lexer("(Hello)?"); + + $lexer = new Lexer('(Hello)?'); $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - + $random = new MersenneRandom(107559); - - - $result =''; - $generator->generate($result,$random); - $this->assertMatchesRegularExpression('/(Hello)?/',$result); - - + + $result = ''; + $generator->generate($result, $random); + $this->assertMatchesRegularExpression('/(Hello)?/', $result); } - - + public function testParserLexerError() { - $this->expectException(RegexException::class); + $this->expectException(RegexException::class); $this->expectExceptionMessage("Error found STARTING at position 3 after `\(0[` with msg Negated Character Set ranges not supported at this time"); - $lexer = new Lexer('\(0[^23478]\)[0-9]{4}-[0-9]{4}'); - + $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); + $parser = new Parser($lexer, $container, $head); $generator = $parser->parse()->getResult(); - } - - + public function testParserLexerErrorB() { - $lexer = new Lexer('\(0[23478]\)[9-4]{4}-[0-9]{4}'); - + $container = new Scope(); $head = new Scope(); - $parser = new Parser($lexer,$container,$head); - - $this->expectException(RegexException::class); + $parser = new Parser($lexer, $container, $head); + + $this->expectException(RegexException::class); $this->expectExceptionMessage("Error found STARTING at position 16 after `\(0[23478]\)[9-4]` with msg Character class range 9 - 4 is out of order"); - - + $generator = $parser->parse()->getResult(); - } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/QuantifierParserTest.php b/src/ReverseRegex/Test/QuantifierParserTest.php index c8254c3..b10849d 100644 --- a/src/ReverseRegex/Test/QuantifierParserTest.php +++ b/src/ReverseRegex/Test/QuantifierParserTest.php @@ -1,211 +1,179 @@ moveNext(); - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(1,$scope->getMinOccurances()); - $this->assertEquals(5,$scope->getMaxOccurances()); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + + $lexer->moveNext(); + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(1, $scope->getMinOccurances()); + $this->assertEquals(5, $scope->getMaxOccurances()); } - - + public function testQuantiferSingleValue() { - $pattern = '{5}'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - - - $lexer->moveNext(); - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(5,$scope->getMinOccurances()); - $this->assertEquals(5,$scope->getMaxOccurances()); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + + $lexer->moveNext(); + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(5, $scope->getMinOccurances()); + $this->assertEquals(5, $scope->getMaxOccurances()); } - + public function testQuantiferSpacesIncluded() { - $pattern = '{ 1 , 5 }'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - - - $lexer->moveNext(); - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(1,$scope->getMinOccurances()); - $this->assertEquals(5,$scope->getMaxOccurances()); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + + $lexer->moveNext(); + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(1, $scope->getMinOccurances()); + $this->assertEquals(5, $scope->getMaxOccurances()); } - + public function testFailerAlphaCaracters() { $pattern = '{ 1 , 5a }'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + $lexer->moveNext(); - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Quantifier expects and integer compitable string"); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Quantifier expects and integer compitable string'); - - $qual->parse($scope,$scope,$lexer); - + $qual->parse($scope, $scope, $lexer); } - - + public function testFailerMissingMaximumCaracters() { $pattern = '{ 1 ,}'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + $lexer->moveNext(); - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Quantifier expects and integer compitable string"); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Quantifier expects and integer compitable string'); - - $qual->parse($scope,$scope,$lexer); - + $qual->parse($scope, $scope, $lexer); } - public function testFailerMissingMinimumCaracters() { $pattern = '{,1}'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - - $lexer->moveNext(); + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Quantifier expects and integer compitable string"); + $lexer->moveNext(); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Quantifier expects and integer compitable string'); - $qual->parse($scope,$scope,$lexer); - + $qual->parse($scope, $scope, $lexer); } - - + public function testMissingClosureCharacter() { $pattern = '{1,1'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - - $lexer->moveNext(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Closing quantifier token `}` not found"); + $lexer->moveNext(); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Closing quantifier token `}` not found'); - $qual->parse($scope,$scope,$lexer); - + $qual->parse($scope, $scope, $lexer); } - - - + public function testNestingQuantifiers() { $pattern = '{1,1{1,1}'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - - $lexer->moveNext(); + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); - $this->expectException(RegexException::class); - $this->expectExceptionMessage("Nesting Quantifiers is not allowed"); + $lexer->moveNext(); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('Nesting Quantifiers is not allowed'); - $qual->parse($scope,$scope,$lexer); - + $qual->parse($scope, $scope, $lexer); } - - + public function testStarQuantifier() { $pattern = 'az*'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + $lexer->moveNext(); $lexer->moveNext(); $lexer->moveNext(); - - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(0,$scope->getMinOccurances()); - $this->assertEquals(PHP_INT_MAX,$scope->getMaxOccurances()); - + + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(0, $scope->getMinOccurances()); + $this->assertEquals(PHP_INT_MAX, $scope->getMaxOccurances()); } - - + public function testCrossQuantifier() { $pattern = 'az+'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + $lexer->moveNext(); $lexer->moveNext(); $lexer->moveNext(); - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(1,$scope->getMinOccurances()); - $this->assertEquals(PHP_INT_MAX,$scope->getMaxOccurances()); - + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(1, $scope->getMinOccurances()); + $this->assertEquals(PHP_INT_MAX, $scope->getMaxOccurances()); } - + public function testQuestionQuantifier() { $pattern = 'az?'; - $lexer = new Lexer($pattern); - $scope = new Scope(); - $qual = new Quantifier(); - + $lexer = new Lexer($pattern); + $scope = new Scope(); + $qual = new Quantifier(); + $lexer->moveNext(); $lexer->moveNext(); $lexer->moveNext(); - $qual->parse($scope,$scope,$lexer); - - $this->assertEquals(0,$scope->getMinOccurances()); - $this->assertEquals(1,$scope->getMaxOccurances()); - + $qual->parse($scope, $scope, $lexer); + + $this->assertEquals(0, $scope->getMinOccurances()); + $this->assertEquals(1, $scope->getMaxOccurances()); } - - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/ScopeTest.php b/src/ReverseRegex/Test/ScopeTest.php index a8ca6ec..704330d 100644 --- a/src/ReverseRegex/Test/ScopeTest.php +++ b/src/ReverseRegex/Test/ScopeTest.php @@ -1,181 +1,164 @@ assertInstanceOf('ReverseRegex\Generator\RepeatInterface',$scope); + $this->assertInstanceOf('ReverseRegex\Generator\RepeatInterface', $scope); } - + public function testScopeImplementsContextInterface() { $scope = new Scope('scope1'); - $this->assertInstanceOf('ReverseRegex\Generator\ContextInterface',$scope); + $this->assertInstanceOf('ReverseRegex\Generator\ContextInterface', $scope); } - + public function testScopeExtendsNode() { $scope = new Scope('scope1'); - $this->assertInstanceOf('ReverseRegex\Generator\Node',$scope); + $this->assertInstanceOf('ReverseRegex\Generator\Node', $scope); } - + public function testScopeImplementsAlternateInterface() { $scope = new Scope('scope1'); - $this->assertInstanceOf('ReverseRegex\Generator\AlternateInterface',$scope); + $this->assertInstanceOf('ReverseRegex\Generator\AlternateInterface', $scope); } - public function testAlternateInterface() { $scope = new Scope('scope1'); $this->assertFalse($scope->usingAlternatingStrategy()); - + $scope->useAlternatingStrategy(true); $this->assertTrue($scope->usingAlternatingStrategy()); } - - + public function testRepeatInterface() { - $scope = new Scope('scope1'); - + $scope = new Scope('scope1'); + $scope->setMaxOccurances(10); $scope->setMinOccurances(5); - $this->assertEquals(10,$scope->getMaxOccurances()); - $this->assertEquals(5,$scope->getMinOccurances()); - $this->assertEquals(5,$scope->getOccuranceRange()); + $this->assertEquals(10, $scope->getMaxOccurances()); + $this->assertEquals(5, $scope->getMinOccurances()); + $this->assertEquals(5, $scope->getOccuranceRange()); } - - + public function testAttachChild() { - $scope = new Scope('scope1'); - $scope2 = new Scope('scope2'); - - $scope->attach($scope2)->rewind(); - $this->assertEquals($scope2,$scope->current()); + $scope = new Scope('scope1'); + $scope2 = new Scope('scope2'); + + $scope->attach($scope2)->rewind(); + $this->assertEquals($scope2, $scope->current()); } - - + public function testRepeatQuota() { $gen = new MersenneRandom(703); - + $scope = new Scope('scope1'); $scope->setMinOccurances(1); $scope->setMaxOccurances(6); - - $this->assertEquals(3,$scope->calculateRepeatQuota($gen)); - + + $this->assertEquals(3, $scope->calculateRepeatQuota($gen)); } - - + public function testGenerateErrorNotChildren() { $gen = new MersenneRandom(700); - + $scope = new Scope('scope1'); $scope->setMinOccurances(1); $scope->setMaxOccurances(6); - + $result = ''; - $this->expectException(RegexException::class); - $this->expectExceptionMessage("No child scopes to call must be atleast 1"); + $this->expectException(RegexException::class); + $this->expectExceptionMessage('No child scopes to call must be atleast 1'); - - $scope->generate($result,$gen); - + $scope->generate($result, $gen); } - - + public function testGenerate() { - $gen = new MersenneRandom(700); $result = ''; - + $scope = new Scope('scope1'); $scope->setMinOccurances(6); $scope->setMaxOccurances(6); - + $child = $this->getMockBuilder('ReverseRegex\Generator\Scope')->setMethods(['generate'])->getMock(); - + $child->expects($this->exactly(6)) ->method('generate') - ->with($this->isType('string'),$this->equalTo($gen)) - ->will($this->returnCallback(function(&$sResult){ + ->with($this->isType('string'), $this->equalTo($gen)) + ->will($this->returnCallback(function (&$sResult) { return $sResult .= 'a'; - })); - + $scope->attach($child); - - $result = $scope->generate($result,$gen); - - $this->assertEquals('aaaaaa',$result); - + + $result = $scope->generate($result, $gen); + + $this->assertEquals('aaaaaa', $result); } - + public function testGetNode() { $scope = new Scope('scope1'); - - - - for($i = 1; $i <= 6; $i++) { - $scope->attach(new Scope('label_'.$i)); + + for ($i = 1; $i <= 6; ++$i) { + $scope->attach(new Scope('label_'.$i)); } - + $other_scope = $scope->get(6); - $this->assertInstanceOf('ReverseRegex\Generator\Scope',$other_scope); - $this->assertEquals('label_6',$other_scope->getLabel()); - + $this->assertInstanceOf('ReverseRegex\Generator\Scope', $other_scope); + $this->assertEquals('label_6', $other_scope->getLabel()); + $other_scope = $scope->get(1); - $this->assertInstanceOf('ReverseRegex\Generator\Scope',$other_scope); - $this->assertEquals('label_1',$other_scope->getLabel()); - - + $this->assertInstanceOf('ReverseRegex\Generator\Scope', $other_scope); + $this->assertEquals('label_1', $other_scope->getLabel()); + $other_scope = $scope->get(3); - $this->assertInstanceOf('ReverseRegex\Generator\Scope',$other_scope); - $this->assertEquals('label_3',$other_scope->getLabel()); - + $this->assertInstanceOf('ReverseRegex\Generator\Scope', $other_scope); + $this->assertEquals('label_3', $other_scope->getLabel()); + $other_scope = $scope->get(0); - $this->assertEquals(null,$other_scope); + $this->assertEquals(null, $other_scope); } - - + public function testGenerateWithAlternatingStrategy() { - $scope = new Scope('scope1'); - $gen = new MersenneRandom(700); + $scope = new Scope('scope1'); + $gen = new MersenneRandom(700); $result = ''; - + $scope->setMinOccurances(7); $scope->setMaxOccurances(7); - - for($i = 1; $i <= 6; $i++) { + + for ($i = 1; $i <= 6; ++$i) { $lit = new LiteralScope('label_'.$i); $lit->addLiteral($i); $scope->attach($lit); $lit = null; } - + $scope->useAlternatingStrategy(); - $scope->generate($result,$gen); - $this->assertMatchesRegularExpression('/[1-6]{7}/',$result); - + $scope->generate($result, $gen); + $this->assertMatchesRegularExpression('/[1-6]{7}/', $result); } - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/ShortTest.php b/src/ReverseRegex/Test/ShortTest.php index d34edea..3867fae 100644 --- a/src/ReverseRegex/Test/ShortTest.php +++ b/src/ReverseRegex/Test/ShortTest.php @@ -1,157 +1,144 @@ moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { - $this->assertMatchesRegularExpression('/\d/',$value); + + foreach ($result as $value) { + $this->assertMatchesRegularExpression('/\d/', $value); } - } - + public function testNotDigit() { $lexer = new Lexer('\D'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { - $this->assertMatchesRegularExpression('/\D/',$value); + + foreach ($result as $value) { + $this->assertMatchesRegularExpression('/\D/', $value); } - } - + public function testWhitespace() { $lexer = new Lexer('\s'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { + + foreach ($result as $value) { $this->assertTrue(!empty($value)); } } - + public function testNonWhitespace() { $lexer = new Lexer('\S'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { + + foreach ($result as $value) { $this->assertTrue(!empty($value)); } } - + public function testWord() { $lexer = new Lexer('\w'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { - $this->assertMatchesRegularExpression('/\w/',$value); + + foreach ($result as $value) { + $this->assertMatchesRegularExpression('/\w/', $value); } - } - - + public function testNonWord() { - $lexer = new Lexer('\W'); + $lexer = new Lexer('\W'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - foreach($result as $value) { - $this->assertMatchesRegularExpression('/\W/',$value); + + foreach ($result as $value) { + $this->assertMatchesRegularExpression('/\W/', $value); } - - } - - - + public function testDotRange() { $lexer = new Lexer('.'); $scope = new Scope(); $parser = new Short(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); - $parser->parse($head,$scope,$lexer); - + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - + // match 0..127 char in ASSCI Chart - $this->assertCount(128,$result); - - + $this->assertCount(128, $result); } - - } -/* End of File */ \ No newline at end of file diff --git a/src/ReverseRegex/Test/UnicodeTest.php b/src/ReverseRegex/Test/UnicodeTest.php index 3851fff..8c72eba 100644 --- a/src/ReverseRegex/Test/UnicodeTest.php +++ b/src/ReverseRegex/Test/UnicodeTest.php @@ -1,161 +1,139 @@ moveNext(); $lexer->moveNext(); $this->expectException(RegexException::class); $this->expectExceptionMessage('Property \p (Unicode Property) not supported use \x to specify unicode character or range'); - - $parser->parse($scope,$scope,$lexer); - + + $parser->parse($scope, $scope, $lexer); } - - + public function testErrorNoOpeningBrace() { - $lexer = new Lexer('\Xaaaaa'); $scope = new Scope(); $parser = new Unicode(); - + $lexer->moveNext(); $lexer->moveNext(); $this->expectException(RegexException::class); $this->expectExceptionMessage('Expecting character { after \X none found'); - - $parser->parse($scope,$scope,$lexer); - + + $parser->parse($scope, $scope, $lexer); } - - + public function testErrorNested() { $lexer = new Lexer('\X{aa{aa}'); $scope = new Scope(); $parser = new Unicode(); - + $lexer->moveNext(); $lexer->moveNext(); $this->expectException(RegexException::class); $this->expectExceptionMessage('Nesting hex value ranges is not allowed'); - - $parser->parse($scope,$scope,$lexer); - + + $parser->parse($scope, $scope, $lexer); } - - - + public function testErrorUnclosed() { $lexer = new Lexer('\X{aaaa'); $scope = new Scope(); $parser = new Unicode(); - + $lexer->moveNext(); $lexer->moveNext(); $this->expectException(RegexException::class); $this->expectExceptionMessage('Closing quantifier token `}` not found'); - - $parser->parse($scope,$scope,$lexer); - - + + $parser->parse($scope, $scope, $lexer); } - - + public function testErrorEmptyToken() { $lexer = new Lexer('\X{}'); $scope = new Scope(); $parser = new Unicode(); - + $lexer->moveNext(); $lexer->moveNext(); $this->expectException(RegexException::class); $this->expectExceptionMessage('No hex number found inside the range'); - - $parser->parse($scope,$scope,$lexer); - + + $parser->parse($scope, $scope, $lexer); } - - + public function testsExampleA() { $lexer = new Lexer('\X{FA24}'); $scope = new Scope(); $parser = new Unicode(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - $this->assertEquals('﨤',$result[0]); - + + $this->assertEquals('﨤', $result[0]); } - - + public function testShortErrorWhenBraces() { $lexer = new Lexer('\x{64'); $scope = new Scope(); $parser = new Unicode(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $this->expectException(RegexException::class); + + $this->expectException(RegexException::class); $this->expectExceptionMessage('Braces not supported here'); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); } - + public function testShortX() { $lexer = new Lexer('\x64'); $scope = new Scope(); $parser = new Unicode(); - $head = new LiteralScope('lit1',$scope); - + $head = new LiteralScope('lit1', $scope); + $lexer->moveNext(); $lexer->moveNext(); - - $parser->parse($head,$scope,$lexer); - + + $parser->parse($head, $scope, $lexer); + $result = $head->getLiterals(); - - $this->assertEquals('d',$result[0]); - - + + $this->assertEquals('d', $result[0]); } - - } -/* End of File */ \ No newline at end of file