From a16dac234e68344ad586cbbe9982956f9d88a791 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 25 Feb 2025 08:49:43 +0100
Subject: [PATCH] git subrepo pull (merge) --force --branch=main packages/PEGTL

subrepo:
  subdir:   "packages/PEGTL"
  merged:   "d7b821b1e"
upstream:
  origin:   "git@github.com:taocpp/PEGTL.git"
  branch:   "main"
  commit:   "d7b821b1e"
git-subrepo:
  version:  "0.4.9"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "30db3b8"
---
 packages/PEGTL/.clang-tidy                    |   4 +-
 packages/PEGTL/.cmake/test_filesystem.cpp.in  |  22 ---
 packages/PEGTL/.github/workflows/android.yml  |  29 ++--
 packages/PEGTL/.github/workflows/linux.yml    | 114 ++++++--------
 packages/PEGTL/.github/workflows/macos.yml    |  65 ++++----
 packages/PEGTL/.github/workflows/msys.yml     |  56 +++++++
 packages/PEGTL/.github/workflows/windows.yml  |  91 ++++--------
 packages/PEGTL/.gitrepo                       |   6 +-
 packages/PEGTL/.pkg-config/pegtl.pc.in        |   7 +
 packages/PEGTL/CMakeLists.txt                 |  73 +--------
 packages/PEGTL/README.md                      |   8 +-
 packages/PEGTL/doc/Actions-and-States.md      |   2 +-
 packages/PEGTL/doc/Changelog.md               |  27 +++-
 packages/PEGTL/doc/Contrib-and-Examples.md    |   4 +
 packages/PEGTL/doc/Control-and-Debug.md       |  20 ++-
 packages/PEGTL/doc/Errors-and-Exceptions.md   |  61 ++++----
 packages/PEGTL/doc/Getting-Started.md         |   4 +-
 packages/PEGTL/doc/Inputs-and-Parsing.md      |  28 ++--
 packages/PEGTL/doc/Installing-and-Using.md    |  22 +--
 packages/PEGTL/doc/Migration-Guide.md         |   6 +-
 packages/PEGTL/doc/README.md                  |  11 +-
 packages/PEGTL/doc/Rule-Reference.md          | 140 ++++++++++++++----
 .../PEGTL/include/tao/pegtl/buffer_input.hpp  |  19 ++-
 packages/PEGTL/include/tao/pegtl/config.hpp   |   3 +-
 .../tao/pegtl/contrib/analyze_traits.hpp      |   7 +-
 .../include/tao/pegtl/contrib/coverage.hpp    |  11 ++
 .../tao/pegtl/contrib/nested_exceptions.hpp   | 112 ++++++++++++++
 .../include/tao/pegtl/contrib/parse_tree.hpp  |  12 +-
 .../tao/pegtl/contrib/remove_first_state.hpp  |  16 +-
 .../tao/pegtl/contrib/remove_last_states.hpp  |  30 ++--
 .../tao/pegtl/contrib/shuffle_states.hpp      |  32 +++-
 .../tao/pegtl/contrib/state_control.hpp       |  13 +-
 .../PEGTL/include/tao/pegtl/contrib/trace.hpp |   7 +
 .../tao/pegtl/internal/action_input.hpp       |  28 ++--
 .../include/tao/pegtl/internal/apply.hpp      |   2 +-
 .../PEGTL/include/tao/pegtl/internal/at.hpp   |   2 +-
 .../PEGTL/include/tao/pegtl/internal/bump.hpp |   8 +-
 .../tao/pegtl/internal/extract_position.hpp   |  30 ++++
 .../include/tao/pegtl/internal/filesystem.hpp |  65 --------
 .../pegtl/internal/has_current_position.hpp   |  24 +++
 .../include/tao/pegtl/internal/if_apply.hpp   |   4 +-
 .../{frobnicator.hpp => inputerator.hpp}      |  22 +--
 .../tao/pegtl/internal/missing_apply.hpp      |   2 +-
 .../include/tao/pegtl/internal/mmap_file.hpp  |   4 +-
 .../tao/pegtl/internal/mmap_file_posix.hpp    |  33 ++---
 .../tao/pegtl/internal/mmap_file_win32.hpp    |  39 +++--
 .../PEGTL/include/tao/pegtl/internal/must.hpp |   2 +-
 .../include/tao/pegtl/internal/not_at.hpp     |   2 +-
 .../tao/pegtl/internal/path_to_string.hpp     |   9 +-
 .../tao/pegtl/internal/pegtl_string.hpp       |   2 +-
 .../tao/pegtl/internal/read_file_stdio.hpp    |  43 +++---
 .../include/tao/pegtl/internal/rematch.hpp    |   6 +-
 .../tao/pegtl/internal/rewind_guard.hpp       |   4 +-
 .../include/tao/pegtl/internal/rules.hpp      |   3 +-
 .../tao/pegtl/internal/stream_to_string.hpp   |  26 ++++
 .../pegtl/internal/try_catch_raise_nested.hpp |  97 ++++++++++++
 ...ch_type.hpp => try_catch_return_false.hpp} |  46 ++++--
 packages/PEGTL/include/tao/pegtl/match.hpp    |  14 +-
 .../PEGTL/include/tao/pegtl/memory_input.hpp  |  43 +++---
 .../PEGTL/include/tao/pegtl/mmap_input.hpp    |   6 +-
 packages/PEGTL/include/tao/pegtl/normal.hpp   |  23 ++-
 packages/PEGTL/include/tao/pegtl/parse.hpp    |  15 +-
 .../PEGTL/include/tao/pegtl/parse_error.hpp   | 114 ++++----------
 .../include/tao/pegtl/parse_error_base.hpp    |  45 ++++++
 packages/PEGTL/include/tao/pegtl/position.hpp |  13 +-
 .../PEGTL/include/tao/pegtl/read_input.hpp    |  10 +-
 .../PEGTL/include/tao/pegtl/rewind_mode.hpp   |   5 +-
 packages/PEGTL/include/tao/pegtl/rules.hpp    |  11 +-
 .../PEGTL/src/example/pegtl/abnf2pegtl.cpp    |   8 +-
 packages/PEGTL/src/example/pegtl/csv2.cpp     |   1 +
 .../PEGTL/src/example/pegtl/expression.cpp    |  14 +-
 .../PEGTL/src/example/pegtl/indent_aware.cpp  |   1 +
 packages/PEGTL/src/example/pegtl/iri.cpp      |  33 +++--
 packages/PEGTL/src/example/pegtl/json_ast.cpp |   4 +-
 .../PEGTL/src/example/pegtl/json_build.cpp    |   4 +-
 .../PEGTL/src/example/pegtl/json_coverage.cpp |   4 +-
 .../PEGTL/src/example/pegtl/json_parse.cpp    |   4 +-
 .../PEGTL/src/example/pegtl/json_trace.cpp    |   4 +-
 packages/PEGTL/src/example/pegtl/proto3.cpp   |   7 +-
 .../contrib => src/example/pegtl}/proto3.hpp  |  14 +-
 packages/PEGTL/src/example/pegtl/recover.cpp  |   2 +-
 .../PEGTL/src/example/pegtl/s_expression.cpp  |   4 +-
 .../PEGTL/src/example/pegtl/token_input.cpp   |  36 ++---
 packages/PEGTL/src/example/pegtl/uri.cpp      |  33 +++--
 packages/PEGTL/src/test/pegtl/CMakeLists.txt  |  10 +-
 .../PEGTL/src/test/pegtl/actions_three.cpp    |   2 +-
 packages/PEGTL/src/test/pegtl/actions_two.cpp |   9 +-
 .../PEGTL/src/test/pegtl/contrib_coverage.cpp |   6 +-
 .../src/test/pegtl/contrib_parse_tree.cpp     |   2 +-
 .../test/pegtl/contrib_remove_first_state.cpp |   2 +-
 .../test/pegtl/contrib_remove_last_states.cpp |   2 +-
 .../src/test/pegtl/contrib_state_control.cpp  |  56 ++++++-
 .../PEGTL/src/test/pegtl/contrib_trace1.cpp   |   2 +-
 .../PEGTL/src/test/pegtl/contrib_trace2.cpp   |   2 +-
 packages/PEGTL/src/test/pegtl/file_read.cpp   |   2 +-
 .../src/test/pegtl/internal_file_mapper.cpp   |   2 +-
 packages/PEGTL/src/test/pegtl/parse_error.cpp |  10 +-
 packages/PEGTL/src/test/pegtl/position.cpp    |  40 ++---
 packages/PEGTL/src/test/pegtl/rule_rep.cpp    |  14 +-
 .../PEGTL/src/test/pegtl/rule_rep_min_max.cpp |   2 +-
 .../pegtl/rule_try_catch_raise_nested.cpp     |  53 +++++++
 ...ch.cpp => rule_try_catch_return_false.cpp} |  10 +-
 packages/PEGTL/src/test/pegtl/rule_until.cpp  |   6 +-
 packages/PEGTL/src/test/pegtl/test.hpp        |  28 ++--
 packages/PEGTL/src/test/pegtl/verify_file.hpp |   4 +-
 packages/PEGTL/src/test/pegtl/verify_seqs.hpp |  12 +-
 src/language/PEGGrammar.hpp                   |   6 +-
 tests/test_ASTNode.cpp                        |  14 +-
 tests/test_ASTNodeDataType.cpp                |  48 +++---
 .../test_ASTNodeNaturalConversionChecker.cpp  |  16 +-
 tests/test_ParseError.cpp                     |   6 +-
 tests/test_SymbolTable.cpp                    |  16 +-
 112 files changed, 1444 insertions(+), 975 deletions(-)
 delete mode 100644 packages/PEGTL/.cmake/test_filesystem.cpp.in
 create mode 100644 packages/PEGTL/.github/workflows/msys.yml
 create mode 100644 packages/PEGTL/.pkg-config/pegtl.pc.in
 create mode 100644 packages/PEGTL/include/tao/pegtl/contrib/nested_exceptions.hpp
 create mode 100644 packages/PEGTL/include/tao/pegtl/internal/extract_position.hpp
 delete mode 100644 packages/PEGTL/include/tao/pegtl/internal/filesystem.hpp
 create mode 100644 packages/PEGTL/include/tao/pegtl/internal/has_current_position.hpp
 rename packages/PEGTL/include/tao/pegtl/internal/{frobnicator.hpp => inputerator.hpp} (61%)
 create mode 100644 packages/PEGTL/include/tao/pegtl/internal/stream_to_string.hpp
 create mode 100644 packages/PEGTL/include/tao/pegtl/internal/try_catch_raise_nested.hpp
 rename packages/PEGTL/include/tao/pegtl/internal/{try_catch_type.hpp => try_catch_return_false.hpp} (54%)
 create mode 100644 packages/PEGTL/include/tao/pegtl/parse_error_base.hpp
 rename packages/PEGTL/{include/tao/pegtl/contrib => src/example/pegtl}/proto3.hpp (97%)
 create mode 100644 packages/PEGTL/src/test/pegtl/rule_try_catch_raise_nested.cpp
 rename packages/PEGTL/src/test/pegtl/{rule_try_catch.cpp => rule_try_catch_return_false.cpp} (64%)

diff --git a/packages/PEGTL/.clang-tidy b/packages/PEGTL/.clang-tidy
index d938e19e0..b4ec5b208 100644
--- a/packages/PEGTL/.clang-tidy
+++ b/packages/PEGTL/.clang-tidy
@@ -5,6 +5,8 @@
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
+# Enable google-readability-casting again when it doesn't give false positives for C-style casts.
+
 Checks: >-
   bugprone-*,
   -bugprone-easily-swappable-parameters,
@@ -14,7 +16,7 @@ Checks: >-
   google-build-namespaces,
   google-default-arguments,
   google-global-names-in-headers,
-  google-readability-casting,
+  -google-readability-casting,
   llvm-*,
   -llvm-namespace-comment,
   misc-*,
diff --git a/packages/PEGTL/.cmake/test_filesystem.cpp.in b/packages/PEGTL/.cmake/test_filesystem.cpp.in
deleted file mode 100644
index 587e5f320..000000000
--- a/packages/PEGTL/.cmake/test_filesystem.cpp.in
+++ /dev/null
@@ -1,22 +0,0 @@
-// This is a dummy program that just needs to compile and link to tell us if
-// the C++17 std::filesystem API is available. Use CMake's configure_file
-// command to replace the FILESYSTEM_HEADER and FILESYSTEM_NAMESPACE tokens
-// for each combination of headers and namespaces which we want to pass to the
-// CMake try_compile command.
-
-#include <@FILESYSTEM_HEADER@>
-
-// clang-format off
-int main()
-{
-#if defined( __cpp_exceptions )
-   try {
-      throw @FILESYSTEM_NAMESPACE@::filesystem_error( "instantiate one to make sure it links", std::make_error_code( std::errc::function_not_supported ) );
-   }
-   catch( const @FILESYSTEM_NAMESPACE@::filesystem_error& error ) {
-      return -1;
-   }
-#endif
-
-   return !@FILESYSTEM_NAMESPACE@::temp_directory_path().is_absolute();
-}
diff --git a/packages/PEGTL/.github/workflows/android.yml b/packages/PEGTL/.github/workflows/android.yml
index 11b3c2e00..865c2c568 100644
--- a/packages/PEGTL/.github/workflows/android.yml
+++ b/packages/PEGTL/.github/workflows/android.yml
@@ -15,8 +15,6 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        image:
-          - r22
         platform:
           - android-27
           - android-29
@@ -24,16 +22,23 @@ jobs:
           - armeabi-v7a
           - arm64-v8a
         build_type: [Debug, Release]
-
-    runs-on: ubuntu-latest
-
-    container:
-      image: bojoe/cpp-android-ndk-build-env-ubuntu:${{ matrix.image }}
-      options: --user root
-
+    runs-on: ubuntu-24.04
     steps:
-      - uses: actions/checkout@v3
+      - name: Install Dependencies
+        run: |
+          sudo apt -qq update
+          sudo apt -qq install -y ninja-build --no-install-recommends --no-install-suggests
+
+      - uses: actions/checkout@v4
 
-      - run: cmake -H$GITHUB_WORKSPACE -B/home/developer/build -GNinja -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.abi }} -DANDROID_PLATFORM=${{ matrix.platform }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+      - name: Configure CMake
+        run: |
+          cmake -S $GITHUB_WORKSPACE -B build \
+          -GNinja \
+          -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
+          -DANDROID_ABI=${{ matrix.abi }} \
+          -DANDROID_PLATFORM=${{ matrix.platform }} \
+          -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
 
-      - run: cmake --build /home/developer/build
+      - name: Build project
+        run: cmake --build build/
diff --git a/packages/PEGTL/.github/workflows/linux.yml b/packages/PEGTL/.github/workflows/linux.yml
index b3f95a4f2..5eb47e8b0 100644
--- a/packages/PEGTL/.github/workflows/linux.yml
+++ b/packages/PEGTL/.github/workflows/linux.yml
@@ -11,75 +11,55 @@ on:
       - 'doc/**'
 
 jobs:
-  linux:
+  linux-build:
     strategy:
       fail-fast: false
       matrix:
-        compiler:
-          - g++-9
-          - g++-10
-          - g++-11
-          - g++-12
-          - clang++-12
-          - clang++-13
-          - clang++-14
-        build_type: [Debug, Release]
-
-    runs-on: ubuntu-latest
-
-    env:
-      CXX: ${{ matrix.compiler }}
-
-    steps:
-    - uses: actions/checkout@v3
-
-    - run: cmake -E make_directory build
-
-    - working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-
-    - working-directory: build/
-      run: cmake --build .
-
-    - working-directory: build/
-      run: ctest --output-on-failure
-
-  linux-old:
-    strategy:
-      fail-fast: false
-      matrix:
-        compiler:
-          - g++-8
-          - clang++-6.0
-          - clang++-7
-          - clang++-8
-          - clang++-9
-          - clang++-10
-          - clang++-11
-        build_type: [Debug, Release]
-
-    runs-on: ubuntu-20.04
-
-    env:
-      CXX: ${{ matrix.compiler }}
+        platform:
+          - os: ubuntu-24.04
+            compiler: g++-12
+          - os: ubuntu-24.04
+            compiler: g++-13
+          - os: ubuntu-24.04
+            compiler: g++-14
+          - os: ubuntu-24.04
+            compiler: clang++-16
+          - os: ubuntu-24.04
+            compiler: clang++-17
+          - os: ubuntu-24.04
+            compiler: clang++-18
+          - os: ubuntu-22.04
+            compiler: g++-11
+          - os: ubuntu-22.04
+            compiler: clang++-13
+          - os: ubuntu-22.04
+            compiler: clang++-14
+          - os: ubuntu-22.04
+            compiler: clang++-15
+        build_type: [Release, Debug]
+    runs-on: ${{ matrix.platform.os }}
 
     steps:
-    - uses: actions/checkout@v3
+      - name: Install Dependencies
+        run: |
+          sudo apt -qq update
+          sudo apt -qq install -y ninja-build --no-install-recommends --no-install-suggests
 
-    - run: sudo apt-get update -y
+      - uses: actions/checkout@v4
 
-    - run: sudo apt-get install -y ${{ matrix.compiler }}
+      - name: Configure CMake
+        run: |
+          cmake -S $GITHUB_WORKSPACE -B build \
+          -GNinja \
+          -DCMAKE_CXX_COMPILER=${{ matrix.platform.compiler }} \
+          -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
 
-    - run: cmake -E make_directory build
-
-    - working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-
-    - working-directory: build/
-      run: cmake --build .
+      - name: Build project
+        run: cmake --build build/
 
-    - working-directory: build/
-      run: ctest --output-on-failure
+      - name: Run tests
+        working-directory: build/
+        run: ctest -C ${{ matrix.build_type }} --output-on-failure
 
   linux-gcc-extra:
     strategy:
@@ -88,15 +68,16 @@ jobs:
         flags: ["-fno-rtti", "-fno-exceptions"]
         build_type: [Debug, Release]
 
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
+    - uses: seanmiddleditch/gha-setup-ninja@v5
 
     - run: cmake -E make_directory build
 
     - working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}"
+      run: cmake $GITHUB_WORKSPACE -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}"
 
     - working-directory: build/
       run: cmake --build .
@@ -111,18 +92,19 @@ jobs:
         flags: ["-fno-rtti", "-fno-exceptions", "-fms-extensions"]
         build_type: [Debug, Release]
 
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
 
     env:
       CXX: clang++
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
+    - uses: seanmiddleditch/gha-setup-ninja@v5
 
     - run: cmake -E make_directory build
 
     - working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}"
+      run: cmake $GITHUB_WORKSPACE -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}"
 
     - working-directory: build/
       run: cmake --build .
diff --git a/packages/PEGTL/.github/workflows/macos.yml b/packages/PEGTL/.github/workflows/macos.yml
index 842b1ab7c..157ae3539 100644
--- a/packages/PEGTL/.github/workflows/macos.yml
+++ b/packages/PEGTL/.github/workflows/macos.yml
@@ -16,46 +16,39 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - xcode: 11
+          - llvm: 18
             build_type: Debug
-            os: macos-11
-          - xcode: 11
+            os: macos-14
+          - llvm: 18
             build_type: Release
-            os: macos-11
-          - xcode: 12
+            os: macos-14
+          - llvm: 16
             build_type: Debug
-            os: macos-11
-          - xcode: 12
+            os: macos-13
+          - llvm: 16
             build_type: Release
-            os: macos-11
-          - xcode: 13
-            build_type: Debug
-            os: macos-12
-          - xcode: 13
-            build_type: Release
-            os: macos-12
-          - xcode: 14
-            build_type: Debug
-            os: macos-12
-          - xcode: 14
-            build_type: Release
-            os: macos-12
+            os: macos-13
     runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v3
-
-    - uses: maxim-lobanov/setup-xcode@v1
-      with:
-        xcode-version: ${{ matrix.xcode }}
-
-    - run: cmake -E make_directory build
-
-    - working-directory: build/
-      run: cmake $GITHUB_WORKSPACE
-
-    - working-directory: build/
-      run: cmake --build . --config ${{ matrix.build_type }}
-
-    - working-directory: build/
-      run: ctest --config ${{ matrix.build_type }} --output-on-failure
+    - name: Install Dependencies
+      run: |
+        brew update
+        brew install llvm@${{ matrix.llvm }}
+        brew install ninja
+
+    - uses: actions/checkout@v4
+    - name: Configure CMake
+      run: |
+        cmake -S $GITHUB_WORKSPACE -B build \
+          -GNinja \
+          -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
+          -DCMAKE_CXX_COMPILER=$(brew --prefix llvm@${{ matrix.llvm }})/bin/clang++ \
+          -DCMAKE_LINKER=$(brew --prefix llvm@${{ matrix.llvm }})/bin/ld.lld
+
+    - name: Build project
+      run: cmake --build build/ --config ${{ matrix.build_type }}
+
+    - name: Run tests
+      working-directory: build/
+      run: ctest -C ${{ matrix.build_type }} --output-on-failure
diff --git a/packages/PEGTL/.github/workflows/msys.yml b/packages/PEGTL/.github/workflows/msys.yml
new file mode 100644
index 000000000..9618e9ce2
--- /dev/null
+++ b/packages/PEGTL/.github/workflows/msys.yml
@@ -0,0 +1,56 @@
+name: msys2
+
+on:
+  push:
+    paths-ignore:
+      - 'README.md'
+      - 'doc/**'
+  pull_request:
+    paths-ignore:
+      - 'README.md'
+      - 'doc/**'
+
+jobs:
+  msys2:
+    strategy:
+      fail-fast: false
+      matrix:
+        platform: 
+          - 'UCRT64'
+          - 'CLANG64'
+        build_type: [Debug, Release]
+
+    defaults:
+      run:
+        shell: msys2 {0}
+
+    runs-on: windows-latest
+
+    steps:
+    - uses: actions/checkout@v3
+
+    - uses: msys2/setup-msys2@v2
+      with:
+        msystem: ${{matrix.platform}}
+        install: >-
+          bison
+          dos2unix
+          git
+        pacboy: >-
+          cc:p
+          cmake:p
+          ninja:p
+          pkgconf:p
+        update: true
+
+    - run: cmake -E make_directory build
+      shell: msys2 {0}
+      
+    - working-directory: build/
+      run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+
+    - working-directory: build/
+      run: cmake --build .
+
+    - working-directory: build/
+      run: ctest --output-on-failure
diff --git a/packages/PEGTL/.github/workflows/windows.yml b/packages/PEGTL/.github/workflows/windows.yml
index 42eacfd4a..b61a7fd04 100644
--- a/packages/PEGTL/.github/workflows/windows.yml
+++ b/packages/PEGTL/.github/workflows/windows.yml
@@ -11,94 +11,57 @@ on:
       - 'doc/**'
 
 jobs:
-  vs2022:
+  windows-msvc:
     strategy:
       fail-fast: false
       matrix:
         build_type: [Debug, Release]
+        os: [windows-2022, windows-2019]
 
-    runs-on: windows-latest
+    runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
-    - run: cmake -E make_directory build
+    - name: Configure Visual Studio Environment
+      uses: ilammy/msvc-dev-cmd@v1.13.0
 
-    - shell: bash
-      working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -G "Visual Studio 17 2022"
+    - name: Install Ninja
+      uses: seanmiddleditch/gha-setup-ninja@v4
 
-    - working-directory: build/
-      run: cmake --build . --config ${{ matrix.build_type }}
+    - name: Configure CMake
+      run: cmake ${{ github.workspace }} -G "Ninja" -B build
 
-    - working-directory: build/
-      run: ctest -C ${{ matrix.build_type }} --output-on-failure
-
-  vs2022-clang:
-    strategy:
-      fail-fast: false
-      matrix:
-        build_type: [Debug, Release]
-
-    runs-on: windows-latest
-
-    steps:
-    - uses: actions/checkout@v3
-
-    - run: cmake -E make_directory build
-
-    - shell: bash
-      working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -G "Visual Studio 17 2022" -T ClangCL
-
-    - working-directory: build/
-      run: cmake --build . --config ${{ matrix.build_type }}
+    - name: Build project
+      run: cmake --build ${{ github.workspace }}\build --config ${{ matrix.build_type }}
 
-    - working-directory: build/
+    - name: Run tests
+      working-directory: ${{ github.workspace }}\build
       run: ctest -C ${{ matrix.build_type }} --output-on-failure
 
-  vs2019:
+  windows-clang:
     strategy:
       fail-fast: false
       matrix:
         build_type: [Debug, Release]
+        os: [windows-2022, windows-2019]
 
-    runs-on: windows-2019
+    runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
-    - run: cmake -E make_directory build
-
-    - shell: bash
-      working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -G "Visual Studio 16 2019"
-
-    - working-directory: build/
-      run: cmake --build . --config ${{ matrix.build_type }}
-
-    - working-directory: build/
-      run: ctest -C ${{ matrix.build_type }} --output-on-failure
-
-  vs2019-clang:
-    strategy:
-      fail-fast: false
-      matrix:
-        build_type: [Debug, Release]
-
-    runs-on: windows-2019
-
-    steps:
-    - uses: actions/checkout@v3
+    - name: Configure Visual Studio Environment
+      uses: ilammy/msvc-dev-cmd@v1.13.0
 
-    - run: cmake -E make_directory build
+    - name: Install Ninja
+      uses: seanmiddleditch/gha-setup-ninja@v4
 
-    - shell: bash
-      working-directory: build/
-      run: cmake $GITHUB_WORKSPACE -G "Visual Studio 16 2019" -T ClangCL
+    - name: Configure CMake
+      run: cmake -S ${{ github.workspace }} -B build -G "Ninja" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
 
-    - working-directory: build/
-      run: cmake --build . --config ${{ matrix.build_type }}
+    - name: Build project
+      run: cmake --build ${{ github.workspace }}\build --config ${{ matrix.build_type }}
 
-    - working-directory: build/
+    - working-directory: ${{ github.workspace }}\build
       run: ctest -C ${{ matrix.build_type }} --output-on-failure
diff --git a/packages/PEGTL/.gitrepo b/packages/PEGTL/.gitrepo
index 4ac43b7e4..c8518e9b1 100644
--- a/packages/PEGTL/.gitrepo
+++ b/packages/PEGTL/.gitrepo
@@ -6,7 +6,7 @@
 [subrepo]
 	remote = git@github.com:taocpp/PEGTL.git
 	branch = main
-	commit = dc3d82928755046be3d66efb3015ed8b03f299ac
-	parent = e00b72ebcd9d2add12cfe0e6fe4d114a7858dfa5
+	commit = d7b821b1e5ed6ab321625f50427c4ae0b78909d5
+	parent = 7c198d9eef2fdba45643340774e1e85368fa1070
 	method = merge
