]> git.andy128k.dev Git - pegp.git/commitdiff
initial version
authorAndrey Kutejko <andy128k@gmail.com>
Sun, 11 Aug 2013 11:10:38 +0000 (14:10 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Sun, 11 Aug 2013 11:10:38 +0000 (14:10 +0300)
.gitignore [new file with mode: 0644]
composer.json [new file with mode: 0644]
composer.lock [new file with mode: 0644]
lib/input.php [new file with mode: 0644]
lib/parser.php [new file with mode: 0644]
lib/result.php [new file with mode: 0644]
lib/shortcuts.php [new file with mode: 0644]
t/CalculatorTest.php [new file with mode: 0644]
t/PropertiesTest.php [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..fcac4a7
--- /dev/null
@@ -0,0 +1,2 @@
+/vendor
+
diff --git a/composer.json b/composer.json
new file mode 100644 (file)
index 0000000..269856a
--- /dev/null
@@ -0,0 +1,18 @@
+{
+  "name": "andy128k/pegp",
+  "description": "PEG",
+  "license": "MIT",
+  "authors": [
+    {
+      "name": "Andrey Kutejko",
+      "email": "andy128k@gmail.com"
+    }
+  ],
+  "autoload": {
+    "classmap" : ["lib"]
+  },
+  "require-dev": {
+    "phpunit/phpunit": "3.7.*"
+  }
+}
+
diff --git a/composer.lock b/composer.lock
new file mode 100644 (file)
index 0000000..2b4d50a
--- /dev/null
@@ -0,0 +1,439 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
+    ],
+    "hash": "3e9668f4e1ddee877ae96c3d3e4cd05f",
+    "packages": [
+
+    ],
+    "packages-dev": [
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "1.2.12",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "1.2.12"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.12",
+                "reference": "1.2.12",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "phpunit/php-file-iterator": ">=1.3.0@stable",
+                "phpunit/php-text-template": ">=1.1.1@stable",
+                "phpunit/php-token-stream": ">=1.1.3@stable"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "3.7.*@dev"
+            },
+            "suggest": {
+                "ext-dom": "*",
+                "ext-xdebug": ">=2.0.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "PHP/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+            "keywords": [
+                "coverage",
+                "testing",
+                "xunit"
+            ],
+            "time": "2013-07-06 06:26:16"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "1.3.3",
+            "source": {
+                "type": "git",
+                "url": "git://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "1.3.3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3",
+                "reference": "1.3.3",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "File/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+            "homepage": "http://www.phpunit.de/",
+            "keywords": [
+                "filesystem",
+                "iterator"
+            ],
+            "time": "2012-10-11 04:44:38"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "1.1.4",
+            "source": {
+                "type": "git",
+                "url": "git://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "1.1.4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4",
+                "reference": "1.1.4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "Text/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Simple template engine.",
+            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+            "keywords": [
+                "template"
+            ],
+            "time": "2012-10-31 11:15:28"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "1.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "1.0.5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1.0.5",
+                "reference": "1.0.5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "PHP/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Utility class for timing",
+            "homepage": "https://github.com/sebastianbergmann/php-timer/",
+            "keywords": [
+                "timer"
+            ],
+            "time": "2013-08-02 07:42:54"
+        },
+        {
+            "name": "phpunit/php-token-stream",
+            "version": "1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+                "reference": "1.2.0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.2.0",
+                "reference": "1.2.0",
+                "shasum": ""
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "PHP/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Wrapper around PHP's tokenizer extension.",
+            "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+            "keywords": [
+                "tokenizer"
+            ],
+            "time": "2013-08-04 05:57:48"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "3.7.23",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "3.7.23"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.23",
+                "reference": "3.7.23",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-pcre": "*",
+                "ext-reflection": "*",
+                "ext-spl": "*",
+                "php": ">=5.3.3",
+                "phpunit/php-code-coverage": "~1.2.1",
+                "phpunit/php-file-iterator": ">=1.3.1",
+                "phpunit/php-text-template": ">=1.1.1",
+                "phpunit/php-timer": ">=1.0.4",
+                "phpunit/phpunit-mock-objects": "~1.2.0",
+                "symfony/yaml": "~2.0"
+            },
+            "require-dev": {
+                "pear-pear/pear": "1.9.4"
+            },
+            "suggest": {
+                "ext-json": "*",
+                "ext-simplexml": "*",
+                "ext-tokenizer": "*",
+                "phpunit/php-invoker": ">=1.1.0,<1.2.0"
+            },
+            "bin": [
+                "composer/bin/phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.7.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "PHPUnit/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                "",
+                "../../symfony/yaml/"
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "The PHP Unit Testing framework.",
+            "homepage": "http://www.phpunit.de/",
+            "keywords": [
+                "phpunit",
+                "testing",
+                "xunit"
+            ],
+            "time": "2013-08-02 19:14:44"
+        },
+        {
+            "name": "phpunit/phpunit-mock-objects",
+            "version": "1.2.3",
+            "source": {
+                "type": "git",
+                "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git",
+                "reference": "1.2.3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip",
+                "reference": "1.2.3",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "phpunit/php-text-template": ">=1.1.1@stable"
+            },
+            "suggest": {
+                "ext-soap": "*"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "PHPUnit/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                ""
+            ],
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sb@sebastian-bergmann.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Mock Object library for PHPUnit",
+            "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+            "keywords": [
+                "mock",
+                "xunit"
+            ],
+            "time": "2013-01-13 10:24:48"
+        },
+        {
+            "name": "symfony/yaml",
+            "version": "v2.3.2",
+            "target-dir": "Symfony/Component/Yaml",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Yaml.git",
+                "reference": "v2.3.2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.2",
+                "reference": "v2.3.2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Yaml\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Yaml Component",
+            "homepage": "http://symfony.com",
+            "time": "2013-07-11 19:36:36"
+        }
+    ],
+    "aliases": [
+
+    ],
+    "minimum-stability": "stable",
+    "stability-flags": [
+
+    ],
+    "platform": [
+
+    ],
+    "platform-dev": [
+
+    ]
+}
diff --git a/lib/input.php b/lib/input.php
new file mode 100644 (file)
index 0000000..9441af4
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+class PegpInput
+{
+    public $data, $length, $pos;
+
+    public function __construct($data, $length=null, $pos=0)
+    {
+        $this->data = $data;
+        $this->length = $length ? $length : strlen($data);
+        $this->pos = $pos;
+    }
+
+    public function pick($length=PHP_INT_MAX)
+    {
+        $length = min($length, $this->length - $this->pos);
+        if ($length > 0)
+            return substr($this->data, $this->pos, $length);
+        else
+            return '';
+    }
+
+    public function advance($len)
+    {
+        return new PegpInput($this->data, $this->length, $this->pos + $len);
+    }
+}
+
diff --git a/lib/parser.php b/lib/parser.php
new file mode 100644 (file)
index 0000000..5f2950a
--- /dev/null
@@ -0,0 +1,260 @@
+<?php
+
+abstract class PegpParser
+{
+    public $comment = null;
+    private $drop = false;
+    private $value = null;
+
+    public function parseString($string)
+    {
+        $input = new PegpInput($string);
+        $result = $this->parse($input);
+        if (!$result->isSuccess())
+            throw new Exception('Parse failed. Expected ' . $result->result->getComment() . ' at ' . $result->input->pos);
+        if ($input->length != $result->input->pos)
+            throw new Exception('Parse failed. Unparsed tail at ' . $result->input->pos);
+        return $result->result;
+    }
+
+    public function parse(PegpInput $input)
+    {
+        $result = $this->doParse($input);
+        if ($result->isSuccess()) {
+            return $this->process($result);
+        } else {
+            return $result;
+        }
+    }
+
+    public abstract function doParse(PegpInput $input);
+
+    protected function process($result)
+    {
+        if ($this->drop) {
+            return PegpResult::success($result->input, null);
+        } elseif ($this->value !== null) {
+            return PegpResult::success($result->input, $this->value);
+        } else {
+            return $result;
+        }
+    }
+
+    public function getComment()
+    {
+        return $this->comment;
+    }
+
+    public function setComment($comment)
+    {
+        $this->comment = $comment;
+        return $this;
+    }
+
+    public function drop()
+    {
+        $this->drop = true;
+        return $this;
+    }
+
+    public function value($value)
+    {
+        $this->value = $value;
+        return $this;
+    }
+}
+
+class PegpString extends PegpParser
+{
+    private $str, $caseInsensitive;
+
+    public function __construct($str, $caseInsensitive=false)
+    {
+        $this->str = $str;
+        $this->caseInsensitive = $caseInsensitive;
+    }
+
+    public function doParse(PegpInput $input)
+    {
+        $len = strlen($this->str);
+        if (0 == substr_compare($input->data, $this->str, $input->pos, $len, $this->caseInsensitive)) { // ?? len
+            return PegpResult::success(
+                $input->advance($len),
+                $this->str
+            );
+        } else {
+            return PegpResult::failure($input, $this);
+        }
+    }
+
+    public function getComment()
+    {
+        if ($this->comment !== null)
+            return $this->comment;
+        else
+            return '<string '.$this->str.'>';
+    }
+}
+
+class PegpRegex extends PegpParser
+{
+    private $expr;
+
+    public function __construct($expr, $flags='', $delimiter='#')
+    {
+        $this->expr = $delimiter . '^' . $expr . $delimiter . $flags;
+    }
+
+    public function doParse(PegpInput $input)
+    {
+        if (preg_match($this->expr, $input->pick(), $m)) {
+            return PegpResult::success(
+                $input->advance(strlen($m[0])),
+                $m
+            );
+        } else {
+            return PegpResult::failure($input, $this);
+        }
+    }
+
+    public function getComment()
+    {
+        if ($this->comment !== null)
+            return $this->comment;
+        else
+            return '<regexp '.$this->expr.'>';
+    }
+}
+
+class PegpSequence extends PegpParser
+{
+    private $parsers, $op = null;
+
+    public function __construct(array $parsers)
+    {
+        $this->parsers = $parsers;
+    }
+
+    public function doParse(PegpInput $input)
+    {
+        $inp = $input;
+        $result = array();
+        foreach ($this->parsers as $parser) {
+            $r = $parser->parse($inp);
+            if ($r->isSuccess()) {
+                $inp = $r->input;
+                if ($r->result !== null)
+                    $result[] = $r->result;
+            } else {
+                return PegpResult::failure($inp, $parser);
+            }
+        }
+        return PegpResult::success($inp, $result);
+    }
+
+    protected function process($result)
+    {
+        switch ($this->op) {
+            case 'join':
+                $result = PegpResult::success($result->input, implode('', $result->result));
+                break;
+            case 'bitOr':
+                $value = 0;
+                foreach ($result->result as $v)
+                    $value |= $v;
+                $result = PegpResult::success($result->input, $value);
+                break;
+            case 'sum':
+                $value = 0;
+                foreach ($result->result as $v)
+                    $value += $v;
+                $result = PegpResult::success($result->input, $value);
+                break;
+            case 'product':
+                $value = 1;
+                foreach ($result->result as $v)
+                    $value *= $v;
+                $result = PegpResult::success($result->input, $value);
+                break;
+        }
+        return parent::process($result);
+    }
+
+    public function join()
+    {
+        $this->op = 'join';
+        return $this;
+    }
+
+    public function bitOr()
+    {
+        $this->op = 'bitOr';
+        return $this;
+    }
+
+    public function sum()
+    {
+        $this->op = 'sum';
+        return $this;
+    }
+
+    public function product()
+    {
+        $this->op = 'product';
+        return $this;
+    }
+}
+
+class PegpOneOf extends PegpParser
+{
+    private $parsers;
+
+    public function __construct(array $parsers)
+    {
+        $this->parsers = $parsers;
+    }
+
+    public function doParse(PegpInput $input)
+    {
+        foreach ($this->parsers as $parser) {
+            $r = $parser->parse($input);
+            if ($r->isSuccess()) {
+                return $r;
+            }
+        }
+        return PegpResult::failure($input, $this);
+    }
+
+    public function getComment()
+    {
+        if ($this->comment !== null)
+            return $this->comment;
+        $comment = array();
+        foreach ($this->parsers as $parser) {
+            $comment[] = $parser->getComment();
+        }
+        return 'one of: '.implode(', ', $comment);
+    }
+}
+
+class PegpOptional extends PegpParser
+{
+    private $parser, $emptyValue;
+
+    public function __construct(PegpParser $parser, $emptyValue='')
+    {
+        $this->parser = $parser;
+        $this->emptyValue = $emptyValue;
+    }
+
+    public function doParse(PegpInput $input)
+    {
+        $r = $this->parser->parse($input);
+        if ($r->isSuccess()) {
+            return $r;
+        } else {
+            return PegpResult::success($input, $this->emptyValue);
+        }
+    }
+}
+
diff --git a/lib/result.php b/lib/result.php
new file mode 100644 (file)
index 0000000..f2e559f
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+class PegpResult
+{
+    private $success;
+    public $input, $result;
+
+    public function __construct($success, PegpInput $input, $result=null)
+    {
+        $this->success = $success;
+        $this->input = $input;
+        $this->result = $result;
+    }
+
+    public static function success(PegpInput $input, $result=null)
+    {
+        return new PegpResult(true, $input, $result);
+    }
+
+    public static function failure(PegpInput $input, $parser=null)
+    {
+        return new PegpResult(false, $input, $parser);
+    }
+
+    public function isSuccess()
+    {
+        return $this->success;
+    }
+}
+
diff --git a/lib/shortcuts.php b/lib/shortcuts.php
new file mode 100644 (file)
index 0000000..91efa2c
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+final class Pegp
+{
+    public static function str($str)
+    {
+        return new PegpString($str);
+    }
+
+    public static function stri($str)
+    {
+        return new PegpString($str, true);
+    }
+
+    public static function re($expr, $flags='', $delimiter='#')
+    {
+        return new PegpRegex($expr, $flags, $delimiter);
+    }
+
+    public static function seq()
+    {
+        return new PegpSequence(func_get_args());
+    }
+
+    public static function oneOf()
+    {
+        return new PegpOneOf(func_get_args());
+    }
+
+    public static function optional($parser, $emptyValue='')
+    {
+        return new PegpOptional($parser, $emptyValue);
+    }
+}
+
diff --git a/t/CalculatorTest.php b/t/CalculatorTest.php
new file mode 100644 (file)
index 0000000..b0d0786
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+class CalculatorTest extends PHPUnit_Framework_TestCase
+{
+    public function assertParse($parser, $input)
+    {
+        $i = new PegpInput($input);
+        $r = $parser->parse($i);
+        $this->assertInstanceOf('PegpResult', $r);
+        $inputAfter = $r->input;
+        $this->assertInstanceOf('PegpInput', $inputAfter);
+
+        if (!$r->isSuccess()) {
+            echo 'Parse failed. Expected ' . $r->result . ' at ' . $r->input->pos . "\n";
+        }
+
+        $this->assertTrue($r->isSuccess());
+        $this->assertEquals($i->data, $inputAfter->data);
+        $this->assertEquals($i->length, $inputAfter->length);
+        $this->assertEquals($i->length, $inputAfter->pos);
+        return $r->result;
+    }
+
+    public function testString()
+    {
+        $p = Pegp::str('test');
+        $this->assertParse($p, 'test');
+    }
+
+    public function testRegex()
+    {
+        $p = Pegp::re('te[xs]t');
+        $this->assertParse($p, 'test');
+        $this->assertParse($p, 'text');
+    }
+
+    public function testSQLStringLiteral()
+    {
+        $p = Pegp::re("'([^\\\\']*[\\\\']')*[^\\\\']*'");
+        $this->assertParse($p, "''");
+        $this->assertParse($p, "'Hello there'");
+        $this->assertParse($p, "'Don\\'t worry. Be happy!'");
+        $this->assertParse($p, "'Don''t worry. Be happy!'");
+    }
+
+    public function testDecimal()
+    {
+        $p = Pegp::re("\\d+(\\.\\d+)?");
+        $r = $this->assertParse($p, '123.45');
+        $this->assertEquals('.45', $r[1]);
+    }
+
+    public function testSequence()
+    {
+        $word = Pegp::re('[a-z]+');
+        $space = Pegp::re('\s+');
+        $optSpace = Pegp::re('\s*');
+        $punctuation = Pegp::re('[.!?]')->setComment('punctiation mark');
+        $p = Pegp::seq($optSpace, $word, $space, $word, $space, $word, $optSpace, $punctuation, $optSpace);
+
+        $r = $this->assertParse($p, "\thow  are you  \n ? ");
+    }
+}
+
diff --git a/t/PropertiesTest.php b/t/PropertiesTest.php
new file mode 100644 (file)
index 0000000..6e22b72
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+class PropertiesTest extends PHPUnit_Framework_TestCase
+{
+    public function assertParse($expected, $parser, $input)
+    {
+        $i = new PegpInput($input);
+        $r = $parser->parse($i);
+        $this->assertInstanceOf('PegpResult', $r);
+        $inputAfter = $r->input;
+        $this->assertInstanceOf('PegpInput', $inputAfter);
+
+        if (!$r->isSuccess()) {
+            echo 'Parse failed. Expected ' . $r->result->getComment() . ' at ' . $r->input->pos . "\n";
+        }
+
+        $this->assertTrue($r->isSuccess());
+        $this->assertEquals($i->data, $inputAfter->data);
+        $this->assertEquals($i->length, $inputAfter->length);
+        $this->assertEquals($i->length, $inputAfter->pos);
+        $this->assertEquals($expected, $r->result);
+    }
+
+    public function testProperties()
+    {
+        $p =
+        Pegp::oneOf(
+            Pegp::stri('default'),
+            Pegp::stri('us'),
+            Pegp::stri('european'),
+            Pegp::seq(
+                Pegp::optional(
+                    Pegp::seq(
+                        Pegp::oneOf(
+                            Pegp::stri('big-endian'),
+                            Pegp::stri('little-endian'),
+                            Pegp::stri('middle-endian')),
+                        Pegp::re('\s+')->drop())->join()),
+                Pegp::oneOf(
+                    Pegp::stri('slashes')->value('/'),
+                    Pegp::stri('dots')->value('.'),
+                    Pegp::stri('hyphens')->value('-'),
+                    Pegp::stri('spaces')->value(' '))));
+
+        $this->assertParse('us', $p, 'us');
+        $this->assertParse(array('big-endian', '-'), $p, 'Big-endian hyphEns');
+        $this->assertParse(array('little-endian', '.'), $p, 'little-endian dots');
+        $this->assertParse(array('middle-endian', '/'), $p, 'Middle-Endian Slashes');
+        $this->assertParse(array('big-endian', ' '), $p, 'big-endian spaces');
+        $this->assertParse(array('', '-'), $p, 'Hyphens');
+    }
+}
+