diff --git a/grammar/tatsu.ebnf b/grammar/tatsu.ebnf
index 6ff697e..f017615 100644
--- a/grammar/tatsu.ebnf
+++ b/grammar/tatsu.ebnf
@@ -25,9 +25,13 @@ directive
     =
     '@@' !'keyword' ~
     (
-            name:('comments' | 'eol_comments' | 'whitespace') ~
+            name:('comments' | 'eol_comments') ~
             ~
             '::' ~ value:regex
+        |
+            name:('whitespace') ~
+            ~
+            '::' ~ value:(regex|'None'|'False'|`None`)
         |
             name:('nameguard' | 'ignorecase' | 'left_recursion' | 'parseinfo')
             ~
@@ -40,7 +44,7 @@ directive
             name:('namechars')
             ~
             '::' ~ value:string
-    )
+    ) ~
     ;
 
 
diff --git a/tatsu/bootstrap.py b/tatsu/bootstrap.py
index b8db14f..88103ff 100644
--- a/tatsu/bootstrap.py
+++ b/tatsu/bootstrap.py
@@ -18,6 +18,7 @@ import sys
 from tatsu.buffering import Buffer
 from tatsu.parsing import Parser
 from tatsu.parsing import tatsumasu, leftrec, nomemo
+from tatsu.parsing import leftrec, nomemo  # noqa
 from tatsu.util import re, generic_main  # noqa
 
 
@@ -120,8 +121,6 @@ class EBNFBootstrapParser(Parser):
                                 self._token('comments')
                             with self._option():
                                 self._token('eol_comments')
-                            with self._option():
-                                self._token('whitespace')
                             self._error('no available options')
                     self.name_last_node('name')
                     self._cut()
@@ -130,6 +129,26 @@ class EBNFBootstrapParser(Parser):
                     self._cut()
                     self._regex_()
                     self.name_last_node('value')
+                with self._option():
+                    with self._group():
+                        self._token('whitespace')
+                    self.name_last_node('name')
+                    self._cut()
+                    self._cut()
+                    self._token('::')
+                    self._cut()
+                    with self._group():
+                        with self._choice():
+                            with self._option():
+                                self._regex_()
+                            with self._option():
+                                self._token('None')
+                            with self._option():
+                                self._token('False')
+                            with self._option():
+                                self._constant('None')
+                            self._error('no available options')
+                    self.name_last_node('value')
                 with self._option():
                     with self._group():
                         with self._choice():
@@ -174,6 +193,7 @@ class EBNFBootstrapParser(Parser):
                     self._string_()
                     self.name_last_node('value')
                 self._error('no available options')