-	cmdver = 0.4.6
+	cmdver = 0.4.9
diff --git a/packages/PEGTL/.pkg-config/pegtl.pc.in b/packages/PEGTL/.pkg-config/pegtl.pc.in
new file mode 100644
index 000000000..daf6c07f9
--- /dev/null
+++ b/packages/PEGTL/.pkg-config/pegtl.pc.in
@@ -0,0 +1,7 @@
+includedir="@CMAKE_INSTALL_PREFIX@/@PEGTL_INSTALL_INCLUDE_DIR@"
+
+Name: @PROJECT_NAME@
+Description: @CMAKE_PROJECT_DESCRIPTION@
+Version: @PROJECT_VERSION@
+URL: @CMAKE_PROJECT_HOMEPAGE_URL@
+Cflags: -I${includedir}
\ No newline at end of file
diff --git a/packages/PEGTL/CMakeLists.txt b/packages/PEGTL/CMakeLists.txt
index 2233099fa..1df6fa021 100644
--- a/packages/PEGTL/CMakeLists.txt
+++ b/packages/PEGTL/CMakeLists.txt
@@ -5,7 +5,7 @@ file(READ "${CMAKE_CURRENT_LIST_DIR}/include/tao/pegtl/version.hpp" version_hpp_
 string(REGEX MATCH "#define TAO_PEGTL_VERSION \"([^\"]+)\"" _ ${version_hpp_data})
 set(PEGTL_VERSION "${CMAKE_MATCH_1}")
 
-project(pegtl VERSION ${PEGTL_VERSION} LANGUAGES CXX)
+project(pegtl VERSION ${PEGTL_VERSION} DESCRIPTION "The Parsing Expression Grammar Template Library" HOMEPAGE_URL https://github.com/taocpp/PEGTL LANGUAGES CXX)
 
 set(PEGTL_IS_MAIN_PROJECT OFF)
 if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
@@ -37,6 +37,7 @@ mark_as_advanced(${PROJECT_NAME}_DIR)
 set(PEGTL_INSTALL_INCLUDE_DIR "include" CACHE STRING "The installation include directory")
 set(PEGTL_INSTALL_DOC_DIR "share/doc/tao/pegtl" CACHE STRING "The installation doc directory")
 set(PEGTL_INSTALL_CMAKE_DIR "share/pegtl/cmake" CACHE STRING "The installation cmake directory")
+set(PEGTL_INSTALL_PKGCONFIG_DIR "share/pkgconfig" CACHE STRING "The installation pkgconfig directory")
 
 # define a header-only library
 add_library(pegtl INTERFACE)
@@ -49,70 +50,6 @@ target_include_directories(pegtl INTERFACE
 # require C++17
 target_compile_features(pegtl INTERFACE cxx_std_17)
 
-option(PEGTL_USE_BOOST_FILESYSTEM "Override the auto-detection of std::filesystem and use Boost.Filesystem" OFF)
-
-# Try compiling a test program with std::filesystem or one of its alternatives
-function(check_filesystem_impl FILESYSTEM_HEADER FILESYSTEM_NAMESPACE OPTIONAL_LIBS OUT_RESULT)
-  set(TEST_FILE "test_${OUT_RESULT}.cpp")
-  configure_file(.cmake/test_filesystem.cpp.in ${TEST_FILE} @ONLY)
-
-  try_compile(TEST_RESULT
-    ${CMAKE_CURRENT_BINARY_DIR}
-    ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE}
-    CXX_STANDARD 17)
-
-  if(NOT TEST_RESULT)
-    # Retry with each of the optional libraries
-    foreach(OPTIONAL_LIB IN LISTS OPTIONAL_LIBS)
-      try_compile(TEST_RESULT
-        ${CMAKE_CURRENT_BINARY_DIR}
-        ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE}
-        LINK_LIBRARIES ${OPTIONAL_LIB}
-        CXX_STANDARD 17)
-
-      if(TEST_RESULT)
-        # Looks like the optional library was required, go ahead and add it to the link options.
-        message(STATUS "Adding ${OPTIONAL_LIB} to the PEGTL to build with ${FILESYSTEM_NAMESPACE}.")
-        target_link_libraries(${PROJECT_NAME} INTERFACE ${OPTIONAL_LIB})
-        break()
-      endif()
-    endforeach()
-  endif()
-
-  set(${OUT_RESULT} ${TEST_RESULT} PARENT_SCOPE)
-endfunction()
-
-if(PEGTL_USE_BOOST_FILESYSTEM)
-  # Force the use of Boost.Filesystem: #include <boost/filesystem.hpp> // boost::filesystem
-  find_package(Boost REQUIRED COMPONENTS filesystem)
-  target_link_libraries(${PROJECT_NAME} INTERFACE Boost::filesystem)
-  target_compile_definitions(${PROJECT_NAME} INTERFACE TAO_PEGTL_BOOST_FILESYSTEM)
-else()
-  # Try compiling a minimal program with each header/namespace, in order of preference:
-  #   C++17: #include <filesystem> // std::filesystem
-  #   Experimental C++17: #include <experimental/filesystem> // std::experimental::filesystem
-  #   Boost.Filesystem: #include <boost/filesystem.hpp> // boost::filesystem
-  check_filesystem_impl("filesystem" "std::filesystem" "stdc++fs;c++fs" STD_FILESYSTEM)
-  if(STD_FILESYSTEM)
-    message(STATUS "Using std::filesystem")
-  else()
-    check_filesystem_impl("experimental/filesystem" "std::experimental::filesystem" "stdc++fs;c++fs" STD_EXPERIMENTAL_FILESYSTEM)
-    if(STD_EXPERIMENTAL_FILESYSTEM)
-      target_compile_definitions(${PROJECT_NAME} INTERFACE TAO_PEGTL_STD_EXPERIMENTAL_FILESYSTEM)
-      message(WARNING "Using std::experimental::filesystem as a fallback")
-    else()
-      find_package(Boost COMPONENTS filesystem)
-      check_filesystem_impl("boost/filesystem.hpp" "boost::filesystem" Boost::filesystem BOOST_FILESYSTEM)
-      if(BOOST_FILESYSTEM)
-        target_compile_definitions(${PROJECT_NAME} INTERFACE TAO_PEGTL_BOOST_FILESYSTEM)
-        message(WARNING "Using Boost.Filesystem as a fallback")
-      else()
-        message(FATAL_ERROR "PEGTL requires C++17, including an implementation of std::filesystem, which your compiler toolchain does not seem to support. You can try installing Boost.Filesystem as a temporary workaround, but there's no guarantee the PEGTL will keep working with your project. Consider upgrading your compiler toolchain or downgrading the PEGTL to the previous version.")
-      endif()
-    endif()
-  endif()
-endif()
-
 # testing
 option(PEGTL_BUILD_TESTS "Build test programs" ${PEGTL_IS_MAIN_PROJECT})
 if(PEGTL_BUILD_TESTS)
@@ -126,9 +63,12 @@ if(PEGTL_BUILD_EXAMPLES)
   add_subdirectory(src/example/pegtl)
 endif()
 
-# Make package findable
+# Make package findable by CMake
 configure_file(.cmake/pegtl-config.cmake.in pegtl-config.cmake @ONLY)
 
+# Make package findable by pkg-config
+configure_file(.pkg-config/pegtl.pc.in pegtl.pc @ONLY)
+
 # Ignore pointer width differences since this is a header-only library
 unset(CMAKE_SIZEOF_VOID_P)
 
@@ -146,6 +86,7 @@ install(EXPORT pegtl-targets
 )
 
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pegtl-config-version.cmake DESTINATION ${PEGTL_INSTALL_CMAKE_DIR})
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pegtl.pc DESTINATION ${PEGTL_INSTALL_PKGCONFIG_DIR})
 install(DIRECTORY include/ DESTINATION ${PEGTL_INSTALL_INCLUDE_DIR})
 install(FILES LICENSE_1_0.txt DESTINATION ${PEGTL_INSTALL_DOC_DIR})
 
diff --git a/packages/PEGTL/README.md b/packages/PEGTL/README.md
index b4883158f..9e355b813 100644
--- a/packages/PEGTL/README.md
+++ b/packages/PEGTL/README.md
@@ -13,7 +13,7 @@
 
 The Parsing Expression Grammar Template Library (PEGTL) is a zero-dependency C++ header-only parser combinator library for creating parsers according to a [Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) (PEG).
 
