diff options
| -rw-r--r-- | src/Gallic/Parser.php | 27 | ||||
| -rw-r--r-- | src/Gallic/Parser/Alternation.php | 9 | ||||
| -rw-r--r-- | src/Gallic/Parser/Grammar.php | 2 | ||||
| -rw-r--r-- | src/Gallic/Parser/Ignore.php | 7 | ||||
| -rw-r--r-- | src/Gallic/Parser/Negation.php | 2 | ||||
| -rw-r--r-- | src/Gallic/Parser/Repetition.php | 25 | ||||
| -rw-r--r-- | src/Gallic/Parser/SList.php | 8 | ||||
| -rw-r--r-- | src/Gallic/Parser/Sequence.php | 10 | ||||
| -rw-r--r-- | src/Gallic/Parser/Transform.php | 2 |
9 files changed, 59 insertions, 33 deletions
diff --git a/src/Gallic/Parser.php b/src/Gallic/Parser.php index cc55e1b..2270685 100644 --- a/src/Gallic/Parser.php +++ b/src/Gallic/Parser.php | |||
| @@ -25,6 +25,12 @@ abstract class Gallic_Parser | |||
| 25 | { | 25 | { |
| 26 | abstract function hasValue(); | 26 | abstract function hasValue(); |
| 27 | 27 | ||
| 28 | /** | ||
| 29 | * Returns either: | ||
| 30 | * false | ||
| 31 | * or | ||
| 32 | * array(length[, value]) | ||
| 33 | */ | ||
| 28 | abstract protected function _parse($str, $offset, $len); | 34 | abstract protected function _parse($str, $offset, $len); |
| 29 | 35 | ||
| 30 | static function __callStatic($name, array $args) | 36 | static function __callStatic($name, array $args) |
| @@ -45,10 +51,11 @@ abstract class Gallic_Parser | |||
| 45 | } | 51 | } |
| 46 | 52 | ||
| 47 | /** | 53 | /** |
| 48 | * Returns either: | 54 | * @param str |
| 49 | * false | 55 | * |
| 50 | * or | 56 | * @return mixed |
| 51 | * array(length[, value]) | 57 | * |
| 58 | * @throws Exception | ||
| 52 | */ | 59 | */ |
| 53 | final function parse($str, $offset = null, $len = null) | 60 | final function parse($str, $offset = null, $len = null) |
| 54 | { | 61 | { |
| @@ -57,6 +64,16 @@ abstract class Gallic_Parser | |||
| 57 | isset($len) | 64 | isset($len) |
| 58 | or $len = strlen($str); | 65 | or $len = strlen($str); |
| 59 | 66 | ||
| 60 | return $this->_parse($str, $offset, $len); | 67 | if (!($match = $this->_parse($str, $offset, $len))) |
| 68 | { | ||
| 69 | throw new Exception(); | ||
| 70 | } | ||
| 71 | |||
| 72 | if ($this->hasValue()) | ||
| 73 | { | ||
| 74 | return $match[1]; | ||
| 75 | } | ||
| 76 | |||
| 77 | return null; | ||
| 61 | } | 78 | } |
| 62 | } | 79 | } |
diff --git a/src/Gallic/Parser/Alternation.php b/src/Gallic/Parser/Alternation.php index 809e82f..f5028f8 100644 --- a/src/Gallic/Parser/Alternation.php +++ b/src/Gallic/Parser/Alternation.php | |||
| @@ -27,6 +27,13 @@ final class Gallic_Parser_Alternation extends Gallic_Parser_Composite | |||
| 27 | continue; | 27 | continue; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | if ($child instanceof Gallic_Parser_Epsilon) | ||
| 31 | { | ||
| 32 | // This child will always succeed, no one will match after. | ||
| 33 | $children[] = $child; | ||
| 34 | break; | ||
| 35 | } | ||
| 36 | |||
| 30 | $hash = spl_object_hash($child); | 37 | $hash = spl_object_hash($child); |
| 31 | if (!isset($children[$hash])) | 38 | if (!isset($children[$hash])) |
| 32 | { | 39 | { |
| @@ -52,7 +59,7 @@ final class Gallic_Parser_Alternation extends Gallic_Parser_Composite | |||
| 52 | { | 59 | { |
| 53 | foreach ($this->_children as $child) | 60 | foreach ($this->_children as $child) |
| 54 | { | 61 | { |
| 55 | if ($match = $child->parse($str, $offset, $len)) | 62 | if ($match = $child->_parse($str, $offset, $len)) |
| 56 | { | 63 | { |
| 57 | if ($this->hasValue()) | 64 | if ($this->hasValue()) |
| 58 | { | 65 | { |
diff --git a/src/Gallic/Parser/Grammar.php b/src/Gallic/Parser/Grammar.php index 81427e8..3e5bc28 100644 --- a/src/Gallic/Parser/Grammar.php +++ b/src/Gallic/Parser/Grammar.php | |||
| @@ -40,7 +40,7 @@ final class Gallic_Parser_Grammar extends Gallic_Parser_Composite | |||
| 40 | 40 | ||
| 41 | protected function _parse($str, $offset, $len) | 41 | protected function _parse($str, $offset, $len) |
| 42 | { | 42 | { |
| 43 | return $this->_children[$this->_top]->parse($str, $offset, $len); | 43 | return $this->_children[$this->_top]->_parse($str, $offset, $len); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | protected function _resolve(Gallic_Parser_Composite $parser) | 46 | protected function _resolve(Gallic_Parser_Composite $parser) |
diff --git a/src/Gallic/Parser/Ignore.php b/src/Gallic/Parser/Ignore.php index a98d18f..faffeb8 100644 --- a/src/Gallic/Parser/Ignore.php +++ b/src/Gallic/Parser/Ignore.php | |||
| @@ -25,7 +25,7 @@ final class Gallic_Parser_Ignore extends Gallic_Parser_Composite | |||
| 25 | 25 | ||
| 26 | protected function _parse($str, $offset, $len) | 26 | protected function _parse($str, $offset, $len) |
| 27 | { | 27 | { |
| 28 | if ($match = $this->_children[0]->parse($str, $offset, $len)) | 28 | if ($match = $this->_children[0]->_parse($str, $offset, $len)) |
| 29 | { | 29 | { |
| 30 | unset($match[1]); | 30 | unset($match[1]); |
| 31 | return $match; | 31 | return $match; |
| @@ -33,9 +33,4 @@ final class Gallic_Parser_Ignore extends Gallic_Parser_Composite | |||
| 33 | 33 | ||
| 34 | return false; | 34 | return false; |
| 35 | } | 35 | } |
| 36 | |||
| 37 | /** | ||
| 38 | * @var callable | ||
| 39 | */ | ||
| 40 | private $_callback; | ||
| 41 | } | 36 | } |
diff --git a/src/Gallic/Parser/Negation.php b/src/Gallic/Parser/Negation.php index 02e68e3..9470e7f 100644 --- a/src/Gallic/Parser/Negation.php +++ b/src/Gallic/Parser/Negation.php | |||
| @@ -32,7 +32,7 @@ final class Gallic_Parser_Negation extends Gallic_Parser_Composite | |||
| 32 | 32 | ||
| 33 | protected function _parse($str, $offset, $len) | 33 | protected function _parse($str, $offset, $len) |
| 34 | { | 34 | { |
| 35 | if ($match = $this->_children[0]->parse($str, $offset, $len)) | 35 | if ($match = $this->_children[0]->_parse($str, $offset, $len)) |
| 36 | { | 36 | { |
| 37 | return false; | 37 | return false; |
| 38 | } | 38 | } |
diff --git a/src/Gallic/Parser/Repetition.php b/src/Gallic/Parser/Repetition.php index 88e9c4d..5bd24e7 100644 --- a/src/Gallic/Parser/Repetition.php +++ b/src/Gallic/Parser/Repetition.php | |||
| @@ -18,13 +18,14 @@ final class Gallic_Parser_Repetition extends Gallic_Parser_Composite | |||
| 18 | 18 | ||
| 19 | protected function _optimize() | 19 | protected function _optimize() |
| 20 | { | 20 | { |
| 21 | parent::_optimize(); | 21 | $child = $this->_children[0]->optimize(); |
| 22 | $has_no_value = !$child->hasValue(); | ||
| 22 | 23 | ||
| 23 | // If “max === 0”, equivalent to ε. | 24 | // If “max === 0 && $has_no_value”, equivalent to ε. |
| 24 | /*if ($this->_max === 0) | 25 | if ($has_no_value && ($this->_max === 0)) |
| 25 | { | 26 | { |
| 26 | return new Gallic_Parser_Epsilon; | 27 | return new Gallic_Parser_Epsilon; |
| 27 | }*/ | 28 | } |
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * If the cardinalities are incorrectly set, this parser will always | 31 | * If the cardinalities are incorrectly set, this parser will always |
| @@ -36,12 +37,18 @@ final class Gallic_Parser_Repetition extends Gallic_Parser_Composite | |||
| 36 | return new Gallic_Parser_Fail; | 37 | return new Gallic_Parser_Fail; |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | // No need to use a sequence to match exactly once. | 40 | /* |
| 40 | /*if (($this->_min === 1) && ($this->_max === 1)) | 41 | * To match exactly once, there is no need to use a repetition. |
| 42 | * | ||
| 43 | * But the equivalence of the replacement is only true if the child has | ||
| 44 | * no value. | ||
| 45 | */ | ||
| 46 | if ($has_no_value && ($this->_min === 1) && ($this->_max === 1)) | ||
| 41 | { | 47 | { |
| 42 | return $this->_children[0]; | 48 | return $child; |
| 43 | }*/ | 49 | } |
| 44 | 50 | ||
| 51 | $this->_children[0] = $child; | ||
| 45 | return $this; | 52 | return $this; |
| 46 | } | 53 | } |
| 47 | 54 | ||
| @@ -56,7 +63,7 @@ final class Gallic_Parser_Repetition extends Gallic_Parser_Composite | |||
| 56 | } | 63 | } |
| 57 | 64 | ||
| 58 | while ((!isset($this->_max) || ($n < $this->_max)) | 65 | while ((!isset($this->_max) || ($n < $this->_max)) |
| 59 | && ($match = $this->_children[0]->parse($str, $offset, $len))) | 66 | && ($match = $this->_children[0]->_parse($str, $offset, $len))) |
| 60 | { | 67 | { |
| 61 | ++$n; | 68 | ++$n; |
| 62 | $offset += $match[0]; | 69 | $offset += $match[0]; |
diff --git a/src/Gallic/Parser/SList.php b/src/Gallic/Parser/SList.php index 2793845..40ead21 100644 --- a/src/Gallic/Parser/SList.php +++ b/src/Gallic/Parser/SList.php | |||
| @@ -32,7 +32,7 @@ final class Gallic_Parser_SList extends Gallic_Parser_Composite | |||
| 32 | * once. | 32 | * once. |
| 33 | */ | 33 | */ |
| 34 | if (($item instanceof Gallic_Parser_Fail) | 34 | if (($item instanceof Gallic_Parser_Fail) |
| 35 | /*|| ($separator instanceof Gallic_Parser_Fail)*/) | 35 | || ($separator instanceof Gallic_Parser_Fail)) |
| 36 | { | 36 | { |
| 37 | return $item; | 37 | return $item; |
| 38 | } | 38 | } |
| @@ -63,7 +63,7 @@ final class Gallic_Parser_SList extends Gallic_Parser_Composite | |||
| 63 | $value = array(); | 63 | $value = array(); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | if ((!$match_i = $item->parse($str, $offset, $len))) | 66 | if ((!$match_i = $item->_parse($str, $offset, $len))) |
| 67 | { | 67 | { |
| 68 | return false; | 68 | return false; |
| 69 | } | 69 | } |
| @@ -74,8 +74,8 @@ final class Gallic_Parser_SList extends Gallic_Parser_Composite | |||
| 74 | $value[] = $match_i[1]; | 74 | $value[] = $match_i[1]; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | while (($match_s = $separator->parse($str, $offset, $len)) | 77 | while (($match_s = $separator->_parse($str, $offset, $len)) |
| 78 | && ($match_i = $item->parse($str, $offset + $match_s[0], $len))) | 78 | && ($match_i = $item->_parse($str, $offset + $match_s[0], $len))) |
| 79 | { | 79 | { |
| 80 | $offset += $match_s[0] + $match_i[0]; | 80 | $offset += $match_s[0] + $match_i[0]; |
| 81 | 81 | ||
diff --git a/src/Gallic/Parser/Sequence.php b/src/Gallic/Parser/Sequence.php index 73c44e6..7a22c93 100644 --- a/src/Gallic/Parser/Sequence.php +++ b/src/Gallic/Parser/Sequence.php | |||
| @@ -14,16 +14,16 @@ final class Gallic_Parser_Sequence extends Gallic_Parser_Composite | |||
| 14 | parent::_optimize(); | 14 | parent::_optimize(); |
| 15 | 15 | ||
| 16 | // An empty sequence will always match. | 16 | // An empty sequence will always match. |
| 17 | /*if (empty($this->_children)) | 17 | if (empty($this->_children)) |
| 18 | { | 18 | { |
| 19 | return new Gallic_Parser_Epsilon; | 19 | return new Gallic_Parser_Epsilon; |
| 20 | }*/ | 20 | } |
| 21 | 21 | ||
| 22 | // No need to use a sequence for one element. | 22 | // No need to use a sequence for one element. |
| 23 | /*if (count($this->_children) === 1) | 23 | if (count($this->_children) === 1) |
| 24 | { | 24 | { |
| 25 | return $this->_children[0]; | 25 | return $this->_children[0]; |
| 26 | }*/ | 26 | } |
| 27 | 27 | ||
| 28 | return $this; | 28 | return $this; |
| 29 | } | 29 | } |
| @@ -39,7 +39,7 @@ final class Gallic_Parser_Sequence extends Gallic_Parser_Composite | |||
| 39 | 39 | ||
| 40 | foreach ($this->_children as $child) | 40 | foreach ($this->_children as $child) |
| 41 | { | 41 | { |
| 42 | if (!($match = $child->parse($str, $offset, $len))) | 42 | if (!($match = $child->_parse($str, $offset, $len))) |
| 43 | { | 43 | { |
| 44 | return false; | 44 | return false; |
| 45 | } | 45 | } |
diff --git a/src/Gallic/Parser/Transform.php b/src/Gallic/Parser/Transform.php index 402621c..d0ec68f 100644 --- a/src/Gallic/Parser/Transform.php +++ b/src/Gallic/Parser/Transform.php | |||
| @@ -28,7 +28,7 @@ final class Gallic_Parser_Transform extends Gallic_Parser_Composite | |||
| 28 | 28 | ||
| 29 | protected function _parse($str, $offset, $len) | 29 | protected function _parse($str, $offset, $len) |
| 30 | { | 30 | { |
| 31 | if (!($match = $this->_children[0]->parse($str, $offset, $len))) | 31 | if (!($match = $this->_children[0]->_parse($str, $offset, $len))) |
| 32 | { | 32 | { |
| 33 | return false; | 33 | return false; |
| 34 | } | 34 | } |