+        self._cut()
         self.ast._define(
             ['name', 'value'],
             []
diff --git a/tatsu/codegen/python.py b/tatsu/codegen/python.py
index 13bbf13..f02c55b 100644
--- a/tatsu/codegen/python.py
+++ b/tatsu/codegen/python.py
@@ -495,6 +495,7 @@ class Grammar(Base):
                 from tatsu.buffering import Buffer
                 from tatsu.parsing import Parser
                 from tatsu.parsing import tatsumasu, leftrec, nomemo
+                from tatsu.parsing import leftrec, nomemo  # noqa
                 from tatsu.util import re, generic_main  # noqa
 
 
diff --git a/tatsu/parser_semantics.py b/tatsu/parser_semantics.py
index 3d8daf8..f0a16ea 100644
--- a/tatsu/parser_semantics.py
+++ b/tatsu/parser_semantics.py
@@ -121,6 +121,10 @@ class EBNFGrammarSemantics(ModelBuilderSemantics):
     def grammar(self, ast, *args):
         directives = OrderedDict((d.name, d.value) for d in ast.directives)
         keywords = set(ast.keywords or [])
+
+        if directives.get('whitespace') in ('None', 'False'):
+            directives['whitespace'] = ''
+
         return grammars.Grammar(
             self.grammar_name,
             list(self.rules.values()),

Allow False as a value for @@whitespace
Currently using this inside my grammar:
```
@@whitespace :: /(?!)/
```
which doesn't match anything.
```
@@whitespace :: False
```
would be more descriptive and probably more performant. `True` would set it to the default value.
Alternatively it could accept a string and then convert it to a regex, just like it does when calling parse with `whitespace=...`
diff --git a/test/grammar/directive_test.py b/test/grammar/directive_test.py
index b91e86e..530def0 100644
--- a/test/grammar/directive_test.py
+++ b/test/grammar/directive_test.py
@@ -4,6 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
 import unittest
 
 import tatsu
+from tatsu.exceptions import FailedParse
 from tatsu.util import trim
 from tatsu.codegen import codegen
 
@@ -23,6 +24,31 @@ class DirectiveTests(unittest.TestCase):
         code = codegen(model)
         compile('test.py', code, EXEC)
 
+    def test_whitespace_none_directive(self):
+        grammars = [
+            '''
+                @@whitespace :: None
+                @@nameguard :: False
+
+                test = {'x'}+ $;
+            ''',
+            '''
+                @@whitespace :: False
+                @@nameguard :: False
+
+                test = {'x'}+ $;
+            ''',
+        ]
+        for grammar in grammars:
+            model = tatsu.compile(grammar, "test")
+            self.assertEquals(['x', 'x'], model.parse('xx', trace=True))
+            try:
+                self.assertEquals(['x', 'x'], model.parse('x x', trace=True))
+            except FailedParse:
+                pass
+            else:
+                self.fail('parsed through non-whitespace')
+
     def test_eol_comments_re_directive(self):
         grammar = '''
             @@eol_comments :: /#.*?$/

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-flake8 pytest-mypy pytest-pylint
3.9
requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==3.3.9
dill==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
flake8==7.2.0
iniconfig==2.1.0
isort==6.0.1
mccabe==0.7.0
mypy==1.15.0
mypy-extensions==1.0.0
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pycodestyle==2.13.0
pyflakes==3.3.1
pylint==3.3.6
pytest==8.3.5
pytest-flake8==1.3.0
pytest-mypy==1.0.0
pytest-pylint==0.21.0
-e git+https://github.com/neogeny/TatSu.git@0b8b13530e9da7a6979aaa038b80316893e25f94#egg=TatSu
tomli==2.2.1
tomlkit==0.13.2
typing_extensions==4.13.0

name: TatSu
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==3.3.9
      - dill==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - flake8==7.2.0
      - iniconfig==2.1.0
      - isort==6.0.1
      - mccabe==0.7.0
      - mypy==1.15.0
      - mypy-extensions==1.0.0
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pylint==3.3.6
      - pytest==8.3.5
      - pytest-flake8==1.3.0
      - pytest-mypy==1.0.0
      - pytest-pylint==0.21.0
      - tomli==2.2.1
      - tomlkit==0.13.2
      - typing-extensions==4.13.0
prefix: /opt/conda/envs/TatSu

test/grammar/directive_test.py::DirectiveTests::test_whitespace_none_directive
test/grammar/directive_test.py::DirectiveTests::test_eol_comments_re_directive test/grammar/directive_test.py::DirectiveTests::test_grammar_directive test/grammar/directive_test.py::DirectiveTests::test_left_recursion_directive test/grammar/directive_test.py::DirectiveTests::test_nameguard_directive test/grammar/directive_test.py::DirectiveTests::test_parseinfo_directive test/grammar/directive_test.py::DirectiveTests::test_whitespace_directive test/grammar/directive_test.py::DirectiveTests::test_whitespace_no_newlines
tatsu/parser_semantics.py tatsu/codegen/python.py tatsu/bootstrap.py grammar/tatsu.ebnf
tatsu/parser_semantics.py tatsu/codegen/python.py tatsu/bootstrap.py grammar/tatsu.ebnf