-**The main branch will go through phases of incompatible changes while parts of the evolution branch are back-ported. Please download [the latest release](https://github.com/taocpp/PEGTL/releases) rather than using unreleased changes from the main branch.**
+During development of a new major version the main branch can go through incompatible changes. For a stable experience please download [the latest release](https://github.com/taocpp/PEGTL/releases) rather than using the main branch.
 
 ## Documentation
 
@@ -25,14 +25,14 @@ The Parsing Expression Grammar Template Library (PEGTL) is a zero-dependency C++
 
 ## Contact
 
-For questions and suggestions regarding the PEGTL, success or failure stories, and any other kind of feedback, please feel free to open a [discussion](https://github.com/taocpp/PEGTL/discussions), an [issue](https://github.com/taocpp/PEGTL/issues) or a [pull request](https://github.com/taocpp/PEGTL/pulls) on GitHub or contact the authors at `taocpp(at)icemx.net`.
+For questions and suggestions regarding the PEGTL, success or failure stories, and any other kind of feedback, please feel free to open a [discussion](https://github.com/taocpp/PEGTL/discussions), an [issue](https://github.com/taocpp/PEGTL/issues) or a [pull request](https://github.com/taocpp/PEGTL/pulls), or contact the authors at `taocpp(at)icemx.net`.
 
 ## Introduction
 
 Grammars are written as regular C++ code, created with template programming (not template meta programming), i.e. nested template instantiations that naturally correspond to the inductive definition of PEGs (and other parser-combinator approaches).
 
 A comprehensive set of [parser rules](doc/Rule-Reference.md) that can be combined and extended by the user is included, as are mechanisms for debugging grammars, and for attaching user-defined [actions](doc/Actions-and-States.md) to grammar rules.
-Here is an example of how a PEG grammar rule is implemented as C++ class with the PEGTL.
+Here is an example of how a parsing expression grammar rule is implemented as C++ class with the PEGTL.
 
 ```c++
 // PEG rule for integers consisting of a non-empty
@@ -71,7 +71,7 @@ The rules are expressed in C++ as template instantiations, and it is the compile
 
 Each commit is automatically tested with multiple architectures, operating systems, compilers, and versions thereof.
 
-Each commit is checked with GCC's and Clang's [sanitizers](https://github.com/google/sanitizers), Clang's [Static Analyzer](https://clang-analyzer.llvm.org/), and [`clang-tidy`](http://clang.llvm.org/extra/clang-tidy/).
+Each commit is checked with the GCC and Clang [sanitizers](https://github.com/google/sanitizers), Clang's [Static Analyzer](https://clang-analyzer.llvm.org/), and [`clang-tidy`](http://clang.llvm.org/extra/clang-tidy/).
 Additionally, we use [CodeQL](https://securitylab.github.com/tools/codeql) to scan for (security) issues.
 
 Code coverage is automatically measured and the unit tests cover 100% of the core library code (for releases).
diff --git a/packages/PEGTL/doc/Actions-and-States.md b/packages/PEGTL/doc/Actions-and-States.md
index 46c2fa5db..8338a4746 100644
--- a/packages/PEGTL/doc/Actions-and-States.md
+++ b/packages/PEGTL/doc/Actions-and-States.md
@@ -368,7 +368,7 @@ struct my_action< my_rule >
 tao::pegtl::parse< my_grammar, my_action >( ... );
 ```
 
-Conversely `tao::pegtl::change_action<>` takes a new action class template as only template parameter and changes the current action in a parsing run to its template parameter.
+Conversely `tao::pegtl::change_action<>` takes a new action class template as its only template parameter and changes the current action in a parsing run to it.
 
 Note that parsing proceeds with the rule to which the action changing action is attached to "as if" the new action had been the current action all along.
 The new action can even perform an action change *on the same rule*, however care should be taken to not introduce infinite cycles of changes.
diff --git a/packages/PEGTL/doc/Changelog.md b/packages/PEGTL/doc/Changelog.md
index b05d176d3..17e7d686f 100644
--- a/packages/PEGTL/doc/Changelog.md
+++ b/packages/PEGTL/doc/Changelog.md
@@ -4,19 +4,34 @@
 
 **Not yet released**
 
+* Use the [**migration guide**](Migration-Guide.md#version-400) when updating.
 * Switched to Boost Software License, Version 1.0.
+* Added [control function](Control-and-Debug.md) to throw nested exceptions.
+* Changed `parse_error` to contain only one `position`, and:
+* Changed to **nested exceptions** for nested [parsing errors](Errors-and-Exceptions.md).
+* Added functions to visit and flatten [nested exceptions](Contrib-and-Examples.md#taopegtlcontribnested_exceptionshpp).
 * Added new customization point for error messages.
 * Added optional source line output for the tracer.
-* Added new atomic rule `everything`.
-* Added new convenience rule `partial`.
-* Added new convenience rule `star_partial`.
-* Added new convenience rule `strict`.
-* Added new convenience rule `star_strict`.
+* Added new atomic rule [`everything`](Rule-Reference.md#everything).
+* Added new convenience rule [`partial`](Rule-Reference.md#partial-r-).
+* Added new convenience rule [`star_partial`](Rule-Reference.md#star_partial-r-).
+* Added new convenience rule [`strict`](Rule-Reference.md#strict-r-).
+* Added new convenience rule [`star_strict`](Rule-Reference.md#star_strict-r-).
+* Added rule [`try_catch_any_return_false`](Rule-Reference.md#try_catch_any_return_false-r-).
+* Renamed rule `try_catch` to [`try_catch_return_false`](Rule-Reference.md#try_catch_return_false-r-).
+* Added rule [`try_catch_std_return_false`](Rule-Reference.md#try_catch_std_return_false-r-).
+* Renamed rule `try_catch_type` to [`try_catch_type_return_false`](Rule-Reference.md#try_catch_type_return_false-e-r-).
+* Added rule [`try_catch_any_raise_nested`](Rule-Reference.md#try_catch_any_raise_nested-r-).
+* Added rule [`try_catch_raise_nested`](Rule-Reference.md#try_catch_raise_nested-r-).
+* Added rule [`try_catch_std_raise_nested`](Rule-Reference.md#try_catch_std_raise_nested-r-).
+* Added rule [`try_catch_type_raise_nested`](Rule-Reference.md#try_catch_type_raise_nested-e-r-).
 * Moved depth counter to adapter class in contrib.
 * Changed default top-level `rewind_mode` to `dontcare`.
+* Replaced `rewind_mode` values `dontcare` and `active` with new value `optional`.
+* Removed support for `boost::filesystem` and `std::experimental::filesystem`.
 * Removed support for building an amalgamated header.
 * Removed support for Visual Studio 2017.
-* Removed support for GCC 7.
+* Removed support for GCC 7 and GCC 8.
 
 ## 3.2.7
 
diff --git a/packages/PEGTL/doc/Contrib-and-Examples.md b/packages/PEGTL/doc/Contrib-and-Examples.md
index a2c09f4fb..ebfc6d22f 100644
--- a/packages/PEGTL/doc/Contrib-and-Examples.md
+++ b/packages/PEGTL/doc/Contrib-and-Examples.md
@@ -52,6 +52,10 @@ For all questions and remarks contact us at **taocpp(at)icemx.net**.
 * JSON grammar according to [RFC 7159](https://tools.ietf.org/html/rfc7159) (for UTF-8 encoded JSON only).
 * Ready for production use.
 
+###### `<tao/pegtl/contrib/nested_exceptions.hpp>`
+
+* Functions to handle exceptions that (might) contain nested exceptions.
+
 ###### `<tao/pegtl/contrib/parse_tree.hpp>`
 
 * See [Parse Tree](Parse-Tree.md).
diff --git a/packages/PEGTL/doc/Control-and-Debug.md b/packages/PEGTL/doc/Control-and-Debug.md
index 58b2143b6..2c22014c2 100644
--- a/packages/PEGTL/doc/Control-and-Debug.md
+++ b/packages/PEGTL/doc/Control-and-Debug.md
@@ -44,9 +44,13 @@ struct normal
 
    template< typename ParseInput,
              typename... States >
-   static void raise( const ParseInput& in, States&&... );
+   static void raise( const ParseInput&, States&&... );
 
-   template< template< typename... > class Action,
+   template< typename Ambient,
+             typename... States >
+   static void raise_nested( const Ambient&, States&&... );
+
+template< template< typename... > class Action,
              typename Iterator,
              typename ParseInput,
              typename... States >
@@ -78,7 +82,8 @@ It is not included in the default control template `normal`, as the existence of
 This might potentially have an impact on the binary size and therefore, one should only add an `unwind()` method if necessary.
 Several other control classes utilize the `unwind()` method to track the execution even in the presence of global errors.
 
-The static member function `raise()` is used to create a global error, and any replacement should again throw an exception, or abort the application.
+The static member function `raise()` is used to create a global error, and any replacement **must** again throw an exception (or abort the application).
+The static member function `raise_nested()` is used to create a global error in cases where a previous error was caught and is to be included in the newly thrown exception as nested exception.
 
 The static member functions `apply()` and `apply0()` can customise how actions with, and without, receiving the matched input are called, respectively.
 Note that these functions should only exist or be visible when an appropriate `apply()` or `apply0` exists in the action class template.
@@ -118,12 +123,11 @@ The included `<tao/pegtl/contrib/trace.hpp>` gives a practical example that show
 
 ## Exception Throwing
 
-The control-hook, the `raise()` static member function, **must** throw an exception.
-For most parts of the PEGTL the exception class is irrelevant and any user-defined data type can be thrown by a user-defined control hook.
-
-The `try_catch` rule only catches exceptions of type `tao::pegtl::parse_error`!
+The control hooks for exceptions, the`raise()` and `raise_nested()` static member functions, **must** both throw an exception.
+For most parts of the PEGTL the exception class is irrelevant and any user-defined data type can be thrown by a user-defined control.
 
-When custom exception types are used then `try_catch_type` must be used with the custom exception class that they are supposed to catch as first template argument.
+The [`try_catch_raise_nested`](Rule-Reference.md#try_catch_raise_nested-r-) and [`try_catch_return_false`](Rule-Reference.md#try_catch_return_false-r-) rules only catches exceptions of type `tao::pegtl::parse_error_base` (or derived)!
+When other exception types need to be caught then other members of the `try_catch_*` family of rules need to be used.
 
 ## Advanced Control
 
diff --git a/packages/PEGTL/doc/Errors-and-Exceptions.md b/packages/PEGTL/doc/Errors-and-Exceptions.md
index d186d3ee4..b9a0122b9 100644
--- a/packages/PEGTL/doc/Errors-and-Exceptions.md
+++ b/packages/PEGTL/doc/Errors-and-Exceptions.md
@@ -6,8 +6,8 @@ A parsing run, a call to one of the `parse()` functions as explained in [Inputs
 * A return value of `false` is called a *local failure* (even when propagated to the top).
 * An exception indicating a *global failure* is thrown.
 
-The PEGTL parsing rules throw exceptions of type `tao::pegtl::parse_error`, some of the inputs throw additional exceptions like `std::system_error` or `std::filesystem_error`.
-Other exception classes can be used freely from actions and custom parsing rules.
+The PEGTL parsing rules throw exceptions of type `tao::pegtl::parse_error`, some of the inputs can throw other exceptions like `std::system_error` or `std::filesystem_error`.
+And other exception classes can be used freely from actions and custom parsing rules.
 
 ## Contents
 
@@ -23,47 +23,48 @@ Other exception classes can be used freely from actions and custom parsing rules
 
 By default, global failure means that an exception of type `tao::pegtl::parse_error` is thrown.
 
+Note that starting with PEGTL version 4.0.0 `parse_error` is no longer a monolithic class derived from `std::runtime_error`.
+To simultaneously allow for different types of position information _and_ a single type that can be used to catch all parse errors there is a base class with the non position-type dependent parts as well as a derived class that is templated over the position type.
+
 Synposis:
 
 ```c++
 namespace tao::pegtl
 {
-   class parse_error
+   class parse_error_base
       : public std::runtime_error
    {
-      parse_error( const char* msg, position p );
-
-      parse_error( const std::string& msg, position p )
-         : parse_error( msg.c_str(), std::move( p ) )
-      {}
+   public:
+      [[nodiscard]] std::string_view message() const noexcept;
+      [[nodiscard]] std::string_view position_string() const noexcept;
+   };
 
-      template< typename ParseInput >
-      parse_error( const char* msg, const ParseInput& in )
-         : parse_error( msg, in.position() )
-      {}
+   template< typename Position >
+   class parse_error_template
+      : public parse_error_base
+   {
+   public:
+      using position_t = Position;
 
-      template< typename ParseInput >
-      parse_error( const std::string& msg, const ParseInput& in )
-         : parse_error( msg, in.position() )
-      {}
+      template< typename Object >
+      parse_error_template( const std::string& msg, const Object& obj );
 
-      const char* what() const noexcept override;
+      [[nodiscard]] const position_t& position_object() const noexcept;
+   };
 
-      std::string_view message() const noexcept;
-      const std::vector< position >& positions() const noexcept;
+   template< typename Object >
+   parse_error_template( const std::string&, const Object& ) -> parse_error_template< std::decay_t< decltype( internal::extract_position( std::declval< Object >() ) ) > >;
 
-      void add_position( position&& p );
-   };
+   using parse_error = parse_error_template< position >;
 }
 ```
 
-The `what()` message will contain all positions as well as the original `msg`.
-This allows retrieval of all information if the exception is handled as a `std::runtime_error` in a generic way.
+The `message()` function returns the original `msg`, while  `position_string()` and `position_object()` provide a string representation of, or the actual position object, respectively.
 
-The `message()` function will return the original `msg`, while `positions()` allows access to the stored positions.
-This is useful to decompose the exception and provide more helpful errors to the user.
+The `Object` passed to the constructor can be either a PEGTL input class, in which case the current position will be extracted and stored in the exception, or it can be an actual position object that will be used "as is".
+The supplied user-defined deduction guide will make sure that the exception object uses the correct type as `position_t` in both of these cases.
 
-The constructors can be used by custom rules to signal global failure, while `add_position()` is often used when you are parsing nested data, so you can append the position in the original file which includes the nested file.
+The string returned by the `what()` function inherited from `std::runtime_error` is a concatenation of the position string and the message supplied to the constructor.
 
 ## Local to Global Failure
 
@@ -95,9 +96,15 @@ See [Custom Exception Messages](#custom-exception-messages) for more information
 
 ## Global to Local Failure
 
-To convert global failure to local failure, the grammar rules [`try_catch`](Rule-Reference.md#try_catch-r-) and [`try_catch_type`](Rule-Reference.md#try_catch_type-e-r-) can be used.
+To convert global failure to local failure, the grammar rule [`try_catch_return_false`](Rule-Reference.md#try_catch_return_false-r-), or one of its variants that give more control over which kinds of exceptions are caught, can be used.
 Since these rules are not very commonplace they are ignored in this document, in other words we assume that global failure always propagages to the top.
 
+## Global to Nested Failure
+
+To add more information to an in-flight exception in the form of another exception the grammar rule [`try_catch_raise_nested`](Rule-Reference.md#try_catch_rause_nested-r-), or one of its variants that give more control over which kinds of exceptions are caught, can be used.
+They throw a new exception that contains the previous one as nested exception.
+Many applications will not use nested exceptions, and those that do will usually only generate them in the case of [nested parsing](Inputs-and-Parsing.md#nested-parsing).
+
 ## Examples for Must Rules
 
 One basic use case of the `must<>` rule is as top-level grammar rule.
diff --git a/packages/PEGTL/doc/Getting-Started.md b/packages/PEGTL/doc/Getting-Started.md
index 20c13d570..8ed7fcafc 100644
--- a/packages/PEGTL/doc/Getting-Started.md
+++ b/packages/PEGTL/doc/Getting-Started.md
@@ -96,7 +96,7 @@ terminate called after throwing an instance of 'tao::pegtl::parse_error'
 Aborted (core dumped)
 ```
 
-Note that, by default, the PEGTL resides in `namespace tao::pegtl`, however this can be changed as explained in [Embedding in Library Interfaces](Installing-and-Using.md#embedding-in-library-interfaces).
+Note that, by default, the PEGTL resides in `namespace tao::pegtl`, however this can be changed as explained in [Embedding in Libraries](Installing-and-Using.md#embedding-in-libraries).
 The entire PEGTL documentation assumes that the default namespace applies.
 
 The PEGTL provides multiple facilities that help to get started and develop your grammar.
@@ -269,7 +269,7 @@ Typically, the following pattern helps to print the exceptions in a human friend
       catch( const pegtl::parse_error& e ) {
 
          // This catch block needs access to the input
-         const auto p = e.positions().front();
+         const auto& p = e.positions_object();
          std::cerr << e.what() << '\n'
                    << in.line_at( p ) << '\n'
                    << std::setw( p.column ) << '^' << std::endl;
diff --git a/packages/PEGTL/doc/Inputs-and-Parsing.md b/packages/PEGTL/doc/Inputs-and-Parsing.md
index d66171142..a85513523 100644
--- a/packages/PEGTL/doc/Inputs-and-Parsing.md
+++ b/packages/PEGTL/doc/Inputs-and-Parsing.md
@@ -53,7 +53,7 @@ All classes and functions on this page are in namespace `tao::pegtl`.
 
 Some input classes allow a choice of tracking mode, or whether the `byte`, `line` and `column` counters are continuously updated during a parsing run with `tracking_mode::eager`, or only calculated on-demand in `position()` by scanning the complete input again with `tracking_mode::lazy`.
 
-Lazy tracking is recommended when the position is used very infrequently, for example only in the case of throwing a `parse_error`.
+Lazy tracking is recommended when the position is used very infrequently, for example at most once when a parsing run ends with an exception of type `parse_error`.
 
 Eager tracking is recommended when the position is used frequently and/or in non-exceptional cases, for example when annotating every AST node with the line number.
 
@@ -309,11 +309,13 @@ bool parse( ParseInput& in,
 
 Nested parsing refers to an (inner) parsing run that is performed "in the middle of" another (outer) parsing run, for example when one file "includes" another file.
 
-The difference to the regular `tao::pegtl::parse()` function is that `tao::pegtl::parse_nested()` takes care of adding to the `std::vector` of `tao::pegtl::position` objects in the exception class `tao::pegtl::parse_error`.
-This allows generating error messages of the form "error in file F1 line L1 included from file F2 line L2...".
+The difference to the regular `tao::pegtl::parse()` function is that when a global failure occurs within `tao::pegtl::parse_nested()` then a new exception is thrown via `Control< Rule >::raise_nested()`.
+The new exception contains the previous one as nested exception. The functions in the header `tao/pegtl/contrib/nested_exceptions.hpp` can be used to work with these nested exceptions.
+The inner-most exception that was thrown first will be the "most nested" exception, i.e. the final one in the linked list of nested exceptions.
 
-Compared to `parse()`, calling `parse_nested()` requires either the input from the outer parsing run or the position as additional first argument.
-Everything else remains the same.
+The position information contained in the nested exceptions allows for error messages like "error in file F1 line L1 included from file F2 line L2 etc."
+
+Calling `parse_nested()` requires the input from the outer parsing run, or the position whithin the outer parsing run, as additional first argument ("additional" as compared to `parse()`).
 
 ```c++
 template< typename Rule,
@@ -321,24 +323,12 @@ template< typename Rule,
           template< typename... > class Control = normal,
           apply_mode A = apply_mode::action,
           rewind_mode M = rewind_mode::dontcare,
-          typename OuterInput,
+          typename OuterInput,  // Can also be class position.
           typename ParseInput,
           typename... States >
 bool parse_nested( const OuterInput& oi,
                    ParseInput& in,
                    States&&... st );
-
-template< typename Rule,
-          template< typename... > class Action = nothing,
-          template< typename... > class Control = normal,
-          apply_mode A = apply_mode::action,
-          rewind_mode M = rewind_mode::required,
-          typename OuterInput,
-          typename ParseInput,
-          typename... States >
-bool parse_nested( position op,
-                   ParseInput& in,
-                   States&&... st );
 ```
 
 ## Incremental Input
@@ -540,7 +530,7 @@ try {
   // call parse on the input 'in' here...
 }
 catch( const parse_error& e ) {
-   const auto p = e.positions().front();
+   const auto& p = e.position_object();
    std::cerr << e.what() << std::endl
              << in.line_at( p ) << '\n'
              << std::setw( p.column ) << '^' << std::endl;
diff --git a/packages/PEGTL/doc/Installing-and-Using.md b/packages/PEGTL/doc/Installing-and-Using.md
index 8996a7295..5561a5cd7 100644
--- a/packages/PEGTL/doc/Installing-and-Using.md
+++ b/packages/PEGTL/doc/Installing-and-Using.md
@@ -3,7 +3,6 @@
 ## Contents
 
 * [Requirements](#requirements)
-* [Filesystem](#filesystem)
 * [Disabling Exceptions](#disabling-exceptions)
 * [Disabling RTTI](#disabling-rtti)
 * [Installation Packages](#installation-packages)
@@ -24,8 +23,8 @@
 
 The PEGTL requires a C++17-capable compiler, e.g. one of
 
-* GCC 8
-* Clang 6
+* GCC 9
+* Clang 7
 * Visual Studio 2019
 
 on either
@@ -46,23 +45,6 @@ It should also work with other C++17 compilers on other Unix systems (or any suf
 The PEGTL is written with an emphasis on clean code and is compatible with
 the `-pedantic`, `-Wall`, `-Wextra` and `-Werror` compiler switches.
 
-## Filesystem
-
-By default the PEGTL uses `std::filesystem` facilities for filenames, however when using older compilers, or preferring the Boost filesystem library, manual intervention might be required.
-
-GCC supports for `std::experimental::filesystem` in `libstdc++fs` since version 7, support for `std::filesystem` in `libstdc++fs` since version 8, and support for `std::filesystem` in regular `libstdc++` since version 9.
-
-Clang [supports](https://libcxx.llvm.org/docs/UsingLibcxx.html) `std::experimental::filesystem` in `libc++experimental` since version 5, `std::filesystem` in `libc++fs` since version 7, and `std::filesystem` in regular `libc++` since version 9.
-
-Some Linux distributions have Clang packages without `libc++` and instead configure Clang to use the `libstdc++` from the default GCC.
-In such cases it is necessary to use e.g. `libstdc++fs` and include `<experimental/filesystem>` when a Clang 8 it used on a system with GCC 7 default compiler.
-
-When building with CMake, the appropriate `std::filesystem` or `std::experimental::filesystem` and matching available C++ standard library are chosen automatically.
-Alternatively `-DPEGTL_BOOST_FILESYSTEM=ON` can be passed to CMake to use `boost::filesystem` and matching Boost library instead.
-
-When building with Make, appropriate flags for `include/tao/pegtl/internal/filesystem.hpp` and the linker need to be set manually or by changing the included `Makefile`.
-Using `-DTAO_PEGTL_BOOST_FILESYSTEM=1` and setting up the compiler and linker to find the Boost headers and libraries and link against `boost_filesystem` can also be set up manually with Make.
-
 ## Disabling Exceptions
 
 The PEGTL is compatible with `-fno-exceptions`, however, when disabling exceptions:
diff --git a/packages/PEGTL/doc/Migration-Guide.md b/packages/PEGTL/doc/Migration-Guide.md
index d037ab5c6..eb51a3023 100644
--- a/packages/PEGTL/doc/Migration-Guide.md
+++ b/packages/PEGTL/doc/Migration-Guide.md
@@ -2,7 +2,11 @@
 
 ## Version 4.0.0
 
-
+* The `try_catch` and `try_catch_type` rules were renamed to `try_catch_return_false` and `try_catch_type_return_false`, respectively.
+* The `rewind_mode` values `active` and `dontcare` have been replaced by the single new value `optional` wherefore code using the old values needs to be updated.
+* Check whether the `rewind_mode` of the top-level `parse()` function, which is now `optional` by default, needs to be set to the previous value of `required` for your parsing runs.
+* The PEGTL generated `parse_error` exceptions now contain a single `position` object (previously a `std::vector< position >`). Nested exceptions are now used to convey multiple positions during nested parsing. The header `tao/pegtl/contrib/nested_exceptions.hpp` contains some functions to work with nested exceptions.
+* The counter used to limit the nesting depth of certain rules at runtime is no longer part of all input classes. When required it needs to be added back to the input by including `tao/pegtl/contrib/input_with_depth.hpp` and using objects of type `tao::pegtl::input_with_depth< Input >` where previously inputs of type `Input` were used.
 
 ## Version 3.0.0
 
diff --git a/packages/PEGTL/doc/README.md b/packages/PEGTL/doc/README.md
index bde86a1e9..d7ac8d6d9 100644
--- a/packages/PEGTL/doc/README.md
+++ b/packages/PEGTL/doc/README.md
@@ -4,7 +4,6 @@
 * [Getting Started](Getting-Started.md)
 * [Installing and Using](Installing-and-Using.md)
   * [Requirements](Installing-and-Using.md#requirements)
-  * [Filesystem](Installing-and-Using.md#filesystem)
   * [Disabling Exceptions](Installing-and-Using.md#disabling-exceptions)
   * [Disabling RTTI](Installing-and-Using.md#disabling-rtti)
   * [Installation Packages](Installing-and-Using.md#installation-packages)
@@ -293,8 +292,14 @@
 * [`terminal_punctuation`](Rule-Reference.md#terminal_punctuation) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup>
 * [`three< C >`](Rule-Reference.md#three-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup>
 * [`trail_canonical_combining_class< V >`](Rule-Reference.md#trail_canonical_combining_class-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-value-properties)</sup>
-* [`try_catch< R... >`](Rule-Reference.md#try_catch-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
-* [`try_catch_type< E, R... >`](Rule-Reference.md#try_catch_type-e-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_any_raise_nested< R... >`](Rule-Reference.md#try_catch_any_raise_nested-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_any_return_false< R... >`](Rule-Reference.md#try_catch_any_return_false-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_raise_nested< R... >`](Rule-Reference.md#try_catch_raise_nested-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_return_false< R... >`](Rule-Reference.md#try_catch_return_false-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_std_raise_nested< R... >`](Rule-Reference.md#try_catch_std_raise_nested-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_std_return_false< R... >`](Rule-Reference.md#try_catch_std_return_false-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_type_raise_nested< E, R... >`](Rule-Reference.md#try_catch_type_raise_nested-e-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
+* [`try_catch_type_return_false< E, R... >`](Rule-Reference.md#try_catch_type_return_false-e-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
 * [`two< C >`](Rule-Reference.md#two-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup>
 * [`unified_ideograph`](Rule-Reference.md#unified_ideograph) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup>
 * [`until< R >`](Rule-Reference.md#until-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup>
diff --git a/packages/PEGTL/doc/Rule-Reference.md b/packages/PEGTL/doc/Rule-Reference.md
index 9ea518b6b..7910ca485 100644
--- a/packages/PEGTL/doc/Rule-Reference.md
+++ b/packages/PEGTL/doc/Rule-Reference.md
@@ -2,14 +2,17 @@
 
 This page contains brief descriptions of all PEGTL rule and combinator classes.
 
-The information about how much input is consumed by the rules only applies to
-when the rules succeed; the PEGTL is implemented in a way that assumes that
-rules **never** consume input when they do not succeed.
+The information about how much input is consumed by the rules only applies when the rules succeed.
+Otherwise there are two failure modes with different requirements.
 
-Remember that there are two failure modes, only the first of which usually leads to back-tracking:
+- *Local failure* is when a rule returns `false` and the rule **must** generally rewind the input to where its match attempt started.
+- *Global failure* is when a rule throws an exception (usually of type `tao::parse_error`)(usually via the control-class' `raise()` function).
 
-- *Local failure* or a return value of `false`, in which case the rule must rewind the input to the position at which the rule match was attempted.
-- *Global failure* or an exception (usually of type `tao::parse_error`) that is usually generated by a control-class' `raise()` static member function.
+Since an exception, by default, aborts a parsing run -- hence the term "global failure" -- there are no assumptions or requirements for the throwing rule to rewind the input.
+
+On the other hand a local failure will frequently lead to back-tracking, i.e. the attempt to match a different rule at the same position in the input, wherefore rules that were previously attempted at the same position must rewind back to where they started in preparation of the next attempt.
+
+Note that in some cases it is not necessary to actually rewind on local failure, see the description of the [rewind_mode](Rules-and-Grammars.md#modes) in the section on [how to implement custom rules](Rules-and-Grammars.md#creating-new-rules).
 
 ## Equivalence
 
@@ -367,7 +370,8 @@ Note that the `true` template parameter to `internal::if_must` corresponds to th
 * Similar to `opt< R... >` with one important difference:
 * Does *not* rewind the input after a partial match of `R...`.
 * Attempts to match the given rules `R...` in the given order.
-* Succeeds and stops matching when one of the given rules fails.
+* Succeeds and stops matching when one of the given rules fails;
+* succeds when all of the given rules succeed.
 * Consumes everything that the successful rules of `R...` consumed.
 * `R` must be a non-empty rule pack.
 * [Equivalent] to `opt< R >` when `R...` is a single rule.
@@ -483,29 +487,109 @@ Note that the `S` do *not* need to match *all* of the input matched by `R` (whic
   - `strict< R... >::rule_t` is `internal::strict< R... >`
   - `strict< R... >::subs_t` is `type_list< R... >`
 
-###### `try_catch< R... >`
+###### `try_catch_any_raise_nested< R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of any type via `catch( ... )` and:
+* Throws a new exception with the caught one as nested exception.
+* Throws via `Control< R >::raise_nested()` when `R...` is a single rule.
+* Throws via `Control< internal::seq< R... > >::raise_nested()` when `R...` is more than one rule.
+* [Meta data] and [implementation] mapping:
+  - `try_catch_any_raise_nested<>::rule_t` is `internal::success`
+  - `try_catch_any_raise_nested< R >::rule_t` is `internal::try_catch_raise_nested< void, R >`
+  - `try_catch_any_raise_nested< R >::subs_t` is `type_list< R >`
+  - `try_catch_any_raise_nested< R... >::rule_t` is `internal::try_catch_raise_nested< void, internal::seq< R... > >`
+  - `try_catch_any_raise_nested< R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_any_return_false< E, R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of any type via `catch( ... )`, and:
+* Converts the global failure (exception) into a local failure (return value `false`).
+* [Meta data] and [implementation] mapping:
+  - `try_catch_any_return_false< E >::rule_t` is `internal::success`
+  - `try_catch_any_return_false< E, R >::rule_t` is `internal::try_catch_return_false< void, R >`
+  - `try_catch_any_return_false< E, R >::subs_t` is `type_list< R >`
+  - `try_catch_any_return_false< E, R... >::rule_t` is `internal::try_catch_return_false< void, internal::seq< R... > >`
+  - `try_catch_any_return_false< E, R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_raise_nested< R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of type `tao::pegtl::parse_error_base` (or derived), and:
+* Throws a new exception with the caught one as nested exception.
+* Throws via `Control< R >::raise_nested()` when `R...` is a single rule.
+* Throws via `Control< internal::seq< R... > >::raise_nested()` when `R...` is more than one rule.
+* [Meta data] and [implementation] mapping:
+  - `try_catch_raise_nested<>::rule_t` is `internal::success`
+  - `try_catch_raise_nested< R >::rule_t` is `internal::try_catch_raise_nested< parse_error_base, R >`
+  - `try_catch_raise_nested< R >::subs_t` is `type_list< R >`
+  - `try_catch_raise_nested< R... >::rule_t` is `internal::try_catch_raise_nested< parse_error_base, internal::seq< R... > >`
+  - `try_catch_raise_nested< R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_return_false< R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of type `tao::pegtl::parse_error_base` (or derived), and:
+* Converts the global failure (exception) into a local failure (return value `false`).
+* [Meta data] and [implementation] mapping:
+  - `try_catch_return_false<>::rule_t` is `internal::success`
+  - `try_catch_return_false< R >::rule_t` is `internal::try_catch_return_false< parse_error_base, R >`
+  - `try_catch_return_false< R >::subs_t` is `type_list< R >`
+  - `try_catch_return_false< R... >::rule_t` is `internal::try_catch_return_false< parse_error_base, internal::seq< R... > >`
+  - `try_catch_return_false< R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_std_raise_nested< R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of type `std::exception` (or derived), and:
+* Throws a new exception with the caught one as nested exception.
+* Throws via `Control< R >::raise_nested()` when `R...` is a single rule.
+* Throws via `Control< internal::seq< R... > >::raise_nested()` when `R...` is more than one rule.
+* [Meta data] and [implementation] mapping:
+  - `try_catch_std_raise_nested<>::rule_t` is `internal::success`
+  - `try_catch_std_raise_nested< R >::rule_t` is `internal::try_catch_raise_nested< std::exception, R >`
+  - `try_catch_std_raise_nested< R >::subs_t` is `type_list< R >`
+  - `try_catch_std_raise_nested< R... >::rule_t` is `internal::try_catch_raise_nested< std::exception, internal::seq< R... > >`
+  - `try_catch_std_raise_nested< R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_std_return_false< E, R... >`
+
+* [Equivalent] to `seq< R... >`, but:
+* Catches exceptions of type `std::exception` (or derived), and:
+* Converts the global failure (exception) into a local failure (return value `false`).
+* [Meta data] and [implementation] mapping:
+  - `try_catch_std_return_false< E >::rule_t` is `internal::success`
+  - `try_catch_std_return_false< E, R >::rule_t` is `internal::try_catch_return_false< std::exception, R >`
+  - `try_catch_std_return_false< E, R >::subs_t` is `type_list< R >`
+  - `try_catch_std_return_false< E, R... >::rule_t` is `internal::try_catch_return_false< std::exception, internal::seq< R... > >`
+  - `try_catch_std_return_false< E, R... >::subs_t` is `type_list< internal::seq< R... > >`
+
+###### `try_catch_type_raise_nested< E, R... >`
 
 * [Equivalent] to `seq< R... >`, but:
-* Converts global failure (exception) into local failure (return value `false`).
-* Catches exceptions of type `tao::pegtl::parse_error`.
+* Catches exceptions of type `E` (or derived), and:
+* Throws a new exception with the caught one as nested exception.
+* Throws via `Control< R >::raise_nested()` when `R...` is a single rule.
+* Throws via `Control< internal::seq< R... > >::raise_nested()` when `R...` is more than one rule.
 * [Meta data] and [implementation] mapping:
-  - `try_catch<>::rule_t` is `internal::success`
-  - `try_catch< R >::rule_t` is `internal::try_catch_type< parse_error, R >`
-  - `try_catch< R >::subs_t` is `type_list< R >`
-  - `try_catch< R... >::rule_t` is `internal::try_catch_type< parse_error, internal::seq< R... > >`
-  - `try_catch< R... >::subs_t` is `type_list< internal::seq< R... > >`
+  - `try_catch_type_raise_nested< E >::rule_t` is `internal::success`
+  - `try_catch_type_raise_nested< E, R >::rule_t` is `internal::try_catch_raise_nested< E, R >`
+  - `try_catch_type_raise_nested< E, R >::subs_t` is `type_list< R >`
+  - `try_catch_type_raise_nested< E, R... >::rule_t` is `internal::try_catch_raise_nested< E, internal::seq< R... > >`
+  - `try_catch_type_raise_nested< E, R... >::subs_t` is `type_list< internal::seq< R... > >`
 
-###### `try_catch_type< E, R... >`
+###### `try_catch_type_return_false< E, R... >`
 
 * [Equivalent] to `seq< R... >`, but:
-* Converts global failure (exception) into local failure (return value `false`).
-* Catches exceptions of type `E`.
+* Catches exceptions of type `E` (or derived), and:
+* Converts the global failure (exception) into a local failure (return value `false`).
 * [Meta data] and [implementation] mapping:
-  - `try_catch_type< E >::rule_t` is `internal::success`
-  - `try_catch_type< E, R >::rule_t` is `internal::try_catch_type< E, R >`
-  - `try_catch_type< E, R >::subs_t` is `type_list< R >`
-  - `try_catch_type< E, R... >::rule_t` is `internal::try_catch_type< E, internal::seq< R... > >`
-  - `try_catch_type< E, R... >::subs_t` is `type_list< internal::seq< R... > >`
+  - `try_catch_type_return_false< E >::rule_t` is `internal::success`
+  - `try_catch_type_return_false< E, R >::rule_t` is `internal::try_catch_return_false< E, R >`
+  - `try_catch_type_return_false< E, R >::subs_t` is `type_list< R >`
+  - `try_catch_type_return_false< E, R... >::rule_t` is `internal::try_catch_return_false< E, internal::seq< R... > >`
+  - `try_catch_type_return_false< E, R... >::subs_t` is `type_list< internal::seq< R... > >`
 
 ###### `until< R >`
 
@@ -1606,8 +1690,14 @@ Binary rules do not rely on other rules.
 * [`terminal_punctuation`](#terminal_punctuation) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup>
 * [`three< C >`](#three-c-) <sup>[(ascii rules)](#ascii-rules)</sup>
 * [`trail_canonical_combining_class< V >`](#trail_canonical_combining_class-v-) <sup>[(icu rules)](#icu-rules-for-value-properties)</sup>
-* [`try_catch< R... >`](#try_catch-r-) <sup>[(convenience)](#convenience)</sup>
-* [`try_catch_type< E, R... >`](#try_catch_type-e-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_any_raise_nested< R... >`](#try_catch_any_raise_nested-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_any_return_false< R... >`](#try_catch_any_return_false-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_raise_nested< R... >`](#try_catch_raise_nested-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_return_false< R... >`](#try_catch_return_false-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_std_raise_nested< R... >`](#try_catch_std_raise_nested-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_std_return_false< R... >`](#try_catch_std_return_false-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_type_raise_nested< E, R... >`](#try_catch_type_raise_nested-e-r-) <sup>[(convenience)](#convenience)</sup>
+* [`try_catch_type_return_false< E, R... >`](#try_catch_type_return_false-e-r-) <sup>[(convenience)](#convenience)</sup>
 * [`two< C >`](#two-c-) <sup>[(ascii rules)](#ascii-rules)</sup>
 * [`unified_ideograph`](#unified_ideograph) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup>
 * [`until< R >`](#until-r-) <sup>[(convenience)](#convenience)</sup>
diff --git a/packages/PEGTL/include/tao/pegtl/buffer_input.hpp b/packages/PEGTL/include/tao/pegtl/buffer_input.hpp
index 20e18a82f..e95f46b91 100644
--- a/packages/PEGTL/include/tao/pegtl/buffer_input.hpp
+++ b/packages/PEGTL/include/tao/pegtl/buffer_input.hpp
@@ -28,7 +28,7 @@
 
 #include "internal/action_input.hpp"
 #include "internal/bump.hpp"
-#include "internal/frobnicator.hpp"
+#include "internal/inputerator.hpp"
 #include "internal/rewind_guard.hpp"
 
 namespace TAO_PEGTL_NAMESPACE
@@ -42,7 +42,7 @@ namespace TAO_PEGTL_NAMESPACE
       using eol_t = Eol;
       using source_t = Source;
 
-      using frobnicator_t = internal::frobnicator;
+      using inputerator_t = internal::inputerator;
 
       using action_t = internal::action_input< buffer_input >;
 
@@ -170,17 +170,17 @@ namespace TAO_PEGTL_NAMESPACE
          return internal::rewind_guard< M, buffer_input >( this );
       }
 
-      [[nodiscard]] const frobnicator_t& rewind_save() noexcept
+      [[nodiscard]] const inputerator_t& rewind_save() noexcept
       {
          return m_current;
       }
 
-      void rewind_restore( const frobnicator_t& data ) noexcept
+      void rewind_restore( const inputerator_t& data ) noexcept
       {
          m_current = data;
       }
 
-      [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const frobnicator_t& it ) const
+      [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const inputerator_t& it ) const
       {
          return TAO_PEGTL_NAMESPACE::position( it, m_source );
       }
@@ -190,7 +190,12 @@ namespace TAO_PEGTL_NAMESPACE
          return position( m_current );
       }
 
-      [[nodiscard]] const frobnicator_t& frobnicator() const noexcept
+      [[nodiscard]] TAO_PEGTL_NAMESPACE::position current_position() const
+      {
+         return position( m_current );
+      }
+
+      [[nodiscard]] const inputerator_t& inputerator() const noexcept
       {
          return m_current;
       }
@@ -222,7 +227,7 @@ namespace TAO_PEGTL_NAMESPACE
       Reader m_reader;
       std::size_t m_maximum;
       std::unique_ptr< char[] > m_buffer;
-      frobnicator_t m_current;
+      inputerator_t m_current;
       char* m_end;
       const Source m_source;
 
diff --git a/packages/PEGTL/include/tao/pegtl/config.hpp b/packages/PEGTL/include/tao/pegtl/config.hpp
index 521623d26..04f779198 100644
--- a/packages/PEGTL/include/tao/pegtl/config.hpp
+++ b/packages/PEGTL/include/tao/pegtl/config.hpp
@@ -1,5 +1,6 @@
 // Copyright (c) 2017-2023 Dr. Colin Hirsch and Daniel Frey
-// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
 #ifndef TAO_PEGTL_CONFIG_HPP
 #define TAO_PEGTL_CONFIG_HPP
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/analyze_traits.hpp b/packages/PEGTL/include/tao/pegtl/contrib/analyze_traits.hpp
index 33f47d4c3..e720f0d2c 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/analyze_traits.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/analyze_traits.hpp
@@ -283,7 +283,12 @@ namespace TAO_PEGTL_NAMESPACE
    {};
 
    template< typename Name, typename Exception, typename... Rules >
-   struct analyze_traits< Name, internal::try_catch_type< Exception, Rules... > >
+   struct analyze_traits< Name, internal::try_catch_raise_nested< Exception, Rules... > >
+      : analyze_traits< Name, typename seq< Rules... >::rule_t >
+   {};
+
+   template< typename Name, typename Exception, typename... Rules >
+   struct analyze_traits< Name, internal::try_catch_return_false< Exception, Rules... > >
       : analyze_traits< Name, typename seq< Rules... >::rule_t >
    {};
 #endif
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/coverage.hpp b/packages/PEGTL/include/tao/pegtl/contrib/coverage.hpp
index 001a9f87c..ccb740483 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/coverage.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/coverage.hpp
@@ -31,6 +31,7 @@ namespace TAO_PEGTL_NAMESPACE
       std::size_t failure = 0;
       std::size_t unwind = 0;
       std::size_t raise = 0;
+      std::size_t raise_nested = 0;
    };
 
    struct coverage_entry
@@ -113,6 +114,16 @@ namespace TAO_PEGTL_NAMESPACE
             }
          }
 
+         template< typename Rule, typename Ambient, typename... States >
+         void raise_nested( const Ambient& /*unused*/, States&&... /*unused*/ )
+         {
+            const auto name = demangle< Rule >();
+            ++result.at( name ).raise_nested;
+            if( !stack.empty() ) {
+               ++result.at( stack.back() ).branches.at( name ).raise_nested;
+            }
+         }
+
          template< typename Rule, typename ParseInput, typename... States >
          void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ )
          {
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/nested_exceptions.hpp b/packages/PEGTL/include/tao/pegtl/contrib/nested_exceptions.hpp
new file mode 100644
index 000000000..90f4c623e
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/contrib/nested_exceptions.hpp
@@ -0,0 +1,112 @@
+// Copyright (c) 2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_CONTRIB_NESTED_EXCEPTIONS_HPP
+#define TAO_PEGTL_CONTRIB_NESTED_EXCEPTIONS_HPP
+
+#if !defined( __cpp_exceptions ) || !defined( __cpp_rtti )
+#error "Exception and RTTI support required for tao/pegtl/contrib/nested_exceptions.hpp"
+#endif
+
+#include <exception>
+#include <vector>
+
+#include "../config.hpp"
+#include "../parse_error.hpp"
+
+// Various utility functions and classes to handle nested exceptions given that parse_nested() now uses them.
+// At this point it's not clear yet how many, and which, of these will become and stay part of the PEGTL.
+
+namespace TAO_PEGTL_NAMESPACE::nested
+{
+   namespace internal
+   {
+      template< typename... >
+      struct rethrower;
+
+      template<>
+      struct rethrower<>
+      {
+         template< typename Processor, typename Caught, typename Visitor >
+         static void rethrow( const Caught& caught, Visitor&& /*unused*/, const std::size_t /*unused*/ )
+         {
+            std::rethrow_if_nested( caught );
+         }
+
+         template< typename Processor, typename Visitor >
+         static void rethrow( const std::exception_ptr& caught, Visitor&& /*unused*/, const std::size_t /*unused*/ )
+         {
+            std::rethrow_exception( caught );
+         }
+      };
+
+      template< typename Exception, typename... Exceptions >
+      struct rethrower< Exception, Exceptions... >
+      {
+         template< typename Processor, typename Caught, typename Visitor >
+         static void rethrow( const Caught& caught, Visitor&& visitor, const std::size_t level )
+         {
+            try {
+               rethrower< Exceptions... >::template rethrow< Processor >( caught, visitor, level );
+            }
+            catch( const Exception& exception ) {
+               Processor::process( exception, visitor, level );
+            }
+         }
+      };
+
+      template< typename Rethrower >
+      struct processor
+      {
+         template< typename Exception, typename Visitor >
+         static void process( const Exception& exception, Visitor&& visitor, const std::size_t level )
+         {
+            Rethrower::template rethrow< processor >( exception, visitor, level + 1 );
+            visitor( exception, level );
+         }
+      };
+
+      template< typename... Exceptions >
+      struct inspector
+      {
+         using Rethrower = rethrower< Exceptions... >;
+         using Processor = processor< Rethrower >;
+
+         template< typename Visitor >
+         static void inspect( const std::exception_ptr& ptr, Visitor&& visitor )
+         {
+            Rethrower::template rethrow< Processor >( ptr, visitor, 0 );
+         }
+      };
+
+   }  // namespace internal
+
+   // Exceptions in an inheritance hierarchy MUST be listed from general to specific,
+   // e.g. inspect< std::exception, std::runtime_error >, otherwise the more specific
+   // exceptions will be caught by the handler for the more general case.
+
+   template< typename... Exceptions, typename Visitor >
+   void inspect( Visitor&& visitor )
+   {
+      internal::inspector< Exceptions... >::inspect( std::current_exception(), visitor );
+   }
+
+   template< typename... Exceptions, typename Visitor >
+   void inspect( const std::exception_ptr& ptr, Visitor&& visitor )
+   {
+      internal::inspector< Exceptions... >::inspect( ptr, visitor );
+   }
+
+   [[nodiscard]] inline std::vector< parse_error > flatten( const std::exception_ptr& ptr = std::current_exception() )
+   {
+      std::vector< parse_error > result;
+      inspect< parse_error >( ptr, [ &result ]( const parse_error& e, const std::size_t /*unused*/ ) {
+         result.emplace_back( e );
+      } );
+      return result;
+   }
+
+}  // namespace TAO_PEGTL_NAMESPACE::nested
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp b/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp
index c442da75e..7a623ec52 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp
@@ -28,8 +28,8 @@
 #include "../rewind_mode.hpp"
 
 #include "../internal/enable_control.hpp"
-#include "../internal/frobnicator.hpp"
 #include "../internal/has_unwind.hpp"
+#include "../internal/inputerator.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::parse_tree
 {
@@ -43,8 +43,8 @@ namespace TAO_PEGTL_NAMESPACE::parse_tree
       std::string_view type;
       Source source;
 
-      TAO_PEGTL_NAMESPACE::internal::frobnicator m_begin;
-      TAO_PEGTL_NAMESPACE::internal::frobnicator m_end;
+      TAO_PEGTL_NAMESPACE::internal::inputerator m_begin;
+      TAO_PEGTL_NAMESPACE::internal::inputerator m_end;
 
       // each node will be default constructed
       basic_node() = default;
@@ -115,7 +115,7 @@ namespace TAO_PEGTL_NAMESPACE::parse_tree
       template< typename... States >
       void remove_content( States&&... /*unused*/ ) noexcept
       {
-         m_end = TAO_PEGTL_NAMESPACE::internal::frobnicator();
+         m_end = TAO_PEGTL_NAMESPACE::internal::inputerator();
       }
 
       // all non-root nodes are initialized by calling this method
@@ -124,14 +124,14 @@ namespace TAO_PEGTL_NAMESPACE::parse_tree
       {
          set_type< Rule >();
          source = in.source();
-         m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator( in.frobnicator() );
+         m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator( in.inputerator() );
       }
 
       // if parsing of the rule succeeded, this method is called
       template< typename Rule, typename ParseInput, typename... States >
       void success( const ParseInput& in, States&&... /*unused*/ ) noexcept
       {
-         m_end = TAO_PEGTL_NAMESPACE::internal::frobnicator( in.frobnicator() );
+         m_end = TAO_PEGTL_NAMESPACE::internal::inputerator( in.inputerator() );
       }
 
       // if parsing of the rule failed, this method is called
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/remove_first_state.hpp b/packages/PEGTL/include/tao/pegtl/contrib/remove_first_state.hpp
index 993d0fca0..68f89599b 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/remove_first_state.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/remove_first_state.hpp
@@ -14,9 +14,9 @@
 namespace TAO_PEGTL_NAMESPACE
 {
    // The first state is removed for most of the control functions forwarded to Base,
-   // start(), success(), failure(), unwind(), raise(), apply(), and apply0(). The call
-   // to match() is unchanged because it can call other grammar rules that require all
-   // states when starting their match to keep an even playing field.
+   // start(), success(), failure(), unwind(), raise(), raise_nested(), apply(), and apply0().
+   // The call to match() is unchanged because it can call other grammar rules that require
+   // all states when starting their match to keep an even playing field.
 
    template< typename Base >
    struct remove_first_state
@@ -46,6 +46,12 @@ namespace TAO_PEGTL_NAMESPACE
          Base::raise( in, st... );
       }
 
+      template< typename Ambient, typename State, typename... States >
+      [[noreturn]] static void raise_nested( const Ambient& am, State&& /*unused*/, States&&... st )
+      {
+         Base::raise_nested( am, st... );
+      }
+
       template< typename ParseInput, typename State, typename... States >
       static auto unwind( const ParseInput& in, State&& /*unused*/, States&&... st )
          -> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, States... > >
@@ -53,8 +59,8 @@ namespace TAO_PEGTL_NAMESPACE
          Base::unwind( in, st... );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename State, typename... States >
-      static auto apply( const Frobnicator& begin, const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st... ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename State, typename... States >
+      static auto apply( const Inputerator& begin, const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st... ) ) )
          -> decltype( Base::template apply< Action >( begin, in, st... ) )
       {
          return Base::template apply< Action >( begin, in, st... );
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/remove_last_states.hpp b/packages/PEGTL/include/tao/pegtl/contrib/remove_last_states.hpp
index 78a2fa68e..34b288da3 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/remove_last_states.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/remove_last_states.hpp
@@ -15,9 +15,9 @@
 namespace TAO_PEGTL_NAMESPACE
 {
    // The last N states are removed for most of the control functions forwarded to Base,
-   // start(), success(), failure(), unwind(), raise(), apply(), and apply0(). The call
-   // to match() is unchanged because it can call other grammar rules that require all
-   // states when starting their match to keep an even playing field.
+   // start(), success(), failure(), unwind(), raise(), raise_nested(),apply(), and apply0().
+   // The call to match() is unchanged because it can call other grammar rules that require
+   // all states when starting their match to keep an even playing field.
 
    template< typename Base, std::size_t N >
    struct remove_last_states
@@ -71,11 +71,23 @@ namespace TAO_PEGTL_NAMESPACE
          raise_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
       }
 
+      template< typename Ambient, typename Tuple, std::size_t... Is >
+      [[noreturn]] static void raise_nested_impl( const Ambient& am, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
+      {
+         Base::raise_nested( am, std::get< Is >( t )... );
+      }
+
+      template< typename Ambient, typename... States >
+      [[noreturn]] static void raise_nested( const Ambient& am, States&&... st )
+      {
+         raise_nested_impl( am, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
+      }
+
       template< typename ParseInput, typename Tuple, std::size_t... Is >
-      static auto unwind_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
+      static auto unwind_impl( const ParseInput& am, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
          -> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, std::tuple_element_t< Is, Tuple >... > >
       {
-         Base::unwind( in, std::get< Is >( t )... );
+         Base::unwind( am, std::get< Is >( t )... );
       }
 
       template< typename ParseInput, typename... States >
@@ -85,15 +97,15 @@ namespace TAO_PEGTL_NAMESPACE
          unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename Tuple, std::size_t... Is >
-      static auto apply_impl( const Frobnicator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Is >( t )... ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename Tuple, std::size_t... Is >
+      static auto apply_impl( const Inputerator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Is >( t )... ) ) )
          -> decltype( Base::template apply< Action >( begin, in, std::get< Is >( t )... ) )
       {
          return Base::template apply< Action >( begin, in, std::get< Is >( t )... );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename... States >
-      static auto apply( const Frobnicator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename... States >
+      static auto apply( const Inputerator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
          -> decltype( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) )
       {
          return apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/shuffle_states.hpp b/packages/PEGTL/include/tao/pegtl/contrib/shuffle_states.hpp
index ad3d2fa7c..559886c49 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/shuffle_states.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/shuffle_states.hpp
@@ -39,7 +39,7 @@ namespace TAO_PEGTL_NAMESPACE
 
    }  // namespace internal
 
-   // Applies 'Shuffle' to the states of start(), success(), failure(), raise(), apply(), and apply0()
+   // Applies 'Shuffle' to the states of start(), success(), failure(), raise(), raise_nested(), apply(), and apply0()
    template< typename Base, typename Shuffle >
    struct shuffle_states
       : Base
@@ -116,6 +116,24 @@ namespace TAO_PEGTL_NAMESPACE
          Base::raise( in, st );
       }
 
+      template< typename Ambient, typename Tuple, std::size_t... Is >
+      [[noreturn]] static void raise_nested_impl( const Ambient& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
+      {
+         Base::raise_nested( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
+      }
+
+      template< typename Ambient, typename... States >
+      [[noreturn]] static void raise_nested( const Ambient& in, States&&... st )
+      {
+         raise_nested_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
+      }
+
+      template< typename Ambient, typename State >
+      [[noreturn]] static void raise_nested( const Ambient& in, State&& st )
+      {
+         Base::raise_nested( in, st );
+      }
+
       template< typename ParseInput, typename Tuple, std::size_t... Is >
       static auto unwind_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
          -> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, std::tuple_element_t< Shuffle::template value< Is, sizeof...( Is ) >, Tuple >... > >
@@ -137,22 +155,22 @@ namespace TAO_PEGTL_NAMESPACE
          Base::unwind( in, st );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename Tuple, std::size_t... Is >
-      static auto apply_impl( const Frobnicator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename Tuple, std::size_t... Is >
+      static auto apply_impl( const Inputerator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
          -> decltype( Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) )
       {
          return Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename... States >
-      static auto apply( const Frobnicator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename... States >
+      static auto apply( const Inputerator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
          -> decltype( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) )
       {
          return apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
       }
 
-      template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename State >
-      static auto apply( const Frobnicator& begin, const ParseInput& in, State&& st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st ) ) )
+      template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename State >
+      static auto apply( const Inputerator& begin, const ParseInput& in, State&& st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st ) ) )
          -> decltype( Base::template apply< Action >( begin, in, st ) )
       {
          return Base::template apply< Action >( begin, in, st );
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/state_control.hpp b/packages/PEGTL/include/tao/pegtl/contrib/state_control.hpp
index 8041efdf8..28c66017d 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/state_control.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/state_control.hpp
@@ -78,6 +78,15 @@ namespace TAO_PEGTL_NAMESPACE
             Control< Rule >::raise( in, st... );
          }
 
+         template< typename Ambient, typename State, typename... States >
+         [[noreturn]] static void raise_nested( const Ambient& am, [[maybe_unused]] State& state, States&&... st )
+         {
+            if constexpr( State::template enable< Rule > ) {
+               state.template raise_nested< Rule >( am, st... );
+            }
+            Control< Rule >::raise_nested( am, st... );
+         }
+
          template< typename ParseInput, typename State, typename... States >
          static auto unwind( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st )
             -> std::enable_if_t< State::template enable< Rule > || ( Control< Rule >::enable && internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) >
@@ -94,8 +103,8 @@ namespace TAO_PEGTL_NAMESPACE
 #endif
          }
 
-         template< template< typename... > class Action, typename Frobnicator, typename ParseInput, typename State, typename... States >
-         static auto apply( const Frobnicator& begin, const ParseInput& in, [[maybe_unused]] State& state, States&&... st )
+         template< template< typename... > class Action, typename Inputerator, typename ParseInput, typename State, typename... States >
+         static auto apply( const Inputerator& begin, const ParseInput& in, [[maybe_unused]] State& state, States&&... st )
             -> decltype( Control< Rule >::template apply< Action >( begin, in, st... ) )
          {
             if constexpr( State::template enable< Rule > ) {
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/trace.hpp b/packages/PEGTL/include/tao/pegtl/contrib/trace.hpp
index 67a880424..e71659138 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/trace.hpp
+++ b/packages/PEGTL/include/tao/pegtl/contrib/trace.hpp
@@ -10,6 +10,7 @@
 #include <iostream>
 #include <string_view>
 #include <tuple>
+#include <vector>
 
 #include "state_control.hpp"
 
@@ -148,6 +149,12 @@ namespace TAO_PEGTL_NAMESPACE
          std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_raise << "raise" << TracerTraits::ansi_reset << ' ' << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
       }
 
+      template< typename Rule, typename Ambient, typename... States >
+      void raise_nested( const Ambient& /*unused*/, States&&... /*unused*/ )
+      {
+         std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_raise << "raise_nested" << TracerTraits::ansi_reset << ' ' << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
+      }
+
       template< typename Rule, typename ParseInput, typename... States >
       void unwind( const ParseInput& in, States&&... /*unused*/ )
       {
diff --git a/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp b/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp
index b37173684..55d43c583 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp
@@ -10,7 +10,7 @@
 #include <string>
 #include <string_view>
 
-#include "frobnicator.hpp"
+#include "inputerator.hpp"
 
 #include "../config.hpp"
 #include "../position.hpp"
@@ -22,9 +22,9 @@ namespace TAO_PEGTL_NAMESPACE::internal
    {
    public:
       using input_t = ParseInput;
-      using frobnicator_t = typename ParseInput::frobnicator_t;
+      using inputerator_t = typename ParseInput::inputerator_t;
 
-      action_input( const frobnicator_t& in_begin, const ParseInput& in_input ) noexcept
+      action_input( const inputerator_t& in_begin, const ParseInput& in_input ) noexcept
          : m_begin( in_begin ),
            m_input( in_input )
       {}
@@ -37,7 +37,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       action_input& operator=( const action_input& ) = delete;
       action_input& operator=( action_input&& ) = delete;
 
-      [[nodiscard]] const frobnicator_t& frobnicator() const noexcept
+      [[nodiscard]] const inputerator_t& inputerator() const noexcept
       {
          return m_begin;
       }
@@ -47,13 +47,18 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return m_input;
       }
 
+      [[nodiscard]] const char* current() const noexcept
+      {
+         return begin();
+      }
+
       [[nodiscard]] const char* begin() const noexcept
       {
-         if constexpr( std::is_same_v< frobnicator_t, const char* > ) {
-            return frobnicator();
+         if constexpr( std::is_same_v< inputerator_t, const char* > ) {
+            return inputerator();
          }
          else {
-            return frobnicator().data;
+            return inputerator().data;
          }
       }
 
@@ -94,11 +99,16 @@ namespace TAO_PEGTL_NAMESPACE::internal
 
       [[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const
       {
-         return input().position( frobnicator() );  // NOTE: Not efficient with lazy inputs.
+         return input().position( inputerator() );  // NOTE: Not efficient with lazy inputs.
+      }
+
+      [[nodiscard]] TAO_PEGTL_NAMESPACE::position current_position() const
+      {
+         return input().position( inputerator() );  // NOTE: Not efficient with lazy inputs.
       }
 
    protected:
-      const frobnicator_t m_begin;
+      const inputerator_t m_begin;
       const ParseInput& m_input;
    };
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/apply.hpp
index e83ba9114..4993fa262 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/apply.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/apply.hpp
@@ -33,7 +33,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       {
          if constexpr( ( A == apply_mode::action ) && ( sizeof...( Actions ) > 0 ) ) {
             using action_t = typename ParseInput::action_t;
-            const action_t i2( in.frobnicator(), in );  // No data -- range is from begin to begin.
+            const action_t i2( in.inputerator(), in );  // No data -- range is from begin to begin.
             return ( apply_single< Actions >::match( i2, st... ) && ... );
          }
          else {
diff --git a/packages/PEGTL/include/tao/pegtl/internal/at.hpp b/packages/PEGTL/include/tao/pegtl/internal/at.hpp
index a28ba3991..b1eaf5bdd 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/at.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/at.hpp
@@ -43,7 +43,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       [[nodiscard]] static bool match( ParseInput& in, States&&... st )
       {
          const auto m = in.template auto_rewind< rewind_mode::required >();
-         return Control< Rule >::template match< apply_mode::nothing, rewind_mode::active, Action, Control >( in, st... );
+         return Control< Rule >::template match< apply_mode::nothing, rewind_mode::optional, Action, Control >( in, st... );
       }
    };
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/bump.hpp b/packages/PEGTL/include/tao/pegtl/internal/bump.hpp
index 5ec599124..a7ae3844a 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/bump.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/bump.hpp
@@ -5,13 +5,13 @@
 #ifndef TAO_PEGTL_INTERNAL_BUMP_HPP
 #define TAO_PEGTL_INTERNAL_BUMP_HPP
 
-#include "frobnicator.hpp"
+#include "inputerator.hpp"
 
 #include "../config.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
-   inline void bump( frobnicator& iter, const std::size_t count, const int ch ) noexcept
+   inline void bump( inputerator& iter, const std::size_t count, const int ch ) noexcept
    {
       for( std::size_t i = 0; i < count; ++i ) {
          if( iter.data[ i ] == ch ) {
@@ -26,14 +26,14 @@ namespace TAO_PEGTL_NAMESPACE::internal
       iter.data += count;
    }
 
-   inline void bump_in_this_line( frobnicator& iter, const std::size_t count ) noexcept
+   inline void bump_in_this_line( inputerator& iter, const std::size_t count ) noexcept
    {
       iter.data += count;
       iter.byte += count;
       iter.column += count;
    }
 
-   inline void bump_to_next_line( frobnicator& iter, const std::size_t count ) noexcept
+   inline void bump_to_next_line( inputerator& iter, const std::size_t count ) noexcept
    {
       ++iter.line;
       iter.byte += count;
diff --git a/packages/PEGTL/include/tao/pegtl/internal/extract_position.hpp b/packages/PEGTL/include/tao/pegtl/internal/extract_position.hpp
new file mode 100644
index 000000000..7105793ca
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/internal/extract_position.hpp
@@ -0,0 +1,30 @@
+// Copyright (c) 2022-2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_INTERNAL_EXTRACT_POSITION_HPP
+#define TAO_PEGTL_INTERNAL_EXTRACT_POSITION_HPP
+
+#include "../config.hpp"
+
+#include "has_current_position.hpp"
+
+namespace TAO_PEGTL_NAMESPACE::internal
+{
+   template< typename T >
+   [[nodiscard]] decltype( auto ) extract_position( const T& t )
+   {
+      if constexpr( !has_current_position< T > ) {
+         return t;  // Assume t is not an input.
+      }
+      else if constexpr( !has_current_position< decltype( *t.current() ) > ) {
+         return t.current_position();  // Assume t is an input of "simple" object (char, enums).
+      }
+      else {
+         return t.current()->current_position();  // Assume t is an input of objects that already have a position (tokens).
+      }
+   }
+
+}  // namespace TAO_PEGTL_NAMESPACE::internal
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/filesystem.hpp b/packages/PEGTL/include/tao/pegtl/internal/filesystem.hpp
deleted file mode 100644
index 311c74577..000000000
--- a/packages/PEGTL/include/tao/pegtl/internal/filesystem.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2020-2023 Dr. Colin Hirsch and Daniel Frey
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef TAO_PEGTL_INTERNAL_FILESYSTEM_HPP
-#define TAO_PEGTL_INTERNAL_FILESYSTEM_HPP
-
-#include "../config.hpp"
-
-#if defined( TAO_PEGTL_BOOST_FILESYSTEM )
-
-#define BOOST_FILESYSTEM_NO_DEPRECATED
-
-#include <boost/filesystem.hpp>
-
-namespace TAO_PEGTL_NAMESPACE::internal
-{
-   namespace filesystem = ::boost::filesystem;
-
-   using error_code = ::boost::system::error_code;
-
-   inline const auto& system_category() noexcept
-   {
-      return ::boost::system::system_category();
-   }
-
-}  // namespace TAO_PEGTL_NAMESPACE::internal
-
-#elif defined( TAO_PEGTL_STD_EXPERIMENTAL_FILESYSTEM )
-
-#include <experimental/filesystem>
-
-namespace TAO_PEGTL_NAMESPACE::internal
-{
-   namespace filesystem = ::std::experimental::filesystem;
-
-   using error_code = ::std::error_code;
-
-   inline const auto& system_category() noexcept
-   {
-      return ::std::system_category();
-   }
-
-}  // namespace TAO_PEGTL_NAMESPACE::internal
-
-#else
-
-#include <filesystem>
-
-namespace TAO_PEGTL_NAMESPACE::internal
-{
-   namespace filesystem = ::std::filesystem;
-
-   using error_code = ::std::error_code;
-
-   inline const auto& system_category() noexcept
-   {
-      return ::std::system_category();
-   }
-
-}  // namespace TAO_PEGTL_NAMESPACE::internal
-
-#endif
-
-#endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/has_current_position.hpp b/packages/PEGTL/include/tao/pegtl/internal/has_current_position.hpp
new file mode 100644
index 000000000..d1ef5e44c
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/internal/has_current_position.hpp
@@ -0,0 +1,24 @@
+// Copyright (c) 2022-2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_INTERNAL_HAS_CURRENT_POSITION_HPP
+#define TAO_PEGTL_INTERNAL_HAS_CURRENT_POSITION_HPP
+
+#include <utility>
+
+#include "../config.hpp"
+
+namespace TAO_PEGTL_NAMESPACE::internal
+{
+   template< typename, typename = void >
+   inline constexpr bool has_current_position = false;
+
+   template< typename C >
+   inline constexpr bool has_current_position< C, decltype( (void)std::declval< C >().current_position(), void() ) > = true;
+
+   // The (void) is to shut up a warning from GCC 9 and 10 about the return value of the nodiscard-function current_position() being ignored.
+
+}  // namespace TAO_PEGTL_NAMESPACE::internal
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp
index 7ce7c4855..b7b6ccb7c 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp
@@ -34,8 +34,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if constexpr( ( A == apply_mode::action ) && ( sizeof...( Actions ) != 0 ) ) {
             using action_t = typename ParseInput::action_t;
             auto m = in.template auto_rewind< rewind_mode::required >();
-            if( Control< Rule >::template match< apply_mode::action, rewind_mode::active, Action, Control >( in, st... ) ) {
-               const action_t i2( m.frobnicator(), in );
+            if( Control< Rule >::template match< apply_mode::action, rewind_mode::optional, Action, Control >( in, st... ) ) {
+               const action_t i2( m.inputerator(), in );
                return m( ( apply_single< Actions >::match( i2, st... ) && ... ) );
             }
             return false;
diff --git a/packages/PEGTL/include/tao/pegtl/internal/frobnicator.hpp b/packages/PEGTL/include/tao/pegtl/internal/inputerator.hpp
similarity index 61%
rename from packages/PEGTL/include/tao/pegtl/internal/frobnicator.hpp
rename to packages/PEGTL/include/tao/pegtl/internal/inputerator.hpp
index d846d6fd7..9e72cf4e7 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/frobnicator.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/inputerator.hpp
@@ -2,8 +2,8 @@
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef TAO_PEGTL_INTERNAL_FROBNICATOR_HPP
-#define TAO_PEGTL_INTERNAL_FROBNICATOR_HPP
+#ifndef TAO_PEGTL_INTERNAL_INPUTERATOR_HPP
+#define TAO_PEGTL_INTERNAL_INPUTERATOR_HPP
 
 #include <cassert>
 #include <cstdlib>
@@ -12,15 +12,15 @@
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
-   struct frobnicator
+   struct inputerator
    {
-      frobnicator() = default;
+      inputerator() noexcept = default;
 
-      explicit frobnicator( const char* in_data ) noexcept
+      explicit inputerator( const char* in_data ) noexcept
          : data( in_data )
       {}
 
-      frobnicator( const char* in_data, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_column ) noexcept
+      inputerator( const char* in_data, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_column ) noexcept
          : data( in_data ),
            byte( in_byte ),
            line( in_line ),
@@ -30,13 +30,13 @@ namespace TAO_PEGTL_NAMESPACE::internal
          assert( in_column != 0 );
       }
 
-      frobnicator( const frobnicator& ) = default;
-      frobnicator( frobnicator&& ) = default;
+      inputerator( const inputerator& ) = default;
+      inputerator( inputerator&& ) = default;
 
-      ~frobnicator() = default;
+      ~inputerator() = default;
 
-      frobnicator& operator=( const frobnicator& ) = default;
-      frobnicator& operator=( frobnicator&& ) = default;
+      inputerator& operator=( const inputerator& ) = default;
+      inputerator& operator=( inputerator&& ) = default;
 
       const char* data = nullptr;
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/missing_apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/missing_apply.hpp
index 688558821..8e1c51ef3 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/missing_apply.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/missing_apply.hpp
@@ -20,7 +20,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       // This function only exists for better error messages, which means that it is only called when we know that it won't compile.
       // LCOV_EXCL_START
       auto m = in.template auto_rewind< rewind_mode::required >();
-      (void)Control::template apply< Action >( m.frobnicator(), in, st... );
+      (void)Control::template apply< Action >( m.inputerator(), in, st... );
       // LCOV_EXCL_STOP
    }
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/mmap_file.hpp b/packages/PEGTL/include/tao/pegtl/internal/mmap_file.hpp
index 361a6f0bd..ff9d205fa 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/mmap_file.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/mmap_file.hpp
@@ -16,7 +16,7 @@
 #else
 #endif
 
-#include "filesystem.hpp"
+#include <filesystem>
 
 #include "../config.hpp"
 
@@ -26,7 +26,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
    {
       const mmap_file_impl data;
 
-      explicit mmap_file( const internal::filesystem::path& path )
+      explicit mmap_file( const std::filesystem::path& path )
          : data( path )
       {}
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/mmap_file_posix.hpp b/packages/PEGTL/include/tao/pegtl/internal/mmap_file_posix.hpp
index 367ae90d4..d44a049c2 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/mmap_file_posix.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/mmap_file_posix.hpp
@@ -6,27 +6,25 @@
 #define TAO_PEGTL_INTERNAL_MMAP_FILE_POSIX_HPP
 
 #include <fcntl.h>
+#include <filesystem>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <utility>
 
 #if !defined( __cpp_exceptions )
 #include <cstdio>
 #include <exception>
 #endif
 
-#include <utility>
-
-#include "filesystem.hpp"
-
 #include "../config.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
    struct mmap_file_open
    {
-      explicit mmap_file_open( const internal::filesystem::path& path )  // NOLINT(modernize-pass-by-value)
+      explicit mmap_file_open( const std::filesystem::path& path )  // NOLINT(modernize-pass-by-value)
          : m_path( path ),
            m_fd( open() )
       {}
@@ -49,8 +47,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( ::fstat( m_fd, &st ) < 0 ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "fstat() failed", m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "fstat() failed", m_path, ec );
 #else
             std::perror( "fstat() failed" );
             std::terminate();
@@ -60,7 +58,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return static_cast< std::size_t >( st.st_size );
       }
 
-      const internal::filesystem::path m_path;
+      const std::filesystem::path m_path;
       const int m_fd;
 
    private:
@@ -77,8 +75,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
             return fd;
          }
 #if defined( __cpp_exceptions )
-         const internal::error_code ec( errno, internal::system_category() );
-         throw internal::filesystem::filesystem_error( "open() failed", m_path, ec );
+         const std::error_code ec( errno, std::system_category() );
+         throw std::filesystem::filesystem_error( "open() failed", m_path, ec );
 #else
          std::perror( "open() failed" );
          std::terminate();
@@ -89,7 +87,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
    class mmap_file_posix
    {
    public:
-      explicit mmap_file_posix( const internal::filesystem::path& path )
+      explicit mmap_file_posix( const std::filesystem::path& path )
          : mmap_file_posix( mmap_file_open( path ) )
       {}
 
@@ -100,8 +98,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( ( m_size != 0 ) && ( reinterpret_cast< intptr_t >( m_data ) == -1 ) ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "mmap() failed", reader.m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "mmap() failed", reader.m_path, ec );
 #else
             std::perror( "mmap() failed" );
             std::terminate();
@@ -132,20 +130,17 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return m_size;
       }
 
-      using iterator = const char*;
-      using const_iterator = const char*;
-
-      [[nodiscard]] iterator data() const noexcept
+      [[nodiscard]] const char* data() const noexcept
       {
          return m_data;
       }
 
-      [[nodiscard]] iterator begin() const noexcept
+      [[nodiscard]] const char* begin() const noexcept
       {
          return m_data;
       }
 
-      [[nodiscard]] iterator end() const noexcept
+      [[nodiscard]] const char* end() const noexcept
       {
          return m_data + m_size;
       }
diff --git a/packages/PEGTL/include/tao/pegtl/internal/mmap_file_win32.hpp b/packages/PEGTL/include/tao/pegtl/internal/mmap_file_win32.hpp
index 5f2a3dbee..df24d8a88 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/mmap_file_win32.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/mmap_file_win32.hpp
@@ -34,13 +34,13 @@
 #include <exception>
 #endif
 
-#include "filesystem.hpp"
+#include <filesystem>
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
    struct mmap_file_open
    {
-      explicit mmap_file_open( const internal::filesystem::path& path )
+      explicit mmap_file_open( const std::filesystem::path& path )
          : m_path( path ),
            m_handle( open() )
       {}
@@ -61,8 +61,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          LARGE_INTEGER size;
          if( !::GetFileSizeEx( m_handle, &size ) ) {
 #if defined( __cpp_exceptions )
-            internal::error_code ec( ::GetLastError(), internal::system_category() );
-            throw internal::filesystem::filesystem_error( "GetFileSizeEx() failed", m_path, ec );
+            std::error_code ec( ::GetLastError(), std::system_category() );
+            throw std::filesystem::filesystem_error( "GetFileSizeEx() failed", m_path, ec );
 #else
             std::perror( "GetFileSizeEx() failed" );
             std::terminate();
@@ -71,7 +71,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return std::size_t( size.QuadPart );
       }
 
-      const internal::filesystem::path m_path;
+      const std::filesystem::path m_path;
       const HANDLE m_handle;
 
    private:
@@ -88,8 +88,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
             return handle;
          }
 #if defined( __cpp_exceptions )
-         internal::error_code ec( ::GetLastError(), internal::system_category() );
-         throw internal::filesystem::filesystem_error( "CreateFile2() failed", m_path, ec );
+         std::error_code ec( ::GetLastError(), std::system_category() );
+         throw std::filesystem::filesystem_error( "CreateFile2() failed", m_path, ec );
 #else
          std::perror( "CreateFile2() failed" );
          std::terminate();
@@ -106,8 +106,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
             return handle;
          }
 #if defined( __cpp_exceptions )
-         internal::error_code ec( ::GetLastError(), internal::system_category() );
-         throw internal::filesystem::filesystem_error( "CreateFileW()", m_path, ec );
+         std::error_code ec( ::GetLastError(), std::system_category() );
+         throw std::filesystem::filesystem_error( "CreateFileW()", m_path, ec );
 #else
          std::perror( "CreateFileW() failed" );
          std::terminate();
@@ -118,7 +118,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
 
    struct mmap_file_mmap
    {
-      explicit mmap_file_mmap( const internal::filesystem::path& path )
+      explicit mmap_file_mmap( const std::filesystem::path& path )
          : mmap_file_mmap( mmap_file_open( path ) )
       {}
 
@@ -160,8 +160,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
             return handle;
          }
 #if defined( __cpp_exceptions )
-         internal::error_code ec( ::GetLastError(), internal::system_category() );
-         throw internal::filesystem::filesystem_error( "CreateFileMappingW() failed", reader.m_path, ec );
+         std::error_code ec( ::GetLastError(), std::system_category() );
+         throw std::filesystem::filesystem_error( "CreateFileMappingW() failed", reader.m_path, ec );
 #else
          std::perror( "CreateFileMappingW() failed" );
          std::terminate();
@@ -172,7 +172,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
    class mmap_file_win32
    {
    public:
-      explicit mmap_file_win32( const internal::filesystem::path& path )
+      explicit mmap_file_win32( const std::filesystem::path& path )
          : mmap_file_win32( mmap_file_mmap( path ) )
       {}
 
@@ -186,8 +186,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
       {
          if( ( m_size != 0 ) && ( intptr_t( m_data ) == 0 ) ) {
 #if defined( __cpp_exceptions )
-            internal::error_code ec( ::GetLastError(), internal::system_category() );
-            throw internal::filesystem::filesystem_error( "MapViewOfFile() failed", ec );
+            std::error_code ec( ::GetLastError(), std::system_category() );
+            throw std::filesystem::filesystem_error( "MapViewOfFile() failed", ec );
 #else
             std::perror( "MapViewOfFile() failed" );
             std::terminate();
@@ -216,20 +216,17 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return m_size;
       }
 
-      using iterator = const char*;
-      using const_iterator = const char*;
-
-      [[nodiscard]] iterator data() const noexcept
+      [[nodiscard]] const char* data() const noexcept
       {
          return m_data;
       }
 
-      [[nodiscard]] iterator begin() const noexcept
+      [[nodiscard]] const char* begin() const noexcept
       {
          return m_data;
       }
 
-      [[nodiscard]] iterator end() const noexcept
+      [[nodiscard]] const char* end() const noexcept
       {
          return m_data + m_size;
       }
diff --git a/packages/PEGTL/include/tao/pegtl/internal/must.hpp b/packages/PEGTL/include/tao/pegtl/internal/must.hpp
index 93be8941f..0a17e91a3 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/must.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/must.hpp
@@ -53,7 +53,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
                 typename... States >
       [[nodiscard]] static bool match( ParseInput& in, States&&... st )
       {
-         if( !Control< Rule >::template match< A, rewind_mode::dontcare, Action, Control >( in, st... ) ) {
+         if( !Control< Rule >::template match< A, rewind_mode::optional, Action, Control >( in, st... ) ) {
             Control< Rule >::raise( static_cast< const ParseInput& >( in ), st... );
          }
          return true;
diff --git a/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp b/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp
index b665d1e73..7fd803eca 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp
@@ -43,7 +43,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       [[nodiscard]] static bool match( ParseInput& in, States&&... st )
       {
          const auto m = in.template auto_rewind< rewind_mode::required >();
-         return !Control< Rule >::template match< apply_mode::nothing, rewind_mode::active, Action, Control >( in, st... );
+         return !Control< Rule >::template match< apply_mode::nothing, rewind_mode::optional, Action, Control >( in, st... );
       }
    };
 
diff --git a/packages/PEGTL/include/tao/pegtl/internal/path_to_string.hpp b/packages/PEGTL/include/tao/pegtl/internal/path_to_string.hpp
index 4d5fe80d1..56091782d 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/path_to_string.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/path_to_string.hpp
@@ -5,19 +5,16 @@
 #ifndef TAO_PEGTL_INTERNAL_PATH_TO_STRING_HPP
 #define TAO_PEGTL_INTERNAL_PATH_TO_STRING_HPP
 
+#include <filesystem>
 #include <string>
 
-#include "filesystem.hpp"
-
 #include "../config.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
-   [[nodiscard]] inline std::string path_to_string( const internal::filesystem::path& path )
+   [[nodiscard]] inline std::string path_to_string( const std::filesystem::path& path )
    {
-#if defined( TAO_PEGTL_BOOST_FILESYSTEM )
-      return path.string();
-#elif defined( __cpp_char8_t )
+#if defined( __cpp_char8_t )
       const auto s = path.u8string();
       return { reinterpret_cast< const char* >( s.data() ), s.size() };
 #else
diff --git a/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp b/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp
index 3811179fd..645f4b732 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp
@@ -55,7 +55,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
 #define TAO_PEGTL_INTERNAL_STRING_AT( S, x, n ) \
    ::TAO_PEGTL_NAMESPACE::internal::string_at< S, ( 0##n < ( sizeof( x ) / sizeof( char ) ) ) ? ( x )[ 0##n ] : 0, ( 0##n < ( sizeof( x ) / sizeof( char ) ) - 1 ) >::type
 
-#define TAO_PEGTL_INTERNAL_JOIN_8( M, S, x, n )                                    \
+#define TAO_PEGTL_INTERNAL_JOIN_8( M, S, x, n )                                               \
    ::TAO_PEGTL_NAMESPACE::internal::string_join< TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##0 ), \
                                                  TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##1 ), \
                                                  TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##2 ), \
diff --git a/packages/PEGTL/include/tao/pegtl/internal/read_file_stdio.hpp b/packages/PEGTL/include/tao/pegtl/internal/read_file_stdio.hpp
index afb08a67e..29210cf1d 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/read_file_stdio.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/read_file_stdio.hpp
@@ -6,6 +6,7 @@
 #define TAO_PEGTL_INTERNAL_READ_FILE_STDIO_HPP
 
 #include <cstdio>
+#include <filesystem>
 #include <memory>
 #include <string>
 #include <utility>
@@ -14,40 +15,34 @@
 #include <exception>
 #endif
 
-#include "filesystem.hpp"
 #include "resize_uninitialized.hpp"
 
 #include "../config.hpp"
 
 namespace TAO_PEGTL_NAMESPACE::internal
 {
-   [[nodiscard]] inline std::FILE* read_file_open( const internal::filesystem::path& path )
+   [[nodiscard]] inline std::FILE* read_file_open( const std::filesystem::path& path )
    {
       errno = 0;
-#if defined( _MSC_VER )
+#if defined( _MSC_VER ) || defined( __MINGW32__ )
       std::FILE* file;
       if( ::_wfopen_s( &file, path.c_str(), L"rb" ) == 0 ) {
          return file;
       }
 #if defined( __cpp_exceptions )
-      const internal::error_code ec( errno, internal::system_category() );
-      throw internal::filesystem::filesystem_error( "_wfopen_s() failed", path, ec );
+      const std::error_code ec( errno, std::system_category() );
+      throw std::filesystem::filesystem_error( "_wfopen_s() failed", path, ec );
 #else
       std::perror( "_wfopen_s() failed" );
       std::terminate();
 #endif
 #else
-#if defined( __MINGW32__ )
-      if( auto* file = std::fopen( path.string().c_str(), "rb" ) )
-#else
-      if( auto* file = std::fopen( path.c_str(), "rbe" ) )
-#endif
-      {
+      if( auto* file = std::fopen( path.c_str(), "rbe" ) ) {
          return file;
       }
 #if defined( __cpp_exceptions )
-      const internal::error_code ec( errno, internal::system_category() );
-      throw internal::filesystem::filesystem_error( "std::fopen() failed", path, ec );
+      const std::error_code ec( errno, std::system_category() );
+      throw std::filesystem::filesystem_error( "std::fopen() failed", path, ec );
 #else
       std::perror( "std::fopen() failed" );
       std::terminate();
@@ -66,11 +61,11 @@ namespace TAO_PEGTL_NAMESPACE::internal
    class read_file_stdio
    {
    public:
-      explicit read_file_stdio( const internal::filesystem::path& path )
+      explicit read_file_stdio( const std::filesystem::path& path )
          : read_file_stdio( read_file_open( path ), path )
       {}
 
-      read_file_stdio( FILE* file, const internal::filesystem::path& path )  // NOLINT(modernize-pass-by-value)
+      read_file_stdio( FILE* file, const std::filesystem::path& path )  // NOLINT(modernize-pass-by-value)
          : m_path( path ),
            m_file( file )
       {}
@@ -89,8 +84,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( std::fseek( m_file.get(), 0, SEEK_END ) != 0 ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "std::fseek() failed [SEEK_END]", m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "std::fseek() failed [SEEK_END]", m_path, ec );
 #else
             std::perror( "std::fseek() failed [SEEK_END]" );
             std::terminate();
@@ -102,8 +97,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( s < 0 ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "std::ftell() failed", m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "std::ftell() failed", m_path, ec );
 #else
             std::perror( "std::ftell() failed" );
             std::terminate();
@@ -114,8 +109,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( std::fseek( m_file.get(), 0, SEEK_SET ) != 0 ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "std::fseek() failed [SEEK_SET]", m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "std::fseek() failed [SEEK_SET]", m_path, ec );
 #else
             std::perror( "std::fseek() failed [SEEK_SET]" );
             std::terminate();
@@ -136,7 +131,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
       }
 
    private:
-      const internal::filesystem::path m_path;
+      const std::filesystem::path m_path;
       const std::unique_ptr< std::FILE, read_file_close > m_file;
 
       void read_impl( void* buffer, const std::size_t length ) const
@@ -145,8 +140,8 @@ namespace TAO_PEGTL_NAMESPACE::internal
          if( std::fread( buffer, length, 1, m_file.get() ) != 1 ) {
             // LCOV_EXCL_START
 #if defined( __cpp_exceptions )
-            const internal::error_code ec( errno, internal::system_category() );
-            throw internal::filesystem::filesystem_error( "std::fread() failed", m_path, ec );
+            const std::error_code ec( errno, std::system_category() );
+            throw std::filesystem::filesystem_error( "std::fread() failed", m_path, ec );
 #else
             std::perror( "std::fread() failed" );
             std::terminate();
diff --git a/packages/PEGTL/include/tao/pegtl/internal/rematch.hpp b/packages/PEGTL/include/tao/pegtl/internal/rematch.hpp
index e5f8ac6fb..063cd32ec 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/rematch.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/rematch.hpp
@@ -56,9 +56,9 @@ namespace TAO_PEGTL_NAMESPACE::internal
       {
          auto m = in.template auto_rewind< rewind_mode::required >();
 
-         if( Control< Head >::template match< A, rewind_mode::active, Action, Control >( in, st... ) ) {
-            memory_input< ParseInput::tracking_mode_v, typename ParseInput::eol_t, typename ParseInput::source_t > i2( m.frobnicator(), in.current(), in.source() );
-            return m( ( Control< Rule >::template match< A, rewind_mode::active, Action, Control >( i2, st... ) && ... && ( i2.restart( m ), Control< Rules >::template match< A, rewind_mode::active, Action, Control >( i2, st... ) ) ) );
+         if( Control< Head >::template match< A, rewind_mode::optional, Action, Control >( in, st... ) ) {
+            memory_input< ParseInput::tracking_mode_v, typename ParseInput::eol_t, typename ParseInput::source_t > i2( m.inputerator(), in.current(), in.source() );
+            return m( ( Control< Rule >::template match< A, rewind_mode::optional, Action, Control >( i2, st... ) && ... && ( i2.restart( m ), Control< Rules >::template match< A, rewind_mode::optional, Action, Control >( i2, st... ) ) ) );
          }
          return false;
       }
diff --git a/packages/PEGTL/include/tao/pegtl/internal/rewind_guard.hpp b/packages/PEGTL/include/tao/pegtl/internal/rewind_guard.hpp
index 8c4a6461a..f54b5edec 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/rewind_guard.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/rewind_guard.hpp
@@ -40,7 +40,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
    class [[nodiscard]] rewind_guard< rewind_mode::required, ParseInput >
    {
    public:
-      static constexpr rewind_mode next_rewind_mode = rewind_mode::active;
+      static constexpr rewind_mode next_rewind_mode = rewind_mode::optional;
 
       using rewind_data = std::decay_t< decltype( std::declval< ParseInput >().rewind_save() ) >;
 
@@ -71,7 +71,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
          return false;
       }
 
-      [[nodiscard]] const rewind_data& frobnicator() const noexcept
+      [[nodiscard]] const rewind_data& inputerator() const noexcept
       {
          return m_saved;
       }
diff --git a/packages/PEGTL/include/tao/pegtl/internal/rules.hpp b/packages/PEGTL/include/tao/pegtl/internal/rules.hpp
index 5a53bcf49..aa88e59b7 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/rules.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/rules.hpp
@@ -64,7 +64,8 @@
 #include "must.hpp"
 #include "raise.hpp"
 #include "star_must.hpp"
-#include "try_catch_type.hpp"
+#include "try_catch_raise_nested.hpp"
+#include "try_catch_return_false.hpp"
 #endif
 
 #endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/stream_to_string.hpp b/packages/PEGTL/include/tao/pegtl/internal/stream_to_string.hpp
new file mode 100644
index 000000000..79139bde1
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/internal/stream_to_string.hpp
@@ -0,0 +1,26 @@
+// Copyright (c) 2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_INTERNAL_STREAM_TO_STRING_HPP
+#define TAO_PEGTL_INTERNAL_STREAM_TO_STRING_HPP
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "../config.hpp"
+
+namespace TAO_PEGTL_NAMESPACE::internal
+{
+   template< typename T >
+   [[nodiscard]] std::string stream_to_string( const T& t )
+   {
+      std::ostringstream oss;
+      oss << t;
+      return std::move( oss ).str();
+   }
+
+}  // namespace TAO_PEGTL_NAMESPACE::internal
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/try_catch_raise_nested.hpp b/packages/PEGTL/include/tao/pegtl/internal/try_catch_raise_nested.hpp
new file mode 100644
index 000000000..b3512b918
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/internal/try_catch_raise_nested.hpp
@@ -0,0 +1,97 @@
+// Copyright (c) 2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_INTERNAL_TRY_CATCH_RAISE_NESTED_HPP
+#define TAO_PEGTL_INTERNAL_TRY_CATCH_RAISE_NESTED_HPP
+
+#if !defined( __cpp_exceptions )
+#error "Exception support required for tao/pegtl/internal/try_catch_raise_nested.hpp"
+#else
+
+#include <type_traits>
+
+#include "enable_control.hpp"
+#include "seq.hpp"
+#include "success.hpp"
+
+#include "../apply_mode.hpp"
+#include "../config.hpp"
+#include "../rewind_mode.hpp"
+#include "../type_list.hpp"
+
+namespace TAO_PEGTL_NAMESPACE::internal
+{
+   template< typename Exception, typename... Rules >
+   struct try_catch_raise_nested
+      : try_catch_raise_nested< Exception, seq< Rules... > >
+   {};
+
+   template< typename Exception >
+   struct try_catch_raise_nested< Exception >
+      : success
+   {};
+
+   template< typename Rule >
+   struct try_catch_raise_nested< void, Rule >
+   {
+      using rule_t = try_catch_raise_nested;
+      using subs_t = type_list< Rule >;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename ParseInput,
+                typename... States >
+      [[nodiscard]] static bool match( ParseInput& in, States&&... st )
+      {
+         auto m = in.template auto_rewind< rewind_mode::required >();
+         using m_t = decltype( m );
+
+         try {
+            return m( Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) );
+         }
+         catch( ... ) {
+            Control< Rule >::raise_nested( in.position( m.inputerator() ), st... );
+         }
+      }
+   };
+
+   template< typename Exception, typename Rule >
+   struct try_catch_raise_nested< Exception, Rule >
+   {
+      using rule_t = try_catch_raise_nested;
+      using subs_t = type_list< Rule >;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename ParseInput,
+                typename... States >
+      [[nodiscard]] static bool match( ParseInput& in, States&&... st )
+      {
+         auto m = in.template auto_rewind< rewind_mode::required >();
+         using m_t = decltype( m );
+
+         try {
+            return m( Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) );
+         }
+         catch( const Exception& ) {
+            Control< Rule >::raise_nested( in.position( m.inputerator() ), st... );
+         }
+      }
+   };
+
+   template< typename Exception, typename... Rules >
+   inline constexpr bool enable_control< try_catch_raise_nested< Exception, Rules... > > = false;
+
+}  // namespace TAO_PEGTL_NAMESPACE::internal
+
+#endif
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp b/packages/PEGTL/include/tao/pegtl/internal/try_catch_return_false.hpp
similarity index 54%
rename from packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp
rename to packages/PEGTL/include/tao/pegtl/internal/try_catch_return_false.hpp
index f61a9ae97..0d46fdf45 100644
--- a/packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp
+++ b/packages/PEGTL/include/tao/pegtl/internal/try_catch_return_false.hpp
@@ -2,11 +2,11 @@
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef TAO_PEGTL_INTERNAL_TRY_CATCH_TYPE_HPP
-#define TAO_PEGTL_INTERNAL_TRY_CATCH_TYPE_HPP
+#ifndef TAO_PEGTL_INTERNAL_TRY_CATCH_RETURN_FALSE_HPP
+#define TAO_PEGTL_INTERNAL_TRY_CATCH_RETURN_FALSE_HPP
 
 #if !defined( __cpp_exceptions )
-#error "Exception support required for tao/pegtl/internal/try_catch_type.hpp"
+#error "Exception support required for tao/pegtl/internal/try_catch_return_false.hpp"
 #else
 
 #include <type_traits>
@@ -23,19 +23,47 @@
 namespace TAO_PEGTL_NAMESPACE::internal
 {
    template< typename Exception, typename... Rules >
-   struct try_catch_type
-      : try_catch_type< Exception, seq< Rules... > >
+   struct try_catch_return_false
+      : try_catch_return_false< Exception, seq< Rules... > >
    {};
 
    template< typename Exception >
-   struct try_catch_type< Exception >
+   struct try_catch_return_false< Exception >
       : success
    {};
 
+   template< typename Rule >
+   struct try_catch_return_false< void, Rule >
+   {
+      using rule_t = try_catch_return_false;
+      using subs_t = type_list< Rule >;
+
+      template< apply_mode A,
+                rewind_mode M,
+                template< typename... >
+                class Action,
+                template< typename... >
+                class Control,
+                typename ParseInput,
+                typename... States >
+      [[nodiscard]] static bool match( ParseInput& in, States&&... st )
+      {
+         auto m = in.template auto_rewind< M >();
+         using m_t = decltype( m );
+
+         try {
+            return m( Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) );
+         }
+         catch( ... ) {
+            return false;
+         }
+      }
+   };
+
    template< typename Exception, typename Rule >
-   struct try_catch_type< Exception, Rule >
+   struct try_catch_return_false< Exception, Rule >
    {
-      using rule_t = try_catch_type;
+      using rule_t = try_catch_return_false;
       using subs_t = type_list< Rule >;
 
       template< apply_mode A,
@@ -61,7 +89,7 @@ namespace TAO_PEGTL_NAMESPACE::internal
    };
 
    template< typename Exception, typename... Rules >
-   inline constexpr bool enable_control< try_catch_type< Exception, Rules... > > = false;
+   inline constexpr bool enable_control< try_catch_return_false< Exception, Rules... > > = false;
 
 }  // namespace TAO_PEGTL_NAMESPACE::internal
 
diff --git a/packages/PEGTL/include/tao/pegtl/match.hpp b/packages/PEGTL/include/tao/pegtl/match.hpp
index f4c953f24..311fd603a 100644
--- a/packages/PEGTL/include/tao/pegtl/match.hpp
+++ b/packages/PEGTL/include/tao/pegtl/match.hpp
@@ -108,9 +108,9 @@ namespace TAO_PEGTL_NAMESPACE
       else {
          constexpr bool enable_action = ( A == apply_mode::action );
 
-         using frobnicator_t = typename ParseInput::frobnicator_t;
-         constexpr bool has_apply_void = enable_action && internal::has_apply< Control< Rule >, void, Action, const frobnicator_t&, const ParseInput&, States... >;
-         constexpr bool has_apply_bool = enable_action && internal::has_apply< Control< Rule >, bool, Action, const frobnicator_t&, const ParseInput&, States... >;
+         using inputerator_t = typename ParseInput::inputerator_t;
+         constexpr bool has_apply_void = enable_action && internal::has_apply< Control< Rule >, void, Action, const inputerator_t&, const ParseInput&, States... >;
+         constexpr bool has_apply_bool = enable_action && internal::has_apply< Control< Rule >, bool, Action, const inputerator_t&, const ParseInput&, States... >;
          constexpr bool has_apply = has_apply_void || has_apply_bool;
 
          constexpr bool has_apply0_void = enable_action && internal::has_apply0< Control< Rule >, void, Action, const ParseInput&, States... >;
@@ -137,15 +137,15 @@ namespace TAO_PEGTL_NAMESPACE
 
          constexpr bool use_guard = has_apply || has_apply0_bool;
 
-         auto m = in.template auto_rewind< ( use_guard ? rewind_mode::required : rewind_mode::dontcare ) >();
+         auto m = in.template auto_rewind< ( use_guard ? rewind_mode::required : rewind_mode::optional ) >();
          Control< Rule >::start( static_cast< const ParseInput& >( in ), st... );
-         auto result = internal::match_control_unwind< Rule, A, ( use_guard ? rewind_mode::active : M ), Action, Control >( in, st... );
+         auto result = internal::match_control_unwind< Rule, A, ( use_guard ? rewind_mode::optional : M ), Action, Control >( in, st... );
          if( result ) {
             if constexpr( has_apply_void ) {
-               Control< Rule >::template apply< Action >( m.frobnicator(), static_cast< const ParseInput& >( in ), st... );
+               Control< Rule >::template apply< Action >( m.inputerator(), static_cast< const ParseInput& >( in ), st... );
             }
             else if constexpr( has_apply_bool ) {
-               result = Control< Rule >::template apply< Action >( m.frobnicator(), static_cast< const ParseInput& >( in ), st... );
+               result = Control< Rule >::template apply< Action >( m.inputerator(), static_cast< const ParseInput& >( in ), st... );
             }
             else if constexpr( has_apply0_void ) {
                Control< Rule >::template apply0< Action >( static_cast< const ParseInput& >( in ), st... );
diff --git a/packages/PEGTL/include/tao/pegtl/memory_input.hpp b/packages/PEGTL/include/tao/pegtl/memory_input.hpp
index 93702353f..52f73898f 100644
--- a/packages/PEGTL/include/tao/pegtl/memory_input.hpp
+++ b/packages/PEGTL/include/tao/pegtl/memory_input.hpp
@@ -25,7 +25,7 @@
 #include "internal/at.hpp"
 #include "internal/bump.hpp"
 #include "internal/eolf.hpp"
-#include "internal/frobnicator.hpp"
+#include "internal/inputerator.hpp"
 #include "internal/rewind_guard.hpp"
 #include "internal/until.hpp"
 
@@ -40,10 +40,10 @@ namespace TAO_PEGTL_NAMESPACE
       class memory_input_base< tracking_mode::eager, Eol, Source >
       {
       public:
-         using frobnicator_t = internal::frobnicator;
+         using inputerator_t = internal::inputerator;
 
          template< typename T >
-         memory_input_base( const frobnicator_t& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > )
+         memory_input_base( const inputerator_t& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > )
             : m_begin( in_begin.data ),
               m_current( in_begin ),
               m_end( in_end ),
@@ -111,7 +111,7 @@ namespace TAO_PEGTL_NAMESPACE
             internal::bump_to_next_line( m_current, in_count );
          }
 
-         [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const frobnicator_t& it ) const
+         [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const inputerator_t& it ) const
          {
             return TAO_PEGTL_NAMESPACE::position( it, m_source );
          }
@@ -130,7 +130,7 @@ namespace TAO_PEGTL_NAMESPACE
 
       protected:
          const char* const m_begin;
-         frobnicator_t m_current;
+         inputerator_t m_current;
          const char* m_end;
          const Source m_source;
 
@@ -142,10 +142,10 @@ namespace TAO_PEGTL_NAMESPACE
       class memory_input_base< tracking_mode::lazy, Eol, Source >
       {
       public:
-         using frobnicator_t = const char*;
+         using inputerator_t = const char*;
 
          template< typename T >
-         memory_input_base( const internal::frobnicator& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > )
+         memory_input_base( const internal::inputerator& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > )
             : m_begin( in_begin ),
               m_current( in_begin.data ),
               m_end( in_end ),
@@ -203,9 +203,9 @@ namespace TAO_PEGTL_NAMESPACE
             m_current += in_count;
          }
 
-         [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const frobnicator_t it ) const
+         [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const inputerator_t it ) const
          {
-            internal::frobnicator c( m_begin );
+            internal::inputerator c( m_begin );
             internal::bump( c, static_cast< std::size_t >( it - m_begin.data ), Eol::ch );
             return TAO_PEGTL_NAMESPACE::position( c, m_source );
          }
@@ -217,8 +217,8 @@ namespace TAO_PEGTL_NAMESPACE
          }
 
       protected:
-         const internal::frobnicator m_begin;
-         frobnicator_t m_current;
+         const internal::inputerator m_begin;
+         inputerator_t m_current;
          const char* m_end;
          const Source m_source;
 
@@ -238,7 +238,7 @@ namespace TAO_PEGTL_NAMESPACE
       using eol_t = Eol;
       using source_t = Source;
 
-      using typename internal::memory_input_base< P, Eol, Source >::frobnicator_t;
+      using typename internal::memory_input_base< P, Eol, Source >::inputerator_t;
 
       using action_t = internal::action_input< memory_input >;
 
@@ -305,12 +305,12 @@ namespace TAO_PEGTL_NAMESPACE
          return static_cast< std::uint8_t >( peek_char( offset ) );
       }
 
-      [[nodiscard]] frobnicator_t& frobnicator() noexcept
+      [[nodiscard]] inputerator_t& inputerator() noexcept
       {
          return this->m_current;
       }
 
-      [[nodiscard]] const frobnicator_t& frobnicator() const noexcept
+      [[nodiscard]] const inputerator_t& inputerator() const noexcept
       {
          return this->m_current;
       }
@@ -320,14 +320,19 @@ namespace TAO_PEGTL_NAMESPACE
       template< rewind_mode M, typename ParseInput >
       void restart( const internal::rewind_guard< M, ParseInput >& m ) noexcept
       {
-         this->m_current = m.frobnicator();
+         this->m_current = m.inputerator();
       }
 
       using internal::memory_input_base< P, Eol, Source >::position;
 
       [[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const
       {
-         return position( frobnicator() );
+         return position( inputerator() );
+      }
+
+      [[nodiscard]] TAO_PEGTL_NAMESPACE::position current_position() const
+      {
+         return position( inputerator() );
       }
 
       void discard() const noexcept {}
@@ -340,12 +345,12 @@ namespace TAO_PEGTL_NAMESPACE
          return internal::rewind_guard< M, memory_input >( this );
       }
 
-      [[nodiscard]] const frobnicator_t& rewind_save() noexcept
+      [[nodiscard]] const inputerator_t& rewind_save() noexcept
       {
          return this->m_current;
       }
 
-      void rewind_restore( const frobnicator_t& data ) noexcept
+      void rewind_restore( const inputerator_t& data ) noexcept
       {
          this->m_current = data;
       }
@@ -365,7 +370,7 @@ namespace TAO_PEGTL_NAMESPACE
          using input_t = memory_input< tracking_mode::lazy, Eol, const char* >;
          input_t in( at( p ), this->end(), "" );
          using grammar = internal::until< internal::at< internal::eolf > >;
-         (void)normal< grammar >::match< apply_mode::nothing, rewind_mode::dontcare, nothing, normal >( in );
+         (void)normal< grammar >::match< apply_mode::nothing, rewind_mode::optional, nothing, normal >( in );
          return in.current();
       }
 
diff --git a/packages/PEGTL/include/tao/pegtl/mmap_input.hpp b/packages/PEGTL/include/tao/pegtl/mmap_input.hpp
index 83f69158b..8cff1026d 100644
--- a/packages/PEGTL/include/tao/pegtl/mmap_input.hpp
+++ b/packages/PEGTL/include/tao/pegtl/mmap_input.hpp
@@ -5,6 +5,7 @@
 #ifndef TAO_PEGTL_MMAP_INPUT_HPP
 #define TAO_PEGTL_MMAP_INPUT_HPP
 
+#include <filesystem>
 #include <string>
 
 #include "config.hpp"
@@ -12,7 +13,6 @@
 #include "memory_input.hpp"
 #include "tracking_mode.hpp"
 
-#include "internal/filesystem.hpp"
 #include "internal/mmap_file.hpp"
 #include "internal/path_to_string.hpp"
 
@@ -23,12 +23,12 @@ namespace TAO_PEGTL_NAMESPACE
       : private internal::mmap_file,
         public memory_input< P, Eol >
    {
-      mmap_input( const internal::filesystem::path& path, const std::string& source )
+      mmap_input( const std::filesystem::path& path, const std::string& source )
          : internal::mmap_file( path ),
            memory_input< P, Eol >( data.begin(), data.end(), source )
       {}
 
-      explicit mmap_input( const internal::filesystem::path& path )
+      explicit mmap_input( const std::filesystem::path& path )
          : mmap_input( path, internal::path_to_string( path ) )
       {}
 
diff --git a/packages/PEGTL/include/tao/pegtl/normal.hpp b/packages/PEGTL/include/tao/pegtl/normal.hpp
index d370d8c2f..64a487050 100644
--- a/packages/PEGTL/include/tao/pegtl/normal.hpp
+++ b/packages/PEGTL/include/tao/pegtl/normal.hpp
@@ -5,6 +5,7 @@
 #ifndef TAO_PEGTL_NORMAL_HPP
 #define TAO_PEGTL_NORMAL_HPP
 
+#include <exception>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -23,7 +24,6 @@
 #include "demangle.hpp"
 #else
 #include "internal/dependent_false.hpp"
-#include <exception>
 #endif
 
 namespace TAO_PEGTL_NAMESPACE
@@ -62,11 +62,28 @@ namespace TAO_PEGTL_NAMESPACE
 #endif
       }
 
+      template< typename Ambient, typename... States >
+      [[noreturn]] static void raise_nested( const Ambient& am, States&&... /*unused*/ )
+      {
+#if defined( __cpp_exceptions )
+         if constexpr( internal::has_error_message< Rule > ) {
+            std::throw_with_nested( parse_error( Rule::error_message, am ) );
+         }
+         else {
+            std::throw_with_nested( parse_error( "parse error matching " + std::string( demangle< Rule >() ), am ) );
+         }
+#else
+         static_assert( internal::dependent_false< Rule >, "exception support required for normal< Rule >::raise_nested()" );
+         (void)am;
+         std::terminate();
+#endif
+      }
+
       template< template< typename... > class Action,
-                typename Frobnicator,
+                typename Inputerator,
                 typename ParseInput,
                 typename... States >
-      static auto apply( const Frobnicator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( Action< Rule >::apply( std::declval< const typename ParseInput::action_t& >(), st... ) ) )
+      static auto apply( const Inputerator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( Action< Rule >::apply( std::declval< const typename ParseInput::action_t& >(), st... ) ) )
          -> decltype( Action< Rule >::apply( std::declval< const typename ParseInput::action_t& >(), st... ) )
       {
          const typename ParseInput::action_t action_input( begin, in );
diff --git a/packages/PEGTL/include/tao/pegtl/parse.hpp b/packages/PEGTL/include/tao/pegtl/parse.hpp
index da05d0a21..ab34ac2a8 100644
--- a/packages/PEGTL/include/tao/pegtl/parse.hpp
+++ b/packages/PEGTL/include/tao/pegtl/parse.hpp
@@ -36,7 +36,7 @@ namespace TAO_PEGTL_NAMESPACE
              template< typename... > class Action = nothing,
              template< typename... > class Control = normal,
              apply_mode A = apply_mode::action,
-             rewind_mode M = rewind_mode::dontcare,
+             rewind_mode M = rewind_mode::optional,
              typename ParseInput,
              typename... States >
    auto parse( ParseInput&& in, States&&... st )
@@ -48,22 +48,21 @@ namespace TAO_PEGTL_NAMESPACE
              template< typename... > class Action = nothing,
              template< typename... > class Control = normal,
              apply_mode A = apply_mode::action,
-             rewind_mode M = rewind_mode::dontcare,
-             typename Outer,
+             rewind_mode M = rewind_mode::optional,
+             typename Ambient,
              typename ParseInput,
              typename... States >
-   auto parse_nested( const Outer& o, ParseInput&& in, States&&... st )
+   auto parse_nested( const Ambient& am, ParseInput&& in, States&&... st )
    {
 #if defined( __cpp_exceptions )
       try {
          return parse< Rule, Action, Control, A, M >( in, st... );
       }
-      catch( parse_error& e ) {
-         e.add_position( internal::get_position( o ) );
-         throw;
+      catch( std::exception& /*unused*/ ) {
+         Control< Rule >::raise_nested( am, st... );
       }
 #else
-      (void)o;
+      (void)am;
       return parse< Rule, Action, Control, A, M >( in, st... );
 #endif
    }
diff --git a/packages/PEGTL/include/tao/pegtl/parse_error.hpp b/packages/PEGTL/include/tao/pegtl/parse_error.hpp
index 954e5717a..b9ec149c2 100644
--- a/packages/PEGTL/include/tao/pegtl/parse_error.hpp
+++ b/packages/PEGTL/include/tao/pegtl/parse_error.hpp
@@ -6,114 +6,54 @@
 #define TAO_PEGTL_PARSE_ERROR_HPP
 
 #include <cstddef>
-#include <memory>
-#include <stdexcept>
 #include <string>
 #include <string_view>
-#include <utility>
-#include <vector>
+#include <type_traits>
 
 #include "config.hpp"
+#include "parse_error_base.hpp"
 #include "position.hpp"
 
+#include "internal/extract_position.hpp"
+#include "internal/stream_to_string.hpp"
+
 namespace TAO_PEGTL_NAMESPACE
 {
-   namespace internal
+   struct disambiguate_t
    {
-      class parse_error
-      {
-      private:
-         std::string m_msg;
-         std::size_t m_prefix = 0;
-         std::vector< position > m_positions;
-
-      public:
-         explicit parse_error( const char* msg )
-            : m_msg( msg )
-         {}
-
-         [[nodiscard]] const char* what() const noexcept
-         {
-            return m_msg.c_str();
-         }
-
-         [[nodiscard]] std::string_view message() const noexcept
-         {
-            return { m_msg.data() + m_prefix, m_msg.size() - m_prefix };
-         }
-
-         [[nodiscard]] const std::vector< position >& positions() const noexcept
-         {
-            return m_positions;
-         }
-
-         void add_position( position&& p )
-         {
-            const auto prefix = to_string( p );
-            m_msg = prefix + ": " + m_msg;
-            m_prefix += prefix.size() + 2;
-            m_positions.emplace_back( std::move( p ) );
-         }
-      };
-
-   }  // namespace internal
+      // TODO: Integrate extract_position into parse_error with SFINAE?
+   };
 
-   class parse_error
-      : public std::runtime_error
+   template< typename Position >
+   class parse_error_template
+      : public parse_error_base
    {
-   private:
-      std::shared_ptr< internal::parse_error > m_impl;
-
    public:
-      parse_error( const char* msg, position p )
-         : std::runtime_error( msg ),
-           m_impl( std::make_shared< internal::parse_error >( msg ) )
-      {
-         m_impl->add_position( std::move( p ) );
-      }
-
-      parse_error( const std::string& msg, position p )
-         : parse_error( msg.c_str(), std::move( p ) )
-      {}
+      using position_t = Position;
 
-      template< typename ParseInput >
-      parse_error( const char* msg, const ParseInput& in )
-         : parse_error( msg, in.position() )
+      template< typename Object >
+      parse_error_template( const std::string& msg, const Object& obj )
+         : parse_error_template( msg, internal::extract_position( obj ), disambiguate_t() )
       {}
 
-      template< typename ParseInput >
-      parse_error( const std::string& msg, const ParseInput& in )
-         : parse_error( msg, in.position() )
-      {}
-
-      [[nodiscard]] const char* what() const noexcept override
+      [[nodiscard]] const position_t& position_object() const noexcept
       {
-         return m_impl->what();
+         return m_position;
       }
 
-      [[nodiscard]] std::string_view message() const noexcept
-      {
-         return m_impl->message();
-      }
+   protected:
+      const position_t m_position;
 
-      [[nodiscard]] const std::vector< position >& positions() const noexcept
-      {
-         return m_impl->positions();
-      }
+      parse_error_template( const std::string& msg, const Position& pos, const disambiguate_t /*unused*/ )
+         : parse_error_base( msg, internal::stream_to_string( pos ) ),
+           m_position( pos )
+      {}
+   };
 
-      void add_position( position&& p )
-      {
-         if( m_impl.use_count() > 1 ) {
-            m_impl = std::make_shared< internal::parse_error >( *m_impl );
-         }
-         m_impl->add_position( std::move( p ) );
-      }
+   template< typename Object >
+   parse_error_template( const std::string&, const Object& ) -> parse_error_template< std::decay_t< decltype( internal::extract_position( std::declval< Object >() ) ) > >;
 
-      void add_position( const position& p )
-      {
-         add_position( position( p ) );
-      }
-   };
+   using parse_error = parse_error_template< position >;  // Temporary -- when the inputs are templated over the position class the parse_error_template will be renamed to parse_error.
 
 }  // namespace TAO_PEGTL_NAMESPACE
 
diff --git a/packages/PEGTL/include/tao/pegtl/parse_error_base.hpp b/packages/PEGTL/include/tao/pegtl/parse_error_base.hpp
new file mode 100644
index 000000000..889f2efb2
--- /dev/null
+++ b/packages/PEGTL/include/tao/pegtl/parse_error_base.hpp
@@ -0,0 +1,45 @@
+// Copyright (c) 2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TAO_PEGTL_PARSE_ERROR_BASE_HPP
+#define TAO_PEGTL_PARSE_ERROR_BASE_HPP
+
+#include <cstddef>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+#include <utility>
+
+#include "config.hpp"
+
+namespace TAO_PEGTL_NAMESPACE
+{
+   class parse_error_base
+      : public std::runtime_error
+   {
+   public:
+      [[nodiscard]] std::string_view message() const noexcept
+      {
+         return { what() + m_position_size + 2, m_message_size };
+      }
+
+      [[nodiscard]] std::string_view position_string() const noexcept
+      {
+         return { what(), m_position_size };
+      }
+
+   protected:
+      const std::size_t m_message_size;
+      const std::size_t m_position_size;
+
+      parse_error_base( const std::string& msg, const std::string& pos )
+         : std::runtime_error( pos + ": " + msg ),
+           m_message_size( msg.size() ),
+           m_position_size( pos.size() )
+      {}
+   };
+
+}  // namespace TAO_PEGTL_NAMESPACE
+
+#endif
diff --git a/packages/PEGTL/include/tao/pegtl/position.hpp b/packages/PEGTL/include/tao/pegtl/position.hpp
index af20a0d55..5cb329eaf 100644
--- a/packages/PEGTL/include/tao/pegtl/position.hpp
+++ b/packages/PEGTL/include/tao/pegtl/position.hpp
@@ -7,13 +7,11 @@
 
 #include <cstdlib>
 #include <ostream>
-#include <sstream>
 #include <string>
-#include <utility>
 
 #include "config.hpp"
 
-#include "internal/frobnicator.hpp"
+#include "internal/inputerator.hpp"
 
 namespace TAO_PEGTL_NAMESPACE
 {
@@ -28,7 +26,7 @@ namespace TAO_PEGTL_NAMESPACE
       position& operator=( const position& ) = default;
 
       template< typename T >
-      position( const internal::frobnicator& in_iter, T&& in_source )
+      position( const internal::inputerator& in_iter, T&& in_source )
          : byte( in_iter.byte ),
            line( in_iter.line ),
            column( in_iter.column ),
@@ -66,13 +64,6 @@ namespace TAO_PEGTL_NAMESPACE
       return os << p.source << ':' << p.line << ':' << p.column;
    }
 
-   [[nodiscard]] inline std::string to_string( const position& p )
-   {
-      std::ostringstream oss;
-      oss << p;
-      return std::move( oss ).str();
-   }
-
 }  // namespace TAO_PEGTL_NAMESPACE
 
 #endif
diff --git a/packages/PEGTL/include/tao/pegtl/read_input.hpp b/packages/PEGTL/include/tao/pegtl/read_input.hpp
index b730aff84..df7d75651 100644
--- a/packages/PEGTL/include/tao/pegtl/read_input.hpp
+++ b/packages/PEGTL/include/tao/pegtl/read_input.hpp
@@ -5,6 +5,7 @@
 #ifndef TAO_PEGTL_READ_INPUT_HPP
 #define TAO_PEGTL_READ_INPUT_HPP
 
+#include <filesystem>
 #include <string>
 
 #include "config.hpp"
@@ -12,7 +13,6 @@
 #include "string_input.hpp"
 #include "tracking_mode.hpp"
 
-#include "internal/filesystem.hpp"
 #include "internal/path_to_string.hpp"
 #include "internal/read_file_stdio.hpp"
 
@@ -22,19 +22,19 @@ namespace TAO_PEGTL_NAMESPACE
    struct read_input
       : string_input< P, Eol >
    {
-      read_input( const internal::filesystem::path& path, const std::string& source )
+      read_input( const std::filesystem::path& path, const std::string& source )
          : string_input< P, Eol >( internal::read_file_stdio( path ).read_string(), source )
       {}
 
-      explicit read_input( const internal::filesystem::path& path )
+      explicit read_input( const std::filesystem::path& path )
          : read_input( path, internal::path_to_string( path ) )
       {}
 
-      read_input( FILE* file, const internal::filesystem::path& path, const std::string& source )
+      read_input( FILE* file, const std::filesystem::path& path, const std::string& source )
          : string_input< P, Eol >( internal::read_file_stdio( file, path ).read_string(), source )
       {}
 
-      read_input( FILE* file, const internal::filesystem::path& path )
+      read_input( FILE* file, const std::filesystem::path& path )
          : read_input( file, path, internal::path_to_string( path ) )
       {}
 
diff --git a/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp b/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp
index e51a4281e..4bea177f2 100644
--- a/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp
+++ b/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp
@@ -9,11 +9,10 @@
 
 namespace TAO_PEGTL_NAMESPACE
 {
-   enum class rewind_mode : char
+   enum class rewind_mode : bool
    {
-      active,
       required,
-      dontcare
+      optional
    };
 
 }  // namespace TAO_PEGTL_NAMESPACE
diff --git a/packages/PEGTL/include/tao/pegtl/rules.hpp b/packages/PEGTL/include/tao/pegtl/rules.hpp
index 9e4c111e1..beb1088b4 100644
--- a/packages/PEGTL/include/tao/pegtl/rules.hpp
+++ b/packages/PEGTL/include/tao/pegtl/rules.hpp
@@ -9,6 +9,7 @@
 
 #include "config.hpp"
 #include "parse_error.hpp"
+#include "position.hpp"
 
 #include "internal/rules.hpp"
 
@@ -72,8 +73,14 @@ namespace TAO_PEGTL_NAMESPACE
       static constexpr const char error_message[] = { Cs..., 0 };
    };
    template< typename Cond, typename... Rules > struct star_must : internal::star_must< Cond, Rules... > {};
-   template< typename... Rules > struct try_catch : internal::try_catch_type< parse_error, Rules... > {};
-   template< typename Exception, typename... Rules > struct try_catch_type : internal::seq< internal::try_catch_type< Exception, Rules... > > {};
+   template< typename... Rules > struct try_catch_raise_nested : internal::try_catch_raise_nested< parse_error_base, Rules... > {};
+   template< typename... Rules > struct try_catch_return_false : internal::try_catch_return_false< parse_error_base, Rules... > {};
+   template< typename... Rules > struct try_catch_any_raise_nested : internal::try_catch_raise_nested< void, Rules... > {};
+   template< typename... Rules > struct try_catch_any_return_false : internal::try_catch_return_false< void, Rules... > {};
+   template< typename... Rules > struct try_catch_std_raise_nested : internal::try_catch_raise_nested< std::exception, Rules... > {};
+   template< typename... Rules > struct try_catch_std_return_false : internal::try_catch_return_false< std::exception, Rules... > {};
+   template< typename Exception, typename... Rules > struct try_catch_type_raise_nested : internal::try_catch_raise_nested< Exception, Rules... > {};
+   template< typename Exception, typename... Rules > struct try_catch_type_return_false : internal::try_catch_return_false< Exception, Rules... > {};
 #endif
    // clang-format on
 
diff --git a/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp b/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp
index dcdfd3548..951a521ba 100644
--- a/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp
+++ b/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp
@@ -178,7 +178,7 @@ namespace TAO_PEGTL_NAMESPACE
             return v.substr( pos );
          }
 
-         void shift( internal::frobnicator& it, int delta )
+         void shift( internal::inputerator& it, int delta )
          {
             it.data += delta;
             it.byte += delta;
@@ -507,7 +507,7 @@ namespace TAO_PEGTL_NAMESPACE
             }
             // if it is an "incremental alternation", we need to consolidate the assigned alternations
             else if( op == "=/" ) {
-               const auto p = previous_rules.find( rname );
+               const auto& p = previous_rules.find( rname );
                if( p == previous_rules.end() ) {
 #if defined( __cpp_exceptions )
                   throw parse_error( "incremental alternation '" + rname + "' without previous rule definition", n->begin() );
@@ -788,10 +788,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
       }
    }
    catch( const parse_error& e ) {
-      const auto p = e.positions().front();
+      const auto& p = e.position_object();
       std::cerr << e.what() << '\n'
                 << in.line_at( p ) << '\n'
-                << std::setw( p.column ) << '^' << '\n';
+                << std::setw( int( p.column ) ) << '^' << '\n';
    }
 #else
    if( const auto root = parse_tree::parse< abnf::grammar::rulelist, abnf::selector, nothing, abnf::control >( in ) ) {
diff --git a/packages/PEGTL/src/example/pegtl/csv2.cpp b/packages/PEGTL/src/example/pegtl/csv2.cpp
index ac0d52e6d..8143779ad 100644
--- a/packages/PEGTL/src/example/pegtl/csv2.cpp
+++ b/packages/PEGTL/src/example/pegtl/csv2.cpp
@@ -5,6 +5,7 @@
 #include <exception>
 #include <iostream>
 #include <utility>
+#include <vector>
 
 #include <tao/pegtl.hpp>
 
diff --git a/packages/PEGTL/src/example/pegtl/expression.cpp b/packages/PEGTL/src/example/pegtl/expression.cpp
index 12be3bb8b..ea1ad7d62 100644
--- a/packages/PEGTL/src/example/pegtl/expression.cpp
+++ b/packages/PEGTL/src/example/pegtl/expression.cpp
@@ -45,7 +45,7 @@ namespace TAO_PEGTL_NAMESPACE::expression
    {
       struct prefix_info
       {
-         prefix_info( const std::string_view n, const unsigned pbp ) noexcept
+         prefix_info( const std::string_view n, const unsigned pbp )
             : name( n ),
               prefix_binding_power( pbp )
          {
@@ -59,11 +59,11 @@ namespace TAO_PEGTL_NAMESPACE::expression
 
       struct infix_postfix_info
       {
-         infix_postfix_info( const std::string_view n, const unsigned lbp, const unsigned rbp = 0 ) noexcept
+         infix_postfix_info( const std::string_view n, const unsigned lbp, const unsigned rbp = 0 )
             : infix_postfix_info( n, std::string_view(), lbp, rbp )
          {}
 
-         infix_postfix_info( const std::string_view n, const std::string_view o, const unsigned lbp, const unsigned rbp = 0 ) noexcept
+         infix_postfix_info( const std::string_view n, const std::string_view o, const unsigned lbp, const unsigned rbp = 0 )
             : name( n ),
               other( o ),
               left_binding_power( lbp ),
@@ -434,12 +434,12 @@ namespace application
       {
          assert( string_stack.size() > args );
 
-         std::string tmp = *( string_stack.end() - args - 1 ) + std::string( op ) + " ";
+         std::string tmp = *( string_stack.end() - int( args ) - 1 ) + std::string( op ) + " ";
          for( std::size_t i = 0; i < args; ++i ) {
             if( i > 0 ) {
                tmp += ", ";
             }
-            tmp += *( string_stack.end() - args + i );
+            tmp += *( string_stack.end() - int( args ) + int( i ) );
          }
          tmp += " " + std::string( o2 );
          string_stack.resize( string_stack.size() - args );
@@ -509,10 +509,10 @@ int main( int argc, char** argv )
          std::cout << "Result: " << res.string_stack.at( 0 ) << std::endl;
       }
       catch( const TAO_PEGTL_NAMESPACE::parse_error& e ) {
-         const auto p = e.positions().front();
+         const auto& p = e.position_object();
          std::cerr << e.what() << '\n'
                    << in.line_at( p ) << '\n'
-                   << std::setw( p.column ) << '^' << '\n';
+                   << std::setw( int( p.column ) ) << '^' << '\n';
       }
    }
    return 0;
diff --git a/packages/PEGTL/src/example/pegtl/indent_aware.cpp b/packages/PEGTL/src/example/pegtl/indent_aware.cpp
index 54cada305..beba07a8b 100644
--- a/packages/PEGTL/src/example/pegtl/indent_aware.cpp
+++ b/packages/PEGTL/src/example/pegtl/indent_aware.cpp
@@ -14,6 +14,7 @@ int main()
 #include <cassert>
 #include <cstddef>
 #include <iostream>
+#include <vector>
 
 #include <tao/pegtl.hpp>
 
diff --git a/packages/PEGTL/src/example/pegtl/iri.cpp b/packages/PEGTL/src/example/pegtl/iri.cpp
index bfc0d876f..508a56ff9 100644
--- a/packages/PEGTL/src/example/pegtl/iri.cpp
+++ b/packages/PEGTL/src/example/pegtl/iri.cpp
@@ -12,11 +12,12 @@ int main()
 }
 #else
 
+#include <iostream>
+#include <stdexcept>
+
 #include <tao/pegtl.hpp>
 #include <tao/pegtl/contrib/iri.hpp>
 
-#include <iostream>
-
 namespace pegtl = TAO_PEGTL_NAMESPACE;
 
 struct IRI
@@ -84,17 +85,23 @@ IRI::IRI( const std::string& iri )
 
 int main( int argc, char** argv )
 {
-   for( int i = 1; i < argc; ++i ) {
-      std::cout << "Parsing " << argv[ i ] << std::endl;
-      const IRI iri( argv[ i ] );
-      std::cout << "IRI.scheme: " << iri.scheme << std::endl;
-      std::cout << "IRI.authority: " << iri.authority << std::endl;
-      std::cout << "IRI.userinfo: " << iri.userinfo << std::endl;
-      std::cout << "IRI.host: " << iri.host << std::endl;
-      std::cout << "IRI.port: " << iri.port << std::endl;
-      std::cout << "IRI.path: " << iri.path << std::endl;
-      std::cout << "IRI.query: " << iri.query << std::endl;
-      std::cout << "IRI.fragment: " << iri.fragment << std::endl;
+   try {
+      for( int i = 1; i < argc; ++i ) {
+         std::cout << "Parsing " << argv[ i ] << std::endl;
+         const IRI iri( argv[ i ] );
+         std::cout << "IRI.scheme: " << iri.scheme << std::endl;
+         std::cout << "IRI.authority: " << iri.authority << std::endl;
+         std::cout << "IRI.userinfo: " << iri.userinfo << std::endl;
+         std::cout << "IRI.host: " << iri.host << std::endl;
+         std::cout << "IRI.port: " << iri.port << std::endl;
+         std::cout << "IRI.path: " << iri.path << std::endl;
+         std::cout << "IRI.query: " << iri.query << std::endl;
+         std::cout << "IRI.fragment: " << iri.fragment << std::endl;
+      }
+   }
+   catch( const std::exception& e ) {
+      std::cerr << "error: " << e.what() << std::endl;
+      return 1;
    }
    return 0;
 }
diff --git a/packages/PEGTL/src/example/pegtl/json_ast.cpp b/packages/PEGTL/src/example/pegtl/json_ast.cpp
index 1b96455ff..3ee91897e 100644
--- a/packages/PEGTL/src/example/pegtl/json_ast.cpp
+++ b/packages/PEGTL/src/example/pegtl/json_ast.cpp
@@ -51,10 +51,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
       pegtl::parse_tree::print_dot( std::cout, *root );
    }
    catch( const pegtl::parse_error& e ) {
-      const auto p = e.positions().front();
+      const auto& p = e.position_object();
       std::cerr << e.what() << std::endl
                 << in.line_at( p ) << std::endl
-                << std::setw( p.column ) << '^' << std::endl;
+                << std::setw( int( p.column ) ) << '^' << std::endl;
       return 1;
    }
 #else
diff --git a/packages/PEGTL/src/example/pegtl/json_build.cpp b/packages/PEGTL/src/example/pegtl/json_build.cpp
index bf945b317..3dd9234ea 100644
--- a/packages/PEGTL/src/example/pegtl/json_build.cpp
+++ b/packages/PEGTL/src/example/pegtl/json_build.cpp
@@ -175,10 +175,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
          pegtl::parse< example::grammar, example::action, example::control >( in, state );
       }
       catch( const pegtl::parse_error& e ) {
-         const auto p = e.positions().front();
+         const auto& p = e.position_object();
          std::cerr << e.what() << '\n'
                    << in.line_at( p ) << '\n'
-                   << std::setw( p.column ) << '^' << std::endl;
+                   << std::setw( int( p.column ) ) << '^' << std::endl;
          return 1;
       }
 #else
diff --git a/packages/PEGTL/src/example/pegtl/json_coverage.cpp b/packages/PEGTL/src/example/pegtl/json_coverage.cpp
index d73124cf1..5773bae9f 100644
--- a/packages/PEGTL/src/example/pegtl/json_coverage.cpp
+++ b/packages/PEGTL/src/example/pegtl/json_coverage.cpp
@@ -35,10 +35,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
       pegtl::coverage< example::grammar, pegtl::nothing, example::control >( in, result );
    }
    catch( const pegtl::parse_error& e ) {
-      const auto p = e.positions().front();
+      const auto& p = e.position_object();
       std::cerr << e.what() << '\n'
                 << in.line_at( p ) << '\n'
-                << std::setw( p.column ) << '^' << std::endl;
+                << std::setw( int( p.column ) ) << '^' << std::endl;
       return 1;
    }
 #else
diff --git a/packages/PEGTL/src/example/pegtl/json_parse.cpp b/packages/PEGTL/src/example/pegtl/json_parse.cpp
index 1681988b0..1fedb8346 100644
--- a/packages/PEGTL/src/example/pegtl/json_parse.cpp
+++ b/packages/PEGTL/src/example/pegtl/json_parse.cpp
@@ -45,10 +45,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
       pegtl::parse< example::grammar, example::action, example::control >( in );
    }
    catch( const pegtl::parse_error& e ) {
-      const auto p = e.positions().front();
+      const auto& p = e.position_object();
       std::cerr << e.what() << '\n'
                 << in.line_at( p ) << '\n'
-                << std::setw( p.column ) << '^' << std::endl;
+                << std::setw( int( p.column ) ) << '^' << std::endl;
       return 1;
    }
 #else
diff --git a/packages/PEGTL/src/example/pegtl/json_trace.cpp b/packages/PEGTL/src/example/pegtl/json_trace.cpp
index c6a1ce673..dc38bf992 100644
--- a/packages/PEGTL/src/example/pegtl/json_trace.cpp
+++ b/packages/PEGTL/src/example/pegtl/json_trace.cpp
@@ -34,10 +34,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
       pegtl::standard_trace< example::grammar, pegtl::nothing, example::control >( in );
    }
    catch( const pegtl::parse_error& e ) {
-      const auto p = e.positions().front();
+      const auto& p = e.position_object();
       std::cerr << e.what() << '\n'
                 << in.line_at( p ) << '\n'
-                << std::setw( p.column ) << '^' << std::endl;
+                << std::setw( int( p.column ) ) << '^' << std::endl;
       return 1;
    }
 #else
diff --git a/packages/PEGTL/src/example/pegtl/proto3.cpp b/packages/PEGTL/src/example/pegtl/proto3.cpp
index d49dcdbd4..0a7b449b4 100644
--- a/packages/PEGTL/src/example/pegtl/proto3.cpp
+++ b/packages/PEGTL/src/example/pegtl/proto3.cpp
@@ -15,7 +15,8 @@ int main()
 
 #include <tao/pegtl.hpp>
 #include <tao/pegtl/contrib/analyze.hpp>
-#include <tao/pegtl/contrib/proto3.hpp>
+
+#include "proto3.hpp"
 
 int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
 {
@@ -31,10 +32,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
          parse< proto3::proto >( in );
       }
       catch( const parse_error& e ) {
-         const auto p = e.positions().front();
+         const auto& p = e.position_object();
          std::cerr << e.what() << '\n'
                    << in.line_at( p ) << '\n'
-                   << std::setw( p.column ) << '^' << '\n';
+                   << std::setw( int( p.column ) ) << '^' << '\n';
       }
    }
    return 0;
diff --git a/packages/PEGTL/include/tao/pegtl/contrib/proto3.hpp b/packages/PEGTL/src/example/pegtl/proto3.hpp
similarity index 97%
rename from packages/PEGTL/include/tao/pegtl/contrib/proto3.hpp
rename to packages/PEGTL/src/example/pegtl/proto3.hpp
index 7be928a14..2acc9c2a4 100644
--- a/packages/PEGTL/include/tao/pegtl/contrib/proto3.hpp
+++ b/packages/PEGTL/src/example/pegtl/proto3.hpp
@@ -2,15 +2,15 @@
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef TAO_PEGTL_CONTRIB_PROTO3_HPP
-#define TAO_PEGTL_CONTRIB_PROTO3_HPP
+#ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_PROTO3_HPP
+#define TAO_PEGTL_SRC_EXAMPLES_PEGTL_PROTO3_HPP
 
-#include "../ascii.hpp"
-#include "../config.hpp"
-#include "../rules.hpp"
+#include <tao/pegtl.hpp>
 
-namespace TAO_PEGTL_NAMESPACE::proto3
+namespace proto3
 {
+   using namespace TAO_PEGTL_NAMESPACE;
+
    // protocol buffer v3
    // https://developers.google.com/protocol-buffers/docs/reference/proto3-spec
 
@@ -141,6 +141,6 @@ namespace TAO_PEGTL_NAMESPACE::proto3
    struct proto : must< sps, head, sps, star< body, sps >, eof > {};
    // clang-format on
 
-}  // namespace TAO_PEGTL_NAMESPACE::proto3
+}  // namespace proto3
 
 #endif
diff --git a/packages/PEGTL/src/example/pegtl/recover.cpp b/packages/PEGTL/src/example/pegtl/recover.cpp
index 12d581e91..375f458ec 100644
--- a/packages/PEGTL/src/example/pegtl/recover.cpp
+++ b/packages/PEGTL/src/example/pegtl/recover.cpp
@@ -34,7 +34,7 @@ template< typename T >
 struct skipping : until< T > {};
 
 template< typename R, typename T >
-struct recoverable : sor< try_catch< must< R >, T >, skipping< T > > {};
+struct recoverable : sor< try_catch_return_false< must< R >, T >, skipping< T > > {};
 
 struct expr_sum;
 struct expr_identifier : identifier {};
diff --git a/packages/PEGTL/src/example/pegtl/s_expression.cpp b/packages/PEGTL/src/example/pegtl/s_expression.cpp
index a93dbb8b6..51a928f7d 100644
--- a/packages/PEGTL/src/example/pegtl/s_expression.cpp
+++ b/packages/PEGTL/src/example/pegtl/s_expression.cpp
@@ -94,10 +94,10 @@ int main( int argc, char** argv )  // NOLINT(bugprone-exception-escape)
          TAO_PEGTL_NAMESPACE::parse< sexpr::main, sexpr::action >( in, fn );
       }
       catch( const TAO_PEGTL_NAMESPACE::parse_error& e ) {
-         const auto p = e.positions().front();
+         const auto& p = e.position_object();
          std::cerr << e.what() << '\n'
                    << in.line_at( p ) << '\n'
-                   << std::setw( p.column ) << '^' << '\n';
+                   << std::setw( int( p.column ) ) << '^' << '\n';
       }
    }
    return 0;
diff --git a/packages/PEGTL/src/example/pegtl/token_input.cpp b/packages/PEGTL/src/example/pegtl/token_input.cpp
index 2ddf46053..0f67f336c 100644
--- a/packages/PEGTL/src/example/pegtl/token_input.cpp
+++ b/packages/PEGTL/src/example/pegtl/token_input.cpp
@@ -24,9 +24,9 @@ namespace TAO_PEGTL_NAMESPACE
    public:
       using input_t = ParseInput;
       using value_t = typename ParseInput::value_t;
-      using frobnicator_t = typename ParseInput::frobnicator_t;
+      using inputerator_t = typename ParseInput::inputerator_t;
 
-      token_action_input( const frobnicator_t& in_begin, const ParseInput& in_input ) noexcept
+      token_action_input( const inputerator_t& in_begin, const ParseInput& in_input ) noexcept
          : m_begin( in_begin ),
            m_input( in_input )
       {}
@@ -39,7 +39,7 @@ namespace TAO_PEGTL_NAMESPACE
       token_action_input& operator=( const token_action_input& ) = delete;
       token_action_input& operator=( token_action_input&& ) = delete;
 
-      [[nodiscard]] const frobnicator_t& frobnicator() const noexcept
+      [[nodiscard]] const inputerator_t& inputerator() const noexcept
       {
          return m_begin;
       }
@@ -49,12 +49,12 @@ namespace TAO_PEGTL_NAMESPACE
          return m_input;
       }
 
-      [[nodiscard]] frobnicator_t begin() const noexcept
+      [[nodiscard]] inputerator_t begin() const noexcept
       {
          return m_begin;
       }
 
-      [[nodiscard]] frobnicator_t end() const noexcept
+      [[nodiscard]] inputerator_t end() const noexcept
       {
          return m_input.current();
       }
@@ -70,7 +70,7 @@ namespace TAO_PEGTL_NAMESPACE
       }
 
    protected:
-      const frobnicator_t m_begin;
+      const inputerator_t m_begin;
       const ParseInput& m_input;
    };
 
@@ -80,12 +80,12 @@ namespace TAO_PEGTL_NAMESPACE
    public:
       using value_t = T;
       using source_t = Source;
-      using frobnicator_t = const T*;
+      using inputerator_t = const T*;
 
       using action_t = token_action_input< token_parse_input >;
 
       template< typename S >
-      token_parse_input( const frobnicator_t in_begin, const frobnicator_t in_end, S&& in_source )
+      token_parse_input( const inputerator_t in_begin, const inputerator_t in_end, S&& in_source )
          : m_begin( in_begin ),
            m_current( in_begin ),
            m_end( in_end ),
@@ -109,17 +109,17 @@ namespace TAO_PEGTL_NAMESPACE
 
       void require( const std::size_t /*unused*/ ) const noexcept {}
 
-      [[nodiscard]] frobnicator_t current() const noexcept
+      [[nodiscard]] inputerator_t current() const noexcept
       {
          return m_current;
       }
 
-      [[nodiscard]] frobnicator_t begin() const noexcept
+      [[nodiscard]] inputerator_t begin() const noexcept
       {
          return m_begin;
       }
 
-      [[nodiscard]] frobnicator_t end( const std::size_t /*unused*/ = 0 ) const noexcept
+      [[nodiscard]] inputerator_t end( const std::size_t /*unused*/ = 0 ) const noexcept
       {
          return m_end;
       }
@@ -135,12 +135,12 @@ namespace TAO_PEGTL_NAMESPACE
          return internal::rewind_guard< M, token_parse_input >( this );
       }
 
-      [[nodiscard]] const frobnicator_t& rewind_save() const noexcept
+      [[nodiscard]] const inputerator_t& rewind_save() const noexcept
       {
          return m_current;
       }
 
-      void rewind_restore( const frobnicator_t& data ) noexcept
+      void rewind_restore( const inputerator_t& data ) noexcept
       {
          m_current = data;
       }
@@ -175,20 +175,20 @@ namespace TAO_PEGTL_NAMESPACE
          return this->current()[ offset ];
       }
 
-      [[nodiscard]] frobnicator_t& frobnicator() noexcept
+      [[nodiscard]] inputerator_t& inputerator() noexcept
       {
          return this->m_current;
       }
 
-      [[nodiscard]] const frobnicator_t& frobnicator() const noexcept
+      [[nodiscard]] const inputerator_t& inputerator() const noexcept
       {
          return this->m_current;
       }
 
    private:
-      const frobnicator_t m_begin;
-      frobnicator_t m_current;
-      const frobnicator_t m_end;
+      const inputerator_t m_begin;
+      inputerator_t m_current;
+      const inputerator_t m_end;
       const Source m_source;
    };
 
diff --git a/packages/PEGTL/src/example/pegtl/uri.cpp b/packages/PEGTL/src/example/pegtl/uri.cpp
index 62ceaf6cc..6704d5415 100644
--- a/packages/PEGTL/src/example/pegtl/uri.cpp
+++ b/packages/PEGTL/src/example/pegtl/uri.cpp
@@ -11,11 +11,12 @@ int main()
 }
 #else
 
+#include <iostream>
+#include <stdexcept>
+
 #include <tao/pegtl.hpp>
 #include <tao/pegtl/contrib/uri.hpp>
 
-#include <iostream>
-
 namespace pegtl = TAO_PEGTL_NAMESPACE;
 
 struct URI
@@ -83,17 +84,23 @@ URI::URI( const std::string& uri )
 
 int main( int argc, char** argv )
 {
-   for( int i = 1; i < argc; ++i ) {
-      std::cout << "Parsing " << argv[ i ] << std::endl;
-      const URI uri( argv[ i ] );
-      std::cout << "URI.scheme: " << uri.scheme << std::endl;
-      std::cout << "URI.authority: " << uri.authority << std::endl;
-      std::cout << "URI.userinfo: " << uri.userinfo << std::endl;
-      std::cout << "URI.host: " << uri.host << std::endl;
-      std::cout << "URI.port: " << uri.port << std::endl;
-      std::cout << "URI.path: " << uri.path << std::endl;
-      std::cout << "URI.query: " << uri.query << std::endl;
-      std::cout << "URI.fragment: " << uri.fragment << std::endl;
+   try {
+      for( int i = 1; i < argc; ++i ) {
+         std::cout << "Parsing " << argv[ i ] << std::endl;
+         const URI uri( argv[ i ] );
+         std::cout << "URI.scheme: " << uri.scheme << std::endl;
+         std::cout << "URI.authority: " << uri.authority << std::endl;
+         std::cout << "URI.userinfo: " << uri.userinfo << std::endl;
+         std::cout << "URI.host: " << uri.host << std::endl;
+         std::cout << "URI.port: " << uri.port << std::endl;
+         std::cout << "URI.path: " << uri.path << std::endl;
+         std::cout << "URI.query: " << uri.query << std::endl;
+         std::cout << "URI.fragment: " << uri.fragment << std::endl;
+      }
+   }
+   catch( const std::exception& e ) {
+      std::cerr << "error: " << e.what() << std::endl;
+      return 1;
    }
    return 0;
 }
diff --git a/packages/PEGTL/src/test/pegtl/CMakeLists.txt b/packages/PEGTL/src/test/pegtl/CMakeLists.txt
index 7f707c33a..608ce61c3 100644
--- a/packages/PEGTL/src/test/pegtl/CMakeLists.txt
+++ b/packages/PEGTL/src/test/pegtl/CMakeLists.txt
@@ -121,7 +121,8 @@ set(test_sources
   rule_star_partial.cpp
   rule_state.cpp
   rule_success.cpp
-  rule_try_catch.cpp
+  rule_try_catch_raise_nested.cpp
+  rule_try_catch_return_false.cpp
   rule_until.cpp
   test_empty.cpp
   test_result.cpp
@@ -162,6 +163,13 @@ foreach(testsourcefile ${test_sources})
   if(ANDROID)
     add_test(NAME ${exename} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} "-DANDROID_NDK=${ANDROID_NDK}" "-DTEST_RESOURCES_DIR=${CMAKE_SOURCE_DIR}" "-DTEST_RESOURCES=src/test/pegtl/data;src/test/pegtl/file_data.txt;Makefile" "-DUNITTEST=${exename}" -P ${CMAKE_CURRENT_SOURCE_DIR}/ExecuteOnAndroid.cmake)
   else()
+    # FIXME: Windows 2022 Clang results in segfault when running for some tests
+    if(CMAKE_SYSTEM_VERSION VERSION_EQUAL "10.0.20348" AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+      if("${exename}" MATCHES "pegtl-test-position" OR "${exename}" MATCHES "pegtl-test-rule_try_catch_raise_nested")
+        message(WARNING "FIXME: Skipping test ${exename} on Windows Clang due to segfault.")
+        continue()
+      endif()
+    endif()
     add_test(NAME ${exename} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${exename})
   endif()
 endforeach()
diff --git a/packages/PEGTL/src/test/pegtl/actions_three.cpp b/packages/PEGTL/src/test/pegtl/actions_three.cpp
index 4accf9c2e..5185274d4 100644
--- a/packages/PEGTL/src/test/pegtl/actions_three.cpp
+++ b/packages/PEGTL/src/test/pegtl/actions_three.cpp
@@ -33,7 +33,7 @@ namespace TAO_PEGTL_NAMESPACE
       bool apply_result;
 
       struct grammar
-         : test_rule< 2, apply_mode::action, rewind_mode::active, any >
+         : test_rule< 2, apply_mode::action, rewind_mode::optional, any >
       {};
 
       template< typename Rule >
diff --git a/packages/PEGTL/src/test/pegtl/actions_two.cpp b/packages/PEGTL/src/test/pegtl/actions_two.cpp
index f55f08134..1f65ec703 100644
--- a/packages/PEGTL/src/test/pegtl/actions_two.cpp
+++ b/packages/PEGTL/src/test/pegtl/actions_two.cpp
@@ -10,11 +10,10 @@ namespace TAO_PEGTL_NAMESPACE
    {
       struct state1
       {
-         char c;
+         char c = 0;
 
          template< typename ParseInput >
          state1( const ParseInput& /*unused*/, std::string& /*unused*/ )
-            : c()
          {}
 
          template< typename ParseInput >
@@ -102,9 +101,9 @@ namespace TAO_PEGTL_NAMESPACE
          template< typename ActionInput >
          static void apply( const ActionInput& in )
          {
-            TAO_PEGTL_TEST_ASSERT( in.frobnicator().byte == count_byte );
-            TAO_PEGTL_TEST_ASSERT( in.frobnicator().line == count_line );
-            TAO_PEGTL_TEST_ASSERT( in.frobnicator().column == count_column );
+            TAO_PEGTL_TEST_ASSERT( in.inputerator().byte == count_byte );
+            TAO_PEGTL_TEST_ASSERT( in.inputerator().line == count_line );
+            TAO_PEGTL_TEST_ASSERT( in.inputerator().column == count_column );
             TAO_PEGTL_TEST_ASSERT( in.input().source() == count_source );
             TAO_PEGTL_TEST_ASSERT( in.size() == 1 );
             TAO_PEGTL_TEST_ASSERT( in.begin() + 1 == in.end() );
diff --git a/packages/PEGTL/src/test/pegtl/contrib_coverage.cpp b/packages/PEGTL/src/test/pegtl/contrib_coverage.cpp
index 2c1d5798f..ff9d3a3d1 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_coverage.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_coverage.cpp
@@ -24,7 +24,7 @@ namespace TAO_PEGTL_NAMESPACE
    }
 
 #if defined( __cpp_exceptions )
-   using grammar = seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >;
+   using grammar = seq< sor< try_catch_return_false< must< one< 'a' > > >, one< 'F' > >, eof >;
 
    void unit_test()
    {
@@ -39,9 +39,9 @@ namespace TAO_PEGTL_NAMESPACE
       TAO_PEGTL_TEST_ASSERT( equals< one< 'a' > >( result, coverage_info{ 1, 0, 1, 0, 1 } ) );  // TODO: Should this really be counted as both failure and raise?
       TAO_PEGTL_TEST_ASSERT( equals< one< 'F' > >( result, coverage_info{ 1, 1, 0, 0, 0 } ) );
       TAO_PEGTL_TEST_ASSERT( equals< eof >( result, coverage_info{ 1, 1, 0, 0, 0 } ) );
-      TAO_PEGTL_TEST_ASSERT( equals< try_catch< must< one< 'a' > > > >( result, coverage_info{ 1, 0, 1, 0, 0 } ) );
+      TAO_PEGTL_TEST_ASSERT( equals< try_catch_return_false< must< one< 'a' > > > >( result, coverage_info{ 1, 0, 1, 0, 0 } ) );
       TAO_PEGTL_TEST_ASSERT( equals< must< one< 'a' > > >( result, coverage_info{ 1, 0, 0, 1, 0 } ) );
-      TAO_PEGTL_TEST_ASSERT( equals< sor< try_catch< must< one< 'a' > > >, one< 'F' > > >( result, coverage_info{ 1, 1, 0, 0, 0 } ) );
+      TAO_PEGTL_TEST_ASSERT( equals< sor< try_catch_return_false< must< one< 'a' > > >, one< 'F' > > >( result, coverage_info{ 1, 1, 0, 0, 0 } ) );
    }
 #else
    using grammar = seq< sor< one< 'a' >, one< 'F' > >, eof >;
diff --git a/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp b/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp
index cf2387fb6..12a932441 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp
@@ -18,7 +18,7 @@ namespace TAO_PEGTL_NAMESPACE
    struct F : seq< E > {};
 
 #if defined( __cpp_exceptions )
-   struct D2 : sor< try_catch< if_must< A, B > >, seq< A, C > > {};
+   struct D2 : sor< try_catch_return_false< if_must< A, B > >, seq< A, C > > {};
 #else
    struct D2 : D {};
 #endif
diff --git a/packages/PEGTL/src/test/pegtl/contrib_remove_first_state.cpp b/packages/PEGTL/src/test/pegtl/contrib_remove_first_state.cpp
index b3283dfb4..e394715a0 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_remove_first_state.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_remove_first_state.cpp
@@ -77,7 +77,7 @@ namespace TAO_PEGTL_NAMESPACE
 
 #if defined( __cpp_exceptions )
    struct test_rule
-      : seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >
+      : seq< sor< try_catch_return_false< must< one< 'a' > > >, one< 'F' > >, eof >
    {};
 #else
    struct test_rule
diff --git a/packages/PEGTL/src/test/pegtl/contrib_remove_last_states.cpp b/packages/PEGTL/src/test/pegtl/contrib_remove_last_states.cpp
index fd9a6149c..a44297938 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_remove_last_states.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_remove_last_states.cpp
@@ -77,7 +77,7 @@ namespace TAO_PEGTL_NAMESPACE
 
 #if defined( __cpp_exceptions )
    struct test_rule
-      : seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >
+      : seq< sor< try_catch_return_false< must< one< 'a' > > >, one< 'F' > >, eof >
    {};
 #else
    struct test_rule
diff --git a/packages/PEGTL/src/test/pegtl/contrib_state_control.cpp b/packages/PEGTL/src/test/pegtl/contrib_state_control.cpp
index 0ee3293ec..b4b6084e6 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_state_control.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_state_control.cpp
@@ -27,7 +27,13 @@ namespace TAO_PEGTL_NAMESPACE
       std::size_t b;
    };
 
-   inline bool operator==( const test_entry& l, const test_entry& r ) noexcept
+   std::ostream& operator<<( std::ostream& os, const test_entry& te )
+   {
+      os << te.rule << " " << te.func << " " << te.b;
+      return os;
+   }
+
+   [[nodiscard]] inline bool operator==( const test_entry& l, const test_entry& r ) noexcept
    {
       return ( l.rule == r.rule ) && ( l.func == r.func ) && ( l.b == r.b );
    }
@@ -68,6 +74,13 @@ namespace TAO_PEGTL_NAMESPACE
          trace.push_back( { demangle< Rule >(), "raise", ++b } );
       }
 
+      template< typename Rule, typename Input, typename... States >
+      void raise_nested( const Input& /*unused*/, const int a, std::size_t& b )
+      {
+         TAO_PEGTL_TEST_ASSERT( a == -1 );
+         trace.push_back( { demangle< Rule >(), "raise_nested", ++b } );
+      }
+
       template< typename Rule, typename Input, typename... States >
       void unwind( const Input& /*unused*/, const int a, std::size_t& b )
       {
@@ -90,7 +103,7 @@ namespace TAO_PEGTL_NAMESPACE
       }
    };
 
-   struct test_grammar : must< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > >, eof >
+   struct test_grammar : must< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > >, eof >
    {};
 
    template< typename Rule >
@@ -137,8 +150,12 @@ namespace TAO_PEGTL_NAMESPACE
       }
    };
 
+   struct test_nested : not_at< try_catch_return_false< try_catch_raise_nested< must< one< 'x' > > > > >
+   {};
+
    void unit_test()
    {
+      // must< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > >, eof >
       {
          test_state< true > st;
          memory_input in( "bb", __FUNCTION__ );
@@ -151,11 +168,11 @@ namespace TAO_PEGTL_NAMESPACE
          b = 0;
          std::size_t i = 0;
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< test_grammar >(), "start", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > > >(), "start", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'a' > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'a' > >(), "failure", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch< seq< one< 'b' >, must< one< 'c' > > > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< seq< one< 'b' >, must< one< 'c' > > > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'b' > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'b' > >(), "apply0", ++b } );
@@ -166,12 +183,12 @@ namespace TAO_PEGTL_NAMESPACE
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'c' > >(), "raise", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< must< one< 'c' > > >(), "unwind", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< seq< one< 'b' >, must< one< 'c' > > > >(), "unwind", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch< seq< one< 'b' >, must< one< 'c' > > > > >(), "failure", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > > >(), "failure", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< two< 'b' > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< two< 'b' > >(), "apply", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< two< 'b' > >(), "success", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > >(), "success", ++b } );
-         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > > >(), "success", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > >(), "success", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< sor< one< 'a' >, try_catch_return_false< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > > > >(), "success", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< eof > >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< eof >(), "start", ++b } );
          TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< eof >(), "success", ++b } );
@@ -192,6 +209,29 @@ namespace TAO_PEGTL_NAMESPACE
          TAO_PEGTL_TEST_ASSERT( st.trace.empty() );
          TAO_PEGTL_TEST_ASSERT( b == 0 );
       }
+      // not_at< try_catch_return_false< try_catch_raise_nested< must< one< 'x' > > > > >
+      {
+         test_state< true > st;
+         memory_input in( "a", __FUNCTION__ );
+         std::size_t b = 0;
+         const bool result = parse< test_nested, nothing, state_control< normal >::type >( in, -1, b, st );
+         TAO_PEGTL_TEST_ASSERT( result );
+         TAO_PEGTL_TEST_ASSERT( b == st.trace.size() );
+         b = 0;
+         std::size_t i = 0;
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< test_nested >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_return_false< try_catch_raise_nested< must< one< 'x' > > > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_raise_nested< must< one< 'x' > > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< must< one< 'x' > > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'x' > >(), "start", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'x' > >(), "failure", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'x' > >(), "raise", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< must< one< 'x' > > >(), "unwind", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< must< one< 'x' > > >(), "raise_nested", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_raise_nested< must< one< 'x' > > > >(), "unwind", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< try_catch_return_false< try_catch_raise_nested< must< one< 'x' > > > > >(), "failure", ++b } );
+         TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< test_nested >(), "success", ++b } );
+      }
    }
 
 }  // namespace TAO_PEGTL_NAMESPACE
diff --git a/packages/PEGTL/src/test/pegtl/contrib_trace1.cpp b/packages/PEGTL/src/test/pegtl/contrib_trace1.cpp
index ec207cf23..9d9ca9e4d 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_trace1.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_trace1.cpp
@@ -13,7 +13,7 @@ namespace test
    using namespace TAO_PEGTL_NAMESPACE;
 
 #if defined( __cpp_exceptions )
-   using grammar = seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >;
+   using grammar = seq< sor< try_catch_return_false< must< one< 'a' > > >, one< 'F' > >, eof >;
 #else
    using grammar = seq< sor< one< 'a' >, one< 'F' > >, eof >;
 #endif
diff --git a/packages/PEGTL/src/test/pegtl/contrib_trace2.cpp b/packages/PEGTL/src/test/pegtl/contrib_trace2.cpp
index a71737968..78c5b1648 100644
--- a/packages/PEGTL/src/test/pegtl/contrib_trace2.cpp
+++ b/packages/PEGTL/src/test/pegtl/contrib_trace2.cpp
@@ -14,7 +14,7 @@ namespace test
    using GRAMMAR2 = seq< one< 'a' >, any, any, any, any, one< 'b' >, eof >;
    using GRAMMAR3 = sor< one< 'a' >, one< 'b' > >;
 #if defined( __cpp_exceptions )
-   using GRAMMAR4 = try_catch< sor< one< 'a' >, must< one< 'b' > > > >;
+   using GRAMMAR4 = try_catch_return_false< sor< one< 'a' >, must< one< 'b' > > > >;
 #endif
 
    template< typename Rule >
diff --git a/packages/PEGTL/src/test/pegtl/file_read.cpp b/packages/PEGTL/src/test/pegtl/file_read.cpp
index 36e07afbf..4bce4f2ac 100644
--- a/packages/PEGTL/src/test/pegtl/file_read.cpp
+++ b/packages/PEGTL/src/test/pegtl/file_read.cpp
@@ -11,7 +11,7 @@ namespace TAO_PEGTL_NAMESPACE
    struct open_input
       : public read_input< P, Eol >
    {
-      explicit open_input( const internal::filesystem::path& path )
+      explicit open_input( const std::filesystem::path& path )
          : read_input< P, Eol >( internal::read_file_open( path ), path )
       {}
    };
diff --git a/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp b/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp
index 1034bea58..fcfae41d5 100644
--- a/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp
+++ b/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp
@@ -25,7 +25,7 @@ namespace TAO_PEGTL_NAMESPACE
          ++failed;
          // LCOV_EXCL_STOP
       }
-      catch( const internal::filesystem::filesystem_error& ) {
+      catch( const std::filesystem::filesystem_error& ) {
       }
       // LCOV_EXCL_START
       catch( ... ) {
diff --git a/packages/PEGTL/src/test/pegtl/parse_error.cpp b/packages/PEGTL/src/test/pegtl/parse_error.cpp
index c8582482c..5c0c39545 100644
--- a/packages/PEGTL/src/test/pegtl/parse_error.cpp
+++ b/packages/PEGTL/src/test/pegtl/parse_error.cpp
@@ -31,8 +31,7 @@ namespace TAO_PEGTL_NAMESPACE
 
          TAO_PEGTL_TEST_ASSERT( e.message() == "parse error matching " + rulename );
 
-         TAO_PEGTL_TEST_ASSERT( e.positions().size() == 1 );
-         const auto& p = e.positions().front();
+         const auto& p = e.position_object();
 
          TAO_PEGTL_TEST_ASSERT( p.byte == 8 );
          TAO_PEGTL_TEST_ASSERT( p.line == 2 );
@@ -45,13 +44,6 @@ namespace TAO_PEGTL_NAMESPACE
          p2.source = "foo";
          p2.line = 42;
          p2.column = 123;
-
-         parse_error e2 = e;
-         e2.add_position( std::move( p2 ) );
-
-         TAO_PEGTL_TEST_ASSERT( e2.what() == "foo:42:123: test_source:2:5: parse error matching " + rulename );
-         TAO_PEGTL_TEST_ASSERT( e.what() == "test_source:2:5: parse error matching " + rulename );
-
          return;
       }
       TAO_PEGTL_TEST_UNREACHABLE;  // LCOV_EXCL_LINE
diff --git a/packages/PEGTL/src/test/pegtl/position.cpp b/packages/PEGTL/src/test/pegtl/position.cpp
index 4759fc68b..1dea2aff5 100644
--- a/packages/PEGTL/src/test/pegtl/position.cpp
+++ b/packages/PEGTL/src/test/pegtl/position.cpp
@@ -2,16 +2,17 @@
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
 
-#if !defined( __cpp_exceptions )
+#if !defined( __cpp_exceptions ) || !defined( __cpp_rtti )
 #include <iostream>
 int main()
 {
-   std::cout << "Exception support disabled, skipping test..." << std::endl;
+   std::cout << "Exception and/or RTTI support disabled, skipping test..." << std::endl;
 }
 #else
 
 #include "test.hpp"
 
+#include <tao/pegtl/contrib/nested_exceptions.hpp>
 #include <tao/pegtl/internal/cstring_reader.hpp>
 
 namespace TAO_PEGTL_NAMESPACE
@@ -93,17 +94,18 @@ namespace TAO_PEGTL_NAMESPACE
       }
    };
 
-   void test_nested_asserts( const parse_error& e )
+   void test_nested_asserts()
    {
-      TAO_PEGTL_TEST_ASSERT( e.positions().size() == 2 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 0 ].source == "inner" );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 0 ].byte == 1 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 0 ].line == 1 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 0 ].column == 2 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 1 ].source == "outer" );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 1 ].byte == 2 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 1 ].line == 1 );
-      TAO_PEGTL_TEST_ASSERT( e.positions()[ 1 ].column == 3 );
+      const std::vector< parse_error > errors = nested::flatten();
+      TAO_PEGTL_TEST_ASSERT( errors.size() == 2 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 0 ].position_object().source == "inner" );
+      TAO_PEGTL_TEST_ASSERT( errors[ 0 ].position_object().byte == 1 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 0 ].position_object().line == 1 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 0 ].position_object().column == 2 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 1 ].position_object().source == "outer" );
+      TAO_PEGTL_TEST_ASSERT( errors[ 1 ].position_object().byte == 2 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 1 ].position_object().line == 1 );
+      TAO_PEGTL_TEST_ASSERT( errors[ 1 ].position_object().column == 3 );
    }
 
    template< typename ParseInput = memory_input<> >
@@ -113,22 +115,22 @@ namespace TAO_PEGTL_NAMESPACE
          memory_input oi( "aabbcc", "outer" );
          parse< outer_grammar, outer_action >( oi, true );
       }
-      catch( const parse_error& e ) {
-         test_nested_asserts( e );
+      catch( ... ) {
+         test_nested_asserts();
       }
       try {
          memory_input oi( "aabbcc", "outer" );
          parse< outer_grammar, outer_action >( oi, false );
       }
-      catch( const parse_error& e ) {
-         test_nested_asserts( e );
+      catch( ... ) {
+         test_nested_asserts();
       }
    }
 
-   void test_frobnicator()
+   void test_inputerator()
    {
       const std::string s = "source";
-      const internal::frobnicator i( nullptr, 1, 2, 3 );
+      const internal::inputerator i( nullptr, 1, 2, 3 );
       const position p( i, s );
       TAO_PEGTL_TEST_ASSERT( p.byte == 1 );
       TAO_PEGTL_TEST_ASSERT( p.line == 2 );
@@ -209,7 +211,7 @@ namespace TAO_PEGTL_NAMESPACE
       test_nested<>();
       test_nested< buffer_input_t >();
 
-      test_frobnicator();
+      test_inputerator();
    }
 
 }  // namespace TAO_PEGTL_NAMESPACE
diff --git a/packages/PEGTL/src/test/pegtl/rule_rep.cpp b/packages/PEGTL/src/test/pegtl/rule_rep.cpp
index 44d4303cd..a39c6fc41 100644
--- a/packages/PEGTL/src/test/pegtl/rule_rep.cpp
+++ b/packages/PEGTL/src/test/pegtl/rule_rep.cpp
@@ -62,13 +62,13 @@ namespace TAO_PEGTL_NAMESPACE
       verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 );
       verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ababab", result_type::success, 2 );
 
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "aba", result_type::local_failure, 3 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "abab", result_type::success, 0 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 );
-      verify_rule< try_catch< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ababab", result_type::success, 2 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "aba", result_type::local_failure, 3 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "abab", result_type::success, 0 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 );
+      verify_rule< try_catch_return_false< must< rep< 2, one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ababab", result_type::success, 2 );
 #endif
    }
 
diff --git a/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp b/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp
index 8cd7143ae..85dfd8ad1 100644
--- a/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp
+++ b/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp
@@ -43,7 +43,7 @@ namespace TAO_PEGTL_NAMESPACE
 #if defined( __cpp_exceptions )
       verify_rule< must< rep_min_max< 3, 4, one< 'a' > > > >( __LINE__, __FILE__, "aa", result_type::global_failure, 0 );
 
-      verify_rule< try_catch< must< rep_min_max< 3, 4, one< 'a' > > > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 );
+      verify_rule< try_catch_return_false< must< rep_min_max< 3, 4, one< 'a' > > > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 );
 #endif
    }
 
diff --git a/packages/PEGTL/src/test/pegtl/rule_try_catch_raise_nested.cpp b/packages/PEGTL/src/test/pegtl/rule_try_catch_raise_nested.cpp
new file mode 100644
index 000000000..a35b81c4f
--- /dev/null
+++ b/packages/PEGTL/src/test/pegtl/rule_try_catch_raise_nested.cpp
@@ -0,0 +1,53 @@
+// Copyright (c) 2014-2023 Dr. Colin Hirsch and Daniel Frey
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined( __cpp_exceptions ) || !defined( __cpp_rtti )
+#include <iostream>
+int main()
+{
+   std::cout << "Exception and/or RTTI support disabled, skipping test..." << std::endl;
+}
+#else
+
+#include "test.hpp"
+#include "verify_seqs.hpp"
+
+#include <tao/pegtl/contrib/nested_exceptions.hpp>
+
+namespace TAO_PEGTL_NAMESPACE
+{
+   template< typename... Rules >
+   using test_try_catch_rule = try_catch_raise_nested< must< Rules... > >;
+
+   template< typename... Rules >
+   using test_try_catch_any_rule = try_catch_any_raise_nested< must< Rules... > >;
+
+   template< template< typename... > class Rule >
+   void verify_nested()
+   {
+      try {
+         memory_input in( "0", __FUNCTION__ );
+         parse< Rule< alpha > >( in );
+         TAO_PEGTL_TEST_UNREACHABLE;
+      }
+      catch( ... ) {
+         const std::vector< parse_error > e = nested::flatten();
+         TAO_PEGTL_TEST_ASSERT( e.size() == 2 );
+      }
+   }
+
+   void unit_test()
+   {
+      verify_seqs< try_catch_raise_nested >();
+      verify_seqs< try_catch_any_raise_nested >();
+
+      verify_nested< test_try_catch_rule >();
+      verify_nested< test_try_catch_any_rule >();
+   }
+
+}  // namespace TAO_PEGTL_NAMESPACE
+
+#include "main.hpp"
+
+#endif
diff --git a/packages/PEGTL/src/test/pegtl/rule_try_catch.cpp b/packages/PEGTL/src/test/pegtl/rule_try_catch_return_false.cpp
similarity index 64%
rename from packages/PEGTL/src/test/pegtl/rule_try_catch.cpp
rename to packages/PEGTL/src/test/pegtl/rule_try_catch_return_false.cpp
index 4fa24e689..5e4a5bb50 100644
--- a/packages/PEGTL/src/test/pegtl/rule_try_catch.cpp
+++ b/packages/PEGTL/src/test/pegtl/rule_try_catch_return_false.cpp
@@ -16,12 +16,18 @@ int main()
 namespace TAO_PEGTL_NAMESPACE
 {
    template< typename... Rules >
-   using test_try_catch_rule = try_catch< must< Rules... > >;
+   using test_try_catch_rule = try_catch_return_false< must< Rules... > >;
+
+   template< typename... Rules >
+   using test_try_catch_any_rule = try_catch_any_return_false< must< Rules... > >;
 
    void unit_test()
    {
-      verify_seqs< try_catch >();
       verify_seqs< test_try_catch_rule >();
+      verify_seqs< try_catch_return_false >();
+
+      verify_seqs< test_try_catch_any_rule >();
+      verify_seqs< try_catch_any_return_false >();
    }
 
 }  // namespace TAO_PEGTL_NAMESPACE
diff --git a/packages/PEGTL/src/test/pegtl/rule_until.cpp b/packages/PEGTL/src/test/pegtl/rule_until.cpp
index 32a19fef4..e8cf0643c 100644
--- a/packages/PEGTL/src/test/pegtl/rule_until.cpp
+++ b/packages/PEGTL/src/test/pegtl/rule_until.cpp
@@ -58,7 +58,7 @@ namespace TAO_PEGTL_NAMESPACE
 #if defined( __cpp_exceptions )
       verify_rule< must< until< one< 'a' > > > >( __LINE__, __FILE__, "bbb", result_type::global_failure, 0 );
 
-      verify_rule< try_catch< must< until< one< 'a' > > > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 );
+      verify_rule< try_catch_return_false< must< until< one< 'a' > > > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 );
 #endif
 
       verify_rule< until< eof, any > >( __LINE__, __FILE__, "", result_type::success, 0 );
@@ -108,8 +108,8 @@ namespace TAO_PEGTL_NAMESPACE
       verify_rule< must< until< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bbb", result_type::global_failure, 0 );
       verify_rule< must< until< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bbbc", result_type::global_failure, 1 );
 
-      verify_rule< try_catch< must< until< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 );
-      verify_rule< try_catch< must< until< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "bbbc", result_type::local_failure, 4 );
+      verify_rule< try_catch_return_false< must< until< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 );
+      verify_rule< try_catch_return_false< must< until< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "bbbc", result_type::local_failure, 4 );
 #endif
 
       bool success = false;
diff --git a/packages/PEGTL/src/test/pegtl/test.hpp b/packages/PEGTL/src/test/pegtl/test.hpp
index 1fdba8266..759dcd2c5 100644
--- a/packages/PEGTL/src/test/pegtl/test.hpp
+++ b/packages/PEGTL/src/test/pegtl/test.hpp
@@ -24,18 +24,18 @@ namespace TAO_PEGTL_NAMESPACE
 
 #define TAO_PEGTL_TEST_UNWRAP( ... ) __VA_ARGS__
 
-#define TAO_PEGTL_TEST_FAILED( MeSSaGe )            \
-   do {                                             \
-      std::cerr << "pegtl: unit test failed for [ " \
-                << TAO_PEGTL_NAMESPACE::demangle< Rule >()   \
-                << " ] "                            \
-                << TAO_PEGTL_TEST_UNWRAP( MeSSaGe ) \
-                << " in line [ "                    \
-                << line                             \
-                << " ] file [ "                     \
-                << file << " ]"                     \
-                << std::endl;                       \
-      ++TAO_PEGTL_NAMESPACE::failed;                         \
+#define TAO_PEGTL_TEST_FAILED( MeSSaGe )                   \
+   do {                                                    \
+      std::cerr << "pegtl: unit test failed for [ "        \
+                << TAO_PEGTL_NAMESPACE::demangle< Rule >() \
+                << " ] "                                   \
+                << TAO_PEGTL_TEST_UNWRAP( MeSSaGe )        \
+                << " in line [ "                           \
+                << line                                    \
+                << " ] file [ "                            \
+                << file << " ]"                            \
+                << std::endl;                              \
+      ++TAO_PEGTL_NAMESPACE::failed;                       \
    } while( false )
 
 #define TAO_PEGTL_TEST_ASSERT( ... )               \
@@ -48,7 +48,7 @@ namespace TAO_PEGTL_NAMESPACE
                    << " ] file [ "                 \
                    << __FILE__ << " ]"             \
                    << std::endl;                   \
-         ++TAO_PEGTL_NAMESPACE::failed;                     \
+         ++TAO_PEGTL_NAMESPACE::failed;            \
       }                                            \
    } while( false )
 
