From fc87625a72b7f235b3a7355fbde648d95796d3ae Mon Sep 17 00:00:00 2001 From: envoyr Date: Thu, 27 Oct 2022 19:07:18 +0200 Subject: [PATCH] add php 8.1 compability, remove console command --- .coveralls.yml | 3 - .travis.yml | 25 ------ LICENSE | 1 + README.md | 14 +--- bin/ngxconf | 2 +- build.xml | 21 ----- composer.json | 35 +++------ examples/build.php | 4 +- phpcs.xml | 11 --- phpspec.yml | 15 ---- phpunit.xml | 27 ------- src/Builder.php | 2 +- src/Command/AddLocationCommand.php | 76 ------------------- src/Command/AddServerCommand.php | 55 -------------- src/Command/AddUpstreamCommand.php | 22 ------ src/Command/AddUpstreamServerCommand.php | 23 ------ src/Command/BaseCommand.php | 55 -------------- src/Command/RemoveLocationCommand.php | 23 ------ src/Command/RemoveServerCommand.php | 52 ------------- src/Command/RemoveUpstream.php | 22 ------ src/Command/RemoveUpstreamServerCommand.php | 23 ------ src/Config/Events.php | 2 +- src/Config/Http.php | 2 +- src/Config/Location.php | 2 +- src/Config/Server.php | 2 +- src/Config/Upstream.php | 2 +- src/Exception/GrammarException.php | 2 +- .../UnrecognizedContextException.php | 2 +- src/Factory.php | 2 +- src/Node/Context.php | 2 +- src/Node/Directive.php | 2 +- src/Node/Literal.php | 2 +- src/Node/Node.php | 2 +- src/Node/Param.php | 2 +- src/Node/RootNode.php | 2 +- src/Parser.php | 2 +- 36 files changed, 35 insertions(+), 506 deletions(-) delete mode 100644 .coveralls.yml delete mode 100644 .travis.yml delete mode 100644 build.xml delete mode 100644 phpcs.xml delete mode 100644 phpspec.yml delete mode 100644 phpunit.xml delete mode 100644 src/Command/AddLocationCommand.php delete mode 100644 src/Command/AddServerCommand.php delete mode 100644 src/Command/AddUpstreamCommand.php delete mode 100644 src/Command/AddUpstreamServerCommand.php delete mode 100644 src/Command/BaseCommand.php delete mode 100644 src/Command/RemoveLocationCommand.php delete mode 100644 src/Command/RemoveServerCommand.php delete mode 100644 src/Command/RemoveUpstream.php delete mode 100644 src/Command/RemoveUpstreamServerCommand.php diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index 585ab53..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1,3 +0,0 @@ -# for php-coveralls -coverage_clover: tests/coverage/clover.xml -json_path: tests/coverage/coveralls-upload.json \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 33e73da..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: php - -php: - - 7.0 - - nightly - -sudo: false - -matrix: - allow_failures: - - php: hhvm - - php: nightly - -before_install: - - composer self-update - -install: - - composer install --prefer-dist --no-interaction - -script: - - bin/phpspec run --format=pretty --no-code-generation - - bin/phpcov merge --clover tests/coverage/clover.xml tests/coverage - -after_success: - - travis_retry php bin/coveralls -v \ No newline at end of file diff --git a/LICENSE b/LICENSE index 2b4fc61..a2c9783 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2016 Madkom S.A. +Copyright (c) 2022 envoyr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index a74f458..fa0ea7f 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,7 @@ NGINX Configurator PHP Library for NGINX configuration parser/generator -![PHP 7.0](https://img.shields.io/badge/PHP-7.0-8C9CB6.svg?style=flat) -[![Build Status](https://travis-ci.org/madkom/nginx-configurator.svg?branch=master)](https://travis-ci.org/madkom/nginx-configurator) -[![Latest Stable Version](https://poser.pugx.org/madkom/nginx-configurator/v/stable)](https://packagist.org/packages/madkom/nginx-configurator) -[![Total Downloads](https://poser.pugx.org/madkom/nginx-configurator/downloads)](https://packagist.org/packages/madkom/nginx-configurator) -[![License](https://poser.pugx.org/madkom/nginx-configurator/license)](https://packagist.org/packages/madkom/nginx-configurator) -[![Coverage Status](https://coveralls.io/repos/github/madkom/nginx-configurator/badge.svg?branch=master)](https://coveralls.io/github/madkom/nginx-configurator?branch=master) -[![Code Climate](https://codeclimate.com/github/madkom/nginx-configurator/badges/gpa.svg)](https://codeclimate.com/github/madkom/nginx-configurator) -[![Issue Count](https://codeclimate.com/github/madkom/nginx-configurator/badges/issue_count.svg)](https://codeclimate.com/github/madkom/nginx-configurator) +![PHP 8.1](https://img.shields.io/badge/PHP-8.1-8C9CB6.svg?style=flat) --- @@ -25,12 +18,12 @@ In near future will provide CLI commands for NGINX configuration. Install with Composer ``` -composer require madkom/nginx-configurator +composer require envoyr/nginx-configurator ``` ## Requirements -This library requires *PHP* in `~7` version. +This library requires *PHP* in `>=8.1` version. ## Usage @@ -215,6 +208,7 @@ $builder->dumpFile('generated.conf'); The MIT License (MIT) Copyright (c) 2016 Madkom S.A. +Copyright (c) 2022 envoyr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/bin/ngxconf b/bin/ngxconf index b6075d9..0765388 100755 --- a/bin/ngxconf +++ b/bin/ngxconf @@ -1,6 +1,6 @@ #!/usr/bin/env php - - - - - - - - - - - - \ No newline at end of file diff --git a/composer.json b/composer.json index 5de6741..512f1f1 100644 --- a/composer.json +++ b/composer.json @@ -1,38 +1,23 @@ { - "name": "madkom/nginx-configurator", + "name": "envoyr/nginx-configurator", "license": "MIT", - "homepage": "http://madkom.pl/", + "homepage": "https://envoyr.com/", "minimum-stability": "dev", "require": { - "madkom/collection": "1.*", - "ferno/loco": "@dev", - "madkom/uri": "1.*" + "envoyr/collection": "dev-main", + "envoyr/loco": "dev-main" }, - "require-dev": { - "henrikbjorn/phpspec-code-coverage": "^2.0.2", - "phpspec/phpspec": "^2.5", - "phpunit/phpunit": "~4", - "knplabs/phpspec-welldone-extension": "dev-master", - "squizlabs/php_codesniffer": "^2.3", - "phpunit/phpcov": "*", - "jakub-onderka/php-parallel-lint": "0.*", - "jakub-onderka/php-console-highlighter": "0.*", - "satooshi/php-coveralls": "dev-master", - "clover/dump": "dev-master", - "symfony/var-dumper": "^3.1" - }, - "repositories": [ - { - "type": "vcs", - "url": "git@github.com:madkom/loco.git" - } - ], + "require-dev": {}, "autoload": { "psr-4": { - "Madkom\\NginxConfigurator\\": "src/" + "Envoyr\\NginxConfigurator\\": "src/" } }, "authors": [ + { + "name": "envoyr", + "email": "hello@envoyr.com" + }, { "name": "Michał Brzuchalski", "email": "m.brzuchalski@madkom.pl" diff --git a/examples/build.php b/examples/build.php index 0174927..529bbb6 100644 --- a/examples/build.php +++ b/examples/build.php @@ -2,15 +2,17 @@ use Madkom\NginxConfigurator\Builder; use Madkom\NginxConfigurator\Config\Location; +use Madkom\NginxConfigurator\Factory; use Madkom\NginxConfigurator\Node\Directive; use Madkom\NginxConfigurator\Node\Literal; use Madkom\NginxConfigurator\Node\Param; require __DIR__ . '/../vendor/autoload.php'; +$factory = new Factory(); $builder = new Builder(); -$server = $builder->addServerNode(80); +$server = $builder->append($factory->createServer(80)); $server->append(new Directive('error_log', [new Param('/var/log/nginx/error.log'), new Param('debug')])); $server->append(new Location(new Param('/test'), null, [ new Directive('error_page', [new Param('401'), new Param('@unauthorized')]), diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 7668727..0000000 --- a/phpcs.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - Project Coding Standard - ./src - - - - - - - \ No newline at end of file diff --git a/phpspec.yml b/phpspec.yml deleted file mode 100644 index b33a7fc..0000000 --- a/phpspec.yml +++ /dev/null @@ -1,15 +0,0 @@ -extensions: - - PhpSpec\Extension\CodeCoverageExtension - - Knp\PhpSpec\WellDone\Extension - -suites: - types: - namespace: Madkom\NginxConfigurator - psr4_prefix: Madkom\NginxConfigurator - spec_path: tests - -code_coverage: - output: tests/coverage/phpspec.cov - format: php - -formatter.name: pretty \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index bf027e9..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - ./tests/phpunit/ - ./vendor - ./app - - - - - ./vendor - ./app - ./bin - ./tests - ./var/bootstrap.php.cache - - - - - - - \ No newline at end of file diff --git a/src/Builder.php b/src/Builder.php index efcba61..63e103d 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -5,7 +5,7 @@ * Date: 18.04.16 * Time: 11:06 */ -namespace Madkom\NginxConfigurator; +namespace Envoyr\NginxConfigurator; use Countable; use Madkom\Collection\CustomTypedCollection; diff --git a/src/Command/AddLocationCommand.php b/src/Command/AddLocationCommand.php deleted file mode 100644 index 76d1191..0000000 --- a/src/Command/AddLocationCommand.php +++ /dev/null @@ -1,76 +0,0 @@ - - */ -class AddLocationCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('location:add'); - $this->setDescription("Adds location context and configuration"); - $this->addArgument('name', InputArgument::OPTIONAL, 'Server hostname:port', 'localhost:80'); - $this->addOption('internal', null, InputOption::VALUE_NONE, 'Adds internal directive'); - $this->addOption( - 'proxy_pass', - null, - InputOption::VALUE_OPTIONAL, - 'Adds proxy_pass url (eg. http://proxy/)' - ); - $this->addOption( - 'proxy_bind', - null, - InputOption::VALUE_OPTIONAL, - 'Adds proxy_bind directive url or variable (eg. $server_addr)' - ); - $this->addOption( - 'proxy_redirect', - null, - InputOption::VALUE_OPTIONAL ^ InputOption::VALUE_IS_ARRAY, - 'Adds proxy_redirect directive (eg. http://$host or https://$host)' - ); - $this->addOption( - 'proxy_set_header', - null, - InputOption::VALUE_OPTIONAL ^ InputOption::VALUE_IS_ARRAY, - 'Adds proxy_set_header directive (eg. "Content-Type: text/html"' - ); - $this->addOption( - 'proxy_pass_request_body', - null, - InputOption::VALUE_OPTIONAL, - 'Adds proxy_pass_requeest_body directive (on|off)', - 'on' - ); - -// // new Directive('internal'), -// new Directive('expires', [new Param('-1')]), -// new Directive('proxy_pass', [new Param('http://172.17.0.1:7777')]), -// new Directive('proxy_bind', [new Param('$server_addr')]), -// new Directive('proxy_redirect', [new Param('http://$host'), new Param('https://$host')]), -// new Directive('proxy_set_header', [new Param('Content-Length'), new Literal("")]), -// new Directive('proxy_pass_request_body', [new Param('off')]), - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - - $proxy_pass = $input->getOption('proxy_pass'); - - } -} diff --git a/src/Command/AddServerCommand.php b/src/Command/AddServerCommand.php deleted file mode 100644 index f715f90..0000000 --- a/src/Command/AddServerCommand.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ -class AddServerCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('server:add'); - $this->setDescription("Adds server context and configuration of port and name"); - $this->addArgument('name', InputArgument::OPTIONAL, 'Server hostname:port', 'localhost:80'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $filename = $input->getOption('file'); - $config = $this->getConfig($input); - - list($name, $port) = explode(':', $input->getArgument('name') . ':80'); - - $listenIPv4 = new Directive('listen', [new Param($port)]); - $listenIPv6 = new Directive('listen', [new Param("[::]:{$port}"), new Param('default'), new Param('ipv6only=on')]); - - // TODO: Find server by name - $server = new Server([$listenIPv4, $listenIPv6]); - if ($name != 'localhost' && !empty($name)) { - $server->append(new Directive('server_name', [new Param($name)])); - } - $config->append($server); - - $builder = new Builder(); - $builder->append($server); - $builder->dumpFile($filename); - } -} diff --git a/src/Command/AddUpstreamCommand.php b/src/Command/AddUpstreamCommand.php deleted file mode 100644 index 6e1ac38..0000000 --- a/src/Command/AddUpstreamCommand.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ -class AddUpstreamCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('upstream:add'); - } -} diff --git a/src/Command/AddUpstreamServerCommand.php b/src/Command/AddUpstreamServerCommand.php deleted file mode 100644 index bc68fab..0000000 --- a/src/Command/AddUpstreamServerCommand.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ -class AddUpstreamServerCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('upstream:server:add'); - $this->setDescription("Adds server directive to upstream context and configuration"); - } -} diff --git a/src/Command/BaseCommand.php b/src/Command/BaseCommand.php deleted file mode 100644 index a9c68f1..0000000 --- a/src/Command/BaseCommand.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ -abstract class BaseCommand extends Command -{ - protected function configure() - { - $this->addOption('file', 'f', InputOption::VALUE_OPTIONAL, 'Output filename', 'php://stdout'); - } - - /** - * @param InputInterface $input - * @return RootNode - * @throws Exception - */ - protected function getConfig(InputInterface $input) : RootNode - { - $filename = $input->getOption('file'); - if ($filename != 'php://stdout' && !file_exists($filename)) { - @touch($filename); - } - if ($filename != 'php://stdout' && file_exists($filename)) { - if (!is_writable($filename)) { - throw new Exception('Given filename is not writable!'); - } - } - if ($filename != 'php://stdout' && file_exists($filename)) { - $parser = new Parser(); - return $parser->parseFile($filename); - } - - return new RootNode(); - } -} diff --git a/src/Command/RemoveLocationCommand.php b/src/Command/RemoveLocationCommand.php deleted file mode 100644 index 3df1731..0000000 --- a/src/Command/RemoveLocationCommand.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ -class RemoveLocationCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('location:remove'); - $this->setDescription("Remove location context and it's configuration"); - } -} diff --git a/src/Command/RemoveServerCommand.php b/src/Command/RemoveServerCommand.php deleted file mode 100644 index 6c6cec0..0000000 --- a/src/Command/RemoveServerCommand.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -class RemoveServerCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('server:remove'); - $this->setDescription("Removes server context and it's configuration"); - $this->addArgument('name', InputArgument::OPTIONAL, 'Server hostname:port', 'localhost:80'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $filename = $input->getOption('file'); - $builder = $this->getConfig($input); - - list($name, $port) = explode(':', $input->getArgument('name') . ':80'); - - $listenIPv4 = new Directive('listen', [new Param($port)]); - $listenIPv6 = new Directive('listen', [new Param("[::]:{$port}"), new Param('default'), new Param('ipv6only=on')]); - - $server = new Server([$listenIPv4, $listenIPv6]); - if ($name != 'localhost' && !empty($name)) { - $server->append(new Directive('server_name', [new Param($name)])); - } - - $builder->appendServerNode($server); - $builder->dumpFile($filename); - } -} diff --git a/src/Command/RemoveUpstream.php b/src/Command/RemoveUpstream.php deleted file mode 100644 index 4128f8b..0000000 --- a/src/Command/RemoveUpstream.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ -class RemoveUpstreamCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('upstream:remove'); - } -} diff --git a/src/Command/RemoveUpstreamServerCommand.php b/src/Command/RemoveUpstreamServerCommand.php deleted file mode 100644 index 9a74c24..0000000 --- a/src/Command/RemoveUpstreamServerCommand.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ -class RemoveUpstreamServerCommand extends BaseCommand -{ - protected function configure() - { - parent::configure(); - $this->setName('upstream:server:remove'); - $this->setDescription("Removes server directive from upstream context and configuration"); - } -} diff --git a/src/Config/Events.php b/src/Config/Events.php index 97a66e4..ab09167 100644 --- a/src/Config/Events.php +++ b/src/Config/Events.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 20:55 */ -namespace Madkom\NginxConfigurator\Config; +namespace Envoyr\NginxConfigurator\Config; use Madkom\NginxConfigurator\Node\Context; use Madkom\NginxConfigurator\Node\Directive; diff --git a/src/Config/Http.php b/src/Config/Http.php index 1e02625..2452e9e 100644 --- a/src/Config/Http.php +++ b/src/Config/Http.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 20:57 */ -namespace Madkom\NginxConfigurator\Config; +namespace Envoyr\NginxConfigurator\Config; use Madkom\NginxConfigurator\Node\Context; use Madkom\NginxConfigurator\Node\Directive; diff --git a/src/Config/Location.php b/src/Config/Location.php index 30b4176..1aa3f73 100644 --- a/src/Config/Location.php +++ b/src/Config/Location.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 21:01 */ -namespace Madkom\NginxConfigurator\Config; +namespace Envoyr\NginxConfigurator\Config; use Madkom\NginxConfigurator\Node\Context; use Madkom\NginxConfigurator\Node\Literal; diff --git a/src/Config/Server.php b/src/Config/Server.php index 2310a86..2dbd798 100644 --- a/src/Config/Server.php +++ b/src/Config/Server.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 21:00 */ -namespace Madkom\NginxConfigurator\Config; +namespace Envoyr\NginxConfigurator\Config; use Madkom\NginxConfigurator\Node\Context; diff --git a/src/Config/Upstream.php b/src/Config/Upstream.php index 7dbc1e4..821d899 100644 --- a/src/Config/Upstream.php +++ b/src/Config/Upstream.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 21:07 */ -namespace Madkom\NginxConfigurator\Config; +namespace Envoyr\NginxConfigurator\Config; use Madkom\NginxConfigurator\Node\Context; use Madkom\NginxConfigurator\Node\Directive; diff --git a/src/Exception/GrammarException.php b/src/Exception/GrammarException.php index 70d93f2..203b585 100644 --- a/src/Exception/GrammarException.php +++ b/src/Exception/GrammarException.php @@ -5,7 +5,7 @@ * Date: 10.04.16 * Time: 09:12 */ -namespace Madkom\NginxConfigurator\Exception; +namespace Envoyr\NginxConfigurator\Exception; use Exception; diff --git a/src/Exception/UnrecognizedContextException.php b/src/Exception/UnrecognizedContextException.php index 4d10dbb..a476756 100644 --- a/src/Exception/UnrecognizedContextException.php +++ b/src/Exception/UnrecognizedContextException.php @@ -5,7 +5,7 @@ * Date: 13.04.16 * Time: 09:22 */ -namespace Madkom\NginxConfigurator\Exception; +namespace Envoyr\NginxConfigurator\Exception; use Exception; diff --git a/src/Factory.php b/src/Factory.php index 2f55bc2..bfeade2 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -5,7 +5,7 @@ * Date: 14.06.16 * Time: 11:22 */ -namespace Madkom\NginxConfigurator; +namespace Envoyr\NginxConfigurator; use Madkom\NginxConfigurator\Config\Location; use Madkom\NginxConfigurator\Config\Server; diff --git a/src/Node/Context.php b/src/Node/Context.php index 14ae923..93c5446 100644 --- a/src/Node/Context.php +++ b/src/Node/Context.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 20:53 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; /** * Class Context diff --git a/src/Node/Directive.php b/src/Node/Directive.php index 1bd8d7d..5e91194 100644 --- a/src/Node/Directive.php +++ b/src/Node/Directive.php @@ -5,7 +5,7 @@ * Date: 06.04.16 * Time: 13:40 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; use Madkom\Collection\CustomTypedCollection; use Traversable; diff --git a/src/Node/Literal.php b/src/Node/Literal.php index a85af02..5f466cd 100644 --- a/src/Node/Literal.php +++ b/src/Node/Literal.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 10:32 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; /** * Class Literal diff --git a/src/Node/Node.php b/src/Node/Node.php index 4ded3be..d840375 100644 --- a/src/Node/Node.php +++ b/src/Node/Node.php @@ -5,7 +5,7 @@ * Date: 06.04.16 * Time: 13:23 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; use Countable; use IteratorAggregate; diff --git a/src/Node/Param.php b/src/Node/Param.php index 17561ab..42c4f3d 100644 --- a/src/Node/Param.php +++ b/src/Node/Param.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 10:31 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; /** * Class Param diff --git a/src/Node/RootNode.php b/src/Node/RootNode.php index dc2391d..0ad1db4 100644 --- a/src/Node/RootNode.php +++ b/src/Node/RootNode.php @@ -5,7 +5,7 @@ * Date: 08.04.16 * Time: 21:18 */ -namespace Madkom\NginxConfigurator\Node; +namespace Envoyr\NginxConfigurator\Node; /** * Class RootNode diff --git a/src/Parser.php b/src/Parser.php index 590c7e8..da72f39 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -5,7 +5,7 @@ * Date: 06.04.16 * Time: 13:01 */ -namespace Madkom\NginxConfigurator; +namespace Envoyr\NginxConfigurator; use Ferno\Loco\ConcParser; use Ferno\Loco\Grammar;