diff --git a/packages/PEGTL/.clang-tidy b/packages/PEGTL/.clang-tidy index d938e19e0f61b42ebc7d62874f0ea1a2dae2ee0b..b4ec5b2083be7452c5172e94117c43427e38bec6 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 587e5f320233411d374142e423abed98742eda86..0000000000000000000000000000000000000000 --- 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 11b3c2e009426471a477a82bcdb8acb461d06746..865c2c568ff00266101abf6140ab9397e78b4338 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 b3f95a4f23053aad8946d0fffca84e06397e2e7d..5eb47e8b0246c238e3d65749002f50b115f1f653 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 842b1ab7cc9143d7421c75c50a1858a0408346f1..157ae3539389db4370114aaf93feba3c393755cd 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 0000000000000000000000000000000000000000..9618e9ce28692b9e2d43c320d8dcd0c9d8dd5ac4 --- /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 42eacfd4ae61aa7c504d55d468c93451583a0898..b61a7fd047572abe2f85bf4308f511d642df6090 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 4ac43b7e4044c9880feadfc6c4cbcf5f5fdf40a2..c8518e9b1251810bb99e71a81d2dca85e1944fc3 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 0000000000000000000000000000000000000000..daf6c07f927111dd489c7fda86f1fecc4cd1f00f --- /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 2233099fa6181105a7e6053740984913bc856534..1df6fa021e64efb60b70543b50ff7c29a1152b22 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 b4883158f56da430e597c132fb41389430cfb968..9e355b813ea505a627a47601816d4e8d09eef4c2 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 46c2fa5dbca93d2820f4ab7594cffbb2574d7513..8338a4746d8516b4f658e5358c436299f6123f75 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 b05d176d3773a8134a13fab8e29d58066787f0aa..17e7d686f9eadc9428b7b9c5019eded92e175f2d 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 a2c09f4fbe6c63250d408433eceb627c063e2e93..ebfc6d22ff4e4b44557da85637492df00193ce59 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 58b2143b6b26b3023a6157d6b44e6c671508bc06..2c22014c2c289efc8729ffffa59054130dd25f91 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 d186d3ee49bde9f9bb5ba4498efccfac95b35bb7..b9a0122b93fc57671d3d74baccf5357c85e18e3d 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 20c13d570d8077d25b8b13098f5a10087ff413e6..8ed7fcafca933e7cef75c78b80cc5201ac7be0c1 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 d661711426c3320766505ddceef4470547e386d9..a8551352308c787be631316fdc34f495893a24ea 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 8996a729560c4089c0ec85621266b0ff5dafb1e9..5561a5cd73de015bc78274bfec6a7eb85adc7d04 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 d037ab5c652a2db9617394d3fc3e94434cb47916..eb51a30234fd63672f68a18882709db439597b0e 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 bde86a1e994764e08dfdfe710a3ef93942d21d17..d7ac8d6d99e2cab59c5dfeecb1fcc4676f768db8 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 9ea518b6beee7fec880dd347cb314404cd2f7cd0..7910ca4854dcfd549c04bd0127bcc740c312c23f 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 20e18a82f6cdeddd11135738dbc692f1b05d2d5d..e95f46b91b57a0a951bb9b5e0330ee7d0332f59a 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 521623d26853772d266101fa1d9a5052d9dabf3e..04f77919846b399eef5ff0d69772d23995d74600 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 33f47d4c3d968e185838b6237ce9ad21a131a0fc..e720f0d2cf4d40d0fd48d6d78926b99fa466ba85 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 001a9f87cf659a3ea48168f9d4bd36ffae7367b3..ccb740483955951c00b56d01ef3b32c675153710 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 0000000000000000000000000000000000000000..90f4c623e7d657dde340db371717422cb822e7e5 --- /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 c442da75ebdb9eaea04e30212495c776f1fe05d0..7a623ec527b809e1b6478be9d69016a397da353a 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 993d0fca019afca7734c7e5603a9781557b2df8f..68f89599b4d791e2ba3ac6a70392896e84f8fe2a 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 78a2fa68e06a603e9224bc5ce223e58bc6762780..34b288da3900c1880dead5a101b9e7f7dff42c71 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 ad3d2fa7cb28f5bd90f3fd6a5691e63d04fbdf9d..559886c494c1db2c202dfe065022cb5cc89885db 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 8041efdf81b97f6eefd9699c3369ddaa0765568c..28c66017d4db46a8a32d204a363125e68900bc2a 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 67a8804248ae96075aacf5117bc52f2c8c5f8a3a..e71659138959a7c2a0ff9fde890566dea3b86137 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 b371736845fcf3efb52a98851443e0312e001b26..55d43c583ccbfec5fbb8db6ef6df6ca314f630d2 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 e83ba91141a4b6c8701ff0c7d743ae3a49186bf6..4993fa262e1a8e84a3cab185294e9878fbcb32a1 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 a28ba39919adb60fe621af974867bc54cb56f2a0..b1eaf5bddf9b842e933d066307715bee10d3f20c 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 5ec599124b8c2211eae0d121238ce90ee9c48469..a7ae3844abdc4b21a5f7682b4de05ea3a515b5f6 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 0000000000000000000000000000000000000000..7105793ca47e41782137fbf8085049f819866822 --- /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 311c74577466be60f5e9379bbe8f255ea70c307b..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..d1ef5e44c3be91f033867e08fc53c28d28637b5d --- /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 7ce7c48550481155e33b10f53ef93deb1942ee78..b7b6ccb7cd2367de0948e2304d7e651ca88be0c5 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 d846d6fd7b504a99163e74ab0d620ae2fa6dc9bf..9e72cf4e7cb60725fd0c8cf3cd43e5172d3553e9 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 6885588210861762a194afb1b808f6303ff5b6c1..8e1c51ef318f2c30dcf2ac9353a135642964deaa 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 361a6f0bdc9edeca5f8e886b1b0893c4a3fb82c9..ff9d205fa6370bd53c87963ba8f439ef87460e33 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 367ae90d4abb9902d8c0006932eb5161d6dce5f9..d44a049c2d175dbc63da0d2a3d624f2e1227a2f9 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 5f2a3dbeeaae26f2611ba56f374cf609f1d813bc..df24d8a8872b511a92471b745d24bcf3e678ac80 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 93be8941fd319d73d19fd9e612dd873ba868ce67..0a17e91a3cbd1c0a23379945bb8ff700c413c23f 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 b665d1e739972e85296026f3b8d759f2f156457b..7fd803ecaf0e897851cc53d3566e501472fadd55 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 4d5fe80d1bcbb2b59675f846be714ca99307bfe7..56091782d5780ac7e26c45cd6645362d34e83142 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 3811179fd8c96672d8c67ccfd6e03cc476b03cee..645f4b732afa630097d44942a5bf54504a84dab8 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 afb08a67ee4e7062f7a6b6a98be599707085389e..29210cf1de7b29ad938174e4420a08e378c9b86e 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 e5f8ac6fb8b1ef81772ca8eeadf9fdb8b555cb53..063cd32eceadfd8012c274ec53e3b255e6864c47 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 8c4a6461ac1f5c21f1f6af0aa2b8eba51f935e0c..f54b5edecbee1f876250da8311f68678a4a0b219 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 5a53bcf498ab5f497a46ed2c0291724ed2bca42a..aa88e59b7d08f0e7a240bd79347def54b743c98e 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 0000000000000000000000000000000000000000..79139bde1d2fc7100c2035faec67d11949f7c970 --- /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 0000000000000000000000000000000000000000..b3512b9181725e4bf3fd9e00adab452ae8176a3b --- /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 f61a9ae9700c42fe6e7e5962da86bd833deb2a88..0d46fdf4527110ebe0440cc7f8be1978612ed1f8 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 f4c953f2458bd15fb62ada87ff0465a8e313870f..311fd603a28032d92835e9856409e9a413040823 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 93702353f9dddb13f5617f2116b8b77ce0a5d521..52f73898fa2d1f3c948d1aa985b4f8f474ec9b21 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 83f69158b4c6d4b682569395ecad35404ec59cec..8cff1026d7fbaf0801fd0884ff2af20cb4411fbf 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 d370d8c2fc747d215987a96bd76f82c309adc62a..64a4870502f97f2bb011205390f0360dd21a14fe 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 da05d0a2150893c99997bc1d28125f43b4eb1fc3..ab34ac2a8af1d8b012a83563ca82383d06c949d1 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 954e5717ace970cdb0e1003cc918ad17da2a56ae..b9ec149c282be4311d05760b4ac5d41cc633b3fd 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 0000000000000000000000000000000000000000..889f2efb2fedf4cef2ecbc8dcfc938663c8ea142 --- /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 af20a0d5511383159767cb6c31b461f81a2c786e..5cb329eaf41b41ef30fa992498493647d282bf1f 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 b730aff8435cb7b2b2e4311445c8a48e6144faa8..df7d75651ed940ee65791e533355adcc2d4dc118 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 e51a4281ea42dba18e91967eb3b53c10b423986c..4bea177f224ac21bb85487386a85a302f6abcb93 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 9e4c111e1decf4847f649d3c7395dc26243b5b59..beb1088b4827e0aa9dcf609681580fc8b9fa5ac0 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 dcdfd3548a4d2ee4f5e0bd8066db2e46f13cdfd2..951a521ba28cb5f10cb5cf4bf2668db6f94296e6 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 ac0d52e6deebd97250293c7a35a0015f14910633..8143779adb43bb7115954a0560b5798a0ef1d28e 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 12be3bb8ba98423fca18e0f810e06a3462add501..ea1ad7d624fc6fb676d2b5103ba40c0e8957331d 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 54cada30506a28998d591acd7f17f23600bd08fc..beba07a8b6d77817891047b3a9301cc9364c687f 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 bfc0d876f4bddf20bd52408ea69f314c241f48f1..508a56ff94d5e577ac4f4b9393d597fffe9bb0e2 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 1b96455ff45be4a983422c944533f4064d26fb6d..3ee91897ef3408dbef88e1f0fa6d7df953123da2 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 bf945b317b447e66164043e5a2e11f39036b20ff..3dd9234eaa0d8baf8f1353e1e821ad5946716d76 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 d73124cf14f4608ac5b319aa60727731f7c5241e..5773bae9fcb66d0c53c31ef8db23e668384d66c3 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 1681988b051e7c76c345d2629cc997e6b84197c8..1fedb834605c49fc71a0a81aed6f49f5b8a6e11e 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 c6a1ce673f624533d6e3eeeb51cd5e3922976ea9..dc38bf9926f03549f98f9e46764b58f2b2087d2a 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 d49dcdbd44097b9eb4927e01730d18373a5f5cd0..0a7b449b46e531e47e403a6503c27a9fcff1af78 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 7be928a145c314078befd3a141ca9968f5a33724..2acc9c2a4cf42b5702dc8aa06fced63b4cd6ef54 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 12d581e918b549cc7e2c524e60ab22c03f491209..375f458ecfbfa1c09b6b8bfa673702073ed1ad7c 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 a93dbb8b68e2db72f11ced567468ebb5746ee77b..51a928f7dda8e5bee4bad867ca110b50a9827afc 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 2ddf46053d78286d3313b277cac881a2ed0960e2..0f67f336c78e47ccde7f40d7a1d2bef5925441f2 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 62ceaf6ccf1ffe392285bc03a866c71ca118340d..6704d5415bf12feb5c0ddae55c4c15d649a9fe2a 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 7f707c33a4c9306c84642b3fe297855212e3d263..608ce61c3d45cc4af2edb482193880c8cc2a8578 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 4accf9c2e9a0c74b32b20f75eae9dc28a4ebce4a..5185274d4c31189ac82a28b4b84cd3f33e5b8364 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 f55f08134fa6b3e765c74e182edea7fd53fa2a40..1f65ec7034c31328933098c4c51d51f465b21012 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 2c1d5798fa870382eeba9f6b084c2d4226c5f9ae..ff9d3a3d1f1d87cdb407b73caabca70b36dd347d 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 cf2387fb6b27c024afd23395459549aa29c60297..12a932441ed7b2442dac0f368ae831b910d72e60 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 b3283dfb433ba2851c0fdf9720b8420f9dec15f2..e394715a019e196cb4aa23ca5d978ea41d43bbc4 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 fd9a6149c5b2704a6f2b9bf682a7764d8599c60c..a442979386084d4bd621515015f33f7605467ed4 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 0ee3293ecba120fac145e9f33532d48e5fdd870a..b4b6084e642b61483c3b04452ee2fa31277acab3 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 ec207cf23123172d425ab396d0741475e4bcfc77..9d9ca9e4d7ecf26aeed0bd9ae4b046a3c4c1b6ae 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 a717379687db4cf8fe206caad1f135b64e5ef421..78c5b1648edd668ad87220137601189b6d2d7a7c 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 36e07afbfbdbbe019d150e23764ba4444fe18eb1..4bce4f2ac0278bf0372cecf99c625b5a9c2c5d47 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 1034bea58edc0117b4eef4a411be8e5c84bb2522..fcfae41d50a542c904b57d977acc3a6afb7ed452 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 c8582482c6f301583eda475b2ee304a3b7b27b1f..5c0c39545cd3d3400eff0b04857fb8e5e8ea40d2 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 4759fc68b34ad8d3b6c220d442c8b59e64f75dd5..1dea2aff55c774dbccc3969661914f49022caa83 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 44d4303cdcfc5096eaa44e795716232b6d997e70..a39c6fc41a347b98e753c706ea59339784b6e4af 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 8cd7143ae892010e16ce7e5d9d0a4efc04b967c5..85dfd8ad1f71ed3a330db5e6c060675c4319aa1b 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 0000000000000000000000000000000000000000..a35b81c4f1007514c5d1a869eea68c7bbbbe4458 --- /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 4fa24e6890664868740901b0e58cae65d04f7b51..5e4a5bb504fb358e9721f1a5b6795cb6ac7d3ff2 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 32a19fef4be7e6f9f6ed5fec83fc8305165ff62f..e8cf0643c8c36bb379f236569dfe5069c71f53f5 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 1fdba82661020ae838b1265ba0b8d6cbcb850a5c..759dcd2c551f16c3918a341a84b08332c148a2ca 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 f146e55dd9b11446d85f3b8716ec36ee4531e97b..bddf8b220d802f525b6d957bd848a8d7a4d77151 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 6b57e0a88e585d111ebb8eee2ba2dfb3d94aaa8e..981a44b70c27857c59c73bddac7176521e517d6c 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 e2aaeec547bfb3793da15e2305a4882d29fd22e3..1188c63b5a5aff2004bada25dc1706c20705d553 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 1a2e5911898ac7d859ecd732916ea6bbf532d5fb..b79771f65942e94ffa97f29ac2f73045a297c008 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 b58ffe19772faef4de5b00e784207b806d101d00..7dacecf68e4fb21c1c7cdf53cec2e3283bb1b30c 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 161b934cb68b1825b5878f380e7cd395a7c612c0..4d1e93c4035c6c55c6c2eb032f0a2d3eec1cb999 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 12ee1ff1332affa22a9e13a2333781d4fa6648c1..e6b53d463e8cbecd7e88475b023e123f825a3eb4 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 ed93b4d21c48499f455d4fe5544608e2fea9324d..26175e162bcb321c5193ce7220c924c75d99c899 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);