@@ -63,7 +63,7 @@ namespace TAO_PEGTL_NAMESPACE
                    << " ] file [ "                  \
                    << __FILE__ << " ]"              \
                    << std::endl;                    \
-         ++TAO_PEGTL_NAMESPACE::failed;                      \
+         ++TAO_PEGTL_NAMESPACE::failed;             \
       }                                             \
       catch( ... ) {                                \
       }                                             \
diff --git a/packages/PEGTL/src/test/pegtl/verify_file.hpp b/packages/PEGTL/src/test/pegtl/verify_file.hpp
index f146e55dd..bddf8b220 100644
--- a/packages/PEGTL/src/test/pegtl/verify_file.hpp
+++ b/packages/PEGTL/src/test/pegtl/verify_file.hpp
@@ -9,7 +9,7 @@
 
 #include "test.hpp"
 
-#if defined( _MSC_VER )
+#if defined( _MSC_VER ) || defined( __MINGW32__ )
 #define TAO_PEGTL_TEST_FILENAME u"src/test/pegtl/file_äöü𝄞_data.txt"
 #else
 #define TAO_PEGTL_TEST_FILENAME "src/test/pegtl/file_äöü𝄞_data.txt"
@@ -63,7 +63,7 @@ namespace TAO_PEGTL_NAMESPACE
             T in( "src/test/pegtl/no_such_file.txt" );
             TAO_PEGTL_TEST_UNREACHABLE;  // LCOV_EXCL_LINE
          }
