X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fbehat%2Fgherkin%2Fsrc%2FBehat%2FGherkin%2FParser.php;fp=vendor%2Fbehat%2Fgherkin%2Fsrc%2FBehat%2FGherkin%2FParser.php;h=0000000000000000000000000000000000000000;hp=5cc85424b13bbe9bc014a9ddaeb8f3bdb3297021;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/behat/gherkin/src/Behat/Gherkin/Parser.php b/vendor/behat/gherkin/src/Behat/Gherkin/Parser.php deleted file mode 100644 index 5cc85424b..000000000 --- a/vendor/behat/gherkin/src/Behat/Gherkin/Parser.php +++ /dev/null @@ -1,699 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Behat\Gherkin; - -use Behat\Gherkin\Exception\LexerException; -use Behat\Gherkin\Exception\ParserException; -use Behat\Gherkin\Node\BackgroundNode; -use Behat\Gherkin\Node\ExampleTableNode; -use Behat\Gherkin\Node\FeatureNode; -use Behat\Gherkin\Node\OutlineNode; -use Behat\Gherkin\Node\PyStringNode; -use Behat\Gherkin\Node\ScenarioInterface; -use Behat\Gherkin\Node\ScenarioNode; -use Behat\Gherkin\Node\StepNode; -use Behat\Gherkin\Node\TableNode; - -/** - * Gherkin parser. - * - * $lexer = new Behat\Gherkin\Lexer($keywords); - * $parser = new Behat\Gherkin\Parser($lexer); - * $featuresArray = $parser->parse('/path/to/feature.feature'); - * - * @author Konstantin Kudryashov - */ -class Parser -{ - private $lexer; - private $input; - private $file; - private $tags = array(); - private $languageSpecifierLine; - - /** - * Initializes parser. - * - * @param Lexer $lexer Lexer instance - */ - public function __construct(Lexer $lexer) - { - $this->lexer = $lexer; - } - - /** - * Parses input & returns features array. - * - * @param string $input Gherkin string document - * @param string $file File name - * - * @return FeatureNode|null - * - * @throws ParserException - */ - public function parse($input, $file = null) - { - $this->languageSpecifierLine = null; - $this->input = $input; - $this->file = $file; - $this->tags = array(); - - try { - $this->lexer->analyse($this->input, 'en'); - } catch (LexerException $e) { - throw new ParserException( - sprintf('Lexer exception "%s" thrown for file %s', $e->getMessage(), $file), - 0, - $e - ); - } - - $feature = null; - while ('EOS' !== ($predicted = $this->predictTokenType())) { - $node = $this->parseExpression(); - - if (null === $node || "\n" === $node) { - continue; - } - - if (!$feature && $node instanceof FeatureNode) { - $feature = $node; - continue; - } - - if ($feature && $node instanceof FeatureNode) { - throw new ParserException(sprintf( - 'Only one feature is allowed per feature file. But %s got multiple.', - $this->file - )); - } - - if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Feature, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - if (!$node instanceof FeatureNode) { - throw new ParserException(sprintf( - 'Expected Feature, but got %s on line: %d%s', - $node->getKeyword(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - } - - return $feature; - } - - /** - * Returns next token if it's type equals to expected. - * - * @param string $type Token type - * - * @return array - * - * @throws Exception\ParserException - */ - protected function expectTokenType($type) - { - $types = (array) $type; - if (in_array($this->predictTokenType(), $types)) { - return $this->lexer->getAdvancedToken(); - } - - $token = $this->lexer->predictToken(); - - throw new ParserException(sprintf( - 'Expected %s token, but got %s on line: %d%s', - implode(' or ', $types), - $this->predictTokenType(), - $token['line'], - $this->file ? ' in file: ' . $this->file : '' - )); - } - - /** - * Returns next token if it's type equals to expected. - * - * @param string $type Token type - * - * @return null|array - */ - protected function acceptTokenType($type) - { - if ($type !== $this->predictTokenType()) { - return null; - } - - return $this->lexer->getAdvancedToken(); - } - - /** - * Returns next token type without real input reading (prediction). - * - * @return string - */ - protected function predictTokenType() - { - $token = $this->lexer->predictToken(); - - return $token['type']; - } - - /** - * Parses current expression & returns Node. - * - * @return string|FeatureNode|BackgroundNode|ScenarioNode|OutlineNode|TableNode|StepNode - * - * @throws ParserException - */ - protected function parseExpression() - { - switch ($type = $this->predictTokenType()) { - case 'Feature': - return $this->parseFeature(); - case 'Background': - return $this->parseBackground(); - case 'Scenario': - return $this->parseScenario(); - case 'Outline': - return $this->parseOutline(); - case 'Examples': - return $this->parseExamples(); - case 'TableRow': - return $this->parseTable(); - case 'PyStringOp': - return $this->parsePyString(); - case 'Step': - return $this->parseStep(); - case 'Text': - return $this->parseText(); - case 'Newline': - return $this->parseNewline(); - case 'Tag': - return $this->parseTags(); - case 'Comment': - return $this->parseComment(); - case 'Language': - return $this->parseLanguage(); - case 'EOS': - return ''; - } - - throw new ParserException(sprintf('Unknown token type: %s', $type)); - } - - /** - * Parses feature token & returns it's node. - * - * @return FeatureNode - * - * @throws ParserException - */ - protected function parseFeature() - { - $token = $this->expectTokenType('Feature'); - - $title = trim($token['value']) ?: null; - $description = null; - $tags = $this->popTags(); - $background = null; - $scenarios = array(); - $keyword = $token['keyword']; - $language = $this->lexer->getLanguage(); - $file = $this->file; - $line = $token['line']; - - // Parse description, background, scenarios & outlines - while ('EOS' !== $this->predictTokenType()) { - $node = $this->parseExpression(); - - if (is_string($node)) { - $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node); - $description .= (null !== $description ? "\n" : '') . $text; - continue; - } - - if (!$background && $node instanceof BackgroundNode) { - $background = $node; - continue; - } - - if ($node instanceof ScenarioInterface) { - $scenarios[] = $node; - continue; - } - - if ($background instanceof BackgroundNode && $node instanceof BackgroundNode) { - throw new ParserException(sprintf( - 'Each Feature could have only one Background, but found multiple on lines %d and %d%s', - $background->getLine(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - - if (!$node instanceof ScenarioNode) { - throw new ParserException(sprintf( - 'Expected Scenario, Outline or Background, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - } - - return new FeatureNode( - rtrim($title) ?: null, - rtrim($description) ?: null, - $tags, - $background, - $scenarios, - $keyword, - $language, - $file, - $line - ); - } - - /** - * Parses background token & returns it's node. - * - * @return BackgroundNode - * - * @throws ParserException - */ - protected function parseBackground() - { - $token = $this->expectTokenType('Background'); - - $title = trim($token['value']); - $keyword = $token['keyword']; - $line = $token['line']; - - if (count($this->popTags())) { - throw new ParserException(sprintf( - 'Background can not be tagged, but it is on line: %d%s', - $line, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - // Parse description and steps - $steps = array(); - $allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment'); - while (in_array($this->predictTokenType(), $allowedTokenTypes)) { - $node = $this->parseExpression(); - - if ($node instanceof StepNode) { - $steps[] = $this->normalizeStepNodeKeywordType($node, $steps); - continue; - } - - if (!count($steps) && is_string($node)) { - $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node); - $title .= "\n" . $text; - continue; - } - - if ("\n" === $node) { - continue; - } - - if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - } - - return new BackgroundNode(rtrim($title) ?: null, $steps, $keyword, $line); - } - - /** - * Parses scenario token & returns it's node. - * - * @return ScenarioNode - * - * @throws ParserException - */ - protected function parseScenario() - { - $token = $this->expectTokenType('Scenario'); - - $title = trim($token['value']); - $tags = $this->popTags(); - $keyword = $token['keyword']; - $line = $token['line']; - - // Parse description and steps - $steps = array(); - while (in_array($this->predictTokenType(), array('Step', 'Newline', 'Text', 'Comment'))) { - $node = $this->parseExpression(); - - if ($node instanceof StepNode) { - $steps[] = $this->normalizeStepNodeKeywordType($node, $steps); - continue; - } - - if (!count($steps) && is_string($node)) { - $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node); - $title .= "\n" . $text; - continue; - } - - if ("\n" === $node) { - continue; - } - - if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - } - - return new ScenarioNode(rtrim($title) ?: null, $tags, $steps, $keyword, $line); - } - - /** - * Parses scenario outline token & returns it's node. - * - * @return OutlineNode - * - * @throws ParserException - */ - protected function parseOutline() - { - $token = $this->expectTokenType('Outline'); - - $title = trim($token['value']); - $tags = $this->popTags(); - $keyword = $token['keyword']; - $examples = null; - $line = $token['line']; - - // Parse description, steps and examples - $steps = array(); - while (in_array($this->predictTokenType(), array('Step', 'Examples', 'Newline', 'Text', 'Comment'))) { - $node = $this->parseExpression(); - - if ($node instanceof StepNode) { - $steps[] = $this->normalizeStepNodeKeywordType($node, $steps); - continue; - } - - if ($node instanceof ExampleTableNode) { - $examples = $node; - continue; - } - - if (!count($steps) && is_string($node)) { - $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node); - $title .= "\n" . $text; - continue; - } - - if ("\n" === $node) { - continue; - } - - if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step or Examples table, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step or Examples table, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); - } - } - - if (null === $examples) { - throw new ParserException(sprintf( - 'Outline should have examples table, but got none for outline "%s" on line: %d%s', - rtrim($title), - $line, - $this->file ? ' in file: ' . $this->file : '' - )); - } - - return new OutlineNode(rtrim($title) ?: null, $tags, $steps, $examples, $keyword, $line); - } - - /** - * Parses step token & returns it's node. - * - * @return StepNode - */ - protected function parseStep() - { - $token = $this->expectTokenType('Step'); - - $keyword = $token['value']; - $keywordType = $token['keyword_type']; - $text = trim($token['text']); - $line = $token['line']; - - $arguments = array(); - while (in_array($predicted = $this->predictTokenType(), array('PyStringOp', 'TableRow', 'Newline', 'Comment'))) { - if ('Comment' === $predicted || 'Newline' === $predicted) { - $this->acceptTokenType($predicted); - continue; - } - - $node = $this->parseExpression(); - - if ($node instanceof PyStringNode || $node instanceof TableNode) { - $arguments[] = $node; - } - } - - return new StepNode($keyword, $text, $arguments, $line, $keywordType); - } - - /** - * Parses examples table node. - * - * @return ExampleTableNode - */ - protected function parseExamples() - { - $token = $this->expectTokenType('Examples'); - - $keyword = $token['keyword']; - - return new ExampleTableNode($this->parseTableRows(), $keyword); - } - - /** - * Parses table token & returns it's node. - * - * @return TableNode - */ - protected function parseTable() - { - return new TableNode($this->parseTableRows()); - } - - /** - * Parses PyString token & returns it's node. - * - * @return PyStringNode - */ - protected function parsePyString() - { - $token = $this->expectTokenType('PyStringOp'); - - $line = $token['line']; - - $strings = array(); - while ('PyStringOp' !== ($predicted = $this->predictTokenType()) && 'Text' === $predicted) { - $token = $this->expectTokenType('Text'); - - $strings[] = $token['value']; - } - - $this->expectTokenType('PyStringOp'); - - return new PyStringNode($strings, $line); - } - - /** - * Parses tags. - * - * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string - */ - protected function parseTags() - { - $token = $this->expectTokenType('Tag'); - $this->tags = array_merge($this->tags, $token['tags']); - - return $this->parseExpression(); - } - - /** - * Returns current set of tags and clears tag buffer. - * - * @return array - */ - protected function popTags() - { - $tags = $this->tags; - $this->tags = array(); - - return $tags; - } - - /** - * Parses next text line & returns it. - * - * @return string - */ - protected function parseText() - { - $token = $this->expectTokenType('Text'); - - return $token['value']; - } - - /** - * Parses next newline & returns \n. - * - * @return string - */ - protected function parseNewline() - { - $this->expectTokenType('Newline'); - - return "\n"; - } - - /** - * Parses next comment token & returns it's string content. - * - * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string - */ - protected function parseComment() - { - $this->expectTokenType('Comment'); - - return $this->parseExpression(); - } - - /** - * Parses language block and updates lexer configuration based on it. - * - * @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string - * - * @throws ParserException - */ - protected function parseLanguage() - { - $token = $this->expectTokenType('Language'); - - if (null === $this->languageSpecifierLine) { - $this->lexer->analyse($this->input, $token['value']); - $this->languageSpecifierLine = $token['line']; - } elseif ($token['line'] !== $this->languageSpecifierLine) { - throw new ParserException(sprintf( - 'Ambiguous language specifiers on lines: %d and %d%s', - $this->languageSpecifierLine, - $token['line'], - $this->file ? ' in file: ' . $this->file : '' - )); - } - - return $this->parseExpression(); - } - - /** - * Parses the rows of a table - * - * @return string[][] - */ - private function parseTableRows() - { - $table = array(); - while (in_array($predicted = $this->predictTokenType(), array('TableRow', 'Newline', 'Comment'))) { - if ('Comment' === $predicted || 'Newline' === $predicted) { - $this->acceptTokenType($predicted); - continue; - } - - $token = $this->expectTokenType('TableRow'); - - $table[$token['line']] = $token['columns']; - } - - return $table; - } - - /** - * Changes step node type for types But, And to type of previous step if it exists else sets to Given - * - * @param StepNode $node - * @param StepNode[] $steps - * @return StepNode - */ - private function normalizeStepNodeKeywordType(StepNode $node, array $steps = array()) - { - if (in_array($node->getKeywordType(), array('And', 'But'))) { - if (($prev = end($steps))) { - $keywordType = $prev->getKeywordType(); - } else { - $keywordType = 'Given'; - } - - $node = new StepNode( - $node->getKeyword(), - $node->getText(), - $node->getArguments(), - $node->getLine(), - $keywordType - ); - } - return $node; - } -}