-         catch( const internal::filesystem::filesystem_error& ) {
+         catch( const std::filesystem::filesystem_error& ) {
          }
       }
 #endif
diff --git a/packages/PEGTL/src/test/pegtl/verify_seqs.hpp b/packages/PEGTL/src/test/pegtl/verify_seqs.hpp
index 6b57e0a88..981a44b70 100644
--- a/packages/PEGTL/src/test/pegtl/verify_seqs.hpp
+++ b/packages/PEGTL/src/test/pegtl/verify_seqs.hpp
@@ -56,12 +56,12 @@ namespace TAO_PEGTL_NAMESPACE
       verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::success, 0 );
       verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 );
 
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 );
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "c", result_type::local_failure, 1 );
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ab", result_type::success, 0 );
-      verify_rule< try_catch< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "c", result_type::local_failure, 1 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "ab", result_type::success, 0 );
+      verify_rule< try_catch_return_false< must< S< one< 'a' >, one< 'b' > > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 );
 #endif
    }
 
diff --git a/src/language/PEGGrammar.hpp b/src/language/PEGGrammar.hpp
index e2aaeec54..1188c63b5 100644
--- a/src/language/PEGGrammar.hpp
+++ b/src/language/PEGGrammar.hpp
@@ -17,7 +17,7 @@ struct starslash  : TAO_PEGTL_STRING("*/") {};
 
 struct comment
     : sor< if_must< slashslash, until< eolf > >,
-           try_catch< slashstar, until< starslash> >,
+           try_catch_return_false< slashstar, until< starslash> >,
            // error management
            if_must<at<slashstar>,raise<slashstar>, until< eof> > > {};
 
@@ -87,7 +87,7 @@ struct basic_type : sor< scalar_type, string_type >{};
 struct type_name_id;
 struct simple_type_specifier : sor< matrix_type, vector_type, basic_type, type_name_id >{};
 
-struct tuple_type_specifier :  sor<try_catch< open_parent, simple_type_specifier, ignored, close_parent >,
+struct tuple_type_specifier :  sor<try_catch_return_false< open_parent, simple_type_specifier, ignored, close_parent >,
 				   // non matching braces management
 				   if_must< at< open_parent >, raise< simple_type_specifier >, until< eof > > >{};
 
@@ -272,7 +272,7 @@ struct close_brace : seq< one< '}' >, ignored >{};
 struct instruction_list;
 
 struct braced_instruction_list
-    :  sor<try_catch< open_brace, instruction_list, close_brace >,
+    :  sor<try_catch_return_false< open_brace, instruction_list, close_brace >,
            // non matching braces management
            if_must< at< one< '{' > >, raise< open_brace >, until< eof > > >{};
 
diff --git a/tests/test_ASTNode.cpp b/tests/test_ASTNode.cpp
index 1a2e59118..b79771f65 100644
--- a/tests/test_ASTNode.cpp
+++ b/tests/test_ASTNode.cpp
@@ -54,8 +54,8 @@ TEST_CASE("ASTNode", "[language]")
       ASTNode ast_node;
       ast_node.source         = "content";
       const char* const start = &ast_node.source[0];
-      ast_node.m_begin        = TAO_PEGTL_NAMESPACE::internal::frobnicator{start};
-      ast_node.m_end          = TAO_PEGTL_NAMESPACE::internal::frobnicator{start + 7};
+      ast_node.m_begin        = TAO_PEGTL_NAMESPACE::internal::inputerator{start};
+      ast_node.m_end          = TAO_PEGTL_NAMESPACE::internal::inputerator{start + 7};
 
       REQUIRE(ast_node.string() == "content");
       REQUIRE(ast_node.string_view() == "content");
@@ -66,13 +66,13 @@ TEST_CASE("ASTNode", "[language]")
       ASTNode ast_node;
       ast_node.source         = "content";
       const char* const start = &ast_node.source[0];
-      ast_node.m_begin        = TAO_PEGTL_NAMESPACE::internal::frobnicator{start + 2};
+      ast_node.m_begin        = TAO_PEGTL_NAMESPACE::internal::inputerator{start + 2};
 
       {
         std::unique_ptr<ASTNode> child0_node = std::make_unique<ASTNode>();
 
-        child0_node->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{start};
-        child0_node->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{start + 3};
+        child0_node->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{start};
+        child0_node->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{start + 3};
 
         ast_node.children.emplace_back(std::move(child0_node));
       }
@@ -80,8 +80,8 @@ TEST_CASE("ASTNode", "[language]")
       {
         std::unique_ptr<ASTNode> child1_node = std::make_unique<ASTNode>();
 
-        child1_node->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{start + 4};
-        child1_node->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{start + 7};
+        child1_node->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{start + 4};
+        child1_node->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{start + 7};
 
         ast_node.children.emplace_back(std::move(child1_node));
       }
diff --git a/tests/test_ASTNodeDataType.cpp b/tests/test_ASTNodeDataType.cpp
index b58ffe197..7dacecf68 100644
--- a/tests/test_ASTNodeDataType.cpp
+++ b/tests/test_ASTNodeDataType.cpp
@@ -116,8 +116,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
       dimension_node->set_type<language::integer>();
       dimension_node->source      = "3";
       const char* const beginning = &dimension_node->source[0];
-      dimension_node->m_begin     = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-      dimension_node->m_end       = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+      dimension_node->m_begin     = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+      dimension_node->m_end       = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       type_node->emplace_back(std::move(dimension_node));
     }
 
@@ -156,8 +156,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "0";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         REQUIRE_THROWS_WITH(getVectorDataType(*type_node), "invalid dimension (must be 1, 2 or 3)");
       }
@@ -165,8 +165,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "1";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         REQUIRE_NOTHROW(getVectorDataType(*type_node));
       }
@@ -174,8 +174,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "4";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         REQUIRE_THROWS_WITH(getVectorDataType(*type_node), "invalid dimension (must be 1, 2 or 3)");
       }
@@ -257,8 +257,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
         dimension0_node->set_type<language::integer>();
         dimension0_node->source     = "3";
         const char* const beginning = &dimension0_node->source[0];
-        dimension0_node->m_begin    = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        dimension0_node->m_end      = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        dimension0_node->m_begin    = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        dimension0_node->m_end      = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
         type_node->emplace_back(std::move(dimension0_node));
       }
       {
@@ -266,8 +266,8 @@ TEST_CASE("ASTNodeDataType", "[language]")
         dimension1_node->set_type<language::integer>();
         dimension1_node->source     = "3";
         const char* const beginning = &dimension1_node->source[0];
-        dimension1_node->m_begin    = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        dimension1_node->m_end      = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        dimension1_node->m_begin    = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        dimension1_node->m_end      = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
         type_node->emplace_back(std::move(dimension1_node));
       }
     }
@@ -314,14 +314,14 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "0";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
       {
         type_node->children[2]->source  = "0";
         const char* const beginning     = &type_node->children[2]->source[0];
-        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
 
       REQUIRE_THROWS_WITH(getMatrixDataType(*type_node), "invalid dimension (must be 1, 2 or 3)");
@@ -329,14 +329,14 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "4";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
       {
         type_node->children[2]->source  = "4";
         const char* const beginning     = &type_node->children[2]->source[0];
-        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
 
       REQUIRE_THROWS_WITH(getMatrixDataType(*type_node), "invalid dimension (must be 1, 2 or 3)");
@@ -347,14 +347,14 @@ TEST_CASE("ASTNodeDataType", "[language]")
       {
         type_node->children[1]->source  = "1";
         const char* const beginning     = &type_node->children[1]->source[0];
-        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[1]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[1]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
       {
         type_node->children[2]->source  = "2";
         const char* const beginning     = &type_node->children[2]->source[0];
-        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        type_node->children[2]->m_begin = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        type_node->children[2]->m_end   = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
       }
       REQUIRE_THROWS_WITH(getMatrixDataType(*type_node), "only square matrices are supported");
     }
diff --git a/tests/test_ASTNodeNaturalConversionChecker.cpp b/tests/test_ASTNodeNaturalConversionChecker.cpp
index 161b934cb..4d1e93c40 100644
--- a/tests/test_ASTNodeNaturalConversionChecker.cpp
+++ b/tests/test_ASTNodeNaturalConversionChecker.cpp
@@ -100,8 +100,8 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]")
         data_node->set_type<language::integer>();
         data_node->source           = "0";
         const char* const beginning = &data_node->source[0];
-        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         SECTION("d = 1")
         {
@@ -150,8 +150,8 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]")
         data_node->set_type<language::integer>();
         data_node->source           = "0";
         const char* const beginning = &data_node->source[0];
-        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         SECTION("d = 1")
         {
@@ -924,8 +924,8 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]")
         data_node->set_type<language::integer>();
         data_node->source           = "1";
         const char* const beginning = &data_node->source[0];
-        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         SECTION("d=1")
         {
@@ -1382,8 +1382,8 @@ TEST_CASE("ASTNodeNaturalConversionChecker", "[language]")
         data_node->set_type<language::integer>();
         data_node->source           = "1";
         const char* const beginning = &data_node->source[0];
-        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning};
-        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::frobnicator{beginning + 1};
+        data_node->m_begin          = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning};
+        data_node->m_end            = TAO_PEGTL_NAMESPACE::internal::inputerator{beginning + 1};
 
         SECTION("d=1")
         {
diff --git a/tests/test_ParseError.cpp b/tests/test_ParseError.cpp
index 12ee1ff13..e6b53d463 100644
--- a/tests/test_ParseError.cpp
+++ b/tests/test_ParseError.cpp
@@ -15,7 +15,7 @@ TEST_CASE("ParseError", "[language]")
 a first line
 a second line
 )";
-    TAO_PEGTL_NAMESPACE::internal::frobnicator i(&source[0], 3, 1, 2);
+    TAO_PEGTL_NAMESPACE::internal::inputerator i(&source[0], 3, 1, 2);
     TAO_PEGTL_NAMESPACE::position p{i, source};
     ParseError parse_error("error message", p);
     REQUIRE(parse_error.positions() == std::vector{p});
@@ -28,9 +28,9 @@ a second line
 a first line
 a second line
 )";
-    TAO_PEGTL_NAMESPACE::internal::frobnicator i0(&source[0], 3, 1, 2);
+    TAO_PEGTL_NAMESPACE::internal::inputerator i0(&source[0], 3, 1, 2);
     TAO_PEGTL_NAMESPACE::position p0{i0, source};
-    TAO_PEGTL_NAMESPACE::internal::frobnicator i1(&source[0], 4, 1, 3);
+    TAO_PEGTL_NAMESPACE::internal::inputerator i1(&source[0], 4, 1, 3);
     TAO_PEGTL_NAMESPACE::position p1{i1, source};
 
     ParseError parse_error("error message", std::vector{p0, p1});
diff --git a/tests/test_SymbolTable.cpp b/tests/test_SymbolTable.cpp
index ed93b4d21..26175e162 100644
--- a/tests/test_SymbolTable.cpp
+++ b/tests/test_SymbolTable.cpp
@@ -5,7 +5,7 @@
 #include <language/utils/SymbolTable.hpp>
 #include <language/utils/TypeDescriptor.hpp>
 
-#include <pegtl/internal/frobnicator.hpp>
+#include <pegtl/internal/inputerator.hpp>
 
 #include <sstream>
 
@@ -18,7 +18,7 @@ TEST_CASE("SymbolTable", "[language]")
     std::shared_ptr root_st = std::make_shared<SymbolTable>();
 
     using namespace TAO_PEGTL_NAMESPACE;
-    position begin_position{internal::frobnicator{"fixture"}, "fixture"};
+    position begin_position{internal::inputerator{"fixture"}, "fixture"};
     begin_position.byte = 2;
 
     auto [i_symbol_a, created_a] = root_st->add("a", begin_position);
@@ -29,7 +29,7 @@ TEST_CASE("SymbolTable", "[language]")
     // Check that one cannot build another "a" in this table
     REQUIRE(not root_st->add("a", begin_position).second);
 
-    position use_position{internal::frobnicator{"fixture"}, "fixture"};
+    position use_position{internal::inputerator{"fixture"}, "fixture"};
     use_position.byte = 3;   // after declarative position
 
     auto [i_search_a, found_a] = root_st->find("a", use_position);
@@ -106,15 +106,15 @@ TEST_CASE("SymbolTable", "[language]")
     std::shared_ptr root_st = std::make_shared<SymbolTable>();
 
     using namespace TAO_PEGTL_NAMESPACE;
-    position begin_position{internal::frobnicator{"fixture"}, "fixture"};
-    position end_declaration{internal::frobnicator{"fixture"}, "fixture"};
+    position begin_position{internal::inputerator{"fixture"}, "fixture"};
+    position end_declaration{internal::inputerator{"fixture"}, "fixture"};
 
     auto [i_root_symbol_a, created_root_a] = root_st->add("a", begin_position);
     REQUIRE(created_root_a);
 
     std::shared_ptr nested_st = std::make_shared<SymbolTable>(root_st);
 
-    position use_position{internal::frobnicator{"fixture"}, "fixture"};
+    position use_position{internal::inputerator{"fixture"}, "fixture"};
     auto [i_search_a, found_a] = nested_st->find("a", use_position);
     REQUIRE(found_a);
     // symbol "a" is the one defined in root_st
@@ -139,13 +139,13 @@ TEST_CASE("SymbolTable", "[language]")
     std::shared_ptr root_st = std::make_shared<SymbolTable>();
 
     using namespace TAO_PEGTL_NAMESPACE;
-    position begin_position{internal::frobnicator{"fixture"}, "fixture"};
+    position begin_position{internal::inputerator{"fixture"}, "fixture"};
     begin_position.byte = 2;
 
     auto [i_symbol_a, created_a] = root_st->add("a", begin_position);
     REQUIRE(i_symbol_a->attributes().position().byte == 2);
 
-    position use_position{internal::frobnicator{"fixture"}, "fixture"};
+    position use_position{internal::inputerator{"fixture"}, "fixture"};
     use_position.byte = 3;   // after declarative position
 
     auto [i_search_a, found_a] = root_st->find("a", use_position);
-- 
GitLab