pax_global_header00006660000000000000000000000064142640725060014520gustar00rootroot0000000000000052 comment=cf639f7f4ee125f68e1ccfba8d99ebc0de57b9fe tao-pegtl-3.2.7/000077500000000000000000000000001426407250600134255ustar00rootroot00000000000000tao-pegtl-3.2.7/.clang-format000066400000000000000000000045601426407250600160050ustar00rootroot00000000000000# the official .clang-format style for https://github.com/taocpp # # clang-format -i -style=file $(find . -name '[^.]*.[hc]pp') Language: Cpp Standard: Latest AccessModifierOffset: -3 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlinesLeft: false AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes BinPackArguments: false BinPackParameters: false BraceWrapping: AfterClass: true AfterControlStatement: false AfterEnum : true AfterFunction : true AfterNamespace : true AfterStruct : true AfterUnion : true AfterExternBlock: true BeforeCatch : true BeforeElse : true IndentBraces : false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false BreakBeforeBinaryOperators: All BreakBeforeBraces: Custom BreakBeforeTernaryOperators: false BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon BreakStringLiterals: false ColumnLimit: 0 CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 3 ContinuationIndentWidth: 3 Cpp11BracedListStyle: false DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true IncludeBlocks: Preserve IndentCaseLabels: true IndentPPDirectives: None IndentWidth: 3 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 NamespaceIndentation: All PointerAlignment: Left ReflowComments: false SortIncludes: true SortUsingDeclarations: false SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: false SpaceBeforeAssignmentOperators: true SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: Never SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: true SpacesInCStyleCastParentheses: false SpacesInParentheses: true SpacesInSquareBrackets: true TabWidth: 8 UseTab: Never tao-pegtl-3.2.7/.clang-tidy000066400000000000000000000021701426407250600154610ustar00rootroot00000000000000Checks: >- bugprone-*, cppcoreguidelines-slicing, cppcoreguidelines-special-member-functions, google-build-explicit-make-pair, google-build-namespaces, google-default-arguments, google-global-names-in-headers, google-readability-casting, llvm-*, -llvm-namespace-comment, misc-*, -misc-no-recursion, -misc-non-private-member-variables-in-classes, -misc-unused-alias-decls, modernize-*, -modernize-avoid-c-arrays, -modernize-concat-nested-namespaces, -modernize-raw-string-literal, -modernize-use-trailing-return-type, performance-*, readability-*, -readability-avoid-const-params-in-decls, -readability-magic-numbers, -readability-static-accessed-through-instance, CheckOptions: - { key: readability-identifier-naming.ClassCase, value: lower_case } - { key: readability-identifier-naming.FunctionCase, value: lower_case } - { key: readability-identifier-naming.ParameterCase, value: lower_case } - { key: readability-identifier-naming.StructCase, value: aNy_CasE } # PEGTL rules - { key: readability-identifier-naming.VariableCase, value: lower_case } WarningsAsErrors: '*' tao-pegtl-3.2.7/.cmake/000077500000000000000000000000001426407250600145635ustar00rootroot00000000000000tao-pegtl-3.2.7/.cmake/pegtl-config.cmake.in000066400000000000000000000003141426407250600205460ustar00rootroot00000000000000# When a dependency is added with add_subdirectory, but searched with find_package # Redirect to the directory added with add_subdirectory add_subdirectory("@PROJECT_SOURCE_DIR@" "@PROJECT_BINARY_DIR@") tao-pegtl-3.2.7/.cmake/test_filesystem.cpp.in000066400000000000000000000014101426407250600211130ustar00rootroot00000000000000// 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(); } tao-pegtl-3.2.7/.codecov.yml000066400000000000000000000000351426407250600156460ustar00rootroot00000000000000ignore: - src/example/**/* tao-pegtl-3.2.7/.github/000077500000000000000000000000001426407250600147655ustar00rootroot00000000000000tao-pegtl-3.2.7/.github/workflows/000077500000000000000000000000001426407250600170225ustar00rootroot00000000000000tao-pegtl-3.2.7/.github/workflows/android.yml000066400000000000000000000016271426407250600211730ustar00rootroot00000000000000name: Android on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: android: strategy: fail-fast: false matrix: image: - r22 platform: - android-27 - android-29 abi: - 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 steps: - uses: actions/checkout@v2 - 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 }} - run: cmake --build /home/developer/build tao-pegtl-3.2.7/.github/workflows/clang-analyze.yml000066400000000000000000000010361426407250600222720ustar00rootroot00000000000000name: clang-analyze on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: clang-analyze: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: sudo apt-get update -yq - run: sudo apt-get install -yq clang-tools - run: scan-build cmake -E make_directory build - working-directory: build/ run: scan-build cmake $GITHUB_WORKSPACE - working-directory: build/ run: scan-build cmake --build . tao-pegtl-3.2.7/.github/workflows/clang-format.yml000066400000000000000000000005671426407250600221270ustar00rootroot00000000000000name: clang-format on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: clang-format: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: DoozyX/clang-format-lint-action@v0.13 with: extensions: 'hpp,cpp' clangFormatVersion: 13 tao-pegtl-3.2.7/.github/workflows/clang-tidy.yml000066400000000000000000000011251426407250600215770ustar00rootroot00000000000000name: clang-tidy on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: clang-tidy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: sudo apt-get update -yq - run: sudo apt-get install -yq clang-tidy - run: find include/ -name '*.hpp' | grep -vF file_mapper_win32.hpp | grep -vF endian_win.hpp | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude - run: find src/ -name '*.cpp' | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude tao-pegtl-3.2.7/.github/workflows/code-coverage.yml000066400000000000000000000011731426407250600222520ustar00rootroot00000000000000name: Code Coverage on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: code-coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - working-directory: build/ run: cmake $GITHUB_WORKSPACE -DPEGTL_BUILD_EXAMPLES=OFF -DCMAKE_CXX_FLAGS="-coverage" - working-directory: build/ run: cmake --build . - working-directory: build/ run: ctest --output-on-failure - working-directory: build/ run: bash <(curl -s https://codecov.io/bash) tao-pegtl-3.2.7/.github/workflows/codeql-analysis.yml000066400000000000000000000046511426407250600226430ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ main, 3.x ] paths-ignore: - 'README.md' - 'doc/**' pull_request: # The branches below must be a subset of the branches above branches: [ main, 3.x ] paths-ignore: - 'README.md' - 'doc/**' schedule: - cron: '31 6 * * 0' jobs: analyze: name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - name: Checkout repository uses: actions/checkout@v2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 tao-pegtl-3.2.7/.github/workflows/linux.yml000066400000000000000000000062251426407250600207110ustar00rootroot00000000000000name: Linux on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: linux: strategy: fail-fast: false matrix: compiler: - g++-9 - g++-10 - clang++-10 - clang++-11 - clang++-12 build_type: [Debug, Release] runs-on: ubuntu-latest env: CXX: ${{ matrix.compiler }} steps: - uses: actions/checkout@v2 - 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-new: strategy: fail-fast: false matrix: compiler: - g++-11 - clang++-13 - clang++-14 build_type: [Debug, Release] runs-on: ubuntu-22.04 env: CXX: ${{ matrix.compiler }} steps: - uses: actions/checkout@v2 - 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++-7 - g++-8 - clang++-6.0 - clang++-7 - clang++-8 - clang++-9 build_type: [Debug, Release] runs-on: ubuntu-latest env: CXX: ${{ matrix.compiler }} steps: - uses: actions/checkout@v2 - run: sudo apt-get update -yq - run: sudo apt-get install -yq ${{ matrix.compiler }} - 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-gcc-extra: strategy: fail-fast: false matrix: flags: ["-fno-rtti"] build_type: [Debug, Release] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - working-directory: build/ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}" - working-directory: build/ run: cmake --build . - working-directory: build/ run: ctest --output-on-failure linux-clang-extra: strategy: fail-fast: false matrix: flags: ["-fno-rtti", "-fms-extensions"] build_type: [Debug, Release] runs-on: ubuntu-latest env: CXX: clang++ steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - working-directory: build/ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="${{ matrix.flags }}" - working-directory: build/ run: cmake --build . - working-directory: build/ run: ctest --output-on-failure tao-pegtl-3.2.7/.github/workflows/macos.yml000066400000000000000000000013751426407250600206550ustar00rootroot00000000000000name: macOS on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: xcode: strategy: fail-fast: false matrix: xcode: ['11', '12', '13'] build_type: [Debug, Release] runs-on: macos-latest steps: - uses: actions/checkout@v2 - 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 tao-pegtl-3.2.7/.github/workflows/no-exceptions.yml000066400000000000000000000013441426407250600223420ustar00rootroot00000000000000name: No-Exceptions on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: no-exceptions: strategy: fail-fast: false matrix: compiler: [g++, clang++] build_type: [Debug, Release] runs-on: ubuntu-latest env: CXX: ${{ matrix.compiler }} steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - working-directory: build/ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS="-fno-exceptions" - working-directory: build/ run: cmake --build . - working-directory: build/ run: ctest --output-on-failure tao-pegtl-3.2.7/.github/workflows/sanitizer.yml000066400000000000000000000013271426407250600215600ustar00rootroot00000000000000name: Sanitizer on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: sanitizer: strategy: fail-fast: false matrix: cxx: [g++, clang++] sanitizer: [address, undefined] runs-on: ubuntu-latest env: CXX: ${{ matrix.cxx }} steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - working-directory: build/ run: cmake $GITHUB_WORKSPACE -DPEGTL_BUILD_EXAMPLES=OFF -DCMAKE_CXX_FLAGS="-fsanitize=${{ matrix.sanitizer }}" - working-directory: build/ run: cmake --build . - working-directory: build/ run: ctest --output-on-failure tao-pegtl-3.2.7/.github/workflows/windows.yml000066400000000000000000000043311426407250600212400ustar00rootroot00000000000000name: Windows on: push: paths-ignore: - 'README.md' - 'doc/**' pull_request: paths-ignore: - 'README.md' - 'doc/**' jobs: vs2022: strategy: fail-fast: false matrix: build_type: [Debug, Release] runs-on: windows-latest steps: - uses: actions/checkout@v2 - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 17 2022" - working-directory: build/ run: cmake --build . --config ${{ matrix.build_type }} - 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@v2 - 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 }} - working-directory: build/ run: ctest -C ${{ matrix.build_type }} --output-on-failure vs2019: strategy: fail-fast: false matrix: build_type: [Debug, Release] runs-on: windows-2019 steps: - uses: actions/checkout@v2 - 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@v2 - run: cmake -E make_directory build - shell: bash working-directory: build/ run: cmake $GITHUB_WORKSPACE -G "Visual Studio 16 2019" -T ClangCL - working-directory: build/ run: cmake --build . --config ${{ matrix.build_type }} - working-directory: build/ run: ctest -C ${{ matrix.build_type }} --output-on-failure tao-pegtl-3.2.7/.gitignore000066400000000000000000000000371426407250600154150ustar00rootroot00000000000000*~ build private /.vs /.vscode tao-pegtl-3.2.7/CMakeLists.txt000066400000000000000000000140561426407250600161730ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.8...3.19) # Read version from version.hpp file(READ "${CMAKE_CURRENT_LIST_DIR}/include/tao/pegtl/version.hpp" version_hpp_data) string(REGEX MATCH "#define TAO_PEGTL_VERSION \"([^\"]+)\"" _ ${version_hpp_data}) set(PEGTL_VERSION "${CMAKE_MATCH_1}") project(pegtl VERSION ${PEGTL_VERSION} LANGUAGES CXX) set(PEGTL_IS_MAIN_PROJECT OFF) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(PEGTL_IS_MAIN_PROJECT ON) endif() if(PEGTL_HAS_PARENT) # Multiple versions of PEGTL can't co-exist if(NOT ${PROJECT_NAME}_VERSION STREQUAL ${PROJECT_VERSION}) message(FATAL_ERROR "Multiple mismatched PEGTL versions") endif() # Only include if this is the first include if(NOT ${PROJECT_NAME}_DIR STREQUAL "${PROJECT_BINARY_DIR}") return() endif() endif() # Keep track of pegtl version set(${PROJECT_NAME}_FOUND TRUE CACHE BOOL "" FORCE) set(${PROJECT_NAME}_VERSION "${PROJECT_VERSION}" CACHE STRING "" FORCE) set(${PROJECT_NAME}_DIR "${PROJECT_BINARY_DIR}" CACHE PATH "" FORCE) mark_as_advanced(${PROJECT_NAME}_FOUND) mark_as_advanced(${PROJECT_NAME}_VERSION) mark_as_advanced(${PROJECT_NAME}_DIR) # installation directories 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") # define a header-only library add_library(pegtl INTERFACE) add_library(taocpp::pegtl ALIAS pegtl) 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 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 // std::filesystem # Experimental C++17: #include // std::experimental::filesystem # Boost.Filesystem: #include // 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) enable_testing() add_subdirectory(src/test/pegtl) endif() # examples option(PEGTL_BUILD_EXAMPLES "Build example programs" ${PEGTL_IS_MAIN_PROJECT}) if(PEGTL_BUILD_EXAMPLES) add_subdirectory(src/example/pegtl) endif() # Make package findable configure_file(.cmake/pegtl-config.cmake.in pegtl-config.cmake @ONLY) # Ignore pointer width differences since this is a header-only library unset(CMAKE_SIZEOF_VOID_P) # Enable version checks in find_package include(CMakePackageConfigHelpers) write_basic_package_version_file(pegtl-config-version.cmake COMPATIBILITY SameMajorVersion) # install and export target install(TARGETS pegtl EXPORT pegtl-targets) install(EXPORT pegtl-targets FILE pegtl-config.cmake NAMESPACE taocpp:: DESTINATION ${PEGTL_INSTALL_CMAKE_DIR} ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pegtl-config-version.cmake DESTINATION ${PEGTL_INSTALL_CMAKE_DIR}) install(DIRECTORY include/ DESTINATION ${PEGTL_INSTALL_INCLUDE_DIR}) install(FILES LICENSE DESTINATION ${PEGTL_INSTALL_DOC_DIR}) export(EXPORT pegtl-targets FILE ${pegtl_BINARY_DIR}/pegtl-targets.cmake NAMESPACE taocpp:: ) tao-pegtl-3.2.7/LICENSE000066400000000000000000000021201426407250600144250ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2007-2022 Dr. Colin Hirsch and Daniel Frey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tao-pegtl-3.2.7/Makefile000066400000000000000000000054021426407250600150660ustar00rootroot00000000000000# The Art of C++ # Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey # Please see LICENSE for license or visit https://github.com/taocpp/PEGTL .SUFFIXES: .SECONDARY: ifeq ($(OS),Windows_NT) UNAME_S := $(OS) ifeq ($(shell gcc -dumpmachine),mingw32) MINGW_CXXFLAGS = -U__STRICT_ANSI__ endif else UNAME_S := $(shell uname -s) endif # For Darwin (Mac OS X / macOS) we assume that the default compiler # clang++ is used; when $(CXX) is some version of g++, then # $(CXXSTD) has to be set to -std=c++17 (or newer) so # that -stdlib=libc++ is not automatically added. ifeq ($(CXXSTD),) CXXSTD := -std=c++17 ifeq ($(UNAME_S),Darwin) CXXSTD += -stdlib=libc++ endif endif # Ensure strict standard compliance and no warnings, can be # changed if desired. CPPFLAGS ?= -pedantic CXXFLAGS ?= -Wall -Wextra -Wshadow -Werror -O3 $(MINGW_CXXFLAGS) HEADERS := $(shell find include -name '*.hpp') SOURCES := $(shell find src -name '*.cpp') DEPENDS := $(SOURCES:%.cpp=build/%.d) BINARIES := $(SOURCES:%.cpp=build/%) UNIT_TESTS := $(filter build/src/test/%,$(BINARIES)) .PHONY: all all: compile check .PHONY: compile compile: $(BINARIES) .PHONY: check check: $(UNIT_TESTS) @set -e; for T in $(UNIT_TESTS); do echo $$T; $$T > /dev/null; done .PHONY: clean clean: @rm -rf build/* @find . -name '*~' -delete build/%.d: %.cpp Makefile @mkdir -p $(@D) $(CXX) $(CXXSTD) -Iinclude $(CPPFLAGS) -MM -MQ $@ $< -o $@ build/%: %.cpp build/%.d $(CXX) $(CXXSTD) -Iinclude $(CPPFLAGS) $(CXXFLAGS) $< $(LDFLAGS) -o $@ .PHONY: amalgamate amalgamate: build/amalgamated/pegtl.hpp build/amalgamated/pegtl.hpp: $(HEADERS) @mkdir -p $(@D) @rm -rf build/include @cp -a include build/ @rm -rf build/include/tao/pegtl/contrib/icu @sed -i -e 's%^#%//#%g' $$(find build/include -name '*.hpp') @sed -i -e 's%^//#include "%#include "%g' $$(find build/include -name '*.hpp') @for i in $$(find build/include -name '*.hpp'); do echo "#pragma once" >tmp.out; echo "#line 1" >>tmp.out; cat $$i >>tmp.out; mv tmp.out $$i; done @echo '#include "tao/pegtl.hpp"' >build/include/amalgamated.hpp @( cd build/include ; for i in tao/pegtl/contrib/*.hpp; do echo "#include \"$$i\""; done ) >>build/include/amalgamated.hpp @echo -e "/*\n\nWelcome to the Parsing Expression Grammar Template Library (PEGTL)." >$@ @echo -e "See https://github.com/taocpp/PEGTL/ for more information, documentation, etc.\n" >>$@ @echo -e "The library is licensed as follows:\n" >>$@ @cat LICENSE >>$@ @echo -e "\n*/\n" >>$@ @( cd build/include ; g++ -E -C -nostdinc amalgamated.hpp ) >>$@ @sed -i -e 's%^//#%#%g' $@ @sed -i -e 's%^# \([0-9]* "[^"]*"\).*%#line \1%g' $@ @sed -i -e 's%^// Copyright.*%%g' $@ @sed -i -e 's%^// Please.*%%g' $@ @echo "Generated/updated $@ successfully." ifeq ($(findstring $(MAKECMDGOALS),clean),) -include $(DEPENDS) endif tao-pegtl-3.2.7/README.md000066400000000000000000000316211426407250600147070ustar00rootroot00000000000000# Welcome to the PEGTL [![Windows](https://github.com/taocpp/PEGTL/actions/workflows/windows.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/windows.yml) [![macOS](https://github.com/taocpp/PEGTL/actions/workflows/macos.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/macos.yml) [![Linux](https://github.com/taocpp/PEGTL/actions/workflows/linux.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/linux.yml) [![Android](https://github.com/taocpp/PEGTL/actions/workflows/android.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/android.yml)
[![clang-analyze](https://github.com/taocpp/PEGTL/actions/workflows/clang-analyze.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/clang-analyze.yml) [![clang-tidy](https://github.com/taocpp/PEGTL/actions/workflows/clang-tidy.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/clang-tidy.yml) [![Sanitizer](https://github.com/taocpp/PEGTL/actions/workflows/sanitizer.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/sanitizer.yml) [![CodeQL](https://github.com/taocpp/PEGTL/actions/workflows/codeql-analysis.yml/badge.svg?branch=3.x)](https://github.com/taocpp/PEGTL/actions/workflows/codeql-analysis.yml) [![Codecov](https://codecov.io/gh/taocpp/PEGTL/branch/3.x/graph/badge.svg?token=ykWa8RRdyk)](https://codecov.io/gh/taocpp/PEGTL) 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). ## Documentation * [Changelog](doc/Changelog.md) * [Version 3.x](doc/README.md) (requires C++17) * [Version 2.x](https://github.com/taocpp/PEGTL/blob/2.x/doc/README.md) (requires C++11) * [Version 1.x](https://github.com/taocpp/PEGTL/blob/1.x/doc/README.md) (requires C++11) ## Contact Join us on Discord For questions and suggestions regarding the PEGTL, success or failure stories, and any other kind of feedback, please feel free to join our [Discord](https://discord.gg/VQYkppcgqN) server, 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`. ## 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. ```c++ // PEG rule for integers consisting of a non-empty // sequence of digits with an optional sign: // sign ::= '+' / '-' // integer ::= sign? digit+ // The same parsing rule implemented with the PEGTL: using namespace tao::pegtl; struct sign : one< '+', '-' > {}; struct integer : seq< opt< sign >, plus< digit > > {}; ``` PEGs are superficially similar to Context-Free Grammars (CFGs), however the more deterministic nature of PEGs gives rise to some very important differences. The included [grammar analysis](doc/Grammar-Analysis.md) finds several typical errors in PEGs, including left recursion. ## Design The PEGTL is designed to be "lean and mean", the core library consists of approximately 6000 lines of code. Emphasis is on simplicity and efficiency, preferring a well-tuned simple approach over complicated optimisations. The PEGTL is mostly concerned with parsing combinators and grammar rules, and with giving the user of the library (the possibility of) full control over all other aspects of a parsing run. Whether/which actions are taken, and whether/which data structures are created during a parsing run, is entirely up to the user. Included are some [examples](doc/Contrib-and-Examples.md#examples) for typical situation like unescaping escape sequences in strings, building a generic [JSON](http://www.json.org/) data structure, and on-the-fly evaluation of arithmetic expressions. Through the use of template programming and template specialisations it is possible to write a grammar once, and use it in multiple ways with different (semantic) actions in different (or the same) parsing runs. With the PEG formalism, the separation into lexer and parser stages is usually dropped -- everything is done in a single grammar. The rules are expressed in C++ as template instantiations, and it is the compiler's task to optimise PEGTL grammars. ## Status 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/). 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). [Releases](https://github.com/taocpp/PEGTL/releases) are done in accordance with [Semantic Versioning](http://semver.org/). Incompatible API changes are *only* allowed to occur between major versions. ## Thank You In appreciation of all contributions here are the people that have [directly contributed](https://github.com/taocpp/PEGTL/graphs/contributors) to the PEGTL and/or its development. [amphaal](https://github.com/amphaal) [anand-bala](https://github.com/anand-bala) [andoma](https://github.com/andoma) [barbieri](https://github.com/barbieri) [bjoe](https://github.com/bjoe) [bwagner](https://github.com/bwagner) [cdiggins](https://github.com/cdiggins) [clausklein](https://github.com/clausklein) [delpinux](https://github.com/delpinux) [dkopecek](https://github.com/dkopecek) [gene-hightower](https://github.com/gene-hightower) [irrequietus](https://github.com/irrequietus) [jedelbo](https://github.com/jedelbo) [joelfrederico](https://github.com/joelfrederico) [johelegp](https://github.com/johelegp) [jovermann](https://github.com/jovermann) [jubnzv](https://github.com/jubnzv) [kelvinhammond](https://github.com/kelvinhammond) [kneth](https://github.com/kneth) [kuzmas](https://github.com/kuzmas) [lambdafu](https://github.com/lambdafu) [lichray](https://github.com/lichray) [michael-brade](https://github.com/michael-brade) [mkrupcale](https://github.com/mkrupcale) [newproggie](https://github.com/newproggie) [obiwahn](https://github.com/obiwahn) [ohanar](https://github.com/ohanar) [pauloscustodio](https://github.com/pauloscustodio) [pleroux0](https://github.com/pleroux0) [quadfault](https://github.com/quadfault) [quarticcat](https://github.com/quarticcat) [ras0219](https://github.com/ras0219) [redmercury](https://github.com/redmercury) [robertcampion](https://github.com/robertcampion) [samhocevar](https://github.com/samhocevar) [sanssecours](https://github.com/sanssecours) [sgbeal](https://github.com/sgbeal) [skyrich62](https://github.com/skyrich62) [studoot](https://github.com/studoot) [svenjo](https://github.com/svenjo) [wickedmic](https://github.com/wickedmic) [wravery](https://github.com/wravery) [zhihaoy](https://github.com/zhihaoy) ## The Art of C++ The PEGTL is part of [The Art of C++](https://taocpp.github.io/). [colinh](https://github.com/colinh) [d-frey](https://github.com/d-frey) [uilianries](https://github.com/uilianries) ## License Open Source Initiative The PEGTL is certified [Open Source](http://www.opensource.org/docs/definition.html) software. It may be used for any purpose, including commercial purposes, at absolutely no cost. It is distributed under the terms of the [MIT license](http://www.opensource.org/licenses/mit-license.html) reproduced here. > Copyright (c) 2007-2022 Dr. Colin Hirsch and Daniel Frey > > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: > > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tao-pegtl-3.2.7/doc/000077500000000000000000000000001426407250600141725ustar00rootroot00000000000000tao-pegtl-3.2.7/doc/Actions-and-States.md000066400000000000000000000772141426407250600201300ustar00rootroot00000000000000# Actions and States In its most simple form, a parsing run only returns whether (a portion of) the input matches the grammar. To actually do something useful during a parsing run it is necessary to attach (user-defined) *actions* to one or more grammar rules. Actions are essentially functions that are called during the parsing run whenever the rule they are attached to successfully matched. When an action is *applied*, the corresponding function receives the *states*, an arbitrary list of (user-defined) objects, as arguments. ## Contents * [Overview](#overview) * [Example](#example) * [States](#states) * [Apply](#apply) * [Apply0](#apply0) * [Inheriting](#inheriting) * [Specialising](#specialising) * [Changing Actions](#changing-actions) * [Via Rules](#via-rules) * [Via Actions](#via-actions) * [Changing States](#changing-states) * [Via Rules](#via-rules-1) * [Via Actions](#via-actions-1) * [Changing Actions and States](#changing-actions-and-states) * [Match](#match) * [Nothing](#nothing) * [Backtracking](#backtracking) * [Troubleshooting](#troubleshooting) * [Boolean Return](#boolean-return) * [State Mismatch](#state-mismatch) * [Legacy Actions](#legacy-actions) ## Overview Actions are implemented as static member functions called `apply()` or `apply0()` of specialisations of custom class templates (which is not quite as difficult as it sounds). States are additional function arguments to `tao::pegtl::parse()` that are forwarded to all actions. To use actions during a parsing run they first need to be implemented. * Define a custom action class template. * Specialise the action class template for every rule for which a function is to be called and * either implement an `apply()` or `apply0()` static member function, * or derive from a class that implements the desired function. The very first step, defining a custom action class template, usually looks like this. ```c++ template< typename Rule > struct my_action : tao::pegtl::nothing< Rule > {}; ``` Instantiations of the primary template for `my_action< Rule >` inherit from `tao::pegtl::nothing< Rule >` to indicate that, by default, neither `my_action< Rule >::apply()` nor `my_action< Rule >::apply0()` are to be called when `Rule` is successfully matched during a parsing run, or, in short, that no action is to be applied to `Rule`. You then specialise the action class template for those rules that you *do* want to call an action on. An example for a simple action for a specific state might look like this. ```c++ template<> struct my_action< my_rule > { template< typename ActionInput > static void apply( const ActionInput& in, my_state& s ) { // ... implement } }; ``` Then the parsing run needs to be set up with the actions and any required states. For this, the initial action can be passed as the second template parameter and the initial states can be passed as additional arguments to `tao::pegtl::parse()`. In order to manage the complexity in larger parsers and/or compose multiple grammars that each bring their own actions which in turn expect certain states, it can be useful to [change the actions](#changing-actions) and/or [change the states](#changing-states) within a parsing run. ## Example Here is a very short example that shows the basic way to put together a parsing run with actions and states. ```c++ // Define a simple grammar consisting of a single rule. struct my_grammar : tao::pegtl::star< tao::pegtl::any > {}; // Primary action class template. template< typename Rule > struct my_action : tao::pegtl::nothing< Rule > {}; // Specialise the action class template. template<> struct my_action< tao::pegtl::any > { // Implement an apply() function that will be called by // the PEGTL every time tao::pegtl::any matches during // the parsing run. template< typename ActionInput > static void apply( const ActionInput& in, std::string& out ) { // Get the portion of the original input that the // rule matched this time as string and append it // to the result string. out += in.string(); } }; template< typename ParseInput > std::string as_string( ParseInput& in ) { // Set up the states, here a single std::string as that is // what our action requires as additional function argument. std::string out; // Start the parsing run with our grammar, action and state. tao::pegtl::parse< my_grammar, my_action >( in, out ); // Do something with the result. return out; } ``` All together the `as_string()` function is a convoluted way of turning an [input](Inputs-and-Parsing.md) into a `std::string` byte-by-byte. In the following we will take a more in-depth look at states and `apply()` and `apply0()` before diving into more advanced subjects. ## States There is not much more to say about the states other than what has already been mentioned, namely that they are a list (colloquial list, not `std::list`) of objects that are * passed by the user as additional arguments to [`tao::pegtl::parse()`](Inputs-and-Parsing.md#parse-function), and then * passed by the PEGTL as additional arguments to all actions' `apply()` or `apply0()` static member functions. The additional arguments to `apply()` and `apply0()` can be chosen freely, however all actions must accept the same list of states since they are all called with the same arguments by default. States are not forwarded with "perfect forwarding" since r-value references don't make much sense when they will be used as action arguments many times. The `parse()` function still uses universal references to bind to the state arguments in order to allow temporary objects. ## Apply As seen above, the actual functions that are called when an action is applied are static member functions named `apply()` of the specialisations of the action class template. ```c++ template<> struct my_action< my_rule > { template< typename ActionInput > static void apply( const ActionInput& in, /* all the states */ ) { // Called whenever matching my_rule during a parsing run // succeeds (and actions are not disabled). The argument // named 'in' represents the matched part of the input. // Can also return bool instead of void. } } ``` The first argument is not the input used in the parsing run, but rather a separate object of distinct type that represents the portion of the input that the rule to which the action is attached just matched. The remaining arguments to `apply()` are the current state arguments. The exact type of the input class passed to `apply()` is not specified. It is best practice to "template over" the type of the input as shown above. Actions can then assume that the input provides (at least) the following interface. The `Input` template parameter is set to the class of the input used as input in the parsing run at the point where the action is applied. For illustrative purposes, we will assume that the input passed to `apply()` is of type `action_input`. Any resemblance to real classes is not a coincidence, see `include/tao/pegtl/internal/action_input.hpp`. ```c++ template< typename ParseInput > class action_input { public: using input_t = ParseInput; using iterator_t = typename ParseInput::iterator_t; bool empty() const noexcept; std::size_t size() const noexcept; const char* begin() const noexcept; // Non-owning pointer! const char* end() const noexcept; // Non-owning pointer! std::string string() const; // std::string( begin(), end() ) std::string_view string_view() const noexcept; // std::string_view( begin(), size() ) char peek_char( const std::size_t offset = 0 ) const noexcept; // begin()[ offset ] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept; // similar pegtl::position position() const noexcept; // Not efficient with tracking_mode::lazy. const ParseInput& input() const noexcept; const iterator_t& iterator() const noexcept; }; ``` Note that `input()` returns the input from the parsing run which will be at the position after what has just been parsed, i.e. for an action input `ai` the assertion `ai.end() == ai.input().current()` will always hold true. Conversely `iterator()` returns a pointer or iterator to the beginning of the action input's data, i.e. where the successful match attempt to the rule the action called with the action input is attached to started. More importantly the `action_input` does **not** own the data it points to, it belongs to the original input used in the parsing run. Therefore **the validity of the pointed-to data might not extend (much) beyond the call to `apply()`**! When the original input has tracking mode `eager`, the `iterator_t` returned by `action_input::iterator()` will contain the `byte`, `line` and `column` counters corresponding to the beginning of the matched input represented by the `action_input`. When the original input has tracking mode `lazy`, then `action_input::position()` is not efficient because it calculates the line number etc. by scanning the complete original input from the beginning Actions often need to store and/or reference portions of the input for after the parsing run, for example when an abstract syntax tree is generated. Some of the syntax tree nodes will contain portions of the input, for example for a variable name in a script language that needs to be stored in the syntax tree just as it occurs in the input data. The **default safe choice** is to copy the matched portions of the input data that are passed to an action by storing a deep copy of the data as `std::string`, as obtained by the input class' `string()` member function, in the data structures built while parsing. When the return type of an action, i.e. its `apply()`, is `bool`, it can retro-actively let the library consider the attempt to match the rule to which the action is attached a (local) failure. For the overall parsing run, there is no difference between a rule returning `false` and an attached action returning `false`, however the action is only called when the rule returned `true`. When an action returns `false`, the library rewinds the input to where it was when the rule to which the action was attached started its successful match. This is unlike `match()` static member functions that have to rewind the input themselves. ## Apply0 In cases where the matched part of the input is not required, an action can implement a static member function called `apply0()` instead of `apply()`. What changes is that `apply0()` will be called without an input as first argument, i.e. only with all the states. ```c++ template<> struct my_action< my_rule > { static void apply0( /* all the states */ ) { // Called whenever matching my_rule during a parsing run // succeeds (and actions are not disabled). Can also return // bool instead of void. } }; ``` Using `apply0()` is never necessary, it is "only" an optimisation with minor benefits at compile time, and potentially more noteworthy benefits at run time. We recommend implementing `apply0()` over `apply()` whenever both are viable. Though an infrequently used feature, `apply0()` can also return `bool` instead of `void`, just like `apply()` and with the same implications. ## Inheriting We will use an example to show how to use existing actions via inheritance. The grammar for this example consists of a couple of simple rules. ```c++ struct plain : tao::pegtl::utf8::range< 0x20, 0x10FFFF > {}; struct escaped : tao::pegtl::one< '\'', '"', '?', '\\', 'a', 'b', 'f', 'n', 'r', 't', 'v' > {}; struct character : tao::pegtl::if_must_else< tao::pegtl::one< '\\' >, escaped, plain > {}; struct text : tao::pegtl::must< tao::pegtl::star< character >, tao::pegtl::eof > {}; ``` Our goal is for a parsing run with the `text` rule to produce a copy of the input where the backslash escape sequences are replaced by the character they represent. When the `plain` rule matches, the bytes of the matched UTF-8-encoded code-point can be appended to the result. When the `escaped` rule matches, the bytes corresponding to the character represented by the escape sequence must be appended to the result. This can be achieved with appropriate specialisations of `my_action` using some [contrib](Contrib-and-Examples.md#contrib) classes from `tao/pegtl/contrib/unescape.hpp`. ```c++ template<> struct my_action< plain > : tao::pegtl::append_all {}; template<> struct my_action< escaped > : tao::pegtl::unescape_c< escaped, '\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v' > {}; ``` For step three the [input for the parsing run](Inputs-and-Parsing.md) is set up as usual. In addition, the actions are passed as second template parameter, and a `std::string` as second argument to `parse()`. Here `unescaped` is the state that is required by the `append_all` and `unescape_c` actions; all additional arguments passed to `parse()` are forwarded to all actions. ```c++ std::string unescape( const std::string& escaped ) { std::string unescaped; tao::pegtl::memory_input in( result, __FUNCTION__ ); tao::pegtl::parse< text, my_action >( in, unescaped ); return unescaped; } ``` At the end of the parsing run, the complete unescaped string can be found in the aptly named variable `unescaped`. A more complete example of how to unescape strings can be found in `src/example/pegtl/unescape.cpp`. ## Specialising The rule class for which an action class template is specialised *must* exactly match the definition of the rule in the grammar. For example consider the following rule. ```c++ struct foo : tao::pegtl::plus< tao::pegtl::alpha > {}; ``` Now an action class template can be specialised for `foo`, or for `tao::pegtl::alpha`, but *not* for `tao::pegtl::plus< tao::pegtl::alpha >`. This because base classes are not taken into consideration by the C++ language when choosing a specialisation, which might be surprising when being used to pointer arguments to functions where conversions from pointer-to-derived to pointer-to-base are performed implicitly and silently. So although the function called by the library to match `foo` is the inherited `tao::pegtl::plus< tao::pegtl::alpha >::match()`, the rule class is `foo` and the function known as `foo::match()`, wherefore an action needs to be specialised for `foo` instead of `tao::pegtl::plus< tao::pegtl::alpha >`. While it is possible to specialise the action class template for `tao::pegtl::alpha`, it might not be a good idea since the action would be applied for *all* occurrences of `tao::pegtl::alpha` in the grammar. To circumvent this issue a new name can be given to the `tao::pegtl::alpha`, a name that will not be "randomly" used in other places of the grammar. ```c++ struct bar : tao::pegtl::alpha {}; struct foo : tao::pegtl::plus< bar > {}; ``` Now an action class template can be specialised for `foo` and `bar`, but again *not* for `tao::pegtl::plus< bar >` or `tao::pegtl::alpha`. More precisely, it could be specialised for the latter two rules, but wouldn't ever be called unless these rules were used elsewhere in the grammar, a different kettle of fish. Note that this is also the reason why you should **not** use type aliases instead of inheritance when defining your grammars. ## Changing Actions The action class template can be changed, and actions enabled or disabled, in ways beyond supplying, or not, an action to `tao::pegtl::parse()` at the start of a parsing run. ### Via Rules The [`tao::pegtl::enable<>`](Rule-Reference.md#enable-r-) and [`tao::pegtl::disable<>`](Rule-Reference.md#disable-r-) rules behave just like [`seq<>`](Rule-Reference.md#seq-r-) but, without touching the current action, enable or disable calling of actions within their sub-rules, respectively. The [`tao::pegtl::action<>`](Rule-Reference.md#action-a-r-) rule also behaves similarly to [`seq<>`](Rule-Reference.md#seq-r-) but takes an action class template as first template parameter and, without enabling or disabling actions, uses its first template parameter as action for the sub-rules. The following two lines effectively do the same thing, namely parse with `my_grammar` as top-level parsing rule without invoking actions (unless actions are enabled again somewhere else). ```c++ tao::pegtl::parse< my_grammar >( ... ); tao::pegtl::parse< tao::pegtl::disable< my_grammar >, my_action >( ... ); ``` Similarly the following two lines both start parsing `my_grammar` with `my_action` (again only unless something changes somewhere else). ```c++ tao::pegtl::parse< my_grammar, my_action >( ... ); tao::pegtl::parse< tao::pegtl::action< my_action, my_grammar > >( ... ); ``` User-defined parsing rules can use `action<>`, `enable<>` and `disable<>` just like any other combinator rules. For example to disable actions in LISP-style comments the following rule could be used as per `src/example/pegtl/s_expression.cpp`. ```c++ struct comment : tao::pegtl::seq< tao::pegtl::one< '#' >, tao::pegtl::disable< cons_list > > {}; ``` The ability to change the actions during a parsing run also allows using the same rules multiple times with different action class templates within a grammar. ### Via Actions The action classes `tao::pegtl::disable_action` and `tao::pegtl::enable_action` can be used to disable and enable actions, respectively, for any rule (and its sub-rules). For example actions can be disabled for `my_rule` in a parsing run using `my_action` as follows. ```c++ template<> struct my_action< my_rule > : tao::pegtl::disable_action {}; 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. 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. ## Changing States The states, too, can be changed in ways beyond supplying them, or not, to `tao::pegtl::parse()` at the start of a parsing run. ### Via Rules The [`state` rule](Rule-Reference.md#state-s-r-) behaves similarly to [`seq`](Rule-Reference.md#seq-r-) but uses the first template parameter as type of a new object. This new object is used replaces the current state(s) for the remainder of the implicit [`seq`](Rule-Reference.md#seq-r-). The new object is constructed with a const-reference to the current input of the parsing run, and all previous states, if any, as arguments. If no such constructor exists, the new object is default constructed. If the implicit [`seq`](Rule-Reference.md#seq-r-) of the sub-rules succeeds, then, by default, a member function named `success()` is called on this "new" object, receiving the same arguments as the constructor. At this point the input will be advanced by whatever the sub-rules have consumed in the meantime. Please consult `include/tao/pegtl/internal/state.hpp` to see how the default behaviour on success can be changed by overriding `tao::pegtl::state<>::success()` in a derived class when using that class instead. Embedding a state change into the grammar with [`state<>`](Rule-Reference.md#state-s-r-) is only recommended when some state is used by custom parsing rules. ### Via Actions The actions `tao::pegtl::change_state<>` and `tao::pegtl::change_states<>` can be used to change from the current to a new set of states while parsing the rules they are attached to. The differences are summarised in this table; note that `change_state` is more similar to the legacy `change_state` control class as included with the 2.z versions of the PEGTL. | Feature | `change_state` | `change_states` | | --- | --- | --- | | Number of new states | one | any | | Construction of new states | optionally with input and old states | default | | Success function on action | if not on new state | required | With `change_state` only a single new state type can be given as template parameter, and only a single new state will be created. The constructor of the new state receives the same arguments as per `tao::pegtl::state<>`, the current input from the parsing run and all previous states. A `success()` static member function is supplied that calls the `success()` member function on the new state, again with the current input from the parsing run and all previous states. The supplied `success()` can of course be overridden in a derived class. With `change_states`, being a variadic template, any number of new state types can be given and an appropriate set of new states will be created (nearly) simultaneously. All new states are default-constructed, if something else is required the reader is encouraged to copy and modify the implementation of `change_states` in their project. The user *must* implement a custom `success()` static member function that takes the current input from the parsing run, the new states, and the old states as arguments. Note that, *unlike* the `tao::pegtl::state<>` combinator, the success functions are *only called when actions are currently enabled*! Using the changing actions is again done via inheritance as shown in the following example for `change_states`. ```c++ template<> struct my_action< my_rule > : tao::pegtl::change_states< new_state_1, new_state_2 > { template< typename ParseInput > static void success( const ParseInput&, new_state_1&, new_state_2&, /* the previous states*/ ) { // Do whatever with both the new and the old states... } }; ``` For a more complete example of how to build a generic JSON data structure with `change_state` and friends see `src/example/pegtl/json_build.cpp`. ## Changing Actions and States The actions `change_action_and_state<>` and `change_action_and_states<>` combine `change_action` with one of the `change_state<>` or `change_states<>` actions, respectively. For `change_action_and_state<>` and `change_action_and_states<>` the new action class template is passed as first template parameter as for `change_action`, followed by the new state(s) as given to `change_state<>` and `change_states<>`. Note that `change_action_and_state<>` and `change_action_and_states<>` behave like `change_action<>` in that they proceed to match the rule to which the changing action is attached to "as if" the new action had been the current action all along. ## Match Besides `apply()` and `apply0()`, an action class specialization can also have a `match()` static member function. The default control class template `normal` will detect the presence of a suitable `match()` function and call this function instead of `tao::pegtl::match()`. ```c++ template<> struct my_action< my_rule > { template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... st ) { // Call the function that would have been called otherwise, // in this case without changing anything... return tao::pegtl::match< Rule, A, M, Action, Control >( in, st... ); } } ``` Implementing a custom `match()` for an action is considered a rather advanced feature that is not used directly very often. All "changing" action classes mentioned in this document are implemented as actions with `match()`. Their implementations can be found in `` and should be studied before implementing a custom action with `match()`. ## Nothing Letting the primary template of an action class template derive from `tao::pegtl::nothing` is recommended, but not necessary. When using `nothing`, some assertions are enabled that are usually very helpful while developing a parser. When not using `nothing`, simply by never mentioning it (as base class), these assertions are disabled and it is possible for an action's `apply()` or `apply0()` implementation to be silently ignored. In the following let `a` be an action template class, i.e. the instantiation of an action class template `action` for some rule `r`, or `using a = action< r >` for short. We say that `apply()` is *callable* when it is the name of a static member function of `a` that returns either `void` or `bool` and can be called with an input and the current states. We say that `apply0()` is *callable* when it is the name of a static member function of `a` that returns either `void` or `bool` and can be called with the current states. The following assertions are always enabled. * There must be at most one callable `apply` or `apply0()` in `a`. * If `nothing< r >` is an accessible base class of `a` then `a` must not have a callable `apply()`. * If `nothing< r >` is an accessible base class of `a` then `a` must not have a callable `apply0()`. * If `require_apply` is an accessible base class of `a` then it must have a callable `apply()`. * If `require_apply0` is an accessible base class of `a` then it must have a callable `apply0()`. The classes `require_apply` and `require_apply0` are also explained in [the State Mismatch section](#state-mismatch). The following assertion is only enabled when `std::is_base_of_v< tao::pegtl::nothing< void >, action< void > >` is `true`. * Either `nothing` must be an accessible base class of `a`, or * `maybe_nothing` must be an accessible base class of `a`, or * `a` must have a callable `apply()` or `apply0()`. The class `tao::pegtl::maybe_nothing` is an accessible base class of all the changing actions explained above. This make is possible, but not necessary, to implement `apply()` or `apply0()` for actions derived from them. Note that `maybe_nothing` can be combined, through multiple inheritance, with one of `nothing< r >`, `require_apply` or `require_apply0`. For example when a class `b` is derived from `change_state`, it also gains that class' `maybe_nothing` as accessible base class. At this point `b` is allowed to either have or not have an `apply()` or `apply0()`. By letting `b` also derive from one of the three mentioned classes, the `maybe_nothing` will be ignored and `b` will be checked to have or not have the functions as dictated by the respective additional base class. ## Backtracking Sometimes there can be *backtracking* during a parsing run which can lead to Actions being called in places where their effects are undesired. While it might be intuitively clear what backtracking is, for the purpose of the following discussion we give a slightly more formal definition. We speak of *backtracking* across a rule `S` when there is a rule `R` of which `S` is a (direct or indirect) sub-rule and during a parsing run 1. `R` returns local failure after 2. `S` succeeded and its success is a requirement for the success of `R` and 3. it is "still possible" for the top-level grammar rule of the parsing run to succeed. In this case the input will have been rewound to the point at which `R` was attempted to match and all effects of `S` on the Input will have been undone, however, and this is the subject of this section, any action attached to `S` will have been already performed without there being an automatic "undo". #### The AAC-Problem In some cases it is easy to rewrite the grammar in a way that prevents backtracking. This simultaneously removes the issue of having to undo actions and improves parsing performance. The prototypical case for which such a rewrite can be done is `R = sor< seq< A, B >, seq< A, C > >` where `A`, `B` and `C` are arbitrary rules. If during a parsing run there are actions attached to `A` and `C`, and the input matches `seq< A, C >` but not `seq< A, B >`, then the action for `A` will be called *twice* before the action for `C`, which gives this problem its "AAC" name, given that what happens is: * Begin `sor< seq< A, B >, seq< A, C > >` * Begin `seq< A, B >` * Begin `A` * Success `A` with action called * Begin `B` * Failure `B` * Failure `seq< A, B >` * Begin `seq< A, C >` * Begin `A` at the same position as the begin `A` above * Success `A` with action called again on the same input * Begin `C` * Success `C` * Success `seq< A, C >` * Success `sor< seq< A, B >, seq< A, C > >` #### Rewriting In practice the structure of the rule might be more complicated than the pure AAC-problem which will make it harder to recognise the pattern. One solution is to rewrite `R` as `R' = seq< A, sor< B, C > >` where of course any action for `A` will be called at most once for every successful match of `R'`. #### Manual Undo Another solution is to undo the effects of the Action attached to `A` in case the encompassing `seq< A, B >` (or `seq< A, C >`) fail. The advantage of this approach is that the implementation of the Action for `A` can pretend that is only called when really needed. The disadvantage is that there is no function on the Action that is called in the case of failure which requires the user to either write a custom `match()` function in the Action for `seq< A, B >` or to implement the `failure()` function in a custom [Control class](Control-and-Debug.md). #### Manual Commit A further solution is to let the Action for `A` perform its job "to the side", and only "commit" the effects to the target data structure in the Action for `seq< A, B >`. For example if the Action attached to `A` takes the matched portion of the Input as `std::string` and appends it to `std::vector< std::string >` one could change said Action for `A` to only fill some temporary string in one of the States, and create an Action for `seq< A, B >` that, after it is called on success of that rule, appends the aforementioned temporary string to the target vector. #### Looking Ahead When everything else fails and a quick-and-dirty solution to Actions being called too often in the presence of backtracking is required and/or performance is not of prime importance it is relatively easy to solve the problem by employing the infinite look-ahead capability of PEGs. When backtracking across `S` is a problem because an Action attached to `S` can be called when `S` succeeds even though there is a higher-up rule `R` that can still fail then simply replace `R` with `seq< at< R >, R >` in the grammar. Remembering that `at` disables all Actions explains how this solves the problem; we first verify without Actions that `R` will indeed match at this point and only then match `R` again with Actions enabled. ## Troubleshooting The following lists a couple of frequently encountered Action-related errors and how to fix them. ### Boolean Return Actions returning `bool` are an advanced use case that should be used with caution. They prevent some internal optimisations, in particular when used with `apply0()`. They can also have weird effects on the semantics of a parsing run, for example `at< rule >` can succeed for the same input for which `rule` fails when there is a `bool`-action attached to `rule` that returns `false` (remember that actions are disabled within `at<>`). ### State Mismatch When an action's `apply()` or `apply0()` expects different states than those present in the parsing run there will either be a possibly not very helpful compiler error, or it will compile without a call to the action, depending on whether `tao::pegtl::nothing<>` is used as base class of the primary action class template. By deriving an action specialisation from either `tao::pegtl::require_apply` or `tao::pegtl::require_apply0`, as appropriate, a -- potentially more helpful -- compiler error can be provoked, so when the grammar contains `my_rule` and the action is `my_action` then silently compiling without a call to `apply0()` is no longer possible. ```c++ template<> struct my_action< my_rule > : require_apply0 { static void apply0( double ) { // ... } } ``` Note that deriving from `require_apply` or `require_apply0` is optional and usually only used for troubleshooting. ## Legacy Actions See the [section on legacy-style action rules](Rule-Reference.md#action-rules). Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Changelog.md000066400000000000000000000756241426407250600164210ustar00rootroot00000000000000# Changelog ## 3.2.7 Released 2022-07-14 * Removed superfluous deprecated include. ## 3.2.6 Released 2022-06-29 * Made `unwind()` optional for parse tree nodes. * Fixed `demangle()` for MSVC, again. * Fixed `demangle()` for GCC 12. ## 3.2.5 Released 2022-02-05 * Added missing include for fallback `demangle()` implementations. ## 3.2.4 Released 2022-02-03 * Fixed `version.hpp`. ## 3.2.3 Released 2022-02-03 * Fixed `static_assert` in `demangle()` with recent MSVC. ## 3.2.2 Released 2021-10-22 * Added rule [`odigit`](Rule-Reference.md#odigit) for octal digits. * Enabled default-constructed state in `state<>`, `change_state<>`, and `change_action_and_state<>`. * Changed rules in [`tao/pegtl/contrib/integer.hpp`](Contrib-and-Examples.md#taopegtlcontribintegerhpp) to not throw by default. * Added [`tao/pegtl/contrib/separated_seq.hpp`](Contrib-and-Examples.md#taopegtlcontribseparated_seqhpp). * Added `tao/pegtl/contrib/iri.hpp` grammar for IRIs. * Added `tao/pegtl/contrib/proto3.hpp` grammar for protocol buffer v3. ## 3.2.1 Released 2021-07-31 * Added an optional limiter to guard against infinite recursion. * Fixed CMake export error. * Improved compile time efficiency. ## 3.2.0 Released 2021-01-15 * Added support for disabling exceptions with [`-fno-exceptions`](Installing-and-Using.md#disabling-exceptions). * Improved efficiency of parse tree nodes. * Fixed namespace issue with `tao::pegtl::demangle()` (was: `tao::demangle()`). ## 3.1.0 Released 2020-12-17 * Made `analyze()` more verbose by default to aid finding the rule cycles. * Added `parse_nested()` overload that accepts a `position` as first argument. * Added some experimental and undocumented `contrib` features and their infrastructure. * Improved CMake support for [``](Installing-and-Using.md#filesystem) fallbacks and alternatives. * Re-enabled support for GCC 7. * Automatically link with `libstdc++fs` or `libc++fs` as needed. * Added automatic fallback from `std::filesystem` to `std::experimental::filesystem`. * Added manual fallback from `std::filesystem` to `boost::filesystem`. * Thank you [Beman Dawes](https://isocpp.org/blog/2020/12/remembering-beman-dawes)! * Converted continuous integration infrastructure to GitHub Actions. ## 3.0.0 Released 2020-11-28 * Use the [**migration guide**](Migration-Guide.md#version-300) when updating. * Infrastructure * Updated required C++ standard to C++17. * Updated required [CMake](https://cmake.org/) version to 3.8. * The macro `TAO_PEGTL_NAMESPACE` now contains the fully qualified namespace, e.g. `tao::pegtl`. * Added `[[nodiscard]]` or `[[noreturn]]` to most non-void functions. * Meta-Data Layer * Replaced `analysis_t` with more general and complete `rule_t` and `subs_t`. * Added functions to visit all rules of a grammar. * Added functions to measure rule coverage of a parsing run. * Moved the analysis function and header to contrib. * Error Handling * Replaced `tao::pegtl::input_error` with `std::system_error` and `std::filesystem::filesystem_error`. * Added [`must_if<>`](Errors-and-Exceptions.md#custom-exception-messages) * Allows to define custom error messages for global errors. * Adds a non-intrusive way to define global parse errors for a grammar retroactively. * Demangling * Removed the need for RTTI. * Some broken/unknown compilers will use RTTI as a fallback, without demangling. * Moved `tao::pegtl::internal::demangle()` to `tao::demangle()`. * Improved generated code to be shorter and more efficient. * Parse Tree * Removed the need for RTTI. * Other * Changed `std::string` to `std::filesystem::path` for filename parameters. * Renamed `byte_in_line` to `column` and use 1-based counting. * Moved rule `eolf` from inline namespace `tao::pegtl::ascii` to `tao::pegtl`. * Changed rules in `tao/pegtl/contrib/integer.hpp` to not accept redundant leading zeros. * Added rules to `tao/pegtl/contrib/integer.hpp` that test unsigned values against a maximum. * Demoted UTF-16 and UTF-32 support to contrib. * Demoted UINT-8, UINT-16, UINT-32 and UINT-64 support to contrib. * Folded `contrib/counter.hpp` into `json_count.cpp`, count is superceded by coverage. * Removed right padding from `contrib/json.hpp`'s `value`. * Cleanup * Removed option of [state](Rule-Reference.md#state-s-r-)'s `S::success()` to have an extended signature to get access to the current `apply_mode`, `rewind_mode`, *action*- and *control* class (template). * Removed compatibility macros starting with `TAOCPP_PEGTL_`. * Removed compatibility uppercase enumerators. * Removed compatibility `peek_byte()` member functions. * Removed compatibility header `changes.hpp` from contrib. ## 2.8.3 Released 2020-04-22 * Fixed excessive read-ahead with incremental inputs. * Added state manipulators `remove_first_state`, `remove_last_states`, `rotate_states_right`, `rotate_states_left`, and `reverse_states` to contrib. * Reduced the number of intermediate parse tree nodes. ## 2.8.2 Released 2020-04-05 * Fixed parse tree node generation to correctly remove intermediate nodes. ## 2.8.1 Released 2019-08-06 * Added fallback symbol demangling if RTTI is disabled. * Fixed missing `string_input<>` in amalgamated header. * Fixed `discard_input*` actions to properly forward the apply mode. * Fixed contrib HTTP grammar for chunked data. ## 2.8.0 Released 2019-04-09 * Use the [**migration guide**](Migration-Guide.md#version-280) when updating. * Changed enumerators to lowercase. * Renamed `tracking_mode::IMMEDIATE` to `tracking_mode::eager`. * Compatibility enumerators with uppercase names are still included. * Will be removed in version 3.0.0. * Renamed `peek_byte()` to `peek_uint8()`. * Compatibility member functions with previous names are still included. * Will be removed in version 3.0.0. * Allowed actions to implement `match`. * Made deriving action class templates from `nothing` optional. * Added debug tools `require_apply` and `require_apply0`. * Added combinator class [`rematch`](Rule-Reference.md#rematch-r-s-). * Improved the [Parse Tree / AST interface](Parse-Tree.md) to mostly hide its internal state. * Added new action-based helpers `change_*.hpp`. * The control-based helpers in `contrib/changes.hpp` are still included. * Will be removed in version 3.0.0. * Added new action-based helpers `disable_action.hpp` and `enable_action.hpp`. * Added new action-based helpers `discard_input.hpp`, `discard_input_on_success.hpp`, and `discard_input_on_failure.hpp`. * Added [Clang Static Analyzer](https://clang-analyzer.llvm.org/) to the CI build. * Added new Makefile target `amalgamate` to generate a single-header version of the PEGTL. * Added support for [Universal Windows Platform (UWP)](https://en.wikipedia.org/wiki/Universal_Windows_Platform). ## 2.7.1 Released 2018-09-29 * Added new ASCII convenience rule [`forty_two`](Rule-Reference.md#forty_two-c-). * Added experimental `if_then` rule. * Simplified how parse tree nodes can be selected. * Reduced the number of intermediate parse tree nodes. * Allowed an action class template to be used with the parse tree. ## 2.7.0 Released 2018-07-31 * Added [`mmap_file<>`](Inputs-and-Parsing.md#file-input) support for Windows. * Added [deduction guides](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction) for the input classes when compiling with C++17. ## 2.6.1 Released 2018-07-22 * Fixed endianness detection in test program. ## 2.6.0 Released 2018-06-22 * Added [Conan](https://conan.io/) [packages](https://bintray.com/taocpp/public-conan/pegtl%3Ataocpp/). * Fixed the UTF-8 decoder to no longer accept UTF-16 surrogates. * Fixed the UTF-16 decoder to no longer accept UTF-16 unmatched surrogates. * Fixed the UTF-32 "decoder" to no longer accept UTF-16 surrogates. * Fixed `pegtl/contrib/unescape.hh` to no longer accept unmatched surrogates. * Optimised convenience rule [`two`](Rule-Reference.md#two-c-). * Added new convenience rule [`three`](Rule-Reference.md#three-c-). ## 2.5.2 Released 2018-05-31 * Fixed [`opt`](Rule-Reference.md#opt-r-) and [`until`](Rule-Reference.md#until-r-s-) to work as documented in some rare edge cases. * Used [`opt_must`](Rule-Reference.md#opt_must-r-s-) and [`star_must`](Rule-Reference.md#star_must-r-s-) to optimise some included grammars. ## 2.5.1 Released 2018-05-14 * Added new convenience rule [`opt_must`](Rule-Reference.md#opt_must-r-s-). * Optimised convenience rule [`if_must`](Rule-Reference.md#if_must-r-s-). * Fixed examples to compile with Visual Studio and MinGW. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with GCC 8. ## 2.5.0 Released 2018-05-01 * Added rules to match Unicode properties via [ICU](http://site.icu-project.org) to contrib. * Improved the [Parse Tree / AST interface](Parse-Tree.md). * Fixed parse tree node generation to correctly remove intermediate nodes. * Added big- and little-endian support to the UTF-16 and UTF-32 rules. * Added rules for UINT-8 and big- and little-endian UINT-16, UINT-32 and UINT-64. * Added member functions to `memory_input<>` to obtain the line around a position. * Added member functions to `memory_input<>` to start again from the beginning. * Added example for Python-style indentation-aware grammars. * Added examples for regular, context-free, and context-sensitive grammars. * Added example for how to parse with a symbol table. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with Clang 6. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with Clang's `-fms-extensions`. * Fixed build with Clang when `-fms-extensions` is used (`clang-cl`). ## 2.4.0 Released 2018-02-17 * Use the [**migration guide**](Migration-Guide.md#version-240) when updating. * Improved and documented the [Parse Tree / AST support](Parse-Tree.md). * Changed prefix of all macros from `TAOCPP_PEGTL_` to `TAO_PEGTL_`. * Compatibility macros with the old names are provided. * They will be removed in version 3.0.0. * Added a deleted overload to prevent creating a `memory_input<>` from a temporary `std::string`. ## 2.3.4 Released 2018-02-08 * Fixed build on older systems where `O_CLOEXEC` is not available. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with Android 6.0 and 7.0. ## 2.3.3 Released 2018-01-01 * Added more `noexcept`-specifications. * Fixed most `clang-tidy`-issues. ## 2.3.2 Released 2017-12-16 * Worked around a Visual Studio 15.5 bug. ## 2.3.1 Released 2017-12-14 * Fixed linkage of `tao::pegtl::internal::file_open`. * Improved error message for missing `source` parameter of `string_input<>`. ## 2.3.0 Released 2017-12-11 * Added constructor to `read_input<>` that accepts a `FILE*`, see issue [#78](https://github.com/taocpp/PEGTL/issues/78). * Enhanced [`apply`](Rule-Reference.md#apply-a-), [`apply0`](Rule-Reference.md#apply0-a-) and [`if_apply`](Rule-Reference.md#if_apply-r-a-) to support `apply()`/`apply0()` returning boolean values. * Simplified implementation of [`raw_string`](Contrib-and-Examples.md#taopegtlcontribraw_stringhpp), the optional `Contents...` rules' `apply()`/`apply0()` are now called with the original states. * Fixed the tracer to work with `apply()`/`apply0()` returning boolean values. * Fixed, simplified and improved [`examples/parse_tree.cpp`](Contrib-and-Examples.md#srcexamplepegtlparse_treecpp). ## 2.2.2 Released 2017-11-22 * Bumped version. ## 2.2.1 Released 2017-11-22 * Celebrating the PEGTL's 10th anniversary! * Fixed missing call to the [control class'](Control-and-Debug.md#control-functions) `failure()` when a rule with `apply()` with a boolean return type fails. * Fixed string handling in [`examples/abnf2pegtl.cc`](Contrib-and-Examples.md#srcexamplepegtlabnf2pegtlcpp). * Simplified/improved Android build. ## 2.2.0 Released 2017-09-24 * Added possibility for an action's `apply()` or `apply0()` to return `bool` which is then used to determine overall success or failure of the rule to which such an action was attached. * Added [``](Contrib-and-Examples.md#taopegtlcontribparse_treehpp) and the [`examples/parse_tree.cpp`](Contrib-and-Examples.md#srcexamplepegtlparse_treecpp) application that shows how to build a [parse tree](https://en.wikipedia.org/wiki/Parse_tree). The example goes beyond a traditional parse tree and demonstrates how to select which nodes to include in the parse tree and how to transform the nodes into an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)-like structure. * Added `bom` rules for UTF-8, UTF-16 and UTF-32. * Added some missing includes for `config.hpp`. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with Clang 5. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with Xcode 9. ## 2.1.4 Released 2017-06-27 * Fixed shadow warning. ## 2.1.3 Released 2017-06-27 * Fixed [`raw_string`](Contrib-and-Examples.md#taopegtlcontribraw_stringhpp) with optional parameters. ## 2.1.2 Released 2017-06-25 * Bumped version. ## 2.1.1 Released 2017-06-25 * Fixed build with MinGW on Windows. * Added [automated testing](https://ci.appveyor.com/project/taocpp/PEGTL) with MinGW. ## 2.1.0 Released 2017-06-23 * Added optional template parameters to [`raw_string`](Contrib-and-Examples.md#taopegtlcontribraw_stringhpp) for rules that the content must match. * Added new contrib rules [`rep_one_min_max`](Contrib-and-Examples.md#taopegtlcontribrep_one_min_maxhpp) and `ellipsis`. * Fixed broken [`TAOCPP_PEGTL_KEYWORD`](Rule-Reference.md#tao_pegtl_keyword--) macro. * Fixed a bug in the contrib HTTP grammar which prevented it from parsing status lines in some cases. * Fixed build with MinGW-w64 on Windows. * Added [automated testing](https://ci.appveyor.com/project/taocpp/PEGTL) with MinGW-w64. * Added [automated testing](https://travis-ci.org/taocpp/PEGTL) with GCC 7. ## 2.0.0 Released 2017-05-18 * Project * Migrated to ["The Art of C++"](https://github.com/taocpp). * Use the [**migration guide**](Migration-Guide.md#version-200) when updating. * Version 2.z can be installed and used in parallel to version 1.y of the PEGTL. * The semantics of all parsing rules and grammars is the same as for versions 1.y. * Input Layer * Added support for custom [incremental input](Inputs-and-Parsing.md#incremental-input) readers. * Added support for parsing [C streams](Inputs-and-Parsing.md#stream-inputs), i.e. `std::FILE*`. * Added support for parsing [C++ streams](Inputs-and-Parsing.md#stream-inputs), i.e. `std::istream`. * Added support for different [EOL-styles](Inputs-and-Parsing.md#line-ending). * Renamed class `position_info` to `position`. * Added the byte position to input classes and `position`. * Added [fast parsing without line counting](Inputs-and-Parsing.md#tracking-mode) (except in errors). * Refactored the `input` class into multiple input classes. * Refactored the file parser classes into [input classes](Inputs-and-Parsing.md#file-input). * Refactored the handling of [nested parsing](Inputs-and-Parsing.md#nested-parsing). * Removed the `begin()` member from class `position`. * Removed most [parsing front-end functions](Inputs-and-Parsing.md#parse-function). * Parsing Rules * Added combinator class [`minus`](Rule-Reference.md#minus-m-s-). * Added ASCII rule class [`keyword`](Rule-Reference.md#keyword-c--). * Added [`string`](Rule-Reference.md#string-c--1) rules for UTF-8, UTF-16 and UTF-32. * Added [`apply`](Rule-Reference.md#apply-a-), [`apply0`](Rule-Reference.md#apply0-a-) and [`if_apply`](Rule-Reference.md#if_apply-r-a-) rules for intrusive actions. * Added incremental input support rules [`discard`](Rule-Reference.md#discard) and [`require`](Rule-Reference.md#require-num-). * String Macros * Renamed to [`TAOCPP_PEGTL_(I)STRING`](Rule-Reference.md#tao_pegtl_istring--). * Increased allowed string length to 512. * Allowed embedded null bytes. * Reduced template instantiation depth. * Other Changes * Added `apply()` and `apply0()` to the [control class](Control-and-Debug.md#control-functions). * Optimised superfluous input markers. * Allowed optimisation of [actions that do not need the input](Actions-and-States.md#apply0). * Replaced layered matching with superior Duseltronik™. * Reduced template instantiation depth. * Added support for [CMake](https://cmake.org/). * Added [automated testing](https://ci.appveyor.com/project/taocpp/PEGTL) with Visual Studio 2015 and 2017. * Added automated testing with Android 5.1, NDK r10e. ## 1.3.1 Released 2016-04-06 * Fixed unit test to use `eol` instead of hard-coded line ending. ## 1.3.0 Released 2016-04-06 * Tentative Android compatibility. * Fixed build with MinGW on Windows. * Changed file reader to open files in binary mode. * Changed `eol` and `eolf` to accept both Unix and MS-DOS line endings. * Optimised bumping the input forward and removed little used bump function. * Simplified grammar analysis algorithm (and more `analyze()` tests). ## 1.2.2 Released 2015-11-12 * Improved the JSON grammar and JSON string escaping. * Added JSON test suite from http://json.org/JSON_checker/. * Optimised bumping the input forward and string unescaping. * Promoted `examples/json_changes.hh` to `pegtl/contrib/changes.hh`. ## 1.2.1 Released 2015-09-21 * Added `file_parser` as alias for `mmap_parser` or `read_parser` depending on availability of the former. * Added Clang 3.7 to the automated tests. * Added Mac OS X with Xcode 6 and Xcode 7 to the automated tests. * Added coverage test and improved test coverage to 100%. * Fixed state changing bug in `json_build_one` example. ## 1.2.0 Released 2015-08-23 * Added [`pegtl_string_t`](Rule-Reference.md#tao_pegtl_string--) and [`pegtl_istring_t`](Rule-Reference.md#tao_pegtl_istring--) to simplify string definitions as follows: ```c++ pegtl::string< 'h', 'e', 'l', 'l', 'o' > // Normal pegtl_string_t( "hello" ) // New shortcut ``` * Added [`examples/abnf2pegtl.cc`](Contrib-and-Examples.md#srcexamplepegtlabnf2pegtlcpp) application that converts grammars based on [ABNF (RFC 5234)](https://tools.ietf.org/html/rfc5234) into a PEGTL C++ grammar. * Added [`contrib/alphabet.hh`](Contrib-and-Examples.md#taopegtlcontribalphabethpp) with integer constants for alphabetic ASCII letters. ## 1.1.0 Released 2015-07-31 * Renamed namespace `pegtl::ucs4` to `pegtl::utf32` and generally adopted UTF-32 in all naming. * Added experimental support for UTF-16 similar to the previously existing UTF-32 parsing rules. * Added support for merging escaped UTF-16 surrogate pairs to `pegtl/contrib/unescape.hh`. * Fixed incorrect handling of escaped UTF-16 surrogate pairs in the JSON examples. * A [state](Rule-Reference.md#state-s-r-)'s `S::success()` can now have an extended signature to get access to the current `apply_mode`, *action*- and *control* class (template). * The `contrib/raw_string` class template now calls `Action::content>::apply()` with the user's state(s). ## 1.0.0 Released 2015-03-29 Version 1.0.0 was a very large refactoring based on the previous years of experience. The core design and approach were kept, but nearly all details of the implementation were changed, and some parts were added to, or removed from, the library. Semantic versioning was introduced with version 1.0.0. * Deprecated old site on Google code and published new version on GitHub. * Removed the semi-automatic pretty-printing of grammar rules; now the class names are used, when possible demangled. * Renamed rule classes with multiple words in their names to use underscores, e.g. `ifmust<>` is now `if_must<>`. * Removed support for incremental/stream parsing to allow for some simplifications and optimisations (*reintroduced in 2.0.0*). * Removed the rules `apply<>` and `if_apply<>` that were used to directly call actions from within the grammar (*reintroduced in 2.0.0*), and: * Where the other method of attaching actions to rules in PEGTL 0.x required specialisation of a given class template `action<>`, in PEGTL 1.y the action class template can be chosen by the user and changed at any point in the grammar. * As a side-effect there is a much cleaner way of enabling and disabling actions in a portion of the grammar. * Actions now have access to the current position in the input, i.e. to the filename, and line and column number. * Actions now receive a pointer to, and the size of, the matched portion of the input (previously a `std::string` with a copy of the matched data), therefore: * ~~There is no distinction between actions that require access to the matched data and those that don't, furthermore~~: * The object via which actions gain access to the matched data is similar to that which rules receive ~~so actions can easily invoke another grammar on the matched data.~~ * The `at<>` and `not_at<>` rules now call their subordinate rules with actions disabled. * The variadic `states...` arguments that are passed through all rule invocations for use by the actions are *not* forwarded with `std::forward<>` anymore since it (usually) doesn't make much sense to move them, and accidentially moving multiple times was a possible error scenario. * There are now five different `rep` rules for repeating a sequence of rules with more control over the acceptable or required number of repetitions. * There are new rules `try_catch<>` and `try_catch_type<>` that convert global errors, i.e. exceptions, into local errors, i.e. a return value of `false`. * Unified concept for actions and debug hooks, i.e. just like the actions are called from a class template that is passed into the top-level `parse()` function, there is another class template that is called for debug/trace and error throwing purposes; both can be changed at any point within the grammar. * A large under-the-hood reorganisation has the benefit of preventing actions from being invoked on rules that are implementation details of other rules, e.g. the `pad< Rule, Padding >` rule contains `star< Padding >` in its implementation, so a specialisation of the action-class-template for `star< Padding >` would be called within `pad<>`, even though the `star< Pad >` was not explicitly written by the user; in PEGTL 1.y these unintended action invocations no longer occur. * Partial support for Unicode has been added in the form of some basic rules like `one<>` and `range<>` also being supplied in a UTF-8 (and experimental UTF-16 and UTF-32) aware version(s) that can correctly process arbitrary code points from `0` to `0x10ffff`. * The supplied input classes work together with the supplied exception throwing to support better error locations when performing nested file parsing, i.e. a `parse_error` contains a vector of parse positions. * Added a function to analyse a grammar for the presence of infinite loops, i.e. cycles in the rules that do not (necessarily) consume any input like left recursion. * As actions are applied to a grammar in a non-invasive way, several common grammars were added to the PEGTL as documented in [Contrib and Examples](Contrib-and-Examples.md). * The `list<>`-rule was replaced by a set of new list rules with different padding semantics. * The `at_one<>` and other rules `foo` that are merely shortcuts for `at< foo >` were removed. * The `if_then<>` rule was removed. * The `error_mode` flag was removed. * The semantics of the `must<>` rules was changed to convert local failure to global failure only for the immediate sub-rules of a `must<>` rule. * The `parse()` functions now return a `bool` and can also produce local failures. To obtain the previous behaviour of success-or-global-failure, the top-level grammar rule has to be wrapped in a `must<>`. ## 0.32 Released 2012-12 * Removed superfluous includes (issue 5 from Google code hosting). * Fixed bug in `not_at` rule regarding wrong propagation of errors (issue 3 from Google code hosting). ## 0.31 Released 2011-02 * Fixed bug in `not_at` rule regarding wrong propagation of errors (issue 3 from Google code hosting). ## 0.30 * Fixed missing template arguments in the implementation of `smart_parse_string()`. ## 0.29 * Fixed broken convenience rules `space_until_eof` and `blank_until_eol`. * Extended the included examples that show how to build parse trees etc. ## 0.28 * Optimised object file footprint of class `printer` and some related functions. * Renamed class `rule_helper` to `rule_base` and `action_helper` to `action_base`. ## 0.27 * Changed the type of exceptions thrown by the library to `pegtl::parse_error`. * Changed class `basic_debug` to only generate a grammar back-trace when a `pegtl::parse_error` is flying. * Changed logging to use a virtual member function on the debug class inherited from common debug base class. * Removed all `*_parse_*_nothrow()` parse functions. * Removed the `_throws` substring from all remaining parse functions and changed the return type to `void`. * Added convenience classes `file_input`, `ascii_file_input` and `dummy_file_input` for custom parse functions. ## 0.26 * Changed pretty-printing of the `until` and `if...` rules (consistency). * Changed pretty-printing of rules to use ":=" instead of "===" (conciseness). * Renamed rule `action` to `ifapply` and removed rule `action_nth` (orthogonality). * Renamed action `apply_nth` to `nth`, and renamed some other actions (consistency). * Extended pretty-printing to the `apply` and `ifapply` rules (completeness). The last of these changes effectively requires custom action classes to derive either from a valid rule class, or from the new class `pegtl::action_helper<>`, passing itself as template argument. ## 0.25 * Fixed and cleaned up the rule pretty-printer in many places (readability). * Added new convenience rule `enclose`, useful for quoted strings (convenience). * Added new rule `apply` to unconditionally apply an action with empty matched string (convenience). * Added action argument to `list` rule and added action `nop` for use as default action (convenience). ## 0.24 * Fixed some bugs in the pretty-printer; still in the experimental phase (usability). ## 0.23 * Added new rules `padl` and `padr` (convenience). * Added example for quoted strings with arbitrary unicode characters (documentation). * Changed rule `pad` to not suppress the padding in diagnostic messages (consistency). ## 0.22 * Cleaned up the source to compile with `-std=c++0x -pedantic` (compliance). * Cleaned out some superfluous compiler flags from the Makefile (minimalism). * Changed the default compiler to `g++`, which can be overriden by `$CXX` (consistency). * Cleaned up unittests for where `char` is signed but `-fno-strict-overflow` is not given (compliance). * Removed `list/not_list/at_list/at_not_list`, but `one/not_one/at_one/at_not_one` are now variadic (orthogonality). * Removed the redundant rules `space_star`, `space_plus`, `blank_star`, and `blank_plus` (minimalism). * Added new rule class `list` (not to be confused with the old, very different, rule `list`) (convenience). * Changed class `seq` to invoke the `marker` with a modified `Must` flag for single-rule sequences (performance). * Changed rule class `until1` to be a specialisation of `until`, rather than have a different name (consistency). * Changed around the order of the template arguments of the `until` rule (consistency and flexibility). * Changed around the order of the template arguments of the `rep` rule and reduced to strict repeat (minimalism). * Changed many rule classes from one template argument to variadic sequence of arguments (flexibility). ## 0.21 * Changed the pretty-printing of rules, this is work in progress (aesthetics). * Fixed the exception that occurred when `mmap()`ing an empty file (correctness). ## 0.20 * Added the missing `pegtl.hh` header file to the release archive... ## 0.19 * Cleanly layered implementation of `action_nth` (flexibility). * Renamed class `action_all` back to `action` (was better that way). * Moved main `pegtl.hh` include file out of `pegtl` directory (simplicity). * Renamed the rule method from `s_match` to `match` (readability). * Renamed the action method from `matched` to `apply` (readability). * Renamed the rule method from `s_insert` to `prepare` (consistency). * Changed the input iterator classes to report byte offsets (consistency). * Added rule and action class to match captured sub-expressions (experiment). * Changed class `action` to invoke arbitrary many actions (succinctness). * Changed classes `ifmust` and `ifthen` to accept arbitrary many 'then' rules (succinctness). * Fixed potential dangling reference in helper class `names` (correctness). ## 0.18 * Added parser functions `parse_forward` for forward iterators (completeness). * Renamed parser functions for input iterators to `parse_input` (consistency). * Added parser functions `parse_file` for files, implemented with `mmap(2)` (necessity). * Added initial support for customised logging of error messages (flexibility). ## 0.17 * Added support for ranges of input iterators with automatic minimal buffering (flexibility). ## 0.16 * Added class `action_nth` (flexibility). * Renamed class `action` to `action_all` (consistency). * Changed class `marker` to a nop when "must" is true (performance). * Changed `dummy_debug` to interpret "must" tracking (consistency). * Fixed typo in name of `PEGTL_IMPURE_OPTIMISATIONS` macro (correctness). * Made the marker class a sub-class of the input class (simplicity). * Renamed some of classes named `white`, `space`, or `blank` (consistency). * Fixed some issues in the R6RS example (CFG to PEG mismatch, only first datum). * Added missing template arguments to `smart_parse`-functions (correctness). ## 0.15 * Removed some small superfluous functions (less is more). * Changed the "must" tracking from run-time to compile-time (better?). ## 0.14 * Optimised behaviour of `seq<>` and `string<>` (performance). * Added detection of division-by-zero to calculator example. * Removed data source debug tracking from the library (simplicity). * Removed run-time limits on rule applications and nesting (simplicity). * Disentangled a couple of header files (maintainability). * Renamed class `iterator_input` to forward_input (consistency). * Added class `string_input` to initialise forward_input from a string (convenience). * Removed template argument Rule to action functor's `matched()` method (simplicity). ## 0.13 * Added more wrapper functions for parsing (convenience). * Renamed existing wrapper functions for parsing (consistency). * Added `rewind()` method to class `iterator_input` (indirect). ## 0.12 * Added more directory structure. * Fixed compile-error in `sexpression.cc` (correctness). ## 0.11 * Fixed back-tracking in class `string` (correctness). * Fixed order of operands in calculator example (correctness). ## 0.10 * Added Scheme R6RS grammar (example). * Fixed behaviour at end-of-input (aesthetics). * Fixed behaviour and use of class `position` (correctness). * Changed to lazy initialisation of pretty-printer (performance). * Changed the design of the input and parser classes (flexibility). * Changed how expression rules provide their printer key (simplicity). ## 0.9 Released 2008 * First public release. ## History Development of the PEGTL started in November 2007 as an experiment in C++0x. It is based on ideas from the YARD library by Christopher Diggins. Copyright (c) 2007-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Contrib-and-Examples.md000066400000000000000000000202501426407250600204270ustar00rootroot00000000000000# Contrib and Examples The PEGTL includes several parts that go beyond the core library functionality. They are included both for convenience and to show how certain things can be done with the PEGTL. ## Notice All feedback is highly welcome, in particular whether more sub-rules to serve as attachment points for actions are required. Similarly, if you have written a grammar with the PEGTL that might be generally useful, you are welcome to contribute it for inclusion in future versions. For all questions and remarks contact us at **taocpp(at)icemx.net**. ## Contents * [Contrib](#contrib) * [Examples](#examples) ## Contrib ###### `` * Core ABNF rules according to [RFC 5234, Appendix B](https://tools.ietf.org/html/rfc5234). * Ready for production use. ###### `` * Constants for ASCII letters. * Shortens `string<'f','o','o'>` to `string`. * Ready for production use. * Superceeded by `TAO_PEGTL_STRING()`. ###### `` * HTTP 1.1 grammar according to [RFC 7230](https://tools.ietf.org/html/rfc7230). * Has been used successfully but is still considered experimental. ###### `` * Grammars and actions for PEGTL-input-to-integer conversions. ###### `` * Limits the nesting level of rules when parsing a grammar, prevents stack overflows. * Can be applied selectively at specific rules to improve efficiency. * See `src/test/pegtl/limit_depth.cpp`. ###### `` * JSON grammar according to [RFC 7159](https://tools.ietf.org/html/rfc7159) (for UTF-8 encoded JSON only). * Ready for production use. ###### `` * See [Parse Tree](Parse-Tree.md). ###### `` * Grammar rules to parse Lua-style long (or raw) string literals. * Ready for production use. ###### `` * Contains optimised version of `rep< N, string< Cs... > >`: * Rule `ascii::rep_string< N, Cs... >`. ###### `` * Contains optimised version of `rep_min_max< Min, Max, ascii::one< C > >`: * Rule `ascii::rep_one_min_max< Min, Max, C >`. ###### `` * Allows to parse rules separated by a separator. * Rule `separated_seq< S, A, B, C, D >` is equivalent to `seq< A, S, B, S, C, S, D >`. ###### `` Utility function `to_string<>()` that converts template classes with arbitrary sequences of characters as template arguments into a `std::string` that contains these characters. ###### `` * See [Tracer](Getting-Started.md#tracer). ###### `` This file contains helpers to unescape JSON and C and similar escape sequences. * Utility functions frequently needed to unescape escape-sequences. * Action classes that perform unescaping of escape-sequences. ###### `` * URI grammar according to [RFC 3986](https://tools.ietf.org/html/rfc3986). * This is still experimental. ## Examples ###### `src/example/pegtl/abnf2pegtl.cpp` Reads a file with an [ABNF (RFC 5234)](https://tools.ietf.org/html/rfc5234)-style grammar and converts it into corresponding PEGTL rules in C++. Some extensions and restrictions compared to RFC 5234: * As we are defining PEGs, the alternations are now ordered (`sor<>`). * The *and*- and *not*-predicates from PEGs have been added as `&` and `!`, respectively. * A single LF is also accepted as line ending. * C++ identifiers are formed by replacing the dashes in rulenames with underscores. * Reserved identifiers (keywords, ...) are rejected. * Numerical values must fit into the corresponding C++ data type. ###### `src/example/pegtl/analyze.cpp` A small example that provokes the [grammar analysis](Grammar-Analysis.md) to find problems. ###### `src/example/pegtl/calculator.cpp` A calculator with all binary operators from the C language that shows * how to use stack-based actions to perform a calculation on-the-fly during the parsing run, and * how to build a grammar with a run-time data structure for arbitrary binary operators with arbitrary precedence and associativity. In addition to the binary operators, round brackets can be used to change the evaluation order. The implementation uses `long` integers as data type for all calculations. ```sh $ build/src/example/pegtl/calculator "2 + 3 * -7" "(2 + 3) * 7" -19 35 ``` In this example the grammar takes a bit of a second place behind the infrastructure for the actions required to actually evaluate the arithmetic expressions. The basic approach is "shift-reduce", which is very close to a stack machine, which is a model often well suited to PEGTL grammar actions: Some actions merely push something onto a stack, while other actions apply some functions to the objects on the stack, usually reducing its size. ###### `src/example/pegtl/chomsky_hierarchy.cpp` Examples of grammars for regular, context-free, and context-sensitive languages. ###### `src/example/pegtl/csv1.cpp` and `src/example/pegtl/csv2.cpp` Two simple examples for grammars that parse different kinds of CSV-style file formats. ###### `src/example/pegtl/hello_world.cpp` Minimal parser-style "hello world" example from the [Getting Started](Getting-Started.md) page. ###### `src/example/pegtl/indent_aware.cpp` Shows one approach to implementing an indentation-aware language with a very very small subset of Python. ###### `src/example/pegtl/json_parse.cpp` Shows how to use the custom error messages defined in `json_errors.hpp` with the `` grammar to parse command line arguments as JSON data. ###### `src/example/pegtl/json_build.cpp` Extends on `json_parse.cpp` by parsing JSON files into generic JSON data structure. ###### `src/example/pegtl/json_count.cpp` Shows how to use a simple custom control to create some parsing statistics while parsing JSON files. ###### `src/example/pegtl/lua53_parse.cpp` Parses all files passed on the command line with a slightly experimental grammar that should correspond to the [Lua](http://www.lua.org/) 5.3 lexer and parser. ###### `src/example/pegtl/modulus_match.cpp` Shows how to implement a custom parsing rule with the simplified calling convention. ###### `src/example/pegtl/parse_tree.cpp` A small example which shows how to create a parse tree for a given grammar using [``](Parse-Tree.md). The example shows how to choose which rules will produce a parse tree node, which rules will store the content, and how to add additional transformations to the parse tree to transform it into an AST-like structure or to simplify it. The output is in [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) format and can be converted into a graph. ```sh $ build/src/example/pegtl/parse_tree "(2*a + 3*b) / (4*n)" | dot -Tsvg -o parse_tree.svg ``` The above will generate an SVG file with a graphical representation of the parse tree. ![Parse Tree](Parse-Tree.svg) ###### `src/example/pegtl/proto3.cpp` Experimental grammar that parses Protocol Buffers (`.proto3`) files. ###### `src/example/pegtl/recover.cpp` See [PEGTL issue 55](https://github.com/taocpp/PEGTL/issues/55) and the source code for a description. ###### `src/example/pegtl/s_expression.cpp` Grammar for a toy-version of S-expressions that shows how to include other files during a parsing run. ###### `src/example/pegtl/sum.cpp` Simple example that adds a list of comma-separated `double`s read from `std::cin`. ###### `src/example/pegtl/symbol_table.cpp` Simple example that shows how to parse with a symbol table. ###### `src/example/pegtl/unescape.cpp` Uses the building blocks from `` to show how to actually unescape a string literal with various typical escape sequences. ###### `src/example/pegtl/uri_trace.cpp` Shows how to use the included [tracer control](#taopegtlcontribtracerhpp), here together with the URI grammar from ``. Invoked with one or more URIs as command line arguments will attempt to parse the URIs while printing trace information to `std::cerr`. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Control-and-Debug.md000066400000000000000000000177571426407250600177410ustar00rootroot00000000000000# Control and Debug Beyond the top-level grammar rule, which *has* to be supplied to a parsing run, and an action class template, which *can* be supplied to a parsing run, a third customisation point within the PEGTL allows the user to provide a *control* class to a parsing run. (Actually the control class is a class template which takes a parsing rule as template argument, however in many cases there will be no specialisations, wherefore we will drop the distinction and pretend here that it is simply a class.) Functions from the control class are called in strategic places during a parsing run and can be used to customise internal behaviour of the PEGTL and/or as debug aids. More precisely, the control class has static member functions to 1. trace which rules are attempted to match where, and whether they succeed or fail, 2. customise which exceptions are thrown in case of errors, 3. customise how an action's `apply()` or `apply0()` is called, 4. customise how a rule's `match()` is called. ## Contents * [Normal Control](#normal-control) * [Control Functions](#control-functions) * [Exception Throwing](#exception-throwing) * [Advanced Control](#advanced-control) * [Changing Control](#changing-control) ## Normal Control The `normal` control class template included with the PEGTL is used by default and shows which hook functions there are. ```c++ template< typename Rule > struct normal { static constexpr bool enable; // See Meta-Data-and-Visit.md template< typename ParseInput, typename... States > static void start( const ParseInput&, States&&... ); template< typename ParseInput, typename... States > static void success( const ParseInput&, States&&... ); template< typename ParseInput, typename... States > static void failure( const ParseInput&, States&&... ); template< typename ParseInput, typename... States > static void raise( const ParseInput& in, States&&... ); template< template< typename... > class Action, typename Iterator, typename ParseInput, typename... States > static auto apply( const Iterator& begin, const ParseInput& in, States&&... st ) -> decltype( ... ); template< template< typename... > class Action, typename ParseInput, typename... States > static auto apply0( const ParseInput&, States&&... st ) -> decltype( ... ); template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... st ); }; ``` The static member functions `start()`, `success()` and `failure()` can be used to debug a grammar by using them to provide insight into what exactly is going on during a parsing run, or to construct a parse tree, etc. There is one more, *optional* hook function: `unwind()`. It is called when a rule throws an exception, e.g. on global error. It's signature is identical to `start()`/`success()`/`failure()`. It is not included in the default control template `normal`, as the existence of an `unwind()` method requires an additional `try`/`catch` block. 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 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. This can be achieved via SFINAE, e.g. with a trailing return type as shown above. The static member function `match()` by default checks if there exists a suitable `match()` in the action class template for the current rule. If so, it is called, otherwise it calls the main `tao::pegtl::match()` function. ## Control Functions For debugging a grammar and tracing exactly what happens during a parsing run, the control class' `start()`, `success()` and `failure()` can be used. In addition, `apply()` and `apply0()` can be used to see which actions are invoked. Before attempting to match a rule `R`, the PEGTL calls `C< R >::start()` where `C` is the current control class template. Depending on what happens during the attempt to match `R`, one of the other three functions might be called. - If `R` succeeds, then `C< R >::success()` is called; compared to the call to `C< R >::start()`, the input will have consumed whatever the successful match of `R` consumed. - If `R` finishes with a local failure, i.e. a return value of `false` from `match()`, then `C< R >::failure()` is called; a failed match **must not** consume input. - If `R` finishes with a global failure, i.e. an exception being thrown from `match()`, then, if present, `C< R >::unwind()` is called. - If `R` is wrapped in `must< R >`, a global failure is generated by calling `C< R >::raise()` to throw some exception as is expected by the PEGTL in this case. Additionally, if matching `R` was successful and actions are enabled: - If `C< R >::apply()` exists, then `C< R >::apply()` is called with the matched input and the current state arguments. - If `C< R >::apply0()` exists, then `C< R >::apply0()` is called with the current state arguments. It is an error when both `C< R >::apply()` and `C< R >::apply0()` exist. Note that the default `C< R >::apply()` is SFINAE-enabled if `A< R >::apply()` exists (where `A` is the current action class template) and calls the latter. A control class might modify state, etc. In case of actions that return `bool`, i.e. actions where `apply()` or `apply0()` return `bool`, `C< R >::success()` is only called when both the rule *and* the action succeed. If either produce a (local) failure then `C< R >::failure()` is called. In all cases where an action is called, the success or failure hooks are invoked after the action returns. The included `` gives a practical example that shows how the control class can be used to debug grammars. ## 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`! 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. ## Advanced Control The control's `match()` is the first, outer-most function in the call-chain that eventually calls the rule's `match()`. For advanced use cases, it is possible to create a custom control class with a custom `match()` that can change "everything" before calling the rule's `match()`. Similarly, the control's `apply()` and `apply0()` can customise action invocation; in particular `apply()` can change how the matched portion of the input is passed to the action. ## Changing Control Just like the action class template, a custom control class template can be used (or changed) by either 1. supplying it as explicit template argument to the `parse()` functions, or 2. setting it as control class with the [`tao::pegtl::control`](Rule-Reference.md#control-c-r-) combinator, or 3. setting it as control class with the `change_control` action. The latter requires the use of a [custom action](Actions-and-States.md). Deriving the specialisation of the custom action for `my_rule` from `tao::pegtl::change_control< my_control >` will switch the current control to `my_control` before attempting to match `my_rule`. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Errors-and-Exceptions.md000066400000000000000000000276711426407250600206640ustar00rootroot00000000000000# Errors and Exceptions A parsing run, a call to one of the `parse()` functions as explained in [Inputs and Parsing](Inputs-and-Parsing.md), can have the same results as calling `match()` on a grammar rule. * A return value of `true` indicates a *successful* match. * 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. ## Contents * [Global Failure](#global-failure) * [Local to Global Failure](#local-to-global-failure) * [Intrusive Local to Global Failure](#intrusive-local-to-global-failure) * [Non-Intrusive Local to Global Failure](#non-intrusive-local-to-global-failure) * [Global to Local Failure](#global-to-local-failure) * [Examples for Must Rules](#examples-for-must-rules) * [Custom Exception Messages](#custom-exception-messages) ## Global Failure By default, global failure means that an exception of type `tao::pegtl::parse_error` is thrown. Synposis: ```c++ namespace tao::pegtl { class parse_error : 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 ) ) {} template< typename ParseInput > parse_error( const char* msg, const ParseInput& in ) : parse_error( msg, in.position() ) {} template< typename ParseInput > parse_error( const std::string& msg, const ParseInput& in ) : parse_error( msg, in.position() ) {} const char* what() const noexcept override; std::string_view message() const noexcept; const std::vector< position >& positions() const noexcept; void add_position( position&& p ); }; } ``` 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 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 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. ## Local to Global Failure ### Intrusive Local to Global Failure A local failure returned by a parsing rule is not necessarily propagated to the top, for example when the rule is * in a rule like `not_at<>`, `opt<>` or `star<>`, or * not the last rule inside an `sor<>` combinator. To convert local failures to global failures, the `must<>` combinator rule can be used (together with related rules like `if_must<>`, `if_must_else<>` and `star_must<>`). The `must<>` rule is equivalent to `seq<>` in that it attempts to match all sub-rules in sequence, but converts all local failures of the (direct) sub-rules to global failures. Global failures can also be unconditionally provoked with the `raise<>` grammar rule, which is more flexible since the template argument can be any type, not just a parsing rule. It should be mentioned that `must< R >` is semantically equivalent to `sor< R, raise< R > >`, but more efficient. In any case, the task of actually throwing an exception is delegated to the [control class'](Control-and-Debug.md) `raise()`. Note that rules and actions can throw exceptions directly, meaning those are not generated from the [control class'](Control-and-Debug.md) `raise()`. ### Non-Intrusive Local to Global Failure If a grammar does not contain any `must<>` rule(s) (or `raise<>`, `if_must<>`, ...), one can still convert a local failure for a rule into a global failure via `must_if<>`. This helper allows one to create a [control class'](Control-and-Debug.md) and provide custom error messages for global failures. If an error message is provided for a rule that would normally return a local failure, it is automatically converted to a global failure. 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. 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. ## Examples for Must Rules One basic use case of the `must<>` rule is as top-level grammar rule. Then a parsing run can only either be successful, or throw an exception, it is not necessary to check the return value of the `parse()` function. For another use case consider the following parsing rules for a simplified C-string literal that only allows `\n`, `\r` and `\t` as escape sequences. The rule `escaped` is for a single escaped character, the rule `content` is for the complete content of such a literal. ```c++ using namespace tao::pegtl; struct escaped : seq< one< '\\' >, one< 'n', 'r', 't' > > {}; struct content : star< sor< escaped, not_one< '\\', '"' > > > {}; struct literal : seq< one< '"' >, content, one< '"' > > {}; ``` The `escaped` rule first matches a backslash, and then one of the allowed subsequent characters. When either of the two `one<>` rules returns a local failure, then so will `escaped` itself. In that case backtracking is performed in the `sor<>` and it will attempt to match the `not_one< '\\', '"' >` at the same input position. This backtracking is appropriate if the `escaped` rule failed to match for lack of a backslash in the input. It is however *not* appropriate when the backslash was not followed by one of the allowed characters since we know that there is no other possibility that will lead to a successful match. We can therefore re-write the `escaped` rule as follows so that once the backslash has matched we need one of the following allowed characters to match, otherwise a global failure is thrown. ```c++ using namespace tao::pegtl; struct escaped : seq< one< '\\' >, must< one< 'n', 'r', 't' > > > {}; ``` A `seq<>` where all but the first sub-rule is inside a `must<>` occurs frequently enough to merit a convenience rule. The following rule is equivalent to the above. ```c++ using namespace tao::pegtl; struct escaped : if_must< one< '\\' >, one< 'n', 'r', 't' > > {}; ``` Now the `escaped` rule can only return local failure when the next input byte is not a backslash. This knowledge can be used to simplify the `content` rule by not needing to exclude the backslash in the following rule. ```c++ using namespace tao::pegtl; struct content : star< sor< escaped, not_one< '"' > > > {}; ``` Finally we apply our "best practice" and give the `one< 'n', 'r', 't' >` rule a dedicated name. This will improve the built-in error message when the global failure is thrown, and also prevents actions or custom error messages (as explained below) from accidentally attaching to the same rule used in multiple places in a grammar. The resulting example is as follows. ```c++ using namespace tao::pegtl; struct escchar : one< 'n', 'r', 't' > {}; struct escaped : if_must< one< '\\' >, escchar > {}; struct content : star< sor< escaped, not_one< '"' > > > {}; struct literal : seq< one< '"' >, content, one< '"' > > {}; ``` The same use of `if_must<>` can be applied to the `literal` rule assuming that it occurs in some `sor<>` where it is the only rule whose matched input can begin with a quotation mark... ## Custom Exception Messages By default, when using any `must<>` error points, the exceptions generated by the PEGTL use the demangled name of the failed parsing rule as descriptive part of the error message. This is often insufficient and one would like to provide more meaningful error messages. A practical technique to provide customised error messages for all `must<>` error points uses the `must_if<>` helper. For an example of this method see `src/example/pegtl/json_errors.hpp`, where all errors that might occur in the supplied JSON grammar are customised like this: ```c++ template< typename > inline constexpr const char* error_message = nullptr; template<> inline constexpr auto error_message< tao::pegtl::json::text > = "no valid JSON"; template<> inline constexpr auto error_message< tao::pegtl::json::end_array > = "incomplete array, expected ']'"; template<> inline constexpr auto error_message< tao::pegtl::json::end_object > = "incomplete object, expected '}'"; template<> inline constexpr auto error_message< tao::pegtl::json::member > = "expected member"; template<> inline constexpr auto error_message< tao::pegtl::json::name_separator > = "expected ':'"; template<> inline constexpr auto error_message< tao::pegtl::json::array_element > = "expected value"; template<> inline constexpr auto error_message< tao::pegtl::json::value > = "expected value"; template<> inline constexpr auto error_message< tao::pegtl::json::digits > = "expected at least one digit"; template<> inline constexpr auto error_message< tao::pegtl::json::xdigit > = "incomplete universal character name"; template<> inline constexpr auto error_message< tao::pegtl::json::escaped > = "unknown escape sequence"; template<> inline constexpr auto error_message< tao::pegtl::json::char_ > = "invalid character in string"; template<> inline constexpr auto error_message< tao::pegtl::json::string::content > = "unterminated string"; template<> inline constexpr auto error_message< tao::pegtl::json::key::content > = "unterminated key"; template<> inline constexpr auto error_message< tao::pegtl::eof > = "unexpected character after JSON value"; // As must_if can not take error_message as a template parameter directly, we need to wrap it: struct error { template< typename Rule > static constexpr auto message = error_message< Rule >; }; template< typename Rule > using control = tao::pegtl::must_if< error >::control< Rule >; ``` `must_if<>` expects a wrapper for the error message as its first template parameter. There is a second parameter for the base control class, which defaults to `tao::pegtl::normal`, and which can combine `must_if`'s control class with other control classes. Since `raise()` is only instantiated for those rules for which `must<>` could trigger an exception, it is sufficient to provide specialisations of the error message string for those rules. Furthermore, there will be a compile-time error (i.e. a `static_assert`) for all rules for which the specialisation was forgotten although `raise()` could be called. The [control class](Control-and-Debug.md) provided by `must_if<>` also turns, by default, local failures into global failure if an error message is provided, i.e. if the error message is not `nullptr`. This means that one can provide additional points in the grammar where a global failure is triggered, even when the grammar contains no `must<>` error points. The above feature also means that a rule which is used both with and without `must<>`, one would not only provide a custom error message for the location where the rule is failing within a `must<>`-context, but local errors in other contexts are implicitly turned into global error. If this behaviour is not intended, one can disable the "turn local to global failure" feature by setting `raise_on_failure` to `false` in the wrapper class: ```c++ struct error { template< typename Rule > static constexpr bool raise_on_failure = false; template< typename Rule > static constexpr auto message = error_message< Rule >; }; ``` It is advisable to choose the error points in the grammar with prudence. This choice becoming particularly cumbersome and/or resulting in a large number of error points might be an indication of the grammar needing some kind of simplification or restructuring. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Getting-Started.md000066400000000000000000000245451426407250600175330ustar00rootroot00000000000000# Getting Started Since the PEGTL is a parser library, here is an "inverse hello world" example that parses, rather than prints, the string `Hello, foo!` for any sequence of alphabetic ASCII characters `foo`. ```c++ #include #include #include namespace pegtl = tao::pegtl; namespace hello { // Parsing rule that matches a literal "Hello, ". struct prefix : pegtl::string< 'H', 'e', 'l', 'l', 'o', ',', ' ' > {}; // Parsing rule that matches a non-empty sequence of // alphabetic ascii-characters with greedy-matching. struct name : pegtl::plus< pegtl::alpha > {}; // Parsing rule that matches a sequence of the 'prefix' // rule, the 'name' rule, a literal "!", and 'eof' // (end-of-file/input), and that throws an exception // on failure. struct grammar : pegtl::must< prefix, name, pegtl::one< '!' >, pegtl::eof > {}; // Class template for user-defined actions that does // nothing by default. template< typename Rule > struct action {}; // Specialisation of the user-defined action to do // something when the 'name' rule succeeds; is called // with the portion of the input that matched the rule. template<> struct action< name > { template< typename ParseInput > static void apply( const ParseInput& in, std::string& v ) { v = in.string(); } }; } // namespace hello int main( int argc, char* argv[] ) { if( argc != 2 ) return 1; // Start a parsing run of argv[1] with the string // variable 'name' as additional argument to the // action; then print what the action put there. std::string name; pegtl::argv_input in( argv, 1 ); pegtl::parse< hello::grammar, hello::action >( in, name ); std::cout << "Good bye, " << name << "!" << std::endl; return 0; } ``` Assuming you are in the main directory of the PEGTL, the above source can be found in the `src/example/pegtl/` directory. Compile the program with something like ```sh $ g++ --std=c++17 -Iinclude src/example/pegtl/hello_world.cpp -o hello_world ``` and then invoke it as follows: ```sh $ ./hello_world 'Hello, world!' Good bye, world! $ ./hello_world 'Hello, Colin!' Good bye, Colin! $ ./hello_world 'Howdy, Paula!' terminate called after throwing an instance of 'tao::pegtl::parse_error' what(): argv[1]:1:0(0): parse error matching hello::prefix Aborted (core dumped) ``` The PEGTL provides multiple facilities that help to get started and develop your grammar. In the following paragraphs we will show several small programs to showcase the capabilities of the PEGTL. Note, however, that all examples shown in this document will lack proper error handling. Frequently an application will include `try-catch` blocks to handle the exceptions. The correct way of handling errors is shown at the last paragraph of this page. ## Parsing Expression Grammars The PEGTL creates parsers according to a [Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) (PEG). The table below shows how the PEG combinators map to PEGTL [rule classes](Rule-Reference.md#combinators) (strictly speaking: class templates). Beyond these standard combinators the PEGTL contains a [large number of additional combinators](Rule-Reference.md) as well as the possibility of [creating custom rules](Rules-and-Grammars.md#creating-new-rules). | PEG | `tao::pegtl::` | | --- | --- | | &*e* | [`at< R... >`](Rule-Reference.md#at-r-) [(combinators)](Rule-Reference.md#combinators) | | !*e* | [`not_at< R... >`](Rule-Reference.md#not_at-r-) [(combinators)](Rule-Reference.md#combinators) | | *e*? | [`opt< R... >`](Rule-Reference.md#opt-r-) [(combinators)](Rule-Reference.md#combinators) | | *e*+ | [`plus< R... >`](Rule-Reference.md#plus-r-) [(combinators)](Rule-Reference.md#combinators) | | *e*1*e*2 | [`seq< R... >`](Rule-Reference.md#seq-r-) [(combinators)](Rule-Reference.md#combinators) | | *e*1 / *e*2 | [`sor< R... >`](Rule-Reference.md#sor-r-) [(combinators)](Rule-Reference.md#combinators) | | *e** | [`star< R... >`](Rule-Reference.md#star-r-) [(combinators)](Rule-Reference.md#combinators) | The PEGTL also contains a [large number of atomic rules](Rule-Reference.md) for matching ASCII and Unicode characters, strings, ranges and similar, beginning-of-file or end-of-line and similar, and more... ## Grammar Analysis Every grammar must be free of cycles that make no progress, i.e. it must not contain unbounded recursive or iterative rules that do not consume any input, as such grammar might enter an infinite loop. One common pattern for these kinds of problematic grammars is the so-called [left recursion](https://en.wikipedia.org/wiki/Left_recursion) that, while not a problem for less deterministic formalisms like CFGs, must be avoided with PEGs in order to prevent aforementioned infinite loops. The PEGTL provides a [grammar analysis](Grammar-Analysis.md) which analyses a grammar for cycles that make no progress. While it could be implemented with compile-time meta-programming, to prevent the compiler from exploding the analysis is done at run-time. It is best practice to create a separate dedicated program that does nothing else but run the grammar analysis, thus keeping this development and debug aid out of the main application. ```c++ #include #include // This example uses the included JSON grammar #include namespace pegtl = tao::pegtl; using grammar = pegtl::must< pegtl::json::text, pegtl::eof >; int main() { if( pegtl::analyze< grammar >() != 0 ) { std::cerr << "cycles without progress detected!\n"; return 1; } return 0; } ``` For more information see [Grammar Analysis](Grammar-Analysis.md). ## Tracer A fundamental tool used when developing a grammar is a tracer that prints every step of a parsing run, thereby showing exactly which rule was attempted to match where, and what the result was. The PEGTL provides a tracer that will print to `stderr`, and of course allows users to write their own tracers with custom output formats. ```c++ #include #include // This example uses the included JSON grammar #include namespace pegtl = tao::pegtl; using grammar = pegtl::must< pegtl::json::text, pegtl::eof >; int main( int argc, char** argv ) { if( argc != 2 ) return 1; pegtl::argv_input in( argv, 1 ); pegtl::standard_trace< grammar >( in ); return 0; } ``` In the above each command line parameter is parsed as a JSON string and a trace is given to understand how the grammar matches the input. For more information see `tao/pegtl/contrib/trace.hpp`. ## Parse Tree / AST When developing parsers, a common goal after creating the grammar is to generate a [parse tree](https://en.wikipedia.org/wiki/Parse_tree) or an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree). The PEGTL provides a [Parse Tree](Parse-Tree.md) builder that can filter and/or transform tree nodes on-the-fly. Additionally, a helper is provided to print out the resulting data structure in [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) format, suitable for creating a graphical representation of the parse tree. The following example uses a selector to choose which rules generate parse tree nodes, as the graphical representation will usually be too large and confusing when not using a filter and generating nodes for *all* rules. ```c++ #include #include #include // This example uses the included JSON grammar #include namespace pegtl = tao::pegtl; using grammar = pegtl::must< pegtl::json::text, pegtl::eof >; template< typename Rule > using selector = pegtl::parse_tree::selector< Rule, pegtl::parse_tree::store_content::on< pegtl::json::null, pegtl::json::true_, pegtl::json::false_, pegtl::json::number, pegtl::json::string, pegtl::json::key, pegtl::json::array, pegtl::json::object, pegtl::json::member > >; int main( int argc, char** argv ) { if( argc != 2 ) return 1; pegtl::argv_input in( argv, 1 ); const auto root = parse_tree::parse< grammar, selector >( in ); if( root ) { parse_tree::print_dot( std::cout, *root ); } return 0; } ``` Running the above program with some example input: ```sh $ build/src/example/pegtl/json_parse_tree '{"foo":[true,{}],"bar":[42,null]}' | dot -Tsvg -o json_parse_tree.svg ``` The above will generate an SVG file with a graphical representation of the parse tree. ![JSON Parse Tree](Json-Parse-Tree.svg) For more information see [Parse Tree](Parse-Tree.md). ## Error Handling Although the PEGTL could be used without exceptions, most programs will use input classes, grammars and/or actions that can throw exceptions. Typically, the following pattern helps to print the exceptions in a human friendly way: ```c++ // The surrounding try/catch for normal exceptions. // These might occur if a file can not be opened, etc. try { tao::pegtl::file_input in( filename ); // The inner try/catch block, see below... try { // The actual parser, tracer, parse tree, ... pegtl::parse< grammar >( in ); } catch( const pegtl::parse_error& e ) { // This catch block needs access to the input const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; } } catch( const std::exception& e ) { // Generic catch block for other exceptions std::cerr << e.what() << std::endl; } ``` For more information see [Errors and Exceptions](Errors-and-Exceptions.md). Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Grammar-Analysis.md000066400000000000000000000135551426407250600176740ustar00rootroot00000000000000# Grammar Analysis The PEGTL contains an `analyze()` function that checks a grammar for rules that can enter an infinite loop without consuming input. ## Content * [Running](#running) * [Example](#example) * [Requirements](#requirements) * [Limitations](#limitations) ## Running In order to run an analysis on a grammar it is necessary to explicitly include ``. Then call `tao::pegtl::analyze()` with the top-level grammar rule as template argument. ```c++ #include const std::size_t issues = tao::pegtl::analyze< my_grammar >(); ``` The `analyze()` function prints some information about the found issues to `std::cout` and returns the total number of issues found. The output can be suppressed by passing `-1` as sole function argument, or be extended to give some information about the issues when called with `1`. Analysing a grammar is usually only done while developing and debugging a grammar, or after changing it. ## Example Regarding the kinds of issues that are detected, consider the following example rules. ```c++ struct bar; struct foo : sor< digit, bar > {}; struct bar : plus< foo > {}; ``` When attempting to match `bar` against an input where the next character is not a digit the parser immediately goes into an infinite loop between `bar` calling `foo` and then `foo` calling `bar` again. As shown by the example program `src/example/pegtl/analyze.cpp`, the grammar analysis will correctly detect a cycle without progress in this grammar. Due to the differences regarding back-tracking and non-deterministic behaviour, this kind of infinite loop is a frequent issue when translating a CFG into a PEG. ## Requirements The `analyze()` function operates on an abstract form of the grammar that is mostly equivalent to the original grammar regarding the possibility of infinite cycles without progress. This abstract form is obtained via specialisations of the `analyze_traits<>` class template which each must have exactly one of `analyze_any_traits`, `analyze_opt_traits`, `analyze_seq_traits` and `analyze_sor_traits` as public (direct or indirect) base class. Specialisations of the `analyze_traits<>` class template are appropriately implemented for all grammar rule classes included with the PEGTL. This support automatically extends to all custom rules built "the usual way" via public inheritance of (combinations and specialisations of) rules included with the PEGTL. For true custom rules, i.e. rules that implement their own `match()` function, the following steps need to be taken for them to work with the grammar analysis. 1. The rule needs a [`rule_t`](Meta-Data-and-Visit.md#rule-type) that, usually for true custom rules, is a type alias for the grammar rule itself. 2. There needs to be a specialisation of the `analyze_traits<>` for the custom rule, with an additional first template parameter: Assuming a custom rule like the following ```c++ struct my_rule { using rule_t = my_rule; template< typename Input > bool match( Input& in ) { return /* Something that always consumes on success... */ ; } }; ``` the analyze traits need to be set up as ```c++ // In namespace TAO_PEGTL_NAMESPACE template< typename Name > struct analyze_traits< Name, my_rule > : analyze_any_traits<> {}; ``` where the base class is chosen as follows. 1. `analyze_any_traits<>` is used for rules that always consume when they succeed. 2. `analyze_opt_traits<>` is used for rules that (can also) succeed without consuming. 3. `analyze_seq_traits<>` is used for rules that, regarding their match behaviour, are equivalent to `seq<>`. 4. `analyze_sor_traits<>` is used for rules that, regarding their match behaviour, are equivalent to `sor<>`. If `my_rule` has rules, that it calls upon as sub-rules, as template parameters, these need to be passed as template parameters to the chosen base class. Note that the first template parameter `Name` is required by the analyse traits of some rules in order to facilitate their transcription in terms of the basic combinators `seq`, `sor` and `opt`. For example `R = plus< T >` is equivalent to `seq< T, opt< R > >`, and the corresponding specialisation of the analyse traits is as follows. ```c++ template< typename Name, typename... Rules > struct analyze_traits< Name, internal::plus< Rules... > > : analyze_traits< Name, typename seq< Rules..., opt< Name > >::rule_t > {}; ``` Note how the specialisation is for `internal::plus` rather than `plus`. The convention is that only the classes that actually implement `match()` define `rule_t`. This greatly reduces both the number of classes that need to define `rule_t` as well as the number of required `analyze_traits` specialisations. Note further how `Name` is required to transform the implicitly iterative rule `plus` into an explicitly recursive form that only uses `seq` and `opt`. The analyse traits have the task of simplifying the grammar in order to keep the core analysis algorithm as simple as possible. Please consult `include/tao/pegtl/contrib/analyze_traits.hpp` for many examples of how to correctly set up analyse traits for more complex rules, in particular for rules that do not directly fall into one of the aforementioned four categories. For any further reaching questions regarding how to set up the traits for custom rules please contact the authors at **taocpp(at)icemx.net**. ## Limitations It has been conjectured, but, given the expressive power of PEGs, not proven, that *all* potential infinite loops are correctly detected. In practice it appears to catch all cases of left-recursion that are typical for grammars converted from CFGs or other formalisms that gracefully handle left-recursion. False positives are a theoretical problem in that, while relatively easy to trigger, they are not usually encountered when dealing with real world grammars. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Inputs-and-Parsing.md000066400000000000000000000661731426407250600201540ustar00rootroot00000000000000# Inputs and Parsing Assuming that the [grammar rules](Rules-and-Grammars.md) are ready, and the [actions and states](Actions-and-States.md) prepared, performing a parsing run consists of two steps: 1. Constructing an *input* class that represents the to-be-parsed data. 2. Calling a PEGTL *parse* function with the input (and any states). ```c++ using namespace tao::pegtl; struct my_grammar : ...; template< typename Rule > struct my_actions {}; // Specialisations of my_actions as required... bool my_parse( const std::string& filename, my_state& state ) { file_input in( filename ); return parse< my_grammar, my_actions >( in, state ); } ``` In the context of PEGTL input classes and positions there is usually an additional (i.e. beyond indicating or supplying the to-be-parsed data) string parameter `source` that identifies where the to-be-parsed data comes from. For example when parsing a file with one of the appropriate included input classes, the filename is automatically used as `source` so that it will appear in exceptions and error messages. In other cases the `source` parameter needs to be explicitly passed to the input's constructor. All classes and functions on this page are in namespace `tao::pegtl`. ## Contents * [Tracking Mode](#tracking-mode) * [Line Ending](#line-ending) * [Source](#source) * [File Input](#file-input) * [Memory Input](#memory-input) * [String Input](#string-input) * [Stream Inputs](#stream-inputs) * [Argument Input](#argument-input) * [Parse Function](#parse-function) * [Nested Parsing](#nested-parsing) * [Incremental Input](#incremental-input) * [Buffer Size](#buffer-size) * [Discard Buffer](#discard-buffer) * [Custom Rules](#custom-rules) * [Custom Readers](#custom-readers) * [Buffer Details](#buffer-details) * [Error Reporting](#error-reporting) * [Deduction Guides](#deduction-guides) ## Tracking Mode 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`. 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. ## Line Ending All input classes allow the choice of which line endings should be recognised by the `eol` and `eolf` rules, and used for line counting. The supported line endings are `cr`, a single carriage-return/`"\r"`/`0x0d` character as used on classic Mac OS, `lf`, a single line-feed/`"\n"`/`0x0a` as used on Unix, Linux, Mac OS X and macOS, and `crlf`, a sequence of both as used on MS-DOS and Windows. The default template parameter for all input classes is `eol::lf_crlf` which recognises both Unix and MS-DOS line endings. The supplied alternatives are `eol::cr`, `eol::lf`, `eol::crlf` and `eol::cr_crlf`. ## Source Some input classes allow a choice of how to store the source parameter, with the default being a `std::string`. When creating many instances of an input class, it can be changed to a non-owning `const char*` to optimise away the memory allocation performed by `std::string`. ## File Input The classes `file_input<>`, `read_input<>` and, on supported platforms, `mmap_input<>`, can be used to parse the contents of a file. * `read_input<>` uses C "stdio" facilities to read the file. * `mmap_input<>` uses `mmap(2)` on POSIX compliant systems or `MapViewOfFile()` on Windows. * `file_input<>` is derived from `mmap_input<>` when available, and `read_input<>` otherwise, inheriting the respective constructors. They immediately make available the complete contents of the file; `read_input<>` reads the entire file upon construction. The constructors that take a `FILE*` argument take ownership of the file pointer, i.e. they `fclose()` it in the destructor. ```c++ template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct read_input { explicit read_input( const std::filesystem::path& path ); read_input( const std::filesystem::path& path, const std::string& source ); read_input( FILE* file, const std::filesystem::path& path ); read_input( FILE* file, const std::filesystem::path& path, const std::string& source ); }; template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct mmap_input { explicit mmap_input( const std::filesystem::path& path ); mmap_input( const std::filesystem::path& path, const std::string& source ); }; template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > using file_input = mmap_input< P, Eol >; // Or read_input when no mmap_input available. ``` ## Memory Input The class `memory_input<>` can be used to parse existing contiguous blocks of memory like the contents of a `std::string`. The input **neither copies the data nor takes ownership, it only keeps pointers**. The various constructors accept the to-be-parsed data in different formats. The `source` parameter is required for all constructors to disambiguate the different overloads. If you don't want to specify a source just use the empty string (`""`). The constructors that only takes a `const char* begin` for the data uses `std::strlen()` to determine the length. It will therefore *only* work correctly with data that is terminated with a 0-byte (and does not contain embedded 0-bytes, which are otherwise fine). The constructors that take additional `byte`, `line` and `column` arguments initialise the internal counters with the supplied values, rather than the defaults of `0`, `1` and `1`. ```c++ template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf, typename Source = std::string > class memory_input { template< typename T > memory_input( const internal::iterator& iter, const char* end, T&& source ) noexcept(...); template< typename T > memory_input( const char* begin, const char* end, T&& source ) noexcept(...); template< typename T > memory_input( const char* begin, const std::size_t size, T&& source ) noexcept(...); template< typename T > memory_input( const std::string& string, T&& source ) noexcept(...); template< typename T > memory_input( const char* begin, T&& source ) noexcept(...); template< typename T > memory_input( const char* begin, const char* end, T&& source, const std::size_t byte, const std::size_t line, const std::size_t column ) noexcept(...); }; ``` ### Examples ###### Example 1 ```c++ memory_input in1( "this is the input to parse", "" ); ``` Construct a `memory_input` with default tracking mode, default end-of-line mode (accepting Unix and MS-DOS line endings), and default source storage. As there are only two parameters, the 5th overload from above is choosen. The data to parse is given directly as a string literal which is not copied. As no pointer to the end or the size of the input is given, the length of the data to be parsed will be determined by calling `strlen` on the pointer passed as the first parameter. The source is the empty string. ###### Example 2 ```c++ struct packet { // ... const std::array< char >& buffer() const noexcept; std::string identifier() const; // ... }; packet p = ...; // some UDP packet class memory_input< tracking_mode::lazy, eol::crlf > in2( p.buffer().begin(), p.buffer().end(), p.identifier() ); ``` Consider a UDP packet that was received and should be parsed. Construct a `memory_input` with lazy tracking mode, MS-DOS end-of-line mode (accepting only MS-DOS line endings), and default source storage. This example chooses the second overload from above. The data to parse is given as two `const char*` pointers (as the data is not null-terminated) and is, of course, not copied. Consider the source to be an identifier for the packet that was received, e.g. a string constructed from the timestamp, the source IP/port, the interface it was received on, a sequence number, or similar information. Note that this example shows why the source parameter is necessary to disambiguate the overloads. If the source would be optional (defaulted), the signature of this overload would also match the first example and therefore be ambiguous. ### Additional Remarks Note that `noexcept(...)` is a conditional noexcept-specification, depending on whether the construction of the source stored in the class can throw given the perfectly-forwarded parameter `source`. Technically, it is implemented as `noexcept( std::is_nothrow_constructible< Source, T&& >::value )`. With the default `Source` type of `std::string`, the `source` parameter to the constructors is usually a `const char*` or (any reference to) a `std::string`, but anything that can be used to construct a `std::string` will work. When `Source` is set to `const char*` then only a `const char *` (or something that can implicitly be converted to one) will work. The implementation of the constructors is different than shown. They should be used "as if" this was the actual signature. ## String Input The class `string_input<>` can also be used to parse a `std::string`. Unlike class `memory_input<>`, this class stores a copied (or moved) version of the data for which it takes ownership. ```c++ template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf, typename Source = std::string > class string_input { template< typename V, typename T > string_input( V&& data, T&& source ) noexcept(...); template< typename V, typename T > string_input( V&& data, T&& source, const std::size_t byte, const std::size_t line, const std::size_t column ) noexcept(...); }; ``` ### Example ```c++ std::string content(); // returns the content string_input in1( content(), "from_content" ); ``` Construct a `string_input` with default tracking mode, default end-of-line mode (accepting Unix and MS-DOS line endings), and default source storage. The data returned from calling `content()` is copied into the input. The source is `from_content`. ### Additional Remarks Note that the implementation of the constructors is different than shown. They should be used "as if" this was the actual signature. ## Stream Inputs The classes `cstream_input<>` and `istream_input<>` can be used to parse data from C-streams (`std::FILE*`) and C++-streams (`std::istream`), respectively. Unlike the file inputs above, they internally use `buffer_input<>` and therefore do *not* read the complete stream upon construction. They all have a single constructor that takes a stream, the maximum buffer size, and the name of the source. Note that these classes only keep a pointer/reference to the stream and do **not** take ownership; in particular `cstream_input<>` does **not** call `std::close()`. See [Incremental Input](#incremental-input) for details on the `maximum` argument, and how to use the mandatory [discard facilities](#discard-buffer). ```c++ template< typename Eol = eol::lf_crlf > struct cstream_input { cstream_input( std::FILE* stream, const std::size_t maximum, const char* source ); cstream_input( std::FILE* stream, const std::size_t maximum, const std::string& source ); }; template< typename Eol = eol::lf_crlf > struct istream_input { istream_input( std::istream& stream, const std::size_t maximum, const char* source ); istream_input( std::istream& stream, const std::size_t maximum, const std::string& source ); }; ``` Note that the implementation of the constructors is different than shown. They should be used "as if" this was the actual signature. ## Argument Input The class `argv_input<>` can be used to parse a string passed from the command line. ```c++ template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > class argv_input { argv_input( char** argv, const std::size_t n ); argv_input( char** argv, const std::size_t n, const char* source ); argv_input( char** argv, const std::size_t n, const std::string& source ); }; ``` If no `source` is given, the source is set to `"argv[N]"` where N is the string representation of `n`. Note that the implementation of the constructors is different than shown. They should be used "as if" this was the actual signature. ## Parse Function The parse functions accept the following template parameters and arguments: - The [`Rule` class](Rules-and-Grammars.md) represents the top-level parsing rule of the grammar and is mandatory. - The [`Action<>` class template](Actions-and-States.md) is required to actually do something during a parsing run. - The [`Control<>` class template](Control-and-Debug.md) is only required for grammar debugging or some advanced uses. - The [`States`](Actions-and-States.md#changing-states) are the types of the objects that are passed to all actions and control hooks. Additionally, two enumeration values can be used to control the behaviour: - The `apply_mode` which can also be set to `nothing` in order to disable action invocations, just like the `disable<>` rule does. - The `rewind_mode` which can also be set to `dontcare` in order to not require rewinding of the input on local failure, a micro optimisation. The result of a parsing run, i.e. an invocation of `tao::pegtl::parse()`, can be either - *success*, a return value of `true`, - *local failure*, a return value of `false`, - *global failure*, an exception of type `tao::pegtl::parse_error`, or - any other exception thrown by the input class or an action function. ```c++ 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 ParseInput, typename... States > bool parse( ParseInput& in, States&&... st ); ``` ## Nested Parsing 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...". 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. ```c++ 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( 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 The PEGTL is designed and optimised for parsing single contiguous blocks of memory like a memory-mapped file or the contents of a `std::string`. In cases where the data does not fit into memory, or other reasons prevent parsing the data as single memory block, an *incremental* input can be used. This allows parsing with only (small) portions of the input in a memory buffer at any single time. The buffer is filled automatically, however the [*discard* facilities](#discard-buffer) must be used to regularly flush the buffer and make space for a new portion of input data. The [stream inputs](#stream-inputs) are ready-to-use input classes for C++-style and C-style streams. Apart from having to use the [discard facilities](#discard-buffer), and some extra care when implementing [custom rules](#custom-rules), they can be used just like any other [input class](Inputs-and-Parsing.md). ### Buffer Size The [stream inputs](#stream-inputs), and all other inputs based on `buffer_input<>`, contain a buffer that is allocated in the constructor. The buffer capacity is the sum of a *maximum* value and a *chunk* size. The maximum value is passed to the constructor as function argument, the chunk size is a (rarely changed) template parameter. The required buffer capacity depends on the grammar, the actions, *and* the input data. The buffer must be able to hold * any and all data for look-ahead performed by the grammar, * any and all data for back-tracking performed by the grammar, * any and all data for actions' [`apply()`](Actions-and-States.md#apply) (not [`apply0()`](Actions-and-States.md#apply0)). For example consider an excerpt from the JSON grammar from `include/tao/pegtl/contrib/json.hpp`. ```c++ struct xdigit : abnf::HEXDIG {}; struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {}; struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {}; struct escaped : sor< escaped_char, unicode > {}; struct unescaped : utf8::range< 0x20, 0x10FFFF > {}; struct char_ : if_then_else< one< '\\' >, must< escaped >, unescaped > {}; struct string_content : until< at< one< '"' > >, must< char_ > > {}; struct string : seq< one< '"' >, must< string_content >, any > { using content = string_content; }; ``` The rule `string_content` matches JSON strings as they occur in a JSON document. If an action with `apply()` (rather than `apply0()`) is attached to the `string_content` rule, the buffer capacity is an upper bound on the length of the JSON strings that can be processed. If the actions are only attached to say `unescaped`, `escaped_char` and `rep< 4, must< xdigit > >`, the latter because it, too, occurs in an (implicit, inside of `list`) unbounded loop, then the JSON strings are processed unescaped-character-by-unescaped-character and escape-sequence-by-escape-sequence. As long as the buffer is [discarded](#discard-buffer) frequently, like after every unescaped character and every single escape sequence, a buffer capacity as small as 8 or 12 should suffice for parsing arbitrarily long JSON strings. Note that the [`eof`](Rule-Reference.md#eof) rule requires at least one byte of free buffer space when there is no unconsumed data in the buffer. ### Discard Buffer To prevent the buffer from overflowing, the `discard()` member function of class `buffer_input<>` must be called regularly. **Discarding invalidates all pointers to the input's data and MUST NOT be used where backtracking to before the discard might occur AND/OR nested within a rule for which an action with input can be called.** Calling `discard()` on a non-buffered input is an empty method and will be optimised away completely. Usually you don't call `discard()` manually. Instead, one of the two following methods might be used. #### Via Rules The [`discard`](Rule-Reference#discard) rule behaves just like the [`success`](Rule-Reference.md#success) rule but calls the discard function on the input before returning `true`. #### Via Actions The `tao::pegtl::discard_input`, `tao::pegtl::discard_input_on_success` and `tao::pegtl::discard_input_on_failure` [actions](Actions-and-States.md) can be used to discard input non-intrusively, i.e. without changing the grammar like with the [`discard`](Rule-Reference.md#discard) rule. These actions are used in the usual way, by deriving a custom action class template specialisation from them. In the case of `discard_input`, the input is discarded unconditionally after every match attempt of the rule that the action is attached to. As `discard_input` is based on the `match()` method, it is unaffected by enabling or disabling actions (which only applies to the `apply`/`apply0`-methods). The other two variants behave as implied by their respective names, keeping in mind that "failure" is to be understood as "local failure" (false), no discard is performed on global failure (exception). Similarly "unconditional" is wrt. success or local failure, not global failure. ```c++ template<> struct my_action< R > : tao::pegtl::discard_input { // It is safe to implement apply() here if appropriate: // discard() will be called by discard_input's match() // only _after_ calling this action's apply(). }; ``` In practice, since the "must"-rules like `must<>` and `if_must<>` inhibit backtracking, they can be good indicators of where to perform a discard. For example consider again this rule from the JSON grammar from `include/tao/pegtl/contrib/json.hpp`. ```c++ struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {}; ``` The `xdigit` rule is within a `must`, wherefore we know that no backtracking is possible, so we could discard after `xdigit` or `must< xdigit >`. However then we can't attach an action with [`apply()`](Actions-and-States.md#apply) to the `rep< 4, ... >` since we would be discarding after every single digit. This is not ideal, it would be more efficient to process all four xdigits in a single action invocation. Looking close we can see that backtracking to before the `rep<>` is actually impossible because once the `list<>` has successfully matched `seq< one< 'u' >, rep< 4, must< xdigit > > >` it will never go back. It will attempt to match another backslash, the list item separator, and if successful loop to the `seq<>`, but once the next character is a `'u'`, the `must<>` in the `rep` seals the deal, there is no way to not complete the next list entry. Therefore we can safely attach an action to the `rep<>` that processes the four xdigits and then discards the input. ```c++ template<> struct my_action< rep< 4, must< xdigit > > : tao::pegtl::discard_input { template< typename ActionInput > static void apply( const ActionInput& in, /* the states */ ) { assert( in.size() == 4 ); // process the 4 xdigits } }; ``` Another good candidate in the JSON grammar to discard after is the `tao::pegtl::json::value` rule... ### Custom Rules All incremental inputs included with the library and documented here are based on `buffer_input<>`. A custom rule that is compatible with incremental inputs needs to pay attention to the `amount` argument in the input's interface. Unlike the inputs based on `memory_input<>`, the `size( amount )` and `end( amount )` member functions do not ignore the `amount` argument, and the `require( amount )` member function is not a complete dummy. ```c++ template< ... > class buffer_input { bool empty(); std::size_t size( const std::size_t amount ); const char* end( const std::size_t amount ); void require( const std::size_t amount ); ... }; ``` The `require( amount )` member function tells the input to make available at least `amount` unconsumed bytes of input data. It is not normally called directly unless there is good reason to prefetch some data. The `empty()`, `size( amount )` and `end( amount )` member functions call `require( amount )`, or, in the case of `empty()`, `require( 1 )`. The `amount` parameter should be understood as a parsing rule wishing to inspect and consume *up to* `amount` bytes of input. A custom rule must make sure to use appropriate values of `amount`. For examples of how the `amount` is set by parsing rules please search for `in.size` in `include/tao/pegtl/internal/`. ### Custom Readers An incremental input consists of `buffer_input<>` together with a *reader*, a class or function that is used by the buffer input to fill the buffer. The buffer input is a class template with multiple template parameters. ```c++ template< typename Reader, typename Eol = eol::lf_crlf, typename Source = std::string, std::size_t Chunk = 64 > class buffer_input; ``` The `Eol` and `Source` parameters are like for the other [input classes](Inputs-and-Parsing.md#memory-input). The `Chunk` parameter is explained below in detail. The `Reader` can be anything that can be called like the following wrapper. ```c++ std::function< std::size_t( char* buffer, const std::size_t length ) > ``` The arguments and return value are similar to other `read()`-style functions, a request to read `length` bytes into the memory pointed to by `buffer` that returns the number of bytes actually read. Reaching the end of the input MUST be the only reason for the reader to return zero. The reader might be called again after returning zero, with the expectation of returning zero again. Note that `buffer_input<>` consumes the first two arguments to its constructor for the *source* and *maximum*, and uses perfect forwarding to pass everything else to the constructor of the embedded instance of `Reader`. For examples of how to implement readers please look at `istream_reader.hpp` and `cstream_reader.hpp` in `include/tao/pegtl/internal/`. ### Buffer Details The buffer input's `Chunk` template parameter is actually used in multiple places. 1. The `maximum` buffer capacity passed by the user is incremented by `Chunk`. 2. A discard does nothing when there are less than `Chunk` bytes of consumed buffered data. 3. The buffer input requests at least `Chunk` bytes from the reader if there is enough space. Note that the first and second point go hand-in-hand, in order to optimise away some discards, the buffer must be extended in order to guarantee that at least `maximum` bytes can be buffered after a call to discard, even when it does nothing. The third point is simply an optimisation to call the reader less frequently. ## Error Reporting When reporting an error, one often wants to print the complete line from the input where the error occurred and a marker at the position where the error is found within that line. To support this, the `memory_input<>` class has member functions `at( p )`, `begin_of_line( p )`, `end_of_line( p )` and `line_at( p )` which take a `tao::pegtl::position` as parameter. The first three functions return a `const char*` to position `p`, the begin-of-line before `p`, or the end-of-line after `p` (or the end of the input if the input is not terminated by an end-of-line), respectively. For convenience, `line_at( p )` returns a `std::string_view` with the complete line around `p`. Example usage: ```c++ // create input 'in' here... try { // call parse on the input 'in' here... } catch( const parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << std::endl << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; } ``` All input classes based on `memory_input<>` support the above, while all classes based on `buffer_input<>` are unable to supply the same functionality as previous input might have been discarded already. Trying to call any of those functions on `buffer_input<>`-based instances will lead to a compile error. ## Deduction Guides All input classes support [deduction guides](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction), e.g. instead of `file_input<> in( "filename.txt" )` one can use `file_input in( "filename.txt" )`. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Installing-and-Using.md000066400000000000000000000307351426407250600204530ustar00rootroot00000000000000# Installing and Using ## Contents * [Requirements](#requirements) * [Filesystem](#filesystem) * [Disabling Exceptions](#disabling-exceptions) * [Disabling RTTI](#disabling-rtti) * [Installation Packages](#installation-packages) * [Using Vcpkg](#using-vcpkg) * [Using Conan](#using-conan) * [Using CMake](#using-cmake) * [CMake Installation](#cmake-installation) * [`find_package`](#find_package) * [`add_subdirectory`](#add_subdirectory) * [Mixing `find_package` and `add_subdirectory`](#mixing-find_package-and-add_subdirectory) * [Manual Installation](#manual-installation) * [Embedding the PEGTL](#embedding-the-pegtl) * [Embedding in Binaries](#embedding-in-binaries) * [Embedding in Libraries](#embedding-in-libraries) * [Embedding in Library Interfaces](#embedding-in-library-interfaces) * [Single Header Version](#single-header-version) ## Requirements The PEGTL requires a C++17-capable compiler, e.g. one of * GCC 7 * Clang 5 * Visual Studio 2017 on either * Linux * macOS * Windows It requires C++17, e.g. using the `--std=c++17` compiler switch. Using newer versions of the C++ standard is supported. Larger projects will frequently require the `/bigobj` option when compiling with Visual Studio on Windows. It should also work with other C++17 compilers on other Unix systems (or any sufficiently compatible platform). 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 `` 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: * The following rules are unavailable: * `raise<>`. * `try_catch<>`. * `try_catch_type<>`. * `must<>`. * `if_must<>`. * `if_must_else<>`. * `list_must<>`. * `opt_must<>`. * `star_must<>`. * The following headers are unavailable: * `tao/pegtl/contrib/http.hpp`. * `tao/pegtl/contrib/integer.hpp`. * `tao/pegtl/contrib/uri.hpp`. * The error control class template `must_if<>` is unavailable. * Some of our tests and examples are disabled or limited (via `#if`). ## Disabling RTTI The PEGTL is compatible with `-fno-rtti` on GCC, Clang, and MSVC. An exception are GCC 9.1 and GCC 9.2, see [bug #91155](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91155). On unknown compilers, we use RTTI by default (for demangling), please report any such compiler and it might be possible to extend support for disabling RTTI for those compilers as well. ## Installation Packages Packaging status Installation packages are available from several package managers. Note that some of the listed packages are not updated regularly. ## Using Vcpkg [![Vcpkg package](https://repology.org/badge/version-for-repo/vcpkg/pegtl.svg)](https://repology.org/project/pegtl/versions) You can download and install the PEGTL using the [Vcpkg] package manager: ```bash vcpkg install pegtl:x64-linux pegtl:x64-osx pegtl:x64-windows ``` The `pegtl` package in Vcpkg is kept up to date by the Vcpkg team members and community contributors. If the version is out-of-date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the Vcpkg repository. For more options and ways to use Vcpkg, please refer to the [Vcpkg documentation]. ## Using Conan You can download and install the PEGTL using the [Conan] package manager: ```bash conan install taocpp-pegtl/@ ``` where `` is the version of the PEGTL you want to use. The `taocpp-pegtl` package in Conan is kept up to date by Conan team members and community contributors. If the version is out-of-date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the Conan Center Index repository. For more options and ways to use Conan, please refer to the [Conan documentation]. ## Using CMake ### CMake Installation The PEGTL can be built and installed using [CMake], e.g. ```sh $ mkdir build $ cd build $ cmake .. $ make $ make install ``` The above will install the PEGTL into the standard installation path on a UNIX system, e.g. `/usr/local/include/`. To change the installation path, use: ```sh $ cmake .. -DCMAKE_INSTALL_PREFIX=../install ``` in the above. ### `find_package` Installation creates a `pegtl-config.cmake` which allows CMake projects to find the PEGTL using `find_package`: ```cmake find_package(pegtl) ``` This exports the `taocpp::pegtl` target which can be linked against any other target. Linking against `taocpp::pegtl` automatically sets the include directories and required flags for C++17 or later. For example: ```cmake add_executable(myexe mysources...) target_link_libraries(myexe PRIVATE taocpp::pegtl) ``` ### `add_subdirectory` The PEGTL can also be added as a dependency with `add_subdirectory`: ```cmake add_subdirectory(path/to/PEGTL) ``` This also exports the `taocpp::pegtl` target which can be linked against any other target just as with the installation case. Due to the global nature of CMake targets the target `pegtl` is also defined, but only `taocpp::pegtl` should be used for consistency. If `PEGTL_BUILD_TESTS` is true then the test targets, `pegtl-test-*`, are also defined and their corresponding tests registered with `add_test`. If `PEGTL_BUILD_EXAMPLES` is true then the example targets, `pegtl-example-*`, are also defined. ### Mixing `find_package` and `add_subdirectory` With the advent of improved methods of managing dependencies (such as [Conan], [CMake FetchContent]), multiple package inclusion methods needs to be able to co-exist. If PEGTL was first included with `find_package` then subsequent calls to `add_subdirectory(path/to/PEGTL)` will skip over the body of the `CMakeLists.txt` and use the installed package if the version matches. If the version does not match a fatal error will be signalled. If PEGTL was first included with `add_subdirectory` then a dummy `pegtl-config.cmake` is created and `pegtl_DIR` is set. Subsequent calls to `find_package(pegtl)` will then use the already added package if the version matches. If the version does not match a fatal error will be signalled. Since CMake targets are global, there exists no way for a CMake project to use two different versions of PEGTL simultaneously and signalling a fatal error becomes the only practical way of handling the inclusion of multiple different PEGTL versions. For more options and ways to use CMake, please refer to the [CMake documentation]. ## Manual Installation Since the PEGTL is a header-only library, _it doesn't itself need to be compiled_. In terms of installation for use in other projects, the following steps are required. - The `include/` directory and the `LICENSE` file should be copied somewhere, e.g. - to `/usr/local/include/` in order to use it system-wide, or - to some appropriate directory within your project, - A compatible compiler with appropriate compiler switches must be used. - The compiler search-path for include files must include (no pun intended) the directory that contains the `tao/pegtl/` directory and `tao/pegtl.hpp` header. The `Makefile` and `.cpp`-files included in the PEGTL distribution archive serve as practical examples on how to develop grammars and applications with the PEGTL. Invoking `make` in the main PEGTL directory builds all included example programs and builds and runs all unit tests. The `Makefile` is as simple as possible, but should manage to build the examples and unit tests on Linux with GCC and on macOS with Clang (as supplied by Apple). When running into problems using other combinations, please consult the `Makefile` for customising the build process. ## Embedding the PEGTL When embedding the PEGTL into other projects, several problems may come up due to the nature of C++ header-only libraries. Depending on the scenario, there are various ways of working around these problems. ### Embedding in Binaries When creating application binaries, i.e. executable files, the PEGTL source tree can be copied to some subdirectory in the application source, and added to the compiler's or project's include paths. No further changes are needed. ### Embedding in Libraries When writing libraries with the PEGTL, it has to be ensured that applications that are built with these libraries, and that themselves use the PEGTL, do not violate the One Definition Rule (ODR) as would be the case when application and libraries contain different versions of the PEGTL. Since the PEGTL does *not* guarantee ABI compatibility, not even across minor or patch releases, libraries *have* to ensure that the symbols for the PEGTL they include differ from those of the applications that use them. This can be achieved by changing the macro `TAO_PEGTL_NAMESPACE` which, by default, is set to `tao::pegtl`. To change the namespace, simply define `TAO_PEGTL_NAMESPACE` to a unique name before including the PEGTL, for example: ```c++ #define TAO_PEGTL_NAMESPACE mylib::pegtl #include #include int main( int argc, char* argv[] ) { if( argc > 1 ) { mylib::pegtl::argv_input in( argv, 1 ); mylib::pegtl::parse< mylib::pegtl::json::text >( in ); } } ``` ### Embedding in Library Interfaces When PEGTL headers are included in headers of a library, setting the namespace to a unique name via `TAO_PEGTL_NAMESPACE` is not sufficient since both the application's and the library's copy of the PEGTL use the same macro names. In this case it is necessary to change the prefix of all macros of the embedded PEGTL from `TAO_PEGTL_` to another unique string in order to prevent macros from clashing. In a Unix-shell, the following command will achieve this: ```sh $ sed -i 's/TAO_PEGTL_/MYLIB_PEGTL_/g' $(find -name '[^.]*.[hc]pp') ``` The above command needs to run from the top-level directory of the embedded PEGTL. Additionally, `MYLIB_PEGTL_NAMESPACE` needs to be set as explained above; alternatively `include/tao/pegtl/config.hpp` can be directly modified. A practical example of how the result looks like can be found in our own header-only JSON library [taoJSON](https://github.com/taocpp/json/). ## Single Header Version You can generate a single-header-version of the PEGTL with the included `Makefile`. In a Unix-shell, the following command will achieve this: ```sh $ make amalgamate ``` The above will generate a `build/amalgamated/pegtl.hpp` which will consist of the headers `tao/pegtl.hpp`, their dependencies, and all headers in `tao/pegtl/contrib/` except for the headers in `tao/pegtl/contrib/icu/`. Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey [Vcpkg]: https://github.com/Microsoft/vcpkg [Vcpkg documentation]: https://github.com/Microsoft/vcpkg/tree/master/docs/index.md [Conan]: https://conan.io/ [Conan documentation]: https://docs.conan.io/ [CMake]: https://cmake.org/ [CMake documentation]: https://cmake.org/documentation/ [CMake FetchContent]: https://cmake.org/cmake/help/latest/module/FetchContent.html tao-pegtl-3.2.7/doc/Json-Parse-Tree.svg000066400000000000000000000234201426407250600175720ustar00rootroot00000000000000 parse_tree x0x1690eb0 ROOT x0x1691240 tao::pegtl::json::object "{\"foo\":[true,{}],\"bar\":[42,null]}" x0x1690eb0->x0x1691240 x0x16913f0 tao::pegtl::json::member "\"foo\":[true,{}]" x0x1691240->x0x16913f0 x0x1691870 tao::pegtl::json::member "\"bar\":[42,null]" x0x1691240->x0x1691870 x0x1691510 tao::pegtl::json::key "\"foo\"" x0x16913f0->x0x1691510 x0x16916c0 tao::pegtl::json::array "[true,{}]" x0x16913f0->x0x16916c0 x0x1691900 tao::pegtl::json::key "\"bar\"" x0x1691870->x0x1691900 x0x1691c70 tao::pegtl::json::array "[42,null]" x0x1691870->x0x1691c70 x0x1691480 tao::pegtl::json::true_ "true" x0x16916c0->x0x1691480 x0x1691b50 tao::pegtl::json::object "{}" x0x16916c0->x0x1691b50 x0x1691630 tao::pegtl::json::number "42" x0x1691c70->x0x1691630 x0x1691e80 tao::pegtl::json::null "null" x0x1691c70->x0x1691e80 tao-pegtl-3.2.7/doc/Meta-Data-and-Visit.md000066400000000000000000000205321426407250600201070ustar00rootroot00000000000000# Meta Data and Visit Each rule has several type aliases that allow for automatic inspection of a grammar and all of its rules for multiple purposes. Note that true custom rules, i.e. rules that implement custom `match()` functions, do **not** need to define these type aliases for parsing. They are only required to support functions based on `visit()` and the [grammar analysis](Grammar-Analysis.md). * [Internals](#internals) * [Rule Type](#rule-type) * [Sub Rules](#sub-rules) * [Grammar Visit](#grammar-visit) * [Grammar Print](#grammar-print) * [Rule Coverage](#rule-coverage) ## Internals While accessible in the namespace `TAO_PEGTL_NAMESPACE`, which defaults to `tao::pegtl`, the [rules and combinators](Rule-Reference.md) included with the PEGTL all have their actual implementation in the sub-namespace `internal`. For example the header `include/tao/pegtl/rules.hpp` shows how the user-facing rules are nothing more than forwarders to their `internal` implementation. The original motivation for this additional level of indirection was to prevent uninteded invocation of user-defined actions due to some PEGTL rules being built from exisiting rules instead of having a dedicated implementation. For example consider `rep_min` from `include/tao/pegtl/internal/rep_min.hpp`. ```c++ template< unsigned Min, typename Rule, typename... Rules > using rep_min = seq< rep< Min, Rule, Rules... >, star< Rule, Rules... > >; ``` The expansion of `rep_min` uses the sub-rule `star< Rule, Rules... >`. If a grammar were to contain both `rep_min` and `star` with the same sub-rules, and an action were provided for `star` with these exact sub-rules, then the action would not only be called for the explicit occurrences of `star` in the grammar but *also* for the corresponding sub-rule of `rep_min`. The action invocation for the sub-rule of `rep_min` is considered surprising and undesirable because it exposes implementation details to the user, forces her to deal with them, and breaks her grammar if the implementation were to change. Therefore it is possible to selectively disable most of the [control](Control-and-Debug.md) functions, including the `apply`-functions that perform action invocation, on a rule-by-rule basis. More precisely, the action and debug control functions are only invoked for a rule `R` when `control< R >::enable` is `true`. ```c++ template< typename Rule > struct normal { static constexpr bool enable = internal::enable_control< Rule >; // ... }; ``` The default control class template `normal` defines `normal< R >::enable` in terms of `internal::enable_control< R >` which is `true` by default, but `false` for all rules in sub-namespace `internal`, thereby hiding all invocations of `internal` rules from all actions and most of the control class functions. The facilities documented on this page however do **not** hide the implementation details since, while debugging a grammar or a parsing run, it is essential to have a complete picture. ## Rule Type For each rule `R`, the type alias `R::rule_t` is defined as the type of the class that actually implements the `match()` function. This is usually the root of the inheritance hierarchy. Note that `R::rule_t` can be completely different from `R`. For example while `seq< R >::rule_t` is `internal::seq< R >`, due to `seq<>` being not only equivalent to `success`, but also implemented in terms of it, `seq<>::rule_t` is actually `internal::success`. In each rule's implementation mapping section the [rule reference](Rule-Reference.md) shows how `rule_t` is defined depending on the template parameters. ## Sub Rules For each rule `R`, the type alias `R::subs_t` is an instantiation of `type_list` with all the direct sub-rules of `R` as template parameters. For example `seq< R, S >::subs_t` is `type_list< R, S >` and `alpha::subs_t` is `type_list<>`. Note that for many rules with sub-rules the corresponding `subs_t` is not as might be expected. For example `enable< R, S >::subs_t` is `type_list< internal::seq< R, S > >` instead of the probably expected `type_list< R, S >`. Please again consult the [Rule Reference](Rule-Reference.md) (or the source) for how `subs_t` is defined for all included rules. ## Grammar Visit The `visit()` function uses `subs_t` to recursively find all sub-rules of a grammar and call a function for each of them. 1. The first, explicit, template parameter of `visit()` is the starting rule of the grammar that is to be inspected. 2. The second, explicit, template parameter of `visit()` is a class template `F` where, for every sub-rule `R`, `visit()` will call `F< R >::visit()`. All arguments given to `visit()` will be passed on to all `F< R >::visit()` calls. The header `include/tao/pegtl/contrib/visit_rt.hpp` contains a drop-in replacement for `visit()` called `visit_rt()` that uses a run-time data structure, rather than compile-time type lists, to make sure the visitor is called only once for every grammar rule. This can be a advantageous when working with large grammars since it reduces the template instantiation depth by shifting some of the work from compile time to run time. Unlike `visit()`, `visit_rt()` returns the number of rules visited. ## Grammar Print The functions `print_rules()` and `print_sub_rules()` from `include/tao/pegtl/contrib/print.hpp` combine the `visit()` function with visitors that print some information about all (sub-)rules of the supplied grammar to the supplied `std::ostream`. See `src/example/pegtl/json_print_rules.cpp` and `src/example/pegtl/json_print_sub_rules.cpp` for how to use these functions, and what the output looks like. As expected, the `internal` sub-rules are printed, too. ## Rule Coverage The function `coverage()` from `include/tao/pegtl/contrib/coverage.hpp` is very similar to the `parse()` function. It is called like `parse()`, with the some of the same template parameters and all of the same function arguments, however it returns an object of type `coverage_result` instead of a `bool`. ```c++ template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > coverage_result coverage( ParseInput& in, States&&... st ); ``` After a parsing run, the `coverage_result` indicates whether the run was a success or a failure, and contains "rule coverage" and "branch coverage" information. The "rule coverage" shows how often each rule was attempted to match, and how many of these attempts were a success or a -- local or global -- failure. The "branch coverage" consists in the matching information also being recorded for each immediate sub-rule of every rule; in the case of an `sor<>` this shows how often each sub-rule was taken, hence the name. The coverage information in the `coverage_result` can either be inspected and processed or printed manually, or the `ostream` output `operator<<` from `include/tao/pegtl/contrib/print_coverage.hpp` can be used. The operator formats the output as JSON. ```c++ std::ostream operator<<( std::ostream&, const coverage_result& ); ``` The coverage information in the `coverage_result` is defined as follows. The `coverage_info` is used in two places, as part of the `coverage_entry` for each rule, and as value in the `branches` map for each immediate sub-rule. ```c++ struct coverage_info { std::size_t start = 0; // How often a rule was attempted to match. std::size_t success = 0; // How many attempts were a success (true). std::size_t failure = 0; // How many attempts were a local failure (false). std::size_t unwind = 0; // How many attempts were aborted due to an exception (thrown here or elsewhere). std::size_t raise = 0; // How many attempts were a global failure (exception thrown at this rule). }; struct coverage_entry : coverage_info // The coverage_info for each rule. { std::map< std::string_view, coverage_info > branches; // The coverage_info for each immediate sub-rule. }; struct coverage_result { std::string_view grammar; // Name of the top-level grammar rule. std::string source; // From the input. std::map< std::string_view, coverage_entry > map; // The coverage_entry for each rule. bool result; // Whether the parsing run was a success. }; ``` As usual, unless otherwise indicated, all functions and data structure are in the namespace `tao::pegtl`. Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Migration-Guide.md000066400000000000000000000075151426407250600175100ustar00rootroot00000000000000# Migration Guide ## Version 3.0.0 * The build system needs to be configured for C++17 or later. * The macro `TAO_PEGTL_NAMESPACE` now defines the fully qualified namespace and was changed from `pegtl` to `tao::pegtl`. When setting `TAO_PEGTL_NAMESPACE`, adapt as needed; in case of doubt, add `tao::` as prefix. * The 0-based `byte_in_line` was replaced with the 1-based `column`. * The control class template's `apply()` and `apply0()` must only be visible (e.g. via SFINAE) when an action class template function with the appropriate signature exists. See `tao::pegtl::normal` as example. * If you have a use-case for [state](Rule-Reference.md#state-s-r-)'s `S::success()` to have an extended signature to get access to the current `apply_mode`, `rewind_mode`, *action*- and *control* class (template), please let us know and we'll re-add this feature. * The compatibility macros starting with `TAOCPP_PEGTL_` were removed, the corresponding `TAO_PEGTL_`-prefixed macros must be used. * The compatibility uppercase enumerators were removed, the corresponding lowercase enumerators must be used. * The compatibility `peek_byte()` member functions were removed, the `peek_uint8()` member functions must be used. * The compatibility header `changes.hpp` was removed, use the action-based `change_*.hpp` headers. * The parse tree nodes provide `node->type` (a `std::string_view`) instead of `node->name()`. * The parse tree nodes provide `node->string_view()` and `node->string()` instead of `node->content()`. ## Version 2.8.0 * All enumerators were changed from uppercase to lowercase. * The enumerator `tracking_mode::IMMEDIATE` was renamed to `tracking_mode::eager`. * The input-classes' `peek_byte()` member function was renamed to `peek_uint8()`. Compatibility enumerators and functions are provided, they will be removed in version 3.0.0. ## Version 2.4.0 * The common prefix for all macros was changed from `TAOCPP_PEGTL_` to `TAO_PEGTL_`. Compatibility macros are provided, they will be removed in version 3.0.0. ## Version 2.0.0 Some of the [changes](Changelog.md#200) for version 2.0.0 require modifications to any source using the PEGTL. The good news is that the semantics of all parsing rules and grammars is the same as for versions 1.x. Existing grammars will continue to work as before once the following list of mostly naming and namespace related changes is taken into account. * Everything in the PEGTL is now in namespace `tao::pegtl`. * The file name extensions were changed from `.hh` to `.hpp`. * The main include file is now ``, all other include files are ``. * The distribution of tasks between [the parse functions and input classes](Inputs-and-Parsing.md) was changed. * The string macros have been renamed from `pegtl_(i)string_t` to `TAOCPP_PEGTL_(I)STRING`. * The `begin()` member function of the input-classes is now called `current()`. * The first argument to actions' `apply()` is now of type `tao::pegtl::internal::action_input< ... >`. For flexibility and future compatibility it is recommended to "template over" the first argument to `apply()` as shown in [Actions and States](Actions-and-States.md#actions). The `pegtl` part of the namespace can be controlled with the `TAOCPP_PEGTL_NAMESPACE` macro which is set in `include/tao/pegtl/config.hpp` if not defined previously. Most of the other changes for version 2.0.0 extend or optimise the PEGTL without breaking compatibility. Applications integrated more tightly with the PEGTL might require additional changes. Please contact the authors at `taocpp(at)icemx.net` for any further questions when updating the PEGTL. ## Version 1.0.0 There were [many important changes](Changelog.md#100) leading up to version 1.0.0. Please contact the authors at `taocpp(at)icemx.net` for any further questions when updating the PEGTL. Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Parse-Tree.md000066400000000000000000000237401426407250600164710ustar00rootroot00000000000000# Parse Tree The PEGTL provides facilities for building a [parse tree](https://en.wikipedia.org/wiki/Parse_tree) (or [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). It provides the basic infrastructure to build a parse tree that * by default is *complete*, with one tree node for every successfully matched rule, * with an optional *selection* to only generate nodes for a chosen subset of rules; * by default uses the included tree node class that stores all pertinent information, * but can also be used with a custom tree node class that adheres to certain rules; * and supports on-the-fly tree transformations; some of the more common ones are included. ## Content * [Full Parse Tree](#full-parse-tree) * [Partial Parse Tree](#partial-parse-tree) * [Transforming Nodes](#transforming-nodes) * [Transformers](#transformers) * [`tao::pegtl::parse_tree::node`](#taopegtlparse_treenode) * [Custom Node Class](#custom-node-class) * [Requirements](#requirements) ## Full Parse Tree To obtain a (complete) parse tree, simply call `tao::pegtl::parse_tree::parse()` with a grammar and an input. ```c++ #include auto root = tao::pegtl::parse_tree::parse< my_grammar >( in ); ``` The result is a `std::unique_ptr< tao::pegtl::parse_tree::node >`. The pointer is empty when the input did not match the grammar, otherwise it contains the root node of the resulting parse tree. The tree nodes have a `type` member that contains the name of the grammar rule of which it represents a successful match, `begin()` and `end()` member functions to access the position of the matched portion of the input, `string()` and `string_view()` to actually access said matched input, and a vector called `children` with unique pointers to the child nodes. Note that the included tree node class **points** to the matched data, rather than copying it into the node, wherefore the input **must** still be "alive" when accessing the matched data! A more complete description of the included tree node class can be found below. ## Partial Parse Tree Usually only a subset of grammar rules should generate parse tree nodes. In order to select the grammar rules for which a successful match is to generate a parse tree node, a second template parameter can be passed to `parse_tree::parse()`. This parameter is a class template that is called a *selector*. For each rule `Rule`, the boolean value `selector< Rule >::value` determines whether a parse tree node is generated. ```c++ template< typename Rule > struct my_selector : std::false_type {}; template<> struct my_selector< my_rule_1 > : std::true_type {}; template<> struct my_selector< my_rule_2 > : std::true_type {}; template<> struct my_selector< my_rule_3 > : std::true_type {}; // ... auto root = tao::pegtl::parse_tree::parse< my_grammar, my_selector >( in ); ``` Note that the example uses a white-list style; the default is `std::false_type` and only rules listed with a specialisation deriving from `std::true_type` will generate nodes. The opposite, a black-list style, is of course possible, too. The PEGTL includes a selector class and additional utility classes to allow for a less verbose specification of a selector. The following definition of `my_selector` will behave just like the one above. ```c++ template< typename Rule > using my_selector = tao::pegtl::parse_tree::selector< Rule, tao::pegtl::parse_tree::store_content::on< my_rule_1, my_rule_2, my_rule_3 > >; // ... auto root = tao::pegtl::parse_tree::parse< my_grammar, my_selector >( in ); ``` Note that `store_content` further specifies that the information about the matched portion of the input be stored in the generated nodes; other possibilities are discussed below. ## Transforming Nodes A parse tree, full or partial, can still be too closely related to the structure of the grammar. In order to simplify the tree (or otherwise improve its structure), an optional `transform()` static member function can be added to each specialization of the selector class template (that generates a node). This function gets passed a reference to the current node, which also gives access to the children, but not to the parent: ```c++ template<> struct my_selector< my_rule_2 > : std::true_type { static void transform( std::unique_ptr< node >& n ) { // modify n... } }; ``` `transform` can modify `n` in any way you like, the [`parse_tree.cpp`](https://github.com/taocpp/PEGTL/blob/main/src/example/pegtl/parse_tree.cpp)-example shows two techniques for marking nodes as "content-less", and for transforming the parse tree into an AST. It is also possible to call `n.reset()`, or otherwise set `n` to an empty pointer, which effectively removes `n` (and all of its child nodes) from the parse tree. ## Transformer As shown above, the selector class template allows to specify which nodes should be stored. Several additional helper classes are predefined that have common `transform` methods. The selector allows to add multiple sections with different helpers like this: ```c++ template< typename Rule > using my_selector = tao::pegtl::parse_tree::selector< Rule, tao::pegtl::parse_tree::store_content::on< my_rule_1, my_rule_2, my_rule_3 >, tao::pegtl::parse_tree::remove_content::on< my_rule_4, my_rule_5 >, tao::pegtl::parse_tree::apply< my_helper >::on< my_rule_7, my_rule_8 > >; ``` Note that each rule may only be used in one section, it is an error to add a rule to multiple sections. `store_content` and `remove_content` are predefined by the library, whereas `my_helper` can be defined by yourself. ###### `tao::pegtl::parse_tree::store_content` This stores the node, including pointing to the content it matched on. ###### `tao::pegtl::parse_tree::remove_content` This stores the node, but calls the node's `remove_content` member function. ###### `tao::pegtl::parse_tree::fold_one` This stores the node, but when a node has exactly one child, the node replaces itself with this child, otherwise removes its own content (not children). ###### `tao::pegtl::parse_tree::discard_empty` This stores the node, except for when the node does *not* have any children, in which case it removes itself, otherwise removes its own content (not children). ### Example An example of using some of the transformers can be found in `src/example/pegtl/abnf2pegtl.cpp`. ## `tao::pegtl::parse_tree::node` This is the interface of the node class used by `tao::pegtl::parse_tree::parse` when no custom node class is specified. ```c++ template< typename T, typename Source = std::string_view > struct basic_node { using node_t = T; using children_t = std::vector< std::unique_ptr< node_t > >; children_t children; std::string_view type; Source source; bool is_root() const noexcept; template< typename U > bool is_type() const noexcept; template< typename U > void set_type() noexcept; // precondition from here on: !is_root() position begin() const; position end() const; bool has_content() const noexcept; std::string_view string_view() const noexcept; // precondition: has_content() std::string string() const; // precondition: has_content() template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > memory_input< P, Eol > as_memory_input() const; // useful for transform: void remove_content(); }; struct node : basic_node< node > {}; ``` The name is the demangled name of the rule. By default, all nodes (except the root node) can provide the content that matched, i.e. the part of the input that the rule the node was created for matched. It is only necessary to check `has_content()` when `remove_content()` was used by a transform function (either directly or indirectly via one of the convenience helpers), otherwise all nodes except for the root will always "have content". See [`parse_tree.cpp`](https://github.com/taocpp/PEGTL/blob/main/src/example/pegtl/parse_tree.cpp) for more information on how to output (or otherwise use) the nodes. ## Custom Node Class For more control over how data is stored/handled in the nodes, a custom node class can be utilised. The type of node is passed as an additional template parameter to the parse tree `parse()` function. ```c++ auto r1 = tao::pegtl::parse_tree::parse< my_grammar, my_node >( in ); auto r2 = tao::pegtl::parse_tree::parse< my_grammar, my_node, my_selector >( in ); ``` Note that `my_node` is a class, while `my_selector` is a class template. A custom node class must implement the following interface. ```c++ struct my_node { // Must be default constructible my_node() = default; // Nodes are always owned/handled by a std::unique_ptr // and never copied or assigned... my_node( const my_node& ) = delete; my_node( my_node&& ) = delete; my_node& operator=( const my_node& ) = delete; my_node& operator=( my_node&& ) = delete; // Must be destructible ~my_node() = default; // All non-root nodes receive a call to start() when // a match is attempted for Rule in a parsing run... template< typename Rule, typename ParseInput, typename... States > void start( const ParseInput& in, States&&... st ); // ...and later a call to success() when the match succeeded... template< typename Rule, typename ParseInput, typename... States > void success( const ParseInput& in, States&&... st ); // ...or to failure() when a (local) failure was encountered. template< typename Rule, typename ParseInput, typename... States > void failure( const ParseInput& in, States&&... st ); // After a call to success(), and the (optional) call to the selector's // transform() did not discard a node, it is passed to its parent node // with a call to the parent node's emplace_back() member function. template< typename... States > void emplace_back( std::unique_ptr< node_t > child, States&&... st ); }; ``` ## Requirements The parse tree uses a rule's meta data supplied by [`subs_t`](Meta-Data-and-Visit.md#sub-rules) for internal optimizations. Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Parse-Tree.svg000066400000000000000000000215521426407250600166670ustar00rootroot00000000000000 parse_tree x0x1604e70 ROOT x0x1605200 example::divide x0x1604e70->x0x1605200 x0x16053b0 example::plus x0x1605200->x0x16053b0 x0x1605a60 example::multiply x0x1605200->x0x1605a60 x0x1605560 example::multiply x0x16053b0->x0x1605560 x0x16057e0 example::multiply x0x16053b0->x0x16057e0 x0x16059d0 example::integer "4" x0x1605a60->x0x16059d0 x0x1605b10 example::variable "n" x0x1605a60->x0x1605b10 x0x16054d0 example::integer "2" x0x1605560->x0x16054d0 x0x1605610 example::variable "a" x0x1605560->x0x1605610 x0x1605750 example::integer "3" x0x16057e0->x0x1605750 x0x1605890 example::variable "b" x0x16057e0->x0x1605890 tao-pegtl-3.2.7/doc/Performance-Notes.md000066400000000000000000000045251426407250600200510ustar00rootroot00000000000000# Performance Notes Notes on performance characteristics and optimisation possibilities when writing parsers with the PEGTL. ###### Backtracking For performance reasons a grammar should be designed to minimise backtracking. We will start with a simple example. ```c++ using namespace tao::pegtl; struct R = sor< seq< A, B >, seq< A, C > > {}; // R = (AB)/(AC) ``` If the input matches `seq< A, C >`, then matching `R` on said input will parse `A` twice (assuming that `B` does not match anything that `C` does). The first time `A` will match successfully during the unsuccessful attempt to match `seq< A, B >`. The second time `A` will match the same part of the input successfully again during the successful attempt to match `seq< A, C >`. The solution is to change the grammar as follows. ```c++ struct R = seq< A, sor< B, C > > {}; // R = A(B/C) ``` Not backtracking over `A` has the additional advantage of not triggering any action attached to `A` twice. In practice, opportunities to remove superfluous backtracking might not be as obvious as with such a simple rule. For a more complex example please look at the comment to the Lua 5.3 grammar in `src/example/pegtl/lua53_parse.cpp`. It shows how to eliminate both left-recursion and superfluous backtracking with multiple rules and recursions. ###### Whitespace etc. ###### Regarding `at` and `one` The `at<>`-rule never consumes input, and therefore always uses an input-marker to rewind the input back to where it started, regardless of the match-result. In the context of optimising our [JSON library](https://github.com/taocpp/json), we noticed that the combination `at< one< ... > >` could be combined into an optimised `at_one< ... >` rule: Instead of `one< ... >` advancing the input, and `at< one< ... > >` rewinding, the combined rule would omit both the advancing and the rewinding. Put to the test, the optimised `at_one< '"' >` rule did not show any performance advantage over `at< one< '"' > >`, at least with `-O3`. Presumably the compiler was smart enough to perform the optimisation by itself. However with `-O0`, the optimised `at_one< '"' >` was faster by 5-10% in a [JSON library](https://github.com/taocpp/json) micro-benchmark. We still need to test whether the compiler manages to perform the same optimisation in more complex cases. Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/README.md000066400000000000000000000671321426407250600154620ustar00rootroot00000000000000# PEGTL Documentation * [Project](https://github.com/taocpp/PEGTL) * [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) * [Using Vcpkg](Installing-and-Using.md#using-vcpkg) * [Using Conan](Installing-and-Using.md#using-conan) * [Using CMake](Installing-and-Using.md#using-cmake) * [CMake Installation](Installing-and-Using.md#cmake-installation) * [`find_package`](Installing-and-Using.md#find_package) * [`add_subdirectory`](Installing-and-Using.md#add_subdirectory) * [Mixing `find_package` and `add_subdirectory`](Installing-and-Using.md#mixing-find_package-and-add_subdirectory) * [Manual Installation](Installing-and-Using.md#manual-installation) * [Embedding the PEGTL](Installing-and-Using.md#embedding-the-pegtl) * [Embedding in Binaries](Installing-and-Using.md#embedding-in-binaries) * [Embedding in Libraries](Installing-and-Using.md#embedding-in-libraries) * [Embedding in Library Interfaces](Installing-and-Using.md#embedding-in-library-interfaces) * [Single Header Version](Installing-and-Using.md#single-header-version) * [Rules and Grammars](Rules-and-Grammars.md) * [Combining Existing Rules](Rules-and-Grammars.md#combining-existing-rules) * [Toy S-Expression Grammar](Rules-and-Grammars.md#toy-s-expression-grammar) * [Creating New Rules](Rules-and-Grammars.md#creating-new-rules) * [Simple Rules](Rules-and-Grammars.md#simple-rules) * [Complex Rules](Rules-and-Grammars.md#complex-rules) * [Actions and States](Actions-and-States.md) * [Overview](Actions-and-States.md#overview) * [Example](Actions-and-States.md#example) * [States](Actions-and-States.md#states) * [Apply](Actions-and-States.md#apply) * [Apply0](Actions-and-States.md#apply0) * [Inheriting](Actions-and-States.md#inheriting) * [Specialising](Actions-and-States.md#specialising) * [Changing Actions](Actions-and-States.md#changing-actions) * [Via Rules](Actions-and-States.md#via-rules) * [Via Actions](Actions-and-States.md#via-actions) * [Changing States](Actions-and-States.md#changing-states) * [Via Rules](Actions-and-States.md#via-rules-1) * [Via Actions](Actions-and-States.md#via-actions-1) * [Changing Actions and States](Actions-and-States.md#changing-actions-and-states) * [Match](Actions-and-States.md#match) * [Nothing](Actions-and-States.md#nothing) * [Backtracking](Actions-and-States.md#backtracking) * [Troubleshooting](Actions-and-States.md#troubleshooting) * [Boolean Return](Actions-and-States.md#boolean-return) * [State Mismatch](Actions-and-States.md#state-mismatch) * [Legacy Actions](Actions-and-States.md#legacy-actions) * [Errors and Exceptions](Errors-and-Exceptions.md) * [Global Failure](Errors-and-Exceptions.md#global-failure) * [Local to Global Failure](Errors-and-Exceptions.md#local-to-global-failure) * [Intrusive Local to Global Failure](Errors-and-Exceptions.md#intrusive-local-to-global-failure) * [Non-Intrusive Local to Global Failure](Errors-and-Exceptions.md#non-intrusive-local-to-global-failure) * [Global to Local Failure](Errors-and-Exceptions.md#global-to-local-failure) * [Examples for Must Rules](Errors-and-Exceptions.md#examples-for-must-rules) * [Custom Exception Messages](Errors-and-Exceptions.md#custom-exception-messages) * [Rule Reference](Rule-Reference.md) * [Meta Rules](Rule-Reference.md#meta-rules) * [Combinators](Rule-Reference.md#combinators) * [Convenience](Rule-Reference.md#convenience) * [Action Rules](Rule-Reference.md#action-rules) * [Atomic Rules](Rule-Reference.md#atomic-rules) * [ASCII Rules](Rule-Reference.md#ascii-rules) * [Unicode Rules](Rule-Reference.md#unicode-rules) * [ICU Support](Rule-Reference.md#icu-support) * [Basic ICU Rules](Rule-Reference.md#basic-icu-rules) * [ICU Rules for Binary Properties](Rule-Reference.md#icu-rules-for-binary-properties) * [ICU Rules for Enumerated Properties](Rule-Reference.md#icu-rules-for-enumerated-properties) * [ICU Rules for Value Properties](Rule-Reference.md#icu-rules-for-value-properties) * [Binary Rules](Rule-Reference.md#binary-rules) * [Full Index](Rule-Reference.md#full-index) * [Inputs and Parsing](Inputs-and-Parsing.md) * [Tracking Mode](Inputs-and-Parsing.md#tracking-mode) * [Line Ending](Inputs-and-Parsing.md#line-ending) * [Source](Inputs-and-Parsing.md#source) * [File Input](Inputs-and-Parsing.md#file-input) * [Memory Input](Inputs-and-Parsing.md#memory-input) * [String Input](Inputs-and-Parsing.md#string-input) * [Stream Inputs](Inputs-and-Parsing.md#stream-inputs) * [Argument Input](Inputs-and-Parsing.md#argument-input) * [Parse Function](Inputs-and-Parsing.md#parse-function) * [Nested Parsing](Inputs-and-Parsing.md#nested-parsing) * [Incremental Input](Inputs-and-Parsing.md#incremental-input) * [Buffer Size](Inputs-and-Parsing.md#buffer-size) * [Discard Buffer](Inputs-and-Parsing.md#discard-buffer) * [Custom Rules](Inputs-and-Parsing.md#custom-rules) * [Custom Readers](Inputs-and-Parsing.md#custom-readers) * [Buffer Details](Inputs-and-Parsing.md#buffer-details) * [Error Reporting](Inputs-and-Parsing.md#error-reporting) * [Deduction Guides](Inputs-and-Parsing.md#deduction-guides) * [Control and Debug](Control-and-Debug.md) * [Normal Control](Control-and-Debug.md#normal-control) * [Control Functions](Control-and-Debug.md#control-functions) * [Exception Throwing](Control-and-Debug.md#exception-throwing) * [Advanced Control](Control-and-Debug.md#advanced-control) * [Changing Control](Control-and-Debug.md#changing-control) * [Parse Tree](Parse-Tree.md) * [Full Parse Tree](Parse-Tree.md#full-parse-tree) * [Partial Parse Tree](Parse-Tree.md#partial-parse-tree) * [Transforming Nodes](Parse-Tree.md#transforming-nodes) * [Transformer](Parse-Tree.md#transformer) * [`tao::pegtl::parse_tree::node`](Parse-Tree.md#taopegtlparse_treenode) * [Custom Node Class](Parse-Tree.md#custom-node-class) * [Requirements](Parse-Tree.md#requirements) * [Meta Data and Visit](Meta-Data-and-Visit.md) * [Internals](Meta-Data-and-Visit.md#internals) * [Rule Type](Meta-Data-and-Visit.md#rule-type) * [Sub Rules](Meta-Data-and-Visit.md#sub-rules) * [Grammar Visit](Meta-Data-and-Visit.md#grammar-visit) * [Grammar Print](Meta-Data-and-Visit.md#grammar-print) * [Rule Coverage](Meta-Data-and-Visit.md#rule-coverage) * [Contrib and Examples](Contrib-and-Examples.md) * [Contrib](Contrib-and-Examples.md#contrib) * [Examples](Contrib-and-Examples.md#examples) * [Grammar Analysis](Grammar-Analysis.md) * [Running](Grammar-Analysis.md#running) * [Example](Grammar-Analysis.md#example) * [Requirements](Grammar-Analysis.md#requirements) * [Limitations](Grammar-Analysis.md#limitations) * [Changelog](Changelog.md) * [Migration Guide](Migration-Guide.md) # Rule Reference Index * [`action< A, R... >`](Rule-Reference.md#action-a-r-) [(meta rules)](Rule-Reference.md#meta-rules) * [`alnum`](Rule-Reference.md#alnum) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`alpha`](Rule-Reference.md#alpha) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`alphabetic`](Rule-Reference.md#alphabetic) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`any`](Rule-Reference.md#any) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`any`](Rule-Reference.md#any-1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`any`](Rule-Reference.md#any-2) [(binary rules)](Rule-Reference.md#binary-rules) * [`apply< A... >`](Rule-Reference.md#apply-a-) [(action rules)](Rule-Reference.md#action-rules) * [`apply0< A... >`](Rule-Reference.md#apply0-a-) [(action rules)](Rule-Reference.md#action-rules) * [`ascii_hex_digit`](Rule-Reference.md#ascii_hex_digit) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`at< R... >`](Rule-Reference.md#at-r-) [(combinators)](Rule-Reference.md#combinators) * [`bidi_class< V >`](Rule-Reference.md#bidi_class-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`bidi_control`](Rule-Reference.md#bidi_control) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`bidi_mirrored`](Rule-Reference.md#bidi_mirrored) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`binary_property< P >`](Rule-Reference.md#binary_property-p-) [(icu rules)](Rule-Reference.md#basic-icu-rules) * [`binary_property< P, V >`](Rule-Reference.md#binary_property-p-v-) [(icu rules)](Rule-Reference.md#basic-icu-rules) * [`blank`](Rule-Reference.md#blank) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`block< V >`](Rule-Reference.md#block-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`bof`](Rule-Reference.md#bof) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`bol`](Rule-Reference.md#bol) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`bom`](Rule-Reference.md#bom) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`bytes< Num >`](Rule-Reference.md#bytes-num-) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`canonical_combining_class< V >`](Rule-Reference.md#canonical_combining_class-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-value-properties) * [`case_sensitive`](Rule-Reference.md#case_sensitive) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`control< C, R... >`](Rule-Reference.md#control-c-r-) [(meta rules)](Rule-Reference.md#meta-rules) * [`dash`](Rule-Reference.md#dash) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`decomposition_type< V >`](Rule-Reference.md#decomposition_type-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`default_ignorable_code_point`](Rule-Reference.md#default_ignorable_code_point) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`deprecated`](Rule-Reference.md#deprecated) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`diacritic`](Rule-Reference.md#diacritic) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`digit`](Rule-Reference.md#digit) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`disable< R... >`](Rule-Reference.md#disable-r-) [(meta rules)](Rule-Reference.md#meta-rules) * [`discard`](Rule-Reference.md#discard) [(meta rules)](Rule-Reference.md#meta-rules) * [`east_asian_width< V >`](Rule-Reference.md#east_asian_width-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`enable< R... >`](Rule-Reference.md#enable-r-) [(meta-rules)](Rule-Reference.md#meta-rules) * [`eof`](Rule-Reference.md#eof) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`eol`](Rule-Reference.md#eol) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`eolf`](Rule-Reference.md#eolf) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`extender`](Rule-Reference.md#extender) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`failure`](Rule-Reference.md#failure) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`forty_two< C... >`](Rule-Reference.md#forty_two-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`full_composition_exclusion`](Rule-Reference.md#full_composition_exclusion) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`general_category< V >`](Rule-Reference.md#general_category-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`grapheme_base`](Rule-Reference.md#grapheme_base) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`grapheme_cluster_break< V >`](Rule-Reference.md#grapheme_cluster_break-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`grapheme_extend`](Rule-Reference.md#grapheme_extend) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`grapheme_link`](Rule-Reference.md#grapheme_link) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`hangul_syllable_type< V >`](Rule-Reference.md#hangul_syllable_type-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`hex_digit`](Rule-Reference.md#hex_digit) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`hyphen`](Rule-Reference.md#hyphen) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`id_continue`](Rule-Reference.md#id_continue) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`id_start`](Rule-Reference.md#id_start) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`identifier_first`](Rule-Reference.md#identifier_first) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`identifier_other`](Rule-Reference.md#identifier_other) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`identifier`](Rule-Reference.md#identifier) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`ideographic`](Rule-Reference.md#ideographic) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`ids_binary_operator`](Rule-Reference.md#ids_binary_operator) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`ids_trinary_operator`](Rule-Reference.md#ids_trinary_operator) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`if_apply< R, A... >`](Rule-Reference.md#if_apply-r-a-) [(action rules)](Rule-Reference.md#action-rules) * [`if_must< R, S... >`](Rule-Reference.md#if_must-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`if_must_else< R, S, T >`](Rule-Reference.md#if_must_else-r-s-t-) [(convenience)](Rule-Reference.md#convenience) * [`if_then_else< R, S, T >`](Rule-Reference.md#if_then_else-r-s-t-) [(convenience)](Rule-Reference.md#convenience) * [`istring< C... >`](Rule-Reference.md#istring-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`join_control`](Rule-Reference.md#join_control) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`joining_group< V >`](Rule-Reference.md#joining_group-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`joining_type< V >`](Rule-Reference.md#joining_type-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`keyword< C... >`](Rule-Reference.md#keyword-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`lead_canonical_combining_class< V >`](Rule-Reference.md#lead_canonical_combining_class-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-value-properties) * [`line_break< V >`](Rule-Reference.md#line_break-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`list< R, S >`](Rule-Reference.md#list-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`list< R, S, P >`](Rule-Reference.md#list-r-s-p-) [(convenience)](Rule-Reference.md#convenience) * [`list_must< R, S >`](Rule-Reference.md#list_must-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`list_must< R, S, P >`](Rule-Reference.md#list_must-r-s-p-) [(convenience)](Rule-Reference.md#convenience) * [`list_tail< R, S >`](Rule-Reference.md#list_tail-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`list_tail< R, S, P >`](Rule-Reference.md#list_tail-r-s-p-) [(convenience)](Rule-Reference.md#convenience) * [`logical_order_exception`](Rule-Reference.md#logical_order_exception) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`lower`](Rule-Reference.md#lower) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`lowercase`](Rule-Reference.md#lowercase) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`mask_not_one< M, C... >`](Rule-Reference.md#mask_not_one-m-c-) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_not_range< M, C, D >`](Rule-Reference.md#mask_not_range-m-c-d-) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_one< M, C... >`](Rule-Reference.md#mask_one-m-c-) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_range< M, C, D >`](Rule-Reference.md#mask_range-m-c-d-) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_ranges< M, C1, D1, C2, D2, ... >`](Rule-Reference.md#mask_ranges-m-c1-d1-c2-d2--) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_ranges< M, C1, D1, C2, D2, ..., E >`](Rule-Reference.md#mask_ranges-m-c1-d1-c2-d2--e-) [(binary rules)](Rule-Reference.md#binary-rules) * [`mask_string< M, C... >`](Rule-Reference.md#mask_string-m-c-) [(binary rules)](Rule-Reference.md#binary-rules) * [`math`](Rule-Reference.md#math) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`minus< M, S >`](Rule-Reference.md#minus-m-s-) [(convenience)](Rule-Reference.md#convenience) * [`must< R... >`](Rule-Reference.md#must-r-) [(convenience)](Rule-Reference.md#convenience) * [`nfc_inert`](Rule-Reference.md#nfc_inert) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`nfd_inert`](Rule-Reference.md#nfd_inert) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`nfkc_inert`](Rule-Reference.md#nfkc_inert) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`nfkd_inert`](Rule-Reference.md#nfkd_inert) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`noncharacter_code_point`](Rule-Reference.md#noncharacter_code_point) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`not_at< R... >`](Rule-Reference.md#not_at-r-) [(combinators)](Rule-Reference.md#combinators) * [`not_one< C... >`](Rule-Reference.md#not_one-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`not_one< C... >`](Rule-Reference.md#not_one-c--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`not_one< C... >`](Rule-Reference.md#not_one-c--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`not_range< C, D >`](Rule-Reference.md#not_range-c-d-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`not_range< C, D >`](Rule-Reference.md#not_range-c-d--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`not_range< C, D >`](Rule-Reference.md#not_range-c-d--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`nul`](Rule-Reference.md#nul) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`numeric_type< V >`](Rule-Reference.md#numeric_type-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`odigit`](Rule-Reference.md#odigit) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`one< C... >`](Rule-Reference.md#one-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`one< C... >`](Rule-Reference.md#one-c--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`one< C... >`](Rule-Reference.md#one-c--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`opt< R... >`](Rule-Reference.md#opt-r-) [(combinators)](Rule-Reference.md#combinators) * [`opt_must< R, S...>`](Rule-Reference.md#opt_must-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`pad< R, S, T = S >`](Rule-Reference.md#pad-r-s-t--s-) [(convenience)](Rule-Reference.md#convenience) * [`pad_opt< R, P >`](Rule-Reference.md#pad_opt-r-p-) [(convenience)](Rule-Reference.md#convenience) * [`pattern_syntax`](Rule-Reference.md#pattern_syntax) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`pattern_white_space`](Rule-Reference.md#pattern_white_space) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`plus< R... >`](Rule-Reference.md#plus-r-) [(combinators)](Rule-Reference.md#combinators) * [`posix_alnum`](Rule-Reference.md#posix_alnum) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`posix_blank`](Rule-Reference.md#posix_blank) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`posix_graph`](Rule-Reference.md#posix_graph) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`posix_print`](Rule-Reference.md#posix_print) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`posix_xdigit`](Rule-Reference.md#posix_xdigit) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`print`](Rule-Reference.md#print) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`property_value< P, V >`](Rule-Reference.md#property_value-p-v-) [(icu rules)](Rule-Reference.md#basic-icu-rules) * [`quotation_mark`](Rule-Reference.md#quotation_mark) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`radical`](Rule-Reference.md#radical) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`raise< T >`](Rule-Reference.md#raise-t-) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`range< C, D >`](Rule-Reference.md#range-c-d-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`range< C, D >`](Rule-Reference.md#range-c-d--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`range< C, D >`](Rule-Reference.md#range-c-d--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2--) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2---1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2---2) [(binary rules)](Rule-Reference.md#binary-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`rematch< R, S... >`](Rule-Reference.md#rematch-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`rep< Num, R... >`](Rule-Reference.md#rep-num-r-) [(convenience)](Rule-Reference.md#convenience) * [`rep_max< Max, R... >`](Rule-Reference.md#rep_max-max-r-) [(convenience)](Rule-Reference.md#convenience) * [`rep_min< Min, R... >`](Rule-Reference.md#rep_min-min-r-) [(convenience)](Rule-Reference.md#convenience) * [`rep_min_max< Min, Max, R... >`](Rule-Reference.md#rep_min_max-min-max-r-) [(convenience)](Rule-Reference.md#convenience) * [`rep_opt< Num, R... >`](Rule-Reference.md#rep_opt-num-r-) [(convenience)](Rule-Reference.md#convenience) * [`require< Num >`](Rule-Reference.md#require-num-) [(meta-rules)](Rule-Reference.md#meta-rules) * [`s_term`](Rule-Reference.md#s_term) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`segment_starter`](Rule-Reference.md#segment_starter) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`sentence_break< V >`](Rule-Reference.md#sentence_break-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`seq< R... >`](Rule-Reference.md#seq-r-) [(combinators)](Rule-Reference.md#combinators) * [`seven`](Rule-Reference.md#seven) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`shebang`](Rule-Reference.md#shebang) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`soft_dotted`](Rule-Reference.md#soft_dotted) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`sor< R... >`](Rule-Reference.md#sor-r-) [(combinators)](Rule-Reference.md#combinators) * [`space`](Rule-Reference.md#space) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`star< R... >`](Rule-Reference.md#star-r-) [(combinators)](Rule-Reference.md#combinators) * [`star_must< R, S... >`](Rule-Reference.md#star_must-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`state< S, R... >`](Rule-Reference.md#state-s-r-) [(meta rules)](Rule-Reference.md#meta-rules) * [`string< C... >`](Rule-Reference.md#string-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`string< C... >`](Rule-Reference.md#string-c--1) [(unicode rules)](Rule-Reference.md#unicode-rules) * [`string< C... >`](Rule-Reference.md#string-c--2) [(binary rules)](Rule-Reference.md#binary-rules) * [`success`](Rule-Reference.md#success) [(atomic rules)](Rule-Reference.md#atomic-rules) * [`TAO_PEGTL_ISTRING( "..." )`](Rule-Reference.md#tao_pegtl_istring--) [(ascii rules)](Rule-Reference.md#ascii_rules) * [`TAO_PEGTL_KEYWORD( "..." )`](Rule-Reference.md#tao_pegtl_keyword--) [(ascii rules)](Rule-Reference.md#ascii_rules) * [`TAO_PEGTL_STRING( "..." )`](Rule-Reference.md#tao_pegtl_string--) [(ascii rules)](Rule-Reference.md#ascii_rules) * [`terminal_punctuation`](Rule-Reference.md#terminal_punctuation) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`three< C >`](Rule-Reference.md#three-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`trail_canonical_combining_class< V >`](Rule-Reference.md#trail_canonical_combining_class-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-value-properties) * [`try_catch< R... >`](Rule-Reference.md#try_catch-r-) [(convenience)](Rule-Reference.md#convenience) * [`try_catch_type< E, R... >`](Rule-Reference.md#try_catch_type-e-r-) [(convenience)](Rule-Reference.md#convenience) * [`two< C >`](Rule-Reference.md#two-c-) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`unified_ideograph`](Rule-Reference.md#unified_ideograph) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`until< R >`](Rule-Reference.md#until-r-) [(convenience)](Rule-Reference.md#convenience) * [`until< R, S... >`](Rule-Reference.md#until-r-s-) [(convenience)](Rule-Reference.md#convenience) * [`upper`](Rule-Reference.md#upper) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`uppercase`](Rule-Reference.md#uppercase) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`variation_selector`](Rule-Reference.md#variation_selector) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`white_space`](Rule-Reference.md#white_space) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`word_break< V >`](Rule-Reference.md#word_break-v-) [(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties) * [`xdigit`](Rule-Reference.md#xdigit) [(ascii rules)](Rule-Reference.md#ascii-rules) * [`xid_continue`](Rule-Reference.md#xid_continue) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) * [`xid_start`](Rule-Reference.md#xid_start) [(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties) Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/doc/Rule-Reference.md000066400000000000000000002077041426407250600173310ustar00rootroot00000000000000# Rule Reference 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. Remember that there are two failure modes, only the first of which usually leads to back-tracking: - *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. ## Equivalence Some rule classes are said to be *equivalent to* a combination of other rules. Here, *equivalence* is with respect to which inputs are matched, but not (necessarily) how the rule is implemented. For rules other than `must<>` that contain "must" in their name, rule equivalence shows which rule will be used to call the control class' `raise()` function when certain sub-rules fail to match. ## Implementation The "meta data and implementation mapping" section of each rule's description shows both how the rule is implemented and what the [meta data](Meta-Data-and-Visit.md) looks like. When the list of sub-rules is empty then the definition of `subs_t` is omitted from the description. ## Parameter Packs The documentation will use [(template parameter) packs](https://en.cppreference.com/w/cpp/language/parameter_pack) when zero-or-more or one-or-more of a (template) parameter are allowed. For example `seq< R... >` accepts zero-or-more template parameters. In the zero case, i.e. `seq<>`, we describe `R` as "empty". When at least one parameter is given, i.e. `seq< A >` or `seq< A, B, C >`, `R` is "non-empty". ## Contents * [Meta Rules](#meta-rules) * [Combinators](#combinators) * [Convenience](#convenience) * [Action Rules](#action-rules) * [Atomic Rules](#atomic-rules) * [ASCII Rules](#ascii-rules) * [Unicode Rules](#unicode-rules) * [ICU Support](#icu-support) * [Basic ICU Rules](#basic-icu-rules) * [ICU Rules for Binary Properties](#icu-rules-for-binary-properties) * [ICU Rules for Enumerated Properties](#icu-rules-for-enumerated-properties) * [ICU Rules for Value Properties](#icu-rules-for-value-properties) * [Binary Rules](#binary-rules) * [Full Index](#full-index) ## Meta Rules These rules are in namespace `tao::pegtl`. ###### `action< A, R... >` * [Equivalent] to `seq< R... >`, but: * Uses the given class template `A` for [actions](Actions-and-States.md). * Does not `enable` or `disable` actions while matching `R...`. * [Meta data] and [implementation] mapping: - `action< A >::rule_t` is `internal::success` - `action< A, R >::rule_t` is `internal::action< A, R >` - `action< A, R >::subs_t` is `type_list< R >` - `action< A, R... >::rule_t` is `internal::action< A, internal::seq< R... > >` - `action< A, R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `control< C, R... >` * [Equivalent] to `seq< R... >`, but: * Uses the given class template `C` as [control class](Control-and-Debug.md). * [Meta data] and [implementation] mapping: - `control< C >::rule_t` is `internal::success` - `control< C, R >::rule_t` is `internal::control< C, R >` - `control< C, R >::subs_t` is `type_list< R >` - `control< C, R... >:rule_t` is `internal::control< C, internal::seq< R... > >` - `control< C, R... >:subs_t` is `type_list< internal::seq< R... > >` ###### `disable< R... >` * [Equivalent] to `seq< R... >`, but: * Disables all actions. * [Meta data] and [implementation] mapping: - `disable<>::rule_t` is `internal::success` - `disable< R >::rule_t` is `internal::disable<, R >` - `disable< R >::subs_t` is `type_list< R >` - `disable< R... >::rule_t` is `internal::disable< internal::seq< R... > >` - `disable< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `discard` * [Equivalent] to `success`, but: * Calls the input's `discard()` member function. * Must not be used where backtracking to before the `discard` might occur and/or nested within a rule for which an action with input can be called. * See [Incremental Input](Inputs-and-Parsing.md#incremental-input) for details. * [Meta data] and [implementation] mapping: - `discard::rule_t` is `internal::discard` ###### `enable< R... >` * [Equivalent] to `seq< R... >`, but: * Enables all actions (if any). * [Meta data] and [implementation] mapping: - `enable<>::rule_t` is `internal::success` - `enable< R >::rule_t` is `internal::enable< R >` - `enable< R >::subs_t` is `type_list< R >` - `enable< R... >::rule_t` is `internal::enable< internal::seq< R... > >` - `enable< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `require< Num >` * Succeeds if at least `Num` further input bytes are available. * With [Incremental Input](Inputs-and-Parsing.md#incremental-input) reads the bytes into the buffer. * [Meta data] and [implementation] mapping: - `require< 0 >::rule_t` is `internal::success` - `require< N >::rule_t` is `internal::require< N >` ###### `state< S, R... >` * [Equivalent] to `seq< R... >`, but: * Replaces all state arguments with a new instance `s` of type `S`. * `s` is constructed with the input and all previous states as arguments. * If `seq< R... >` succeeds then `s.success()` is called with the input after the match and all previous states as arguments. * [Meta data] and [implementation] mapping: - `state< S >::rule_t` is `internal::success` - `state< S, R >::rule_t` is `internal::state< S, R >` - `state< S, R >::subs_t` is `type_list< R >` - `state< S, R... >::rule_t` is `internal::state< S, internal::seq< R... > >` - `state< S, R... >::subs_t` is `type_list< internal::seq< R... > >` ## Combinators Combinators (or combinator rules) are rules that combine (other) rules into new ones. These are the classical **PEG** combinator rules and are defined in namespace `tao::pegtl`. ###### `at< R... >` * PEG **and-predicate** &*e* * Succeeds if and only if `seq< R... >` would succeed. * Consumes nothing, i.e. rewinds after matching. * Disables all actions. * [Meta data] and [implementation] mapping: - `at<>::rule_t` is `internal::success` - `at< R >::rule_t` is `internal::at< R >` - `at< R >::subs_t` is `type_list< R >` - `at< R... >::rule_t` is `internal::at< internal::seq< R... > >` - `at< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `not_at< R... >` * PEG **not-predicate** !*e* * Succeeds if and only if `seq< R... >` would **not** succeed. * Consumes nothing, i.e. rewinds after matching. * Disables all actions. * [Meta data] and [implementation] mapping: - `not_at<>::rule_t` is `internal::failure` - `not_at< R >::rule_t` is `internal::not_at< R >` - `not_at< R >::subs_t` is `type_list< R >` - `not_at< R... >::rule_t` is `internal::not_at< internal::seq< R... > >` - `not_at< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `opt< R... >` * PEG **optional** *e*? * Optional `seq< R... >`, i.e. attempt to match `seq< R... >` and signal success regardless of the result. * [Equivalent] to `sor< seq< R... >, success >`. * [Meta data] and [implementation] mapping: - `opt<>::rule_t` is `internal::success` - `opt< R >::rule_t` is `internal::opt< R >` - `opt< R >::subs_t` is `type_list< R >` - `opt< R... >::rule_t` is `internal::opt< internal::seq< R... > >` - `opt< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `plus< R... >` * PEG **one-or-more** *e*+ * Matches `seq< R... >` as often as possible and succeeds if it matches at least once. * [Equivalent] to `rep_min< 1, R... >`. * `R` must be a non-empty rule pack. * [Meta data] and [implementation] mapping: - `plus< R >::rule_t` is `internal::plus< R >` - `plus< R >::subs_t` is `type_list< R >` - `plus< R... >::rule_t` is `internal::plus< internal::seq< R... > >` - `plus< R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `seq< R... >` * PEG **sequence** *e*1 *e*2 * Sequence or *conjunction* of rules. * Matches the given rules `R...` in the given order. * Fails and stops matching when one of the given rules fails. * Consumes everything that the rules `R...` consumed. * Succeeds if `R` is an empty rule pack. * [Meta data] and [implementation] mapping: - `seq<>::rule_t` is `internal::success` - `seq< R >::rule_t` is `internal::seq< R >` - `seq< R >::subs_t` is `type_list< R >` - `seq< R... >::rule_t` is `internal::seq< R... >` - `seq< R... >::subs_t` is `type_list< R... >` ###### `sor< R... >` * PEG **ordered choice** *e*1 / *e*2 * Choice or *disjunction* of rules. * Matches the given rules `R...` in the given order. * Succeeds and stops matching when one of the given rules succeeds. * Consumes whatever the first rule that succeeded consumed. * Fails if `R` is an empty rule pack. * [Meta data] and [implementation] mapping: - `sor<>::rule_t` is `internal::failure` - `sor< R >::rule_t` is `internal::sor< R >` - `sor< R >::subs_t` is `type_list< R >` - `sor< R... >::rule_t` is `internal::sor< R... >` - `sor< R... >::subs_t` is `type_list< R... >` ###### `star< R... >` * PEG **zero-or-more** *e** * Matches `seq< R... >` as often as possible and always succeeds. * `R` must be a non-empty rule pack. * [Meta data] and [implementation] mapping: - `star< R >::rule_t` is `internal::star< R >` - `star< R >::subs_t` is `type_list< R >` - `star< R... >::rule_t` is `internal::star< internal::seq< R... > >` - `star< R... >::subs_t` is `type_list< internal::seq< R... > >` ## Convenience The PEGTL offers a variety of convenience rules which help writing concise grammars as well as offering performance benefits over the equivalent implementation with classical PEG combinators. These rules are in namespace `tao::pegtl`. ###### `if_must< R, S... >` * Attempts to match `R` and depending on the result proceeds with either `must< S... >` or `failure`. * [Equivalent] to `seq< R, must< S... > >`. * [Equivalent] to `if_then_else< R, must< S... >, failure >`. * [Meta data] and [implementation] mapping: - `if_must< R >::rule_t` is `internal::if_must< false, R >` - `if_must< R >::subs_t` is `type_list< R >` - `if_must< R, S... >::rule_t` is `internal::if_must< false, R, S... >` - `if_must< R, S... >::subs_t` is `type_list< R, internal::must< S... > >` Note that the `false` template parameter to `internal::if_must` corresponds to the `failure` in the equivalent description using `if_then_else`. ###### `if_must_else< R, S, T >` * Attempts to match `R` and depending on the result proceeds with either `must< S >` or `must< T >`. * [Equivalent] to `if_then_else< R, must< S >, must< T > >`. * [Meta data] and [implementation] mapping: - `if_must_else< R, S, T >::rule_t` is `internal::if_then_else< R, internal::must< S >, internal::must< T > >` - `if_must_else< R, S, T >::subs_t` is `type_list< R, internal::must< S >, internal::must< T > >` ###### `if_then_else< R, S, T >` * [Equivalent] to `sor< seq< R, S >, seq< not_at< R >, T > >`. * [Meta data] and [implementation] mapping: - `if_then_else< R, S, T >::rule_t` is `internal::if_then_else< R, S, T>` - `if_then_else< R, S, T >::subs_t` is `type_list< R, S, T >` ###### `list< R, S >` * Matches a non-empty list of `R` separated by `S`. * [Equivalent] to `seq< R, star< S, R > >`. * [Meta data] and [implementation] mapping: - `list< R, S >::rule_t` is `internal::seq< R, internal::star< S, R > >` - `list< R, S >::subs_t` is `type_list< R, internal::star< S, R > >` ###### `list< R, S, P >` * Matches a non-empty list of `R` separated by `S` where each `S` can be padded by `P`. * [Equivalent] to `seq< R, star< pad< S, P >, R > >`. * [Meta data] and [implementation] mapping: - `list< R, S, P >::rule_t` is `internal::seq< R, internal::star< internal::pad< S, P >, R > >` - `list< R, S, P >::subs_t` is `type_list< R, internal::star< internal::pad< S, P >, R > >` ###### `list_must< R, S >` * Matches a non-empty list of `R` separated by `S`. * Similar to `list< R, S >`, but if there is an `S` it **must** be followed by an `R`. * [Equivalent] to `seq< R, star< if_must< S, R > > >`. * [Meta data] and [implementation] mapping: - `list_must< R, S >::rule_t` is `internal::seq< R, internal::star< S, internal::must< R > > >` - `list_must< R, S >::subs_t` is `type_list< R, internal::star< S, internal::must< R > > >` ###### `list_must< R, S, P >` * Matches a non-empty list of `R` separated by `S` where each `S` can be padded by `P`. * Similar to `list< R, S, P >`, but if there is an `S` it **must** be followed by an `R`. * [Equivalent] to `seq< R, star< if_must< pad< S, P >, R > > >`. * [Meta data] and [implementation] mapping: - `list_must< R, S, P >::rule_t` is `internal::seq< R, internal::star< internal::pad< S, P >, internal::must< R > > >` - `list_must< R, S, P >::subs_t` is `type_list< R, internal::star< internal::pad< S, P >, internal::must< R > > >` ###### `list_tail< R, S >` * Matches a non-empty list of `R` separated by `S` with optional trailing `S`. * [Equivalent] to `seq< list< R, S >, opt< S > >`. * [Meta data] and [implementation] mapping: - `list_tail< R, S >::rule_t` is `internal::seq< R, internal::star< S, R >, internal::opt< S > >` - `list_tail< R, S >::subs_t` is `type_list< R, internal::star< S, R >, internal::opt< S > >` ###### `list_tail< R, S, P >` * Matches a non-empty list of `R` separated by `S` with optional trailing `S` and padding `P` inside the list. * [Equivalent] to `seq< list< R, S, P >, opt< star< P >, S > >`. * [Meta data] and [implementation] mapping: - `list_tail< R, S, P >::rule_t` is `internal::seq< R, internal::star< internal::pad< S, P >, R >, internal::opt< internal::star< P >, S > >` - `list_tail< R, S, P >::subs_t` is `type_list< R, internal::star< internal::pad< S, P >, R > >, internal::opt< internal::star< P >, S > >` ###### `minus< M, S >` * Succeeds if `M` matches, and `S` does *not* match *all* of the input that `M` matched. * [Equivalent] to `rematch< M, not_at< S, eof > >`. * [Meta data] and [implementation] mapping: - `minus< M, S >::rule_t` is `internal::rematch< M, internal::not_at< S, internal::eof > >` - `minus< M, S >::subs_t` is `type_list< M, internal::not_at< S, internal::eof > >` ###### `must< R... >` * [Equivalent] to `seq< R... >`, but: * Converts local failure of `R...` into global failure. * Calls `raise< R >` for the `R` that failed. * [Equivalent] to `seq< sor< R, raise< R > >... >`. * [Meta data] and [implementation] mapping: - `must<>::rule_t` is `internal::success` - `must< R >::rule_t` is `internal::must< R >` - `must< R >::subs_t` is `type_list< R >` - `must< R... >::rule_t` is `internal::seq< internal::must< R >... >::rule_t` - `must< R... >::subs_t` is `type_list< internal::must< R... > >` Note that `must` uses a different pattern to handle multiple sub-rules compared to the other `seq`-equivalent rules (which use `rule< seq< R... > >` rather than `seq< rule< R >... >`). ###### `opt_must< R, S... >` * [Equivalent] to `opt< if_must< R, S... > >`. * [Equivalent] to `if_then_else< R, must< S... >, success >`. * [Meta data] and [implementation] mapping: - `opt_must< R >::rule_t` is `internal::if_must< true, R >` - `opt_must< R >::subs_t` is `type_list< R >` - `opt_must< R, S... >::rule_t` is `internal::if_must< true, R, S... >` - `opt_must< R, S... >::subs_t` is `type_list< R, internal::must< S... > >` Note that the `true` template parameter to `internal::if_must` corresponds to the `success` in the equivalent description using `if_then_else`. ###### `pad< R, S, T = S >` * Matches an `R` that can be padded by arbitrary many `S` on the left and `T` on the right. * [Equivalent] to `seq< star< S >, R, star< T > >`. * [Meta data] and [implementation] mapping: - `pad< R, S, T >::rule_t` is `internal::seq< internal::star< S >, R, internal::star< T > >` - `pad< R, S, T >::subs_t` is `type_list< internal::star< S >, R, internal::star< T > >` ###### `pad_opt< R, P >` * Matches an optional `R` that can be padded by arbitrary many `P` or just arbitrary many `P`. * [Equivalent] to `seq< star< P >, opt< R, star< P > > >`. * [Meta data] and [implementation] mapping: - `pad_opt< R, P >::rule_t` is `internal::seq< internal::star< P >, internal::opt< R, internal::star< P > > >` - `pad_opt< R, P >::subs_t` is `type_list< internal::star< P >, internal::opt< R, internal::star< P > > >` ###### `rematch< R, S... >` * Succeeds if `R` matches, and each `S` matches the input that `R` matched. * Ignores all `S` for the [grammar analysis](Grammar-Analysis.md). * [Meta data] and [implementation] mapping: - `rematch< R, S... >::rule_t` is `internal::rematch< R, S... >` - `rematch< R, S... >::subs_t` is `type_list< R, S... >` Note that the `S` do *not* need to match *all* of the input matched by `R` (which is why `minus` uses `eof` in its implementation). ###### `rep< Num, R... >` * Matches `seq< R... >` for `Num` times without checking for further matches. * [Equivalent] to `seq< seq< R... >, ..., seq< R... > >` where `seq< R... >` is repeated `Num` times. * [Meta data] and [implementation] mapping: - `rep< 0, R... >::rule_t` is `internal::success` - `rep< N >::rule_t` is `internal::success` - `rep< N, R >::rule_t` is `internal::rep< N, R >` - `rep< N, R >::subs_t` is `type_list< R >` - `rep< N, R... >::rule_t` is `internal::rep< N, internal::seq< R... > >` - `rep< N, R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `rep_max< Max, R... >` * Matches `seq< R... >` for at most `Max` times and verifies that it doesn't match more often. * [Equivalent] to `rep_min_max< 0, Max, R... >`. * [Meta data] and [implementation] mapping: - `rep_max< 0, R >::rule_t` is `internal::not_at< R >` - `rep_max< 0, R >::subs_t` is `type_list< R >` - `rep_max< 0, R... >::rule_t` is `internal::not_at< internal::seq< R... > >` - `rep_max< 0, R... >::subs_t` is `type_list< internal::seq< R... > >` - `rep_max< Max >::rule_t` is `internal::failure` - `rep_max< Max, R >::rule_t` is `internal::rep_min_max< 0, Max, R >` - `rep_max< Max, R >::subs_t` is `type_list< R >` - `rep_max< Max, R... >::rule_t` is `internal::rep_min_max< 0, Max, internal::seq< R... > >` - `rep_max< Max, R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `rep_min< Min, R... >` * Matches `seq< R... >` as often as possible and succeeds if it matches at least `Min` times. * [Equivalent] to `seq< rep< Min, R... >, star< R... > >`. * `R` must be a non-empty rule pack. * [Meta data] and [implementation] mapping: - `rep_min< Min, R... >::rule_t` is `internal::seq< internal::rep< Min, R... >, internal::star< R... > >` - `rep_min< Min, R... >::subs_t` is `type_list< internal::rep< Min, R... >, internal::star< R... > >` ###### `rep_min_max< Min, Max, R... >` * Matches `seq< R... >` for `Min` to `Max` times and verifies that it doesn't match more often. * [Equivalent] to `seq< rep< Min, R... >, rep_opt< Max - Min, R... >, not_at< R... > >`. * [Meta data] and [implementation] mapping: - `rep_min_max< 0, 0, R >::rule_t` is `internal::not_at< R >` - `rep_min_max< 0, 0, R >::subs_t` is `type_list< R >` - `rep_min_max< 0, 0, R... >::rule_t` is `internal::not_at< internal::seq< R... > >` - `rep_min_max< 0, 0, R... >::subs_t` is `type_list< internal::seq< R... > >` - `rep_min_max< Min, Max >::rule_t` is `internal::failure` - `rep_min_max< Min, Max, R >::rule_t` is `internal::rep_min_max< Min, Max, R >` - `rep_min_max< Min, Max, R >::subs_t` is `type_list< R >` - `rep_min_max< Min, Max, R... >::rule_t` is `internal::rep_min_max< Min, Max, internal::seq< R... > >` - `rep_min_max< Min, Max, R... >::subs_t` is `type_list< internal::seq< R... > >` ###### `rep_opt< Num, R... >` * Matches `seq< R... >` for zero to `Num` times without check for further matches. * [Equivalent] to `rep< Num, opt< R... > >`. * [Meta data] and [implementation] mapping: - `rep_opt< 0, R... >::rule_t` is `internal::success` - `rep_opt< Num >::rule_t` is `internal::success` - `rep_opt< Num, R... >::rule_t` is `internal::seq< internal::rep< Num, R... >, internal::star< R... > >` - `rep_opt< Num, R... >::subs_t` is `type_list< internal::rep< Num, R... >, internal::star< R... > >` ###### `star_must< R, S... >` * [Equivalent] to `star< if_must< R, S... > >`. * [Meta data] and [implementation] mapping: - `star_must< R >::rule_t` is `internal::star< internal::if_must< false, R > >` - `star_must< R >::subs_t` is `type_list< internal::if_must< false, R > >` - `star_must< R, S... >::rule_t` is `internal::star< internal::if_must< false, R, S... > >` - `star_must< R, S... >::subs_t` is `type_list< internal::if_must< false, R, S... > >` ###### `try_catch< R... >` * [Equivalent] to `seq< R... >`, but: * Converts global failure (exception) into local failure (return value `false`). * Catches exceptions of type `tao::pegtl::parse_error`. * [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< E, R... >` * [Equivalent] to `seq< R... >`, but: * Converts global failure (exception) into local failure (return value `false`). * Catches exceptions of type `E`. * [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... > >` ###### `until< R >` * Consumes all input until `R` matches. * [Equivalent] to `until< R, any >`. * [Meta data] and [implementation] mapping: - `until< R >::rule_t` is `internal::until< R >` - `until< R >::subs_t` is `type_list< R >` ###### `until< R, S... >` * Matches `seq< S... >` as long as `at< R >` does not match and succeeds when `R` matches. * [Equivalent] to `seq< star< not_at< R >, S... >, R >`. * Does not apply if `S` is an empty rule pack, see the previous entry for the semantics of `until< R >`. * [Meta data] and [implementation] mapping: - `until< R, S >::rule_t` is `internal::until< R, S >` - `until< R, S >::subs_t` is `type_list< R, S >` - `until< R, S... >::rule_t` is `internal::until< R, internal::seq< S... > >` - `until< R, S... >::subs_t` is `type_list< R, internal::seq< S... > >` ## Action Rules These rules are in namespace `tao::pegtl`. These rules replicate the intrusive way actions were called from within the grammar in the PEGTL 0.x with the `apply<>` and `if_apply<>` rules. The actions for these rules are classes (rather than class templates as required for `parse()` and the `action<>`-rule). These rules respect the current `apply_mode`, but do **not** use the control class to invoke the actions. ###### `apply< A... >` * Calls `A::apply()` for all `A`, in order, with an empty input and all states as arguments. * If any `A::apply()` has a boolean return type and returns `false`, no further `A::apply()` calls are made and the result is equivalent to `failure`, otherwise: * [Equivalent] to `success` wrt. parsing. * [Meta data] and [implementation] mapping: - `apply< A... >::rule_t` is `internal::apply< A... >` ###### `apply0< A... >` * Calls `A::apply0()` for all `A`, in order, with all states as arguments. * If any `A::apply0()` has a boolean return type and returns `false`, no further `A::apply0()` calls are made and the result is equivalent to `failure`, otherwise: * [Equivalent] to `success` wrt. parsing. * [Meta data] and [implementation] mapping: - `apply0< A... >::rule_t` is `internal::apply0< A... >` ###### `if_apply< R, A... >` * [Equivalent] to `seq< R, apply< A... > >` wrt. parsing, but also: * If `R` matches, calls `A::apply()`, for all `A`, in order, with the input matched by `R` and all states as arguments. * If any `A::apply()` has a boolean return type and returns `false`, no further `A::apply()` calls are made. * [Meta data] and [implementation] mapping: - `if_apply< R, A... >::rule_t` is `internal::if_apply< R, A... >` - `if_apply< R, A... >::subs_t` is `type_list< R >` ## Atomic Rules These rules are in namespace `tao::pegtl`. Atomic rules do not rely on other rules. ###### `bof` * Succeeds at "beginning-of-file", i.e. when the input's `byte()` member function returns zero. * Does not consume input. * Does **not** work with inputs that don't have a `byte()` member function. * [Meta data] and [implementation] mapping: - `bof::rule_t` is `internal::bof` ###### `bol` * Succeeds at "beginning-of-line", i.e. when the input's `column()` member function returns one. * Does not consume input. * Does **not** work with inputs that don't have a `column()` member function. * [Meta data] and [implementation] mapping: - `bol::rule_t` is `internal::bol` ###### `bytes< Num >` * Succeeds when the input contains at least `Num` further bytes. * Consumes these `Num` bytes from the input. * [Meta data] and [implementation] mapping: - `bytes< 0 >::rule_t` is `internal::success` - `bytes< Num >::rule_t` is `internal::bytes< Num >` ###### `eof` * Succeeds at "end-of-file", i.e. when the input is empty or all input has been consumed. * Does not consume input. * [Meta data] and [implementation] mapping: - `eof::rule_t` is `internal::eof` ###### `eol` * Depends on the `Eol` template parameter of the input, by default: * Matches and consumes a Unix or MS-DOS line ending, that is: * [Equivalent] to `sor< one< '\n' >, string< '\r', '\n' > >`. * [Meta data] and [implementation] mapping: - `eol::rule_t` is `internal::eol` ###### `eolf` * [Equivalent] to `sor< eof, eol >`. * [Meta data] and [implementation] mapping: - `eolf::rule_t` is `internal::eolf` ###### `failure` * Dummy rule that never succeeds. * Does not consume input. * [Meta data] and [implementation] mapping: - `failure::rule_t` is `internal::failure` ###### `raise< T >` * Generates a *global failure*. * Calls the control-class' `Control< T >::raise()` static member function. * `T` *can* be a rule, but it does not have to be a rule. * Does not consume input. * [Meta data] and [implementation] mapping: - `raise< T >::rule_t` is `internal::raise< T >` ###### `success` * Dummy rule that always succeeds. * Does not consume input. * [Meta data] and [implementation] mapping: - `success::rule_t` is `internal::success` ## ASCII Rules These rules are in the inline namespace `tao::pegtl::ascii`. The ASCII rules operate on single bytes, without restricting the range of values to 7 bits. They are compatible with input with the 8th bit set in the sense that nothing breaks in their presence. Rules like `ascii::any` or `ascii::not_one< 'a' >` will match all possible byte values, and all possible byte values excluding `'a'`, respectively. However the character class rules like `ascii::alpha` only match the corresponding ASCII characters. (It is possible to match UTF-8 multi-byte characters with the ASCII rules, for example the Euro sign code point `U+20AC`, which is encoded by the UTF-8 sequence `E2 82 AC`, can be matched by either `tao::pegtl::ascii::string< 0xe2, 0x82, 0xac >` or `tao::pegtl::utf8::one< 0x20ac >`.) ASCII rules do not usually rely on other rules. ###### `alnum` * Matches and consumes a single ASCII alphabetic or numeric character. * [Equivalent] to `ranges< 'a', 'z', 'A', 'Z', '0', '9' >`. * [Meta data] and [implementation] mapping: - `ascii::alnum::rule_t` is `internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9' >` ###### `alpha` * Matches and consumes a single ASCII alphabetic character. * [Equivalent] to `ranges< 'a', 'z', 'A', 'Z' >`. * [Meta data] and [implementation] mapping: - `ascii::alpha::rule_t` is `internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' >` ###### `any` * Matches and consumes any single byte, including all ASCII characters. * [Equivalent] to `bytes< 1 >`. * [Meta data] and [implementation] mapping: - `ascii::any::rule_t` is `internal::any< internal::peek_char >` ###### `blank` * Matches and consumes a single ASCII horizontal space or horizontal tabulator character. * [Equivalent] to `one< ' ', '\t' >`. * [Meta data] and [implementation] mapping: - `ascii::blank::rule_t` is `internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' >` ###### `digit` * Matches and consumes a single ASCII decimal digit character. * [Equivalent] to `range< '0', '9' >`. * [Meta data] and [implementation] mapping: - `ascii::digit::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, '0', '9' >` ###### `ellipsis` * Matches and consumes three dots. * [Equivalent] to `three< '.' >`. * [Meta data] and [implementation] mapping: - `ascii::ellipsis::rule_t` is `internal::string< '.', '.', '.' >` ###### `forty_two< C... >` * [Equivalent] to `rep< 42, one< C... > >`. * [Meta data] and [implementation] mapping: - `ascii::forty_two< C >::rule_t` is `internal_rep< 42, internal::one< internal::result_on_found::success, internal::peek_char, C > >` ###### `identifier_first` * Matches and consumes a single ASCII character permissible as first character of a C identifier. * [Equivalent] to `ranges< 'a', 'z', 'A', 'Z', '_' >`. * [Meta data] and [implementation] mapping: - `ascii::identifier_first::rule_t` is `internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '_' >` ###### `identifier_other` * Matches and consumes a single ASCII character permissible as subsequent character of a C identifier. * [Equivalent] to `ranges< 'a', 'z', 'A', 'Z', '0', '9', '_' >`. * [Meta data] and [implementation] mapping: - `ascii::identifier_first::rule_t` is `internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9', '_' >` ###### `identifier` * Matches and consumes an ASCII identifier as defined for the C programming language. * [Equivalent] to `seq< identifier_first, star< identifier_other > >`. * [Meta data] and [implementation] mapping: - `ascii::identifier::rule_t` is `internal::seq< identifier_first, internal::star< identifier_other > >`. ###### `istring< C... >` * Matches and consumes the given ASCII string `C...` with case insensitive matching. * Similar to `string< C... >`, but: * For ASCII letters a-z and A-Z the match is case insensitive. * [Meta data] and [implementation] mapping: - `ascii::istring<>::rule_t` is `internal::success` - `ascii::istring< C... >::rule_t` is `internal::istring< C... >` ###### `keyword< C... >` * Matches and consumes a non-empty string not followed by an identifier character. * [Equivalent] to `seq< string< C... >, not_at< identifier_other > >`. * `C` must be a non-empty character pack. * [Meta data] and [implementation] mapping: - `ascii::keyword< C... >::rule_t` is `internal::seq< internal::string< C... >, internal::not_at< internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9', '_' > > >` ###### `lower` * Matches and consumes a single ASCII lower-case alphabetic character. * [Equivalent] to `range< 'a', 'z' >`. * [Meta data] and [implementation] mapping: - `ascii::lower::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, 'a', 'z' >` ###### `not_one< C... >` * Succeeds when the input is not empty, and: * `C` is an empty character pack or the next input byte is **not** one of `C...`. * Consumes one byte when it succeeds. * [Meta data] and [implementation] mapping: - `ascii::not_one<>::rule_t` is `internal::any< internal::peek_char >` - `ascii::not_one< C... >::rule_t` is `internal::one< result_on_found::failure, internal::peek_char, C... >` ###### `not_range< C, D >` * Succeeds when the input is not empty, and: * The next input byte is **not** in the closed range `C ... D`. * Consumes one byte when it succeeds. * [Meta data] and [implementation] mapping: - `ascii::not_range< C, C >::rule_t` is `internal::one< result_on_found::failure, internal::peek_char, C >` - `ascii::not_range< C, D >::rule_t` is `internal::range< result_on_found::failure, internal::peek_char, C, D >` ###### `nul` * Matches and consumes an ASCII nul character. * [Equivalent] to `one< '\0' >`. - `ascii::nul::rule_t` is `internal::one< result_on_found::success, internal::peek_char, 0 >` ###### `odigit` * Matches and consumes a single ASCII octal digit character. * [Equivalent] to `range< '0', '7' >`. * [Meta data] and [implementation] mapping: - `ascii::digit::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, '0', '7' >` ###### `one< C... >` * Succeeds when the input is not empty, and: * The next input byte is one of `C...`. * Consumes one byte when it succeeds. * Fails if `C` is an empty character pack. * [Meta data] and [implementation] mapping: - `ascii::not_one<>::rule_t` is `internal::failure` - `ascii::not_one< C... >::rule_t` is `internal::one< result_on_found::success, internal::peek_char, C... >` ###### `print` * Matches and consumes any single ASCII character traditionally defined as printable. * [Equivalent] to `range< 32, 126 >`. * [Meta data] and [implementation] mapping: - `ascii::print::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, 32, 126 >` ###### `range< C, D >` * Succeeds when the input is not empty, and: * The next input byte is in the closed range `C ... D`. * Consumes one byte when it succeeds. * [Meta data] and [implementation] mapping: - `ascii::range< C, C >::rule_t` is `internal::one< result_on_found::success, internal::peek_char, C >` - `ascii::range< C, D >::rule_t` is `internal::range< result_on_found::success, internal::peek_char, C, D >` ###### `ranges< C1, D1, C2, D2, ... >` ###### `ranges< C1, D1, C2, D2, ..., E >` * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ... >`. * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ..., one< E > >`. * [Meta data] and [implementation] mapping: - `ascii::ranges<>::rule_t` is `internal::failure` - `ascii::ranges< E >::rule_t` is `internal::one< result_on_found::success, internal::peek_char, E >` - `ascii::ranges< C, D >::rule_t` is `internal::range< result_on_found::success, internal::peek_char, C, D >` - `ascii::ranges< C... >::rule_t` is `internal::ranges< internal::peek_char, C... >` ###### `seven` * Matches and consumes any single true ASCII character that fits into 7 bits. * [Equivalent] to `range< 0, 127 >`. * [Meta data] and [implementation] mapping: - `ascii::seven::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, 0, 127 >` ###### `shebang` * [Equivalent] to `if_must< string< '#', '!' >, until< eolf > >`. * [Meta data] and [implementation] mapping: - `ascii::shebang::rule_t` is `internal::seq< false, internal::string< '#', '!' >, internal::until< internal::eolf > >` - `ascii::shebang::subs_t` is `type_list< internal::string< '#', '!' >, internal::until< internal::eolf > >` ###### `space` * Matches and consumes a single space, line-feed, carriage-return, horizontal-tab, vertical-tab or form-feed. * [Equivalent] to `one< ' ', '\n', '\r', '\t', '\v', '\f' >`. ###### `string< C... >` * Matches and consumes a string, a sequence of bytes or single-byte characters. * [Equivalent] to `seq< one< C >... >`. * [Meta data] and [implementation] mapping: - `ascii::string<>::rule_t` is `internal::success` - `ascii::string< C... >::rule_t` is `internal::string< C... >` ###### `TAO_PEGTL_ISTRING( "..." )` * Macro where `TAO_PEGTL_ISTRING( "foo" )` yields `istring< 'f', 'o', 'o' >`. * The argument must be a string literal. * Works for strings up to 512 bytes of length (excluding trailing `'\0'`). * Strings may contain embedded `'\0'`. ###### `TAO_PEGTL_KEYWORD( "..." )` * Macro where `TAO_PEGTL_KEYWORD( "foo" )` yields `keyword< 'f', 'o', 'o' >`. * The argument must be a string literal. * Works for keywords up to 512 bytes of length (excluding trailing `'\0'`). * Strings may contain embedded `'\0'`. ###### `TAO_PEGTL_STRING( "..." )` * Macro where `TAO_PEGTL_STRING( "foo" )` yields `string< 'f', 'o', 'o' >`. * The argument must be a string literal. * Works for strings up to 512 bytes of length (excluding trailing `'\0'`). * Strings may contain embedded `'\0'`. ###### `three< C >` * Succeeds when the input contains at least three bytes, and: * These three input bytes are all `C`. * Consumes three bytes when it succeeds. * [Meta data] and [implementation] mapping: - `ascii::three< C >::rule_t` is `internal::string< C, C, C >` ###### `two< C >` * Succeeds when the input contains at least two bytes, and: * These two input bytes are both `C`. * Consumes two bytes when it succeeds. * [Meta data] and [implementation] mapping: - `ascii::two< C >::rule_t` is `internal::string< C, C >` ###### `upper` * Matches and consumes a single ASCII upper-case alphabetic character. * [Equivalent] to `range< 'A', 'Z' >`. * [Meta data] and [implementation] mapping: - `ascii::upper::rule_t` is `internal::range< internal::result_on_found::success, internal::peek_char, 'A', 'Z' >` ###### `xdigit` * Matches and consumes a single ASCII hexadecimal digit character. * [Equivalent] to `ranges< '0', '9', 'a', 'f', 'A', 'F' >`. * [Meta data] and [implementation] mapping: - `ascii::xdigit::rule_t` is `internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' >` ## Unicode Rules These rules are available in multiple versions, * in namespace `tao::pegtl::utf8` for UTF-8 encoded inputs, * in namespace `tao::pegtl::utf16_be` for big-endian UTF-16 encoded inputs, * in namespace `tao::pegtl::utf16_le` for little-endian UTF-16 encoded inputs, * in namespace `tao::pegtl::utf32_be` for big-endian UTF-32 encoded inputs, * in namespace `tao::pegtl::utf32_le` for little-endian UTF-32 encoded inputs. For convenience, they also appear in multiple namespace aliases, * namespace alias `tao::pegtl::utf16` for native-endian UTF-16 encoded inputs, * namespace alias `tao::pegtl::utf32` for native-endian UTF-32 encoded inputs. The following limitations apply to the UTF-16 and UTF-32 rules: * Unaligned input leads to unaligned memory access. * The line and column numbers are not counted correctly. * They are not automatically included with `tao/pegtl.hpp`. The UTF-8 rules are included with `include/tao/pegtl.hpp` while the UTF-16 and UTF-32 rules require manual inclusion of the following files. * `tao/pegtl/contrib/utf16.hpp` * `tao/pegtl/contrib/utf32.hpp` While unaligned accesses are no problem on x86 compatible processors, on other architectures they might be very slow or even crash the application. In the following descriptions a Unicode code point is considered *valid* when it is in the range `0` to `0x10ffff`. The parameter N stands for the size of the encoding of the next Unicode code point in the input, i.e. * for UTF-8 the rules are multi-byte-sequence-aware and N is either 1, 2, 3 or 4, * for UTF-16 the rules are surrogate-pair-aware and N is either 2 or 4, and * for UTF-32 everything is simple and N is always 4. It is an error when a code unit in the range `0xd800` to `0xdfff` is encountered outside of a valid UTF-16 surrogate pair (this changed in version 2.6.0). Unicode rules do not rely on other rules. ###### `any` * Succeeds when the input is not empty, and: * The next N bytes encode a valid Unicode code point. * Consumes the N bytes when it succeeds. ###### `bom` * [Equivalent] to `one< 0xfeff >`. ###### `not_one< C... >` * Succeeds when the input is not empty, and: * The next N bytes encode a valid Unicode code point, and: * `C` is an empty character pack or the input code point is **not** one of the given code points `C...`. * Consumes the N bytes when it succeeds. ###### `not_range< C, D >` * Succeeds when the input is not empty, and: * The next N bytes encode a valid Unicode code point, and: * The input code point `B` satisfies `B < C || D < B`. * Consumes the N bytes when it succeeds. ###### `one< C... >` * Succeeds when the input is not empty, and: * The next N bytes encode a valid Unicode code point, and: * `C` is a non-empty character pack and the input code point is one of the given code points `C...`. * Consumes the N bytes when it succeeds. ###### `range< C, D >` * Succeeds when the input is not empty, and: * The next N bytes encode a valid Unicode code point, and: * The input code point `B` satisfies `C <= B && B <= D`. * Consumes the N bytes when it succeeds. ###### `ranges< C1, D1, C2, D2, ... >` * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ... >`. ###### `ranges< C1, D1, C2, D2, ..., E >` * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ..., one< E > >`. ###### `string< C... >` * [Equivalent] to `seq< one< C >... >`. ### ICU Support The following rules depend on the [International Components for Unicode (ICU)](http://icu-project.org/) that provide the means to match characters with specific Unicode character properties. Because of this external dependency the rules are not automatically included in `tao/pegtl.hpp`. The ICU-based rules are again available in multiple versions, * in namespace `tao::pegtl::utf8::icu` for UTF-8 encoded inputs, * in namespace `tao::pegtl::utf16_be::icu` for big-endian UTF-16 encoded inputs, * in namespace `tao::pegtl::utf16_le::icu` for little-endian UTF-16 encoded inputs, * in namespace `tao::pegtl::utf32_be::icu` for big-endian UTF-32 encoded inputs, and * in namespace `tao::pegtl::utf32_le::icu` for little-endian UTF-32 encoded inputs. And, for convenience, they again appear in multiple namespace aliases, * namespace alias `tao::pegtl::utf16::icu` for native-endian UTF-16 encoded inputs, * namespace alias `tao::pegtl::utf32::icu` for native-endian UTF-32 encoded inputs. To use these rules it is necessary to provide an include path to the ICU library, to link the application against `libicu`, and to manually include one or more of the following header files: * `tao/pegtl/contrib/icu/utf8.hpp` * `tao/pegtl/contrib/icu/utf16.hpp` * `tao/pegtl/contrib/icu/utf32.hpp` The convenience ICU rules are supplied for all properties found in ICU version 3.4. Users of later versions can use the basic rules manually or create their own convenience rules derived from the basic rules for additional enumeration values found in those later versions of the ICU library. ### Basic ICU Rules Each of the above namespaces provides two basic rules for matching binary properties and property value matching for enum properties. ###### `binary_property< P, V >` * `P` is a binary property defined by ICU, see [`UProperty`](http://icu-project.org/apiref/icu4c/uchar_8h.html). * `V` is a boolean value. * Succeeds when the input is not empty, and: * The next N bytes encode a valid unicode code point, and: * The code point's property `P`, i.e. [`u_hasBinaryProperty( cp, P )`](http://icu-project.org/apiref/icu4c/uchar_8h.html), equals `V`. * Consumes the N bytes when it succeeds. ###### `binary_property< P >` * Identical to `binary_property< P, true >`. ###### `property_value< P, V >` * `P` is an enumerated property defined by ICU, see [`UProperty`](http://icu-project.org/apiref/icu4c/uchar_8h.html). * `V` is an integer value. * Succeeds when the input is not empty, and: * The next N bytes encode a valid unicode code point, and: * The code point's property `P`, i.e. [`u_getIntPropertyValue( cp, P )`](http://icu-project.org/apiref/icu4c/uchar_8h.html), equals `V`. * Consumes the N bytes when it succeeds. ### ICU Rules for Binary Properties Convenience wrappers for binary properties. ###### `alphabetic` * [Equivalent] to `binary_property< UCHAR_ALPHABETIC >`. ###### `ascii_hex_digit` * [Equivalent] to `binary_property< UCHAR_ASCII_HEX_DIGIT >`. ###### `bidi_control` * [Equivalent] to `binary_property< UCHAR_BIDI_CONTROL >`. ###### `bidi_mirrored` * [Equivalent] to `binary_property< UCHAR_BIDI_MIRRORED >`. ###### `case_sensitive` * [Equivalent] to `binary_property< UCHAR_CASE_SENSITIVE >`. ###### `dash` * [Equivalent] to `binary_property< UCHAR_DASH >`. ###### `default_ignorable_code_point` * [Equivalent] to `binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT >`. ###### `deprecated` * [Equivalent] to `binary_property< UCHAR_DEPRECATED >`. ###### `diacritic` * [Equivalent] to `binary_property< UCHAR_DIACRITIC >`. ###### `extender` * [Equivalent] to `binary_property< UCHAR_EXTENDER >`. ###### `full_composition_exclusion` * [Equivalent] to `binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION >`. ###### `grapheme_base` * [Equivalent] to `binary_property< UCHAR_GRAPHEME_BASE >`. ###### `grapheme_extend` * [Equivalent] to `binary_property< UCHAR_GRAPHEME_EXTEND >`. ###### `grapheme_link` * [Equivalent] to `binary_property< UCHAR_GRAPHEME_LINK >`. ###### `hex_digit` * [Equivalent] to `binary_property< UCHAR_HEX_DIGIT >`. ###### `hyphen` * [Equivalent] to `binary_property< UCHAR_HYPHEN >`. ###### `id_continue` * [Equivalent] to `binary_property< UCHAR_ID_CONTINUE >`. ###### `id_start` * [Equivalent] to `binary_property< UCHAR_ID_START >`. ###### `ideographic` * [Equivalent] to `binary_property< UCHAR_IDEOGRAPHIC >`. ###### `ids_binary_operator` * [Equivalent] to `binary_property< UCHAR_IDS_BINARY_OPERATOR >`. ###### `ids_trinary_operator` * [Equivalent] to `binary_property< UCHAR_IDS_TRINARY_OPERATOR >`. ###### `join_control` * [Equivalent] to `binary_property< UCHAR_JOIN_CONTROL >`. ###### `logical_order_exception` * [Equivalent] to `binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION >`. ###### `lowercase` * [Equivalent] to `binary_property< UCHAR_LOWERCASE >`. ###### `math` * [Equivalent] to `binary_property< UCHAR_MATH >`. ###### `nfc_inert` * [Equivalent] to `binary_property< UCHAR_NFC_INERT >`. ###### `nfd_inert` * [Equivalent] to `binary_property< UCHAR_NFD_INERT >`. ###### `nfkc_inert` * [Equivalent] to `binary_property< UCHAR_NFKC_INERT >`. ###### `nfkd_inert` * [Equivalent] to `binary_property< UCHAR_NFKD_INERT >`. ###### `noncharacter_code_point` * [Equivalent] to `binary_property< UCHAR_NONCHARACTER_CODE_POINT >`. ###### `pattern_syntax` * [Equivalent] to `binary_property< UCHAR_PATTERN_SYNTAX >`. ###### `pattern_white_space` * [Equivalent] to `binary_property< UCHAR_PATTERN_WHITE_SPACE >`. ###### `posix_alnum` * [Equivalent] to `binary_property< UCHAR_POSIX_ALNUM >`. ###### `posix_blank` * [Equivalent] to `binary_property< UCHAR_POSIX_BLANK >`. ###### `posix_graph` * [Equivalent] to `binary_property< UCHAR_POSIX_GRAPH >`. ###### `posix_print` * [Equivalent] to `binary_property< UCHAR_POSIX_PRINT >`. ###### `posix_xdigit` * [Equivalent] to `binary_property< UCHAR_POSIX_XDIGIT >`. ###### `quotation_mark` * [Equivalent] to `binary_property< UCHAR_QUOTATION_MARK >`. ###### `radical` * [Equivalent] to `binary_property< UCHAR_RADICAL >`. ###### `s_term` * [Equivalent] to `binary_property< UCHAR_S_TERM >`. ###### `segment_starter` * [Equivalent] to `binary_property< UCHAR_SEGMENT_STARTER >`. ###### `soft_dotted` * [Equivalent] to `binary_property< UCHAR_SOFT_DOTTED >`. ###### `terminal_punctuation` * [Equivalent] to `binary_property< UCHAR_TERMINAL_PUNCTUATION >`. ###### `unified_ideograph` * [Equivalent] to `binary_property< UCHAR_UNIFIED_IDEOGRAPH >`. ###### `uppercase` * [Equivalent] to `binary_property< UCHAR_UPPERCASE >`. ###### `variation_selector` * [Equivalent] to `binary_property< UCHAR_VARIATION_SELECTOR >`. ###### `white_space` * [Equivalent] to `binary_property< UCHAR_WHITE_SPACE >`. ###### `xid_continue` * [Equivalent] to `binary_property< UCHAR_XID_CONTINUE >`. ###### `xid_start` * [Equivalent] to `binary_property< UCHAR_XID_START >`. ### ICU Rules for Enumerated Properties Convenience wrappers for enumerated properties. ###### `bidi_class< V >` * `V` is of type `UCharDirection`. * [Equivalent] to `property_value< UCHAR_BIDI_CLASS, V >`. ###### `block< V >` * `V` is of type `UBlockCode`. * [Equivalent] to `property_value< UCHAR_BLOCK, V >`. ###### `decomposition_type< V >` * `V` is of type `UDecompositionType`. * [Equivalent] to `property_value< UCHAR_DECOMPOSITION_TYPE, V >`. ###### `east_asian_width< V >` * `V` is of type `UEastAsianWidth`. * [Equivalent] to `property_value< UCHAR_EAST_ASIAN_WIDTH, V >`. ###### `general_category< V >` * `V` is of type `UCharCategory`. * [Equivalent] to `property_value< UCHAR_GENERAL_CATEGORY, V >`. ###### `grapheme_cluster_break< V >` * `V` is of type `UGraphemeClusterBreak`. * [Equivalent] to `property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V >`. ###### `hangul_syllable_type< V >` * `V` is of type `UHangulSyllableType`. * [Equivalent] to `property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V >`. ###### `joining_group< V >` * `V` is of type `UJoiningGroup`. * [Equivalent] to `property_value< UCHAR_JOINING_GROUP, V >`. ###### `joining_type< V >` * `V` is of type `UJoiningType`. * [Equivalent] to `property_value< UCHAR_JOINING_TYPE, V >`. ###### `line_break< V >` * `V` is of type `ULineBreak`. * [Equivalent] to `property_value< UCHAR_LINE_BREAK, V >`. ###### `numeric_type< V >` * `V` is of type `UNumericType`. * [Equivalent] to `property_value< UCHAR_NUMERIC_TYPE, V >`. ###### `sentence_break< V >` * `V` is of type `USentenceBreak`. * [Equivalent] to `property_value< UCHAR_SENTENCE_BREAK, V >`. ###### `word_break< V >` * `V` is of type `UWordBreakValues`. * [Equivalent] to `property_value< UCHAR_WORD_BREAK, V >`. ### ICU Rules for Value Properties Convenience wrappers for enumerated properties that return a value instead of an actual `enum`. ###### `canonical_combining_class< V >` * `V` is of type `std::uint8_t`. * [Equivalent] to `property_value< UCHAR_CANONICAL_COMBINING_CLASS, V >`. ###### `lead_canonical_combining_class< V >` * `V` is of type `std::uint8_t`. * [Equivalent] to `property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V >`. ###### `trail_canonical_combining_class< V >` * `V` is of type `std::uint8_t`. * [Equivalent] to `property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V >`. ## Binary Rules These rules are available in multiple versions, * in namespace `tao::pegtl::uint8` for 8-bit integer values, * in namespace `tao::pegtl::uint16_be` for big-endian 16-bit integer values, * in namespace `tao::pegtl::uint16_le` for little-endian 16-bit integer values, * in namespace `tao::pegtl::uint32_be` for big-endian 32-bit integer values, * in namespace `tao::pegtl::uint32_le` for little-endian 32-bit integer values, * in namespace `tao::pegtl::uint64_be` for big-endian 64-bit integer values, and * in namespace `tao::pegtl::uint64_le` for little-endian 64-bit integer values. The binary rules need to be manually included from their corresponding headers in the `contrib` section. These rules read one or more bytes from the input to form (and match) an 8, 16, 32 or 64-bit value, respectively, and corresponding template parameters are given as either `std::uint8_t`, `std::uint16_t`, `std::uint32_t` or `std::uin64_t`. In the following descriptions, the parameter N is the size of a single value in bytes, i.e. either 1, 2, 4 or 8. The term *input value* indicates a correspondingly sized integer value read from successive bytes of the input. Binary rules do not rely on other rules. ###### `any` * Succeeds when the input contains at least N bytes. * Consumes N bytes when it succeeds. ###### `mask_not_one< M, C... >` * Succeeds when the input contains at least N bytes, and: * `C` is an empty character pack or the (endian adjusted) input value masked with `M` is **not** one of the given values `C...`. * Consumes N bytes when it succeeds. ###### `mask_not_range< M, C, D >` * Succeeds when the input contains at least N bytes, and: * The (endian adjusted) input value `B` satisfies `( B & M ) < C || D < ( B & M )`. * Consumes N bytes when it succeeds. ###### `mask_one< M, C... >` * Succeeds when the input contains at least N bytes, and: * `C` is a non-empty character pack and the (endian adjusted) input value masked with `M` is one of the given values `C...`. * Consumes N bytes when it succeeds. ###### `mask_range< M, C, D >` * Succeeds when the input contains at least N bytes, and: * The (endian adjusted) input value `B` satisfies `C <= ( B & M ) && ( B & M ) <= D`. * Consumes N bytes when it succeeds. ###### `mask_ranges< M, C1, D1, C2, D2, ... >` * [Equivalent] to `sor< mask_range< M, C1, D1 >, mask_range< M, C2, D2 >, ... >`. ###### `mask_ranges< M, C1, D1, C2, D2, ..., E >` * [Equivalent] to `sor< mask_range< M, C1, D1 >, mask_range< M, C2, D2 >, ..., mask_one< M, E > >`. ###### `mask_string< M, C... >` * [Equivalent] to `seq< mask_one< M, C >... >`. ###### `not_one< C... >` * Succeeds when the input contains at least N bytes, and: * `C` is an empty character pack or the (endian adjusted) input value is **not** one of the given values `C...`. * Consumes N bytes when it succeeds. ###### `not_range< C, D >` * Succeeds when the input contains at least N bytes, and: * The (endian adjusted) input value `B` satisfies `B < C || D < B`. * Consumes N bytes when it succeeds. ###### `one< C... >` * Succeeds when the input contains at least N bytes, and: * `C` is a non-empty character pack and the (endian adjusted) input value is one of the given values `C...`. * Consumes N bytes when it succeeds. ###### `range< C, D >` * Succeeds when the input contains at least N bytes, and: * The (endian adjusted) input value `B` satisfies `C <= B && B <= D`. * Consumes N byte when it succeeds. ###### `ranges< C1, D1, C2, D2, ... >` * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ... >`. ###### `ranges< C1, D1, C2, D2, ..., E >` * [Equivalent] to `sor< range< C1, D1 >, range< C2, D2 >, ..., one< E > >`. ###### `string< C... >` * [Equivalent] to `seq< one< C >... >`. ## Full Index * [`action< A, R... >`](#action-a-r-) [(meta rules)](#meta-rules) * [`alnum`](#alnum) [(ascii rules)](#ascii-rules) * [`alpha`](#alpha) [(ascii rules)](#ascii-rules) * [`alphabetic`](#alphabetic) [(icu rules)](#icu-rules-for-binary-properties) * [`any`](#any) [(ascii rules)](#ascii-rules) * [`any`](#any-1) [(unicode rules)](#unicode-rules) * [`any`](#any-2) [(binary rules)](#binary-rules) * [`apply< A... >`](#apply-a-) [(action rules)](#action-rules) * [`apply0< A... >`](#apply0-a-) [(action rules)](#action-rules) * [`ascii_hex_digit`](#ascii_hex_digit) [(icu rules)](#icu-rules-for-binary-properties) * [`at< R... >`](#at-r-) [(combinators)](#combinators) * [`bidi_class< V >`](#bidi_class-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`bidi_control`](#bidi_control) [(icu rules)](#icu-rules-for-binary-properties) * [`bidi_mirrored`](#bidi_mirrored) [(icu rules)](#icu-rules-for-binary-properties) * [`binary_property< P >`](#binary_property-p-) [(icu rules)](#basic-icu-rules) * [`binary_property< P, V >`](#binary_property-p-v-) [(icu rules)](#basic-icu-rules) * [`blank`](#blank) [(ascii rules)](#ascii-rules) * [`block< V >`](#block-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`bof`](#bof) [(atomic rules)](#atomic-rules) * [`bol`](#bol) [(atomic rules)](#atomic-rules) * [`bom`](#bom) [(unicode rules)](#unicode-rules) * [`bytes< Num >`](#bytes-num-) [(atomic rules)](#atomic-rules) * [`canonical_combining_class< V >`](#canonical_combining_class-v-) [(icu rules)](#icu-rules-for-value-properties) * [`case_sensitive`](#case_sensitive) [(icu rules)](#icu-rules-for-binary-properties) * [`control< C, R... >`](#control-c-r-) [(meta rules)](#meta-rules) * [`dash`](#dash) [(icu rules)](#icu-rules-for-binary-properties) * [`decomposition_type< V >`](#decomposition_type-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`default_ignorable_code_point`](#default_ignorable_code_point) [(icu rules)](#icu-rules-for-binary-properties) * [`deprecated`](#deprecated) [(icu rules)](#icu-rules-for-binary-properties) * [`diacritic`](#diacritic) [(icu rules)](#icu-rules-for-binary-properties) * [`digit`](#digit) [(ascii rules)](#ascii-rules) * [`disable< R... >`](#disable-r-) [(meta rules)](#meta-rules) * [`discard`](#discard) [(meta rules)](#meta-rules) * [`east_asian_width< V >`](#east_asian_width-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`enable< R... >`](#enable-r-) [(meta-rules)](#meta-rules) * [`eof`](#eof) [(atomic rules)](#atomic-rules) * [`eol`](#eol) [(atomic rules)](#atomic-rules) * [`eolf`](#eolf) [(atomic rules)](#atomic-rules) * [`extender`](#extender) [(icu rules)](#icu-rules-for-binary-properties) * [`failure`](#failure) [(atomic rules)](#atomic-rules) * [`forty_two< C... >`](#forty_two-c-) [(ascii rules)](#ascii-rules) * [`full_composition_exclusion`](#full_composition_exclusion) [(icu rules)](#icu-rules-for-binary-properties) * [`general_category< V >`](#general_category-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`grapheme_base`](#grapheme_base) [(icu rules)](#icu-rules-for-binary-properties) * [`grapheme_cluster_break< V >`](#grapheme_cluster_break-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`grapheme_extend`](#grapheme_extend) [(icu rules)](#icu-rules-for-binary-properties) * [`grapheme_link`](#grapheme_link) [(icu rules)](#icu-rules-for-binary-properties) * [`hangul_syllable_type< V >`](#hangul_syllable_type-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`hex_digit`](#hex_digit) [(icu rules)](#icu-rules-for-binary-properties) * [`hyphen`](#hyphen) [(icu rules)](#icu-rules-for-binary-properties) * [`id_continue`](#id_continue) [(icu rules)](#icu-rules-for-binary-properties) * [`id_start`](#id_start) [(icu rules)](#icu-rules-for-binary-properties) * [`identifier_first`](#identifier_first) [(ascii rules)](#ascii-rules) * [`identifier_other`](#identifier_other) [(ascii rules)](#ascii-rules) * [`identifier`](#identifier) [(ascii rules)](#ascii-rules) * [`ideographic`](#ideographic) [(icu rules)](#icu-rules-for-binary-properties) * [`ids_binary_operator`](#ids_binary_operator) [(icu rules)](#icu-rules-for-binary-properties) * [`ids_trinary_operator`](#ids_trinary_operator) [(icu rules)](#icu-rules-for-binary-properties) * [`if_apply< R, A... >`](#if_apply-r-a-) [(action rules)](#action-rules) * [`if_must< R, S... >`](#if_must-r-s-) [(convenience)](#convenience) * [`if_must_else< R, S, T >`](#if_must_else-r-s-t-) [(convenience)](#convenience) * [`if_then_else< R, S, T >`](#if_then_else-r-s-t-) [(convenience)](#convenience) * [`istring< C... >`](#istring-c-) [(ascii rules)](#ascii-rules) * [`join_control`](#join_control) [(icu rules)](#icu-rules-for-binary-properties) * [`joining_group< V >`](#joining_group-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`joining_type< V >`](#joining_type-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`keyword< C... >`](#keyword-c-) [(ascii rules)](#ascii-rules) * [`lead_canonical_combining_class< V >`](#lead_canonical_combining_class-v-) [(icu rules)](#icu-rules-for-value-properties) * [`line_break< V >`](#line_break-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`list< R, S >`](#list-r-s-) [(convenience)](#convenience) * [`list< R, S, P >`](#list-r-s-p-) [(convenience)](#convenience) * [`list_must< R, S >`](#list_must-r-s-) [(convenience)](#convenience) * [`list_must< R, S, P >`](#list_must-r-s-p-) [(convenience)](#convenience) * [`list_tail< R, S >`](#list_tail-r-s-) [(convenience)](#convenience) * [`list_tail< R, S, P >`](#list_tail-r-s-p-) [(convenience)](#convenience) * [`logical_order_exception`](#logical_order_exception) [(icu rules)](#icu-rules-for-binary-properties) * [`lower`](#lower) [(ascii rules)](#ascii-rules) * [`lowercase`](#lowercase) [(icu rules)](#icu-rules-for-binary-properties) * [`mask_not_one< M, C... >`](#mask_not_one-m-c-) [(binary rules)](#binary-rules) * [`mask_not_range< M, C, D >`](#mask_not_range-m-c-d-) [(binary rules)](#binary-rules) * [`mask_one< M, C... >`](#mask_one-m-c-) [(binary rules)](#binary-rules) * [`mask_range< M, C, D >`](#mask_range-m-c-d-) [(binary rules)](#binary-rules) * [`mask_ranges< M, C1, D1, C2, D2, ... >`](#mask_ranges-m-c1-d1-c2-d2--) [(binary rules)](#binary-rules) * [`mask_ranges< M, C1, D1, C2, D2, ..., E >`](#mask_ranges-m-c1-d1-c2-d2--e-) [(binary rules)](#binary-rules) * [`mask_string< M, C... >`](#mask_string-m-c-) [(binary rules)](#binary-rules) * [`math`](#math) [(icu rules)](#icu-rules-for-binary-properties) * [`minus< M, S >`](#minus-m-s-) [(convenience)](#convenience) * [`must< R... >`](#must-r-) [(convenience)](#convenience) * [`nfc_inert`](#nfc_inert) [(icu rules)](#icu-rules-for-binary-properties) * [`nfd_inert`](#nfd_inert) [(icu rules)](#icu-rules-for-binary-properties) * [`nfkc_inert`](#nfkc_inert) [(icu rules)](#icu-rules-for-binary-properties) * [`nfkd_inert`](#nfkd_inert) [(icu rules)](#icu-rules-for-binary-properties) * [`noncharacter_code_point`](#noncharacter_code_point) [(icu rules)](#icu-rules-for-binary-properties) * [`not_at< R... >`](#not_at-r-) [(combinators)](#combinators) * [`not_one< C... >`](#not_one-c-) [(ascii rules)](#ascii-rules) * [`not_one< C... >`](#not_one-c--1) [(unicode rules)](#unicode-rules) * [`not_one< C... >`](#not_one-c--2) [(binary rules)](#binary-rules) * [`not_range< C, D >`](#not_range-c-d-) [(ascii rules)](#ascii-rules) * [`not_range< C, D >`](#not_range-c-d--1) [(unicode rules)](#unicode-rules) * [`not_range< C, D >`](#not_range-c-d--2) [(binary rules)](#binary-rules) * [`nul`](#nul) [(ascii rules)](#ascii-rules) * [`numeric_type< V >`](#numeric_type-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`one< C... >`](#one-c-) [(ascii rules)](#ascii-rules) * [`one< C... >`](#one-c--1) [(unicode rules)](#unicode-rules) * [`one< C... >`](#one-c--2) [(binary rules)](#binary-rules) * [`opt< R... >`](#opt-r-) [(combinators)](#combinators) * [`opt_must< R, S...>`](#opt_must-r-s-) [(convenience)](#convenience) * [`pad< R, S, T = S >`](#pad-r-s-t--s-) [(convenience)](#convenience) * [`pad_opt< R, P >`](#pad_opt-r-p-) [(convenience)](#convenience) * [`pattern_syntax`](#pattern_syntax) [(icu rules)](#icu-rules-for-binary-properties) * [`pattern_white_space`](#pattern_white_space) [(icu rules)](#icu-rules-for-binary-properties) * [`plus< R... >`](#plus-r-) [(combinators)](#combinators) * [`posix_alnum`](#posix_alnum) [(icu rules)](#icu-rules-for-binary-properties) * [`posix_blank`](#posix_blank) [(icu rules)](#icu-rules-for-binary-properties) * [`posix_graph`](#posix_graph) [(icu rules)](#icu-rules-for-binary-properties) * [`posix_print`](#posix_print) [(icu rules)](#icu-rules-for-binary-properties) * [`posix_xdigit`](#posix_xdigit) [(icu rules)](#icu-rules-for-binary-properties) * [`print`](#print) [(ascii rules)](#ascii-rules) * [`property_value< P, V >`](#property_value-p-v-) [(icu rules)](#basic-icu-rules) * [`quotation_mark`](#quotation_mark) [(icu rules)](#icu-rules-for-binary-properties) * [`radical`](#radical) [(icu rules)](#icu-rules-for-binary-properties) * [`raise< T >`](#raise-t-) [(atomic rules)](#atomic-rules) * [`range< C, D >`](#range-c-d-) [(ascii rules)](#ascii-rules) * [`range< C, D >`](#range-c-d--1) [(unicode rules)](#unicode-rules) * [`range< C, D >`](#range-c-d--2) [(binary rules)](#binary-rules) * [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2--) [(ascii rules)](#ascii-rules) * [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2---1) [(unicode rules)](#unicode-rules) * [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2---2) [(binary rules)](#binary-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e-) [(ascii rules)](#ascii-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e--1) [(unicode rules)](#unicode-rules) * [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e--2) [(binary rules)](#binary-rules) * [`rematch< R, S... >`](#rematch-r-s-) [(convenience)](#convenience) * [`rep< Num, R... >`](#rep-num-r-) [(convenience)](#convenience) * [`rep_max< Max, R... >`](#rep_max-max-r-) [(convenience)](#convenience) * [`rep_min< Min, R... >`](#rep_min-min-r-) [(convenience)](#convenience) * [`rep_min_max< Min, Max, R... >`](#rep_min_max-min-max-r-) [(convenience)](#convenience) * [`rep_opt< Num, R... >`](#rep_opt-num-r-) [(convenience)](#convenience) * [`require< Num >`](#require-num-) [(meta-rules)](#meta-rules) * [`s_term`](#s_term) [(icu rules)](#icu-rules-for-binary-properties) * [`segment_starter`](#segment_starter) [(icu rules)](#icu-rules-for-binary-properties) * [`sentence_break< V >`](#sentence_break-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`seq< R... >`](#seq-r-) [(combinators)](#combinators) * [`seven`](#seven) [(ascii rules)](#ascii-rules) * [`shebang`](#shebang) [(ascii rules)](#ascii-rules) * [`soft_dotted`](#soft_dotted) [(icu rules)](#icu-rules-for-binary-properties) * [`sor< R... >`](#sor-r-) [(combinators)](#combinators) * [`space`](#space) [(ascii rules)](#ascii-rules) * [`star< R... >`](#star-r-) [(combinators)](#combinators) * [`star_must< R, S... >`](#star_must-r-s-) [(convenience)](#convenience) * [`state< S, R... >`](#state-s-r-) [(meta rules)](#meta-rules) * [`string< C... >`](#string-c-) [(ascii rules)](#ascii-rules) * [`string< C... >`](#string-c--1) [(unicode rules)](#unicode-rules) * [`string< C... >`](#string-c--2) [(binary rules)](#binary-rules) * [`success`](#success) [(atomic rules)](#atomic-rules) * [`TAO_PEGTL_ISTRING( "..." )`](#tao_pegtl_istring--) [(ascii rules)](#ascii_rules) * [`TAO_PEGTL_KEYWORD( "..." )`](#tao_pegtl_keyword--) [(ascii rules)](#ascii_rules) * [`TAO_PEGTL_STRING( "..." )`](#tao_pegtl_string--) [(ascii rules)](#ascii_rules) * [`terminal_punctuation`](#terminal_punctuation) [(icu rules)](#icu-rules-for-binary-properties) * [`three< C >`](#three-c-) [(ascii rules)](#ascii-rules) * [`trail_canonical_combining_class< V >`](#trail_canonical_combining_class-v-) [(icu rules)](#icu-rules-for-value-properties) * [`try_catch< R... >`](#try_catch-r-) [(convenience)](#convenience) * [`try_catch_type< E, R... >`](#try_catch_type-e-r-) [(convenience)](#convenience) * [`two< C >`](#two-c-) [(ascii rules)](#ascii-rules) * [`unified_ideograph`](#unified_ideograph) [(icu rules)](#icu-rules-for-binary-properties) * [`until< R >`](#until-r-) [(convenience)](#convenience) * [`until< R, S... >`](#until-r-s-) [(convenience)](#convenience) * [`upper`](#upper) [(ascii rules)](#ascii-rules) * [`uppercase`](#uppercase) [(icu rules)](#icu-rules-for-binary-properties) * [`variation_selector`](#variation_selector) [(icu rules)](#icu-rules-for-binary-properties) * [`white_space`](#white_space) [(icu rules)](#icu-rules-for-binary-properties) * [`word_break< V >`](#word_break-v-) [(icu rules)](#icu-rules-for-enumerated-properties) * [`xdigit`](#xdigit) [(ascii rules)](#ascii-rules) * [`xid_continue`](#xid_continue) [(icu rules)](#icu-rules-for-binary-properties) * [`xid_start`](#xid_start) [(icu rules)](#icu-rules-for-binary-properties) Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey [Equivalent]: #equivalence [implementation]: #implementation [Meta data]: Meta-Data-and-Visit.md tao-pegtl-3.2.7/doc/Rules-and-Grammars.md000066400000000000000000000367651426407250600201360ustar00rootroot00000000000000# Rules and Grammars Writing a PEGTL grammar means implementing custom parsing rules. Implementing custom parsing rules can be done either by * combining existing rules and combinators into new rules through inheritance, or * implementing a rule from scratch, i.e. writing a class with certain properties. ## Contents * [Combining Existing Rules](#combining-existing-rules) * [Toy S-Expression Grammar](#toy-s-expression-grammar) * [Creating New Rules](#creating-new-rules) * [Simple Rules](#simple-rules) * [Complex Rules](#complex-rules) ## Combining Existing Rules Combining existing rules is by far the more frequent way of creating new rules. Here is an example that shows how existing rules are combined into a new rule through inheritance: ```c++ using namespace tao::pegtl; struct integer : seq< opt< one< '+', '-' > >, // ('+'/'-')? plus< digit > // digit+ > {}; ``` It defines a new rule named `integer` that is a sequence of two parts, an optional character that can be one of `+` or `-`, followed by a non-empty repetition of a digit. Using inheritance in this way incurs no run-time penalty. See the [Rule Reference](Rule-Reference.md) for a complete list of all rules and combinators included with the PEGTL. Recursion, or cycles in the grammar, can be implemented after a forward-declaration of one or more rules. ```c++ struct number : tao::pegtl::plus< tao::pegtl::digit > {}; struct addition; // Forward declaration to break the cyclic dependency. struct bracket : tao::pegtl::if_must< tao::pegtl::one< '(' >, addition, tao::pegtl::one< ')' > > {}; struct atomic : tao::pegtl::sor< number, bracket > {}; struct addition : tao::pegtl::list< atomic, tao::pegtl::one< '+' > > {}; ``` When defining a large set of grammar rules in this way it can be advisable to include a `using namespace tao::pegtl;`-definition at the beginning in order to prevent the frequent repetition of the `tao::pegtl::` namespace qualifier. This `using`-definition is often combined with the practice of confining a PEGTL grammar to a single translation unit, in which case there is no `namespace`-pollution, and the compile time is kept low by including the PEGTL only in the translation unit with the grammar. A grammar is nothing else than a collection of rules. In theory, as long as a grammar does not contain cycles, complete grammars could be implemented as a single, large rule. In practice, this is not advisable as it greatly reduces the readability and testability of the grammar, in addition to being quite unmaintainable. ## Toy S-Expression Grammar To give another example of what a small real-world grammar might look like, below is the grammar for a toy-version of S-expressions. It only supports proper lists, symbols, comments and numbers. Numbers are non-empty sequences of ASCII digits. The rule named `file` is the intended top-level rule of the grammar, i.e. the rule that is supplied as template argument to [the `parse()` function](Inputs-and-Parsing.md#parse-function) in order to start a parsing run with this grammar. ```c++ struct hash_comment : tao::pegtl::until< tao::pegtl::eolf > {}; struct list; struct list_comment : tao::pegtl::if_must< tao::pegtl::at< tao::pegtl::one< '(' > >, tao::pegtl::disable< list > > {}; struct read_include : tao::pegtl::seq< tao::pegtl::one< ' ' >, tao::pegtl::one< '"' >, tao::pegtl::plus< tao::pegtl::not_one< '"' > >, tao::pegtl::one< '"' > > {}; struct hash_include : tao::pegtl::if_must< tao::pegtl::string< 'i', 'n', 'c', 'l', 'u', 'd', 'e' >, read_include > {}; struct hashed : tao::pegtl::if_must< tao::pegtl::one< '#' >, tao::pegtl::sor< hash_include, list_comment, hash_comment > > {}; struct number : tao::pegtl::plus< tao::pegtl::digit > {}; struct symbol : tao::pegtl::identifier {}; struct atom : tao::pegtl::sor< number, symbol > {}; struct anything; struct list : tao::pegtl::if_must< tao::pegtl::one< '(' >, tao::pegtl::until< tao::pegtl::one< ')' >, anything > > {}; struct normal : tao::pegtl::sor< atom, list > {}; struct anything : tao::pegtl::sor< tao::pegtl::space, hashed, normal > {}; struct main : tao::pegtl::until< tao::pegtl::eof, tao::pegtl::must< anything > > {}; ``` In order to let a parsing run do more than verify whether an input conforms to the grammar, it is necessary to attach user-defined *actions* to some grammar rules, as explained in [Actions and States](Actions-and-States.md). ## Creating New Rules Sometimes a grammar requires a parsing rule that can not be readily created as combination of the existing rules. In these cases a custom grammar rule, i.e. a class with a static member function called `match()` that has to adhere to one of two possible interfaces or prototypes, can be implemented from scratch. When implementing a custom rule class, it is important to remember that the input passed to `match()` represents the *remainder* of the complete input. At the beginning of a parsing run, the input represents the complete data-to-be-parsed. During the parsing run, many rules *consume* the data that matched from the input. Consuming data from an input advances the pointer to the data that the input's `begin()` member function returns, and decrements the size by the same amount. The PEGTL makes one **important** assumption about all parsing rules. If a call to `match()` returns with `false`, then the rule **must not** have consumed input (for [complex rules](#complex-rules): only when the `rewind_mode` is `required`). For performance reasons this assumption is neither ensured nor verified by the PEGTL. ### Simple Rules In the simplified rule, `match()` is called with a single argument, the input. It returns a `bool` to indicate success or (local) failure. Rules with the simplified interface are called without the states as arguments. ```c++ struct simple_rule { template< typename ParseInput > static bool match( ParseInput& in ) { ... } }; ``` Here is an excerpt from the included example program `src/example/pegtl/modulus_match.cpp` that shows a simple custom rule. The - slightly artificial - rule `my_rule` uses three important `input` functions, 1. first `empty()` to check whether the input is not empty, 2. then `current()` to access the data and check whether the remainder of the first remaining input character `C` happens to satisfy `C % M == R`, 3. and finally `bump()` to consume one `char` from the input if the two above conditions are satisfied. Note how the return value reflects the result of the checks, and how input is only consumed when the return value is `true`. The remainder of the program checks that all characters of `argv[ 1 ]` are equal to 0 when divided by 3. ```c++ using namespace TAO_PEGTL_NAMESPACE; namespace modulus { template< unsigned M, unsigned R = 0 > struct my_rule { static_assert( M > 1, "Modulus must be greater than 1" ); static_assert( R < M, "Remainder must be less than modulus" ); template< typename ParseInput > static bool match( ParseInput& in ) { if( !in.empty() ) { if( ( ( *in.current() ) % M ) == R ) { in.bump( 1 ); return true; } } return false; } }; struct grammar : until< eolf, must< my_rule< 3 > > > {}; } // namespace modulus int main( int argc, char** argv ) { if( argc > 1 ) { argv_input in( argv, 1 ); parse< modulus::grammar >( in ); } return 0; } ``` ### Complex Rules The complex calling convention gives a rule's `match()` member function access to "everything", i.e. some modes, the action- and control class, and all state arguments. All of these parameters are required for custom rules that need to themselves call other rules for matching. The signature of `match()` in a complex rule takes the following form. ```c++ struct complex_rule { using rule_t = complex_rule; using subs_t = tao::pegtl::empty_list; // Or tao::pegtl::rule_list< sub_rules_of_complex_rule... >. template< tao::pegtl::apply_mode A, tao::pegtl::rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... ) { ... } }; ``` #### Modes The `apply_mode` can take the value `apply_mode::action` or `apply_mode::nothing`, depending on whether actions are currently enabled or disabled. Most custom parsing rules will either ignore, or pass on the `apply_mode` unchanged; usually only the control interprets the `apply_mode`. The `rewind_mode` can take the value `rewind_mode::active`, `rewind_mode::required` or `rewind_mode::dontcare`. When `M` is `rewind_mode::required`, the custom rule's `match()`-implementation **must**, on local failure, rewind the input to where it (the input) was when `match()` was called. When `M` is **not** `rewind_mode::required`, it is not necessary to perform rewinding as either some other rule further up the call stack is already taking care of it (`rewind_mode::active`), or rewinding is not necessary (`rewind_mode::dontcare`). For example within a `must<>`-rule (which converts local failure, a return value of `false` from `match()`, to global failure, an exception) the `rewind_mode` is `dontcare`. The following implementation of the `seq`-rule's `match()` shows how to correctly handle the `rewind_mode`. The input's `mark()` member function uses the `rewind_mode` to choose which input marker to return, either one that takes care of rewinding when required, or a dummy object that does nothing. In the first case, `next_rewind_mode` is set to `active`, otherwise it is equal to `M`, just as required for the next rules called by the current one. The return value of `match()` is then passed through the input marker `m` so that, if the return value is `false` and the marker is not the dummy, it can rewind the input `in`. ```c++ template< typename... Rules > struct seq { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... st ) { auto m = in.template mark< M >(); using m_t = decltype( m ); return m( rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ); } }; ``` #### Example The following excerpt from the included example program `src/example/pegtl/dynamic_match.cpp` shows a complex custom rule that itself makes use of a state argument. This is necessary to cleanly implement dynamic matching, i.e. where a (set of) string(s) that a rule is intended to match depends on some run-time data structure rather than some compile-time type (the latter of which includes all template arguments). The aim is to parse a kind of *long string literal*, an arbitrary string literal that does not require escaping of any special characters, as is common in many scripting languages. In order to allow for arbitrary content without escaping it has to be possible to choose a string sequence that is not part of the string literal as delimiter. For this example we adopt the convention that a long string literal begins with `"[foo["` and ends with `"]foo]"` where `"foo"` is any non-empty string that does not contain a `"["` (quotation marks always excluded). Please note that the following code snippets are not in actual source code order. First we define a rule for the opening of a long string literal as explained above. ```c++ namespace dynamic { struct long_literal_id : tao::pegtl::plus< tao::pegtl::not_one< '[' > > {}; struct long_literal_open : tao::pegtl::seq< tao::pegtl::one< '[' >, long_literal_id, tao::pegtl::one< '[' > > {}; ``` Then we implement an action class with a specialisation for what is the `"foo"`-part of the long string literal's opening sequence. The action stores the matched string that corresponds to `"foo"` in a string variable that is passed as state argument. ```c++ template< typename Rule > struct action {}; template<> struct action< long_literal_id > { template< typename ActionInput > static void apply( const ActionInput& in, std::string& id, const std::string& ) { id = in.string(); } }; ``` The rule for the closing sequence is similar to the opening, with closing instead of opening brackets, and with a custom rule to check for the `"foo"`-part. ```c++ struct long_literal_close : tao::pegtl::seq< tao::pegtl::one< ']' >, long_literal_mark, tao::pegtl::one< ']' > > {}; ``` The custom rule itself 1. first checks whether the input contains enough bytes to match the string stored by the action, 2. then checks whether the input bytes match the stored string, and 3. finally calls `bump()` to consume the correct number of bytes from the input when both checks succeed. ```c++ struct long_literal_mark { template< tao::pegtl::apply_mode A, tao::pegtl::rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput > static bool match( ParseInput& in, const std::string& id, const std::string& ) { if( in.size( id.size() ) >= id.size() ) { if( std::memcmp( in.begin(), id.data(), id.size() ) == 0 ) { in.bump( id.size() ); return true; } } return false; } }; ``` The grammar is completed with another two rules for putting everything together, and an action that stores the body of the long string literal in a second state argument. In this case the rule `long_literal_body` is redundant, however real-world examples frequently contain a rule like `tao::pegtl::any` multiple times, and so it is necessary to give it another name in order to attach different actions to different uses of the same rule. ```c++ struct long_literal_body : tao::pegtl::any {}; struct grammar : tao::pegtl::if_must< long_literal_open, tao::pegtl::until< long_literal_close, long_literal_body >, tao::pegtl::eof > {}; template<> struct action< long_literal_body > { template< typename ActionInput > static void apply( const ActionInput& in, const std::string&, std::string& body ) { body += in.string(); } }; } // namespace dynamic ``` Given the main function... ```c++ int main( int argc, char* argv[] ) { if( argc > 1 ) { std::string id; std::string body; tao::pegtl::argv_input in( argv, 1 ); tao::pegtl::parse< dynamic::grammar, dynamic::action >( in, id, body ); std::cout << "long literal id was: " << id << std::endl; std::cout << "long literal body was: " << body << std::endl; } return 0; } ``` ...we can see the grammar in action in the shell: ```sh $ build/src/example/pegtl/dynamic_match '[foo["[bla]"]foo]' long literal id was: foo long literal body was: "[bla]" $ build/src/example/pegtl/dynamic_match '["fraggle"["[foo["]"fraggle"]' long literal id was: "fraggle" long literal body was: "[foo[" ``` Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey tao-pegtl-3.2.7/include/000077500000000000000000000000001426407250600150505ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/000077500000000000000000000000001426407250600156335ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl.hpp000066400000000000000000000024101426407250600174540ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_HPP #define TAO_PEGTL_HPP #include "pegtl/config.hpp" #include "pegtl/demangle.hpp" #include "pegtl/parse.hpp" #include "pegtl/version.hpp" #include "pegtl/ascii.hpp" #include "pegtl/rules.hpp" #include "pegtl/utf8.hpp" #include "pegtl/argv_input.hpp" #include "pegtl/buffer_input.hpp" #include "pegtl/cstream_input.hpp" #include "pegtl/istream_input.hpp" #include "pegtl/memory_input.hpp" #include "pegtl/read_input.hpp" #include "pegtl/string_input.hpp" // This has to be included *after* the above inputs, // otherwise the amalgamated header will not work! #include "pegtl/file_input.hpp" #include "pegtl/change_action.hpp" #include "pegtl/change_action_and_state.hpp" #include "pegtl/change_action_and_states.hpp" #include "pegtl/change_control.hpp" #include "pegtl/change_state.hpp" #include "pegtl/change_states.hpp" #include "pegtl/disable_action.hpp" #include "pegtl/enable_action.hpp" #include "pegtl/discard_input.hpp" #include "pegtl/discard_input_on_failure.hpp" #include "pegtl/discard_input_on_success.hpp" #include "pegtl/visit.hpp" #if defined( __cpp_exceptions ) #include "pegtl/must_if.hpp" #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/000077500000000000000000000000001426407250600167465ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl/apply_mode.hpp000066400000000000000000000006061426407250600216120ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_APPLY_MODE_HPP #define TAO_PEGTL_APPLY_MODE_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { enum class apply_mode : bool { action = true, nothing = false }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/argv_input.hpp000066400000000000000000000024261426407250600216410ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_ARGV_INPUT_HPP #define TAO_PEGTL_ARGV_INPUT_HPP #include #include #include #include #include "config.hpp" #include "eol.hpp" #include "memory_input.hpp" #include "tracking_mode.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { [[nodiscard]] inline std::string make_argv_source( const std::size_t argn ) { std::ostringstream oss; oss << "argv[" << argn << ']'; return std::move( oss ).str(); } } // namespace internal template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct argv_input : memory_input< P, Eol > { template< typename T > argv_input( char** argv, const std::size_t argn, T&& in_source ) : memory_input< P, Eol >( static_cast< const char* >( argv[ argn ] ), std::forward< T >( in_source ) ) {} argv_input( char** argv, const std::size_t argn ) : argv_input( argv, argn, internal::make_argv_source( argn ) ) {} }; template< typename... Ts > argv_input( Ts&&... ) -> argv_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/ascii.hpp000066400000000000000000000066371426407250600205630ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_ASCII_HPP #define TAO_PEGTL_ASCII_HPP #include "config.hpp" #include "internal/result_on_found.hpp" #include "internal/rules.hpp" namespace TAO_PEGTL_NAMESPACE { inline namespace ascii { // clang-format off struct alnum : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9' > {}; struct alpha : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {}; struct any : internal::any< internal::peek_char > {}; struct blank : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > {}; struct digit : internal::range< internal::result_on_found::success, internal::peek_char, '0', '9' > {}; struct ellipsis : internal::string< '.', '.', '.' > {}; template< char... Cs > struct forty_two : internal::rep< 42, internal::one< internal::result_on_found::success, internal::peek_char, Cs... > > {}; struct identifier_first : internal::identifier_first {}; struct identifier_other : internal::identifier_other {}; struct identifier : internal::identifier {}; template< char... Cs > struct istring : internal::istring< Cs... > {}; template< char... Cs > struct keyword : internal::seq< internal::string< Cs... >, internal::not_at< internal::identifier_other > > { static_assert( sizeof...( Cs ) > 0 ); }; struct lower : internal::range< internal::result_on_found::success, internal::peek_char, 'a', 'z' > {}; template< char... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_char, Cs... > {}; template< char Lo, char Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_char, Lo, Hi > {}; struct nul : internal::one< internal::result_on_found::success, internal::peek_char, char( 0 ) > {}; struct odigit : internal::range< internal::result_on_found::success, internal::peek_char, '0', '7' > {}; template< char... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_char, Cs... > {}; struct print : internal::range< internal::result_on_found::success, internal::peek_char, char( 32 ), char( 126 ) > {}; template< char Lo, char Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_char, Lo, Hi > {}; template< char... Cs > struct ranges : internal::ranges< internal::peek_char, Cs... > {}; struct seven : internal::range< internal::result_on_found::success, internal::peek_char, char( 0 ), char( 127 ) > {}; struct shebang : internal::seq< internal::string< '#', '!' >, internal::until< internal::eolf > > {}; struct space : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\n', '\r', '\t', '\v', '\f' > {}; template< char... Cs > struct string : internal::string< Cs... > {}; template< char C > struct three : internal::string< C, C, C > {}; template< char C > struct two : internal::string< C, C > {}; struct upper : internal::range< internal::result_on_found::success, internal::peek_char, 'A', 'Z' > {}; struct xdigit : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {}; // clang-format on } // namespace ascii } // namespace TAO_PEGTL_NAMESPACE #include "internal/pegtl_string.hpp" #endif tao-pegtl-3.2.7/include/tao/pegtl/buffer_input.hpp000066400000000000000000000141661426407250600221570ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_BUFFER_INPUT_HPP #define TAO_PEGTL_BUFFER_INPUT_HPP #include #include #include #include #include #include #include #if defined( __cpp_exceptions ) #include #else #include #include #endif #include "config.hpp" #include "eol.hpp" #include "memory_input.hpp" #include "position.hpp" #include "tracking_mode.hpp" #include "internal/action_input.hpp" #include "internal/bump.hpp" #include "internal/iterator.hpp" #include "internal/marker.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Reader, typename Eol = eol::lf_crlf, typename Source = std::string, std::size_t Chunk = 64 > class buffer_input { public: using reader_t = Reader; using eol_t = Eol; using source_t = Source; using iterator_t = internal::iterator; using action_t = internal::action_input< buffer_input >; static constexpr std::size_t chunk_size = Chunk; static constexpr tracking_mode tracking_mode_v = tracking_mode::eager; template< typename T, typename... As > buffer_input( T&& in_source, const std::size_t maximum, As&&... as ) : m_reader( std::forward< As >( as )... ), m_maximum( maximum + Chunk ), m_buffer( new char[ maximum + Chunk ] ), m_current( m_buffer.get() ), m_end( m_buffer.get() ), m_source( std::forward< T >( in_source ) ) { static_assert( Chunk != 0, "zero chunk size not implemented" ); assert( m_maximum > maximum ); // Catches overflow; change to >= when zero chunk size is implemented. } buffer_input( const buffer_input& ) = delete; buffer_input( buffer_input&& ) = delete; ~buffer_input() = default; buffer_input& operator=( const buffer_input& ) = delete; buffer_input& operator=( buffer_input&& ) = delete; [[nodiscard]] bool empty() { require( 1 ); return m_current.data == m_end; } [[nodiscard]] std::size_t size( const std::size_t amount ) { require( amount ); return buffer_occupied(); } [[nodiscard]] const char* current() const noexcept { return m_current.data; } [[nodiscard]] const char* end( const std::size_t amount ) { require( amount ); return m_end; } [[nodiscard]] std::size_t byte() const noexcept { return m_current.byte; } [[nodiscard]] std::size_t line() const noexcept { return m_current.line; } [[nodiscard]] std::size_t column() const noexcept { return m_current.column; } [[nodiscard]] const Source& source() const noexcept { return m_source; } [[nodiscard]] char peek_char( const std::size_t offset = 0 ) const noexcept { return m_current.data[ offset ]; } [[nodiscard]] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept { return static_cast< std::uint8_t >( peek_char( offset ) ); } void bump( const std::size_t in_count = 1 ) noexcept { internal::bump( m_current, in_count, Eol::ch ); } void bump_in_this_line( const std::size_t in_count = 1 ) noexcept { internal::bump_in_this_line( m_current, in_count ); } void bump_to_next_line( const std::size_t in_count = 1 ) noexcept { internal::bump_to_next_line( m_current, in_count ); } void discard() noexcept { if( m_current.data > m_buffer.get() + Chunk ) { const auto s = m_end - m_current.data; std::memmove( m_buffer.get(), m_current.data, s ); m_current.data = m_buffer.get(); m_end = m_buffer.get() + s; } } void require( const std::size_t amount ) { if( m_current.data + amount <= m_end ) { return; } if( m_current.data + amount > m_buffer.get() + m_maximum ) { #if defined( __cpp_exceptions ) throw std::overflow_error( "require() beyond end of buffer" ); #else std::fputs( "overflow error: require() beyond end of buffer\n", stderr ); std::terminate(); #endif } if( const auto r = m_reader( m_end, ( std::min )( buffer_free_after_end(), ( std::max )( amount - buffer_occupied(), Chunk ) ) ) ) { m_end += r; } } template< rewind_mode M > [[nodiscard]] internal::marker< iterator_t, M > mark() noexcept { return internal::marker< iterator_t, M >( m_current ); } [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const { return TAO_PEGTL_NAMESPACE::position( it, m_source ); } [[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const { return position( m_current ); } [[nodiscard]] const iterator_t& iterator() const noexcept { return m_current; } [[nodiscard]] std::size_t buffer_capacity() const noexcept { return m_maximum; } [[nodiscard]] std::size_t buffer_occupied() const noexcept { assert( m_end >= m_current.data ); return std::size_t( m_end - m_current.data ); } [[nodiscard]] std::size_t buffer_free_before_current() const noexcept { assert( m_current.data >= m_buffer.get() ); return std::size_t( m_current.data - m_buffer.get() ); } [[nodiscard]] std::size_t buffer_free_after_end() const noexcept { assert( m_buffer.get() + m_maximum >= m_end ); return std::size_t( m_buffer.get() + m_maximum - m_end ); } private: Reader m_reader; std::size_t m_maximum; std::unique_ptr< char[] > m_buffer; iterator_t m_current; char* m_end; const Source m_source; public: std::size_t private_depth = 0; }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_action.hpp000066400000000000000000000021631426407250600222430ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_ACTION_HPP #define TAO_PEGTL_CHANGE_ACTION_HPP #include #include "apply_mode.hpp" #include "config.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class NewAction > struct change_action : maybe_nothing { template< typename Rule, 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 ) { static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" ); return Control< Rule >::template match< A, M, NewAction, Control >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_action_and_state.hpp000066400000000000000000000046611426407250600242720ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_ACTION_AND_STATE_HPP #define TAO_PEGTL_CHANGE_ACTION_AND_STATE_HPP #include #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" #include "internal/dependent_false.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class NewAction, typename NewState > struct change_action_and_state : maybe_nothing { template< typename Rule, 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 ) { static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" ); if constexpr( std::is_constructible_v< NewState, const ParseInput&, States... > ) { NewState s( static_cast< const ParseInput& >( in ), st... ); if( Control< Rule >::template match< A, M, NewAction, Control >( in, s ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else if constexpr( std::is_default_constructible_v< NewState > ) { NewState s; if( Control< Rule >::template match< A, M, NewAction, Control >( in, s ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else { static_assert( internal::dependent_false< NewState >, "unable to instantiate new state" ); } } template< typename ParseInput, typename... States > static void success( const ParseInput& in, NewState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) ) { s.success( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_action_and_states.hpp000066400000000000000000000040611426407250600244470ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_ACTION_AND_STATES_HPP #define TAO_PEGTL_CHANGE_ACTION_AND_STATES_HPP #include #include #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class NewAction, typename... NewStates > struct change_action_and_states : maybe_nothing { template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, std::size_t... Ns, typename ParseInput, typename... States > [[nodiscard]] static bool match( std::index_sequence< Ns... > /*unused*/, ParseInput& in, States&&... st ) { auto t = std::tie( st... ); if( Control< Rule >::template match< A, M, NewAction, Control >( in, std::get< Ns >( t )... ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), st... ); } return true; } return false; } template< typename Rule, 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 ) { static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" ); return match< Rule, A, M, Action, Control >( std::index_sequence_for< NewStates... >(), in, NewStates()..., st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_control.hpp000066400000000000000000000017611426407250600224510ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_CONTROL_HPP #define TAO_PEGTL_CHANGE_CONTROL_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class NewControl > struct change_control : maybe_nothing { template< typename Rule, 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 ) { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, NewControl >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_state.hpp000066400000000000000000000043361426407250600221120ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_STATE_HPP #define TAO_PEGTL_CHANGE_STATE_HPP #include #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" #include "internal/dependent_false.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename NewState > struct change_state : maybe_nothing { template< typename Rule, 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 ) { if constexpr( std::is_constructible_v< NewState, const ParseInput&, States... > ) { NewState s( static_cast< const ParseInput& >( in ), st... ); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else if constexpr( std::is_default_constructible_v< NewState > ) { NewState s; if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else { static_assert( internal::dependent_false< NewState >, "unable to instantiate new state" ); } } template< typename ParseInput, typename... States > static void success( const ParseInput& in, NewState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) ) { s.success( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/change_states.hpp000066400000000000000000000035411426407250600222720ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CHANGE_STATES_HPP #define TAO_PEGTL_CHANGE_STATES_HPP #include #include #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... NewStates > struct change_states : maybe_nothing { template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, std::size_t... Ns, typename ParseInput, typename... States > [[nodiscard]] static bool match( std::index_sequence< Ns... > /*unused*/, ParseInput& in, States&&... st ) { auto t = std::tie( st... ); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, std::get< Ns >( t )... ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), st... ); } return true; } return false; } template< typename Rule, 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 ) { return match< Rule, A, M, Action, Control >( std::index_sequence_for< NewStates... >(), in, NewStates()..., st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/config.hpp000066400000000000000000000004361426407250600207270ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONFIG_HPP #define TAO_PEGTL_CONFIG_HPP #if !defined( TAO_PEGTL_NAMESPACE ) #define TAO_PEGTL_NAMESPACE tao::pegtl #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/000077500000000000000000000000001426407250600204065ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl/contrib/abnf.hpp000066400000000000000000000041431426407250600220270ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ABNF_HPP #define TAO_PEGTL_CONTRIB_ABNF_HPP #include "../config.hpp" #include "../internal/rules.hpp" namespace TAO_PEGTL_NAMESPACE::abnf { // Core ABNF rules according to RFC 5234, Appendix B // clang-format off struct ALPHA : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {}; struct BIT : internal::one< internal::result_on_found::success, internal::peek_char, '0', '1' > {}; struct CHAR : internal::range< internal::result_on_found::success, internal::peek_char, char( 1 ), char( 127 ) > {}; struct CR : internal::one< internal::result_on_found::success, internal::peek_char, '\r' > {}; struct CRLF : internal::string< '\r', '\n' > {}; struct CTL : internal::ranges< internal::peek_char, char( 0 ), char( 31 ), char( 127 ) > {}; struct DIGIT : internal::range< internal::result_on_found::success, internal::peek_char, '0', '9' > {}; struct DQUOTE : internal::one< internal::result_on_found::success, internal::peek_char, '"' > {}; struct HEXDIG : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {}; struct HTAB : internal::one< internal::result_on_found::success, internal::peek_char, '\t' > {}; struct LF : internal::one< internal::result_on_found::success, internal::peek_char, '\n' > {}; struct LWSP : internal::star< internal::sor< internal::string< '\r', '\n' >, internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > >, internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > > {}; struct OCTET : internal::any< internal::peek_char > {}; struct SP : internal::one< internal::result_on_found::success, internal::peek_char, ' ' > {}; struct VCHAR : internal::range< internal::result_on_found::success, internal::peek_char, char( 33 ), char( 126 ) > {}; struct WSP : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::abnf #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/add_state.hpp000066400000000000000000000044051426407250600230520ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ADD_STATE_HPP #define TAO_PEGTL_CONTRIB_ADD_STATE_HPP #include #include "../apply_mode.hpp" #include "../config.hpp" #include "../match.hpp" #include "../nothing.hpp" #include "../rewind_mode.hpp" #include "../internal/dependent_false.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename AddState > struct add_state : maybe_nothing { template< typename Rule, 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 ) { if constexpr( std::is_constructible_v< AddState, const ParseInput&, States... > ) { AddState s( static_cast< const ParseInput& >( in ), st... ); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s, st... ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else if constexpr( std::is_default_constructible_v< AddState > ) { AddState s; if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s, st... ) ) { if constexpr( A == apply_mode::action ) { Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... ); } return true; } return false; } else { static_assert( internal::dependent_false< AddState >, "unable to instantiate new state" ); } } template< typename ParseInput, typename... States > static void success( const ParseInput& in, AddState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) ) { s.success( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/alphabet.hpp000066400000000000000000000056601426407250600227060ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ALPHABET_HPP #define TAO_PEGTL_CONTRIB_ALPHABET_HPP #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::alphabet { static const char a = 'a'; static const char b = 'b'; static const char c = 'c'; static const char d = 'd'; static const char e = 'e'; static const char f = 'f'; static const char g = 'g'; static const char h = 'h'; static const char i = 'i'; static const char j = 'j'; static const char k = 'k'; static const char l = 'l'; static const char m = 'm'; static const char n = 'n'; static const char o = 'o'; static const char p = 'p'; static const char q = 'q'; static const char r = 'r'; static const char s = 's'; static const char t = 't'; static const char u = 'u'; static const char v = 'v'; static const char w = 'w'; static const char x = 'x'; static const char y = 'y'; static const char z = 'z'; static const char A = 'A'; // NOLINT(readability-identifier-naming) static const char B = 'B'; // NOLINT(readability-identifier-naming) static const char C = 'C'; // NOLINT(readability-identifier-naming) static const char D = 'D'; // NOLINT(readability-identifier-naming) static const char E = 'E'; // NOLINT(readability-identifier-naming) static const char F = 'F'; // NOLINT(readability-identifier-naming) static const char G = 'G'; // NOLINT(readability-identifier-naming) static const char H = 'H'; // NOLINT(readability-identifier-naming) static const char I = 'I'; // NOLINT(readability-identifier-naming) static const char J = 'J'; // NOLINT(readability-identifier-naming) static const char K = 'K'; // NOLINT(readability-identifier-naming) static const char L = 'L'; // NOLINT(readability-identifier-naming) static const char M = 'M'; // NOLINT(readability-identifier-naming) static const char N = 'N'; // NOLINT(readability-identifier-naming) static const char O = 'O'; // NOLINT(readability-identifier-naming) static const char P = 'P'; // NOLINT(readability-identifier-naming) static const char Q = 'Q'; // NOLINT(readability-identifier-naming) static const char R = 'R'; // NOLINT(readability-identifier-naming) static const char S = 'S'; // NOLINT(readability-identifier-naming) static const char T = 'T'; // NOLINT(readability-identifier-naming) static const char U = 'U'; // NOLINT(readability-identifier-naming) static const char V = 'V'; // NOLINT(readability-identifier-naming) static const char W = 'W'; // NOLINT(readability-identifier-naming) static const char X = 'X'; // NOLINT(readability-identifier-naming) static const char Y = 'Y'; // NOLINT(readability-identifier-naming) static const char Z = 'Z'; // NOLINT(readability-identifier-naming) } // namespace TAO_PEGTL_NAMESPACE::alphabet #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/analyze.hpp000066400000000000000000000142551426407250600225710ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ANALYZE_HPP #define TAO_PEGTL_CONTRIB_ANALYZE_HPP #include #include #include #include #include #include #include #include #include #include "../config.hpp" #include "../demangle.hpp" #include "analyze_traits.hpp" #include "internal/set_stack_guard.hpp" #include "internal/vector_stack_guard.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { struct analyze_entry { explicit analyze_entry( const analyze_type in_type ) noexcept : type( in_type ) {} const analyze_type type; std::vector< std::string_view > subs; }; class analyze_cycles_impl { public: analyze_cycles_impl( analyze_cycles_impl&& ) = delete; analyze_cycles_impl( const analyze_cycles_impl& ) = delete; ~analyze_cycles_impl() = default; analyze_cycles_impl& operator=( analyze_cycles_impl&& ) = delete; analyze_cycles_impl& operator=( const analyze_cycles_impl& ) = delete; [[nodiscard]] std::size_t problems() { for( auto& i : m_entries ) { assert( m_trace.empty() ); assert( m_stack.empty() ); m_results[ i.first ] = work( i, false ); } // The number of problems returned is not very informative as some problems will be found multiple times. return m_problems; } template< typename Rule > [[nodiscard]] bool consumes() const { // The name "consumes" is a shortcut for "the analyze cycles algorithm could prove that this rule always consumes when it succeeds". return m_results.at( demangle< Rule >() ); } protected: explicit analyze_cycles_impl( const int verbose ) noexcept : m_verbose( verbose ), m_problems( 0 ) {} [[nodiscard]] const std::pair< const std::string_view, analyze_entry >& find( const std::string_view name ) const noexcept { const auto iter = m_entries.find( name ); assert( iter != m_entries.end() ); return *iter; } [[nodiscard]] bool work( const std::pair< const std::string_view, analyze_entry >& entry, const bool accum ) { if( const auto g = set_stack_guard( m_stack, entry.first ) ) { const auto v = vector_stack_guard( m_trace, entry.first ); switch( entry.second.type ) { case analyze_type::any: { bool a = false; for( const auto& r : entry.second.subs ) { a = a || work( find( r ), accum || a ); } return true; } case analyze_type::opt: { bool a = false; for( const auto& r : entry.second.subs ) { a = a || work( find( r ), accum || a ); } return false; } case analyze_type::seq: { bool a = false; for( const auto& r : entry.second.subs ) { a = a || work( find( r ), accum || a ); } return a; } case analyze_type::sor: { bool a = true; for( const auto& r : entry.second.subs ) { a = a && work( find( r ), accum ); } return a; } } assert( false ); // LCOV_EXCL_LINE } assert( !m_trace.empty() ); if( !accum ) { ++m_problems; // LCOV_EXCL_START if( ( m_verbose >= 0 ) && ( m_trace.front() == entry.first ) ) { for( const auto& r : m_trace ) { if( r < entry.first ) { return accum; } } std::cerr << "WARNING: Possible cycle without progress at rule " << entry.first << std::endl; if( m_verbose > 0 ) { for( const auto& r : m_trace ) { std::cerr << "- involved (transformed) rule: " << r << std::endl; } } } // LCOV_EXCL_STOP } return accum; } const int m_verbose; std::size_t m_problems; std::set< std::string_view > m_stack; std::vector< std::string_view > m_trace; std::map< std::string_view, bool > m_results; std::map< std::string_view, analyze_entry > m_entries; }; template< typename Name > std::string_view analyze_insert( std::map< std::string_view, analyze_entry >& entry ) { using Traits = analyze_traits< Name, typename Name::rule_t >; const auto [ i, b ] = entry.try_emplace( demangle< Name >(), Traits::type_v ); if( b ) { analyze_insert_impl( typename Traits::subs_t(), i->second.subs, entry ); } return i->first; } template< typename... Subs > void analyze_insert_impl( type_list< Subs... > /*unused*/, std::vector< std::string_view >& subs, std::map< std::string_view, analyze_entry >& entry ) { ( subs.emplace_back( analyze_insert< Subs >( entry ) ), ... ); } template< typename Grammar > struct analyze_cycles : analyze_cycles_impl { explicit analyze_cycles( const int verbose ) : analyze_cycles_impl( verbose ) { analyze_insert< Grammar >( m_entries ); } }; } // namespace internal template< typename Grammar > [[nodiscard]] std::size_t analyze( const int verbose = 1 ) { return internal::analyze_cycles< Grammar >( verbose ).problems(); } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/analyze_traits.hpp000066400000000000000000000230641426407250600241550ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP #define TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP #include #include "../ascii.hpp" #include "../config.hpp" #include "../rules.hpp" #include "../type_list.hpp" #include "forward.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { enum class analyze_type { any, // Consumption-on-success is always true; assumes bounded repetition of conjunction of sub-rules. opt, // Consumption-on-success not necessarily true; assumes bounded repetition of conjunction of sub-rules. seq, // Consumption-on-success depends on consumption of (non-zero bounded repetition of) conjunction of sub-rules. sor // Consumption-on-success depends on consumption of (non-zero bounded repetition of) disjunction of sub-rules. }; } // namespace internal template< typename... Rules > struct analyze_any_traits { static constexpr internal::analyze_type type_v = internal::analyze_type::any; using subs_t = type_list< Rules... >; }; template< typename... Rules > struct analyze_opt_traits { static constexpr internal::analyze_type type_v = internal::analyze_type::opt; using subs_t = type_list< Rules... >; }; template< typename... Rules > struct analyze_seq_traits { static constexpr internal::analyze_type type_v = internal::analyze_type::seq; using subs_t = type_list< Rules... >; }; template< typename... Rules > struct analyze_sor_traits { static constexpr internal::analyze_type type_v = internal::analyze_type::sor; using subs_t = type_list< Rules... >; }; template< typename Name, template< typename... > class Action, typename... Rules > struct analyze_traits< Name, internal::action< Action, Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name, typename Peek > struct analyze_traits< Name, internal::any< Peek > > : analyze_any_traits<> {}; template< typename Name, typename... Actions > struct analyze_traits< Name, internal::apply< Actions... > > : analyze_opt_traits<> {}; template< typename Name, typename... Actions > struct analyze_traits< Name, internal::apply0< Actions... > > : analyze_opt_traits<> {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::at< Rules... > > : analyze_traits< Name, typename opt< Rules... >::rule_t > {}; template< typename Name > struct analyze_traits< Name, internal::bof > : analyze_opt_traits<> {}; template< typename Name > struct analyze_traits< Name, internal::bol > : analyze_opt_traits<> {}; template< typename Name, unsigned Cnt > struct analyze_traits< Name, internal::bytes< Cnt > > : std::conditional_t< ( Cnt != 0 ), analyze_any_traits<>, analyze_opt_traits<> > {}; template< typename Name, template< typename... > class Control, typename... Rules > struct analyze_traits< Name, internal::control< Control, Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::disable< Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name > struct analyze_traits< Name, internal::discard > : analyze_opt_traits<> {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::enable< Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name > struct analyze_traits< Name, internal::eof > : analyze_opt_traits<> {}; template< typename Name > struct analyze_traits< Name, internal::eol > : analyze_any_traits<> {}; template< typename Name > struct analyze_traits< Name, internal::eolf > : analyze_opt_traits<> {}; template< typename Name > struct analyze_traits< Name, internal::failure > : analyze_any_traits<> {}; template< typename Name, typename Rule, typename... Actions > struct analyze_traits< Name, internal::if_apply< Rule, Actions... > > : analyze_traits< Name, typename Rule::rule_t > {}; template< typename Name, typename Cond, typename Then, typename Else > struct analyze_traits< Name, internal::if_then_else< Cond, Then, Else > > : analyze_traits< Name, typename sor< seq< Cond, Then >, Else >::rule_t > {}; template< typename Name, char... Cs > struct analyze_traits< Name, internal::istring< Cs... > > : std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::not_at< Rules... > > : analyze_traits< Name, typename opt< Rules... >::rule_t > {}; template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t... Cs > struct analyze_traits< Name, internal::one< R, Peek, Cs... > > : analyze_any_traits<> {}; template< typename Name, typename Rule, typename... Rules > struct analyze_traits< Name, internal::opt< Rule, Rules... > > : analyze_opt_traits< Rule, Rules... > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::plus< Rules... > > : analyze_traits< Name, typename seq< Rules..., opt< Name > >::rule_t > {}; template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > struct analyze_traits< Name, internal::range< R, Peek, Lo, Hi > > : analyze_any_traits<> {}; template< typename Name, typename Peek, typename Peek::data_t... Cs > struct analyze_traits< Name, internal::ranges< Peek, Cs... > > : analyze_any_traits<> {}; template< typename Name, typename Head, typename... Rules > struct analyze_traits< Name, internal::rematch< Head, Rules... > > : analyze_traits< Name, typename sor< Head, sor< seq< Rules, any >... > >::rule_t > // TODO: Correct (enough)? {}; template< typename Name, unsigned Cnt, typename... Rules > struct analyze_traits< Name, internal::rep< Cnt, Rules... > > : analyze_traits< Name, std::conditional_t< ( Cnt != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > > {}; template< typename Name, unsigned Min, unsigned Max, typename... Rules > struct analyze_traits< Name, internal::rep_min_max< Min, Max, Rules... > > : analyze_traits< Name, std::conditional_t< ( Min != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > > {}; template< typename Name, unsigned Max, typename... Rules > struct analyze_traits< Name, internal::rep_opt< Max, Rules... > > : analyze_traits< Name, typename opt< Rules... >::rule_t > {}; template< typename Name, unsigned Amount > struct analyze_traits< Name, internal::require< Amount > > : analyze_opt_traits<> {}; template< typename Name, typename Rule, typename... Rules > struct analyze_traits< Name, internal::seq< Rule, Rules... > > : analyze_seq_traits< Rule, Rules... > {}; template< typename Name, typename Rule, typename... Rules > struct analyze_traits< Name, internal::sor< Rule, Rules... > > : analyze_sor_traits< Rule, Rules... > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::star< Rules... > > : analyze_traits< Name, typename opt< Rules..., Name >::rule_t > {}; template< typename Name, typename State, typename... Rules > struct analyze_traits< Name, internal::state< State, Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name, char... Cs > struct analyze_traits< Name, internal::string< Cs... > > : std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> > {}; template< typename Name > struct analyze_traits< Name, internal::success > : analyze_opt_traits<> {}; template< typename Name, typename Cond > struct analyze_traits< Name, internal::until< Cond > > : analyze_traits< Name, typename Cond::rule_t > {}; template< typename Name, typename Cond, typename... Rules > struct analyze_traits< Name, internal::until< Cond, Rules... > > : analyze_traits< Name, typename seq< star< Rules... >, Cond >::rule_t > {}; #if defined( __cpp_exceptions ) template< typename Name, typename Cond, typename... Rules > struct analyze_traits< Name, internal::if_must< true, Cond, Rules... > > : analyze_traits< Name, typename opt< Cond, Rules... >::rule_t > {}; template< typename Name, typename Cond, typename... Rules > struct analyze_traits< Name, internal::if_must< false, Cond, Rules... > > : analyze_traits< Name, typename seq< Cond, Rules... >::rule_t > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::must< Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; template< typename Name, typename T > struct analyze_traits< Name, internal::raise< T > > : analyze_any_traits<> {}; template< typename Name, typename Exception, typename... Rules > struct analyze_traits< Name, internal::try_catch_type< Exception, Rules... > > : analyze_traits< Name, typename seq< Rules... >::rule_t > {}; #endif } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/check_bytes.hpp000066400000000000000000000030441426407250600234030ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_CHECK_BYTES_HPP #define TAO_PEGTL_CONTRIB_CHECK_BYTES_HPP #include "../apply_mode.hpp" #include "../config.hpp" #include "../match.hpp" #include "../nothing.hpp" #include "../rewind_mode.hpp" #if defined( __cpp_exceptions ) #include "../parse_error.hpp" #else #include #include #endif namespace TAO_PEGTL_NAMESPACE { template< std::size_t Maximum > struct check_bytes : maybe_nothing { template< typename Rule, pegtl::apply_mode A, pegtl::rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... st ) { const auto* start = in.current(); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) { if( std::size_t( in.current() - start ) > Maximum ) { #if defined( __cpp_exceptions ) throw TAO_PEGTL_NAMESPACE::parse_error( "maximum allowed rule consumption exceeded", in ); #else std::fputs( "maximum allowed rule consumption exceeded\n", stderr ); std::terminate(); #endif } return true; } return false; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/control_action.hpp000066400000000000000000000063741426407250600241460ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_CONTROL_ACTION_HPP #define TAO_PEGTL_CONTRIB_CONTROL_ACTION_HPP #include #include "../config.hpp" #include "../match.hpp" #include "../nothing.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename, typename Rule, template< typename... > class Action, typename ParseInput, typename... States > inline constexpr bool action_has_unwind = false; template< typename Rule, template< typename... > class Action, typename ParseInput, typename... States > inline constexpr bool action_has_unwind< decltype( (void)Action< Rule >::unwind( std::declval< const ParseInput& >(), std::declval< States&& >()... ) ), Rule, Action, ParseInput, States... > = true; } // namespace internal struct control_action : maybe_nothing { template< typename Rule, 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 ) { #if defined( __cpp_exceptions ) if constexpr( internal::action_has_unwind< void, Rule, Action, ParseInput, States... > ) { try { return control_action::match_impl< Rule, A, M, Action, Control >( in, st... ); } catch( ... ) { Action< Rule >::unwind( const_cast< const ParseInput& >( in ), st... ); throw; } } else { return control_action::match_impl< Rule, A, M, Action, Control >( in, st... ); } #else return control_action::match_impl< Rule, A, M, Action, Control >( in, st... ); #endif } template< typename ParseInput, typename... States > static void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename ParseInput, typename... States > static void success( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename ParseInput, typename... States > static void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} private: template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match_impl( ParseInput& in, States&&... st ) { Action< Rule >::start( const_cast< const ParseInput& >( in ), st... ); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) { Action< Rule >::success( const_cast< const ParseInput& >( in ), st... ); return true; } Action< Rule >::failure( const_cast< const ParseInput& >( in ), st... ); return false; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/coverage.hpp000066400000000000000000000114511426407250600227140ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_COVERAGE_HPP #define TAO_PEGTL_CONTRIB_COVERAGE_HPP #include #include #include #include #include "state_control.hpp" #include "../apply_mode.hpp" #include "../config.hpp" #include "../demangle.hpp" #include "../normal.hpp" #include "../nothing.hpp" #include "../parse.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" #include "../visit.hpp" namespace TAO_PEGTL_NAMESPACE { struct coverage_info { std::size_t start = 0; std::size_t success = 0; std::size_t failure = 0; std::size_t unwind = 0; std::size_t raise = 0; }; struct coverage_entry : coverage_info { std::map< std::string_view, coverage_info > branches; }; using coverage_result = std::map< std::string_view, coverage_entry >; namespace internal { template< typename Rule > struct coverage_insert { static void visit( std::map< std::string_view, coverage_entry >& map ) { visit_branches( map.try_emplace( demangle< Rule >() ).first->second.branches, typename Rule::subs_t() ); } template< typename... Ts > static void visit_branches( std::map< std::string_view, coverage_info >& branches, type_list< Ts... > /*unused*/ ) { ( branches.try_emplace( demangle< Ts >() ), ... ); } }; struct coverage_state { template< typename Rule > static constexpr bool enable = true; explicit coverage_state( coverage_result& in_result ) : result( in_result ) {} coverage_result& result; std::vector< std::string_view > stack; template< typename Rule, typename ParseInput, typename... States > void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) { const auto name = demangle< Rule >(); ++result.at( name ).start; if( !stack.empty() ) { ++result.at( stack.back() ).branches.at( name ).start; } stack.push_back( name ); } template< typename Rule, typename ParseInput, typename... States > void success( const ParseInput& /*unused*/, States&&... /*unused*/ ) { stack.pop_back(); const auto name = demangle< Rule >(); ++result.at( name ).success; if( !stack.empty() ) { ++result.at( stack.back() ).branches.at( name ).success; } } template< typename Rule, typename ParseInput, typename... States > void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) { stack.pop_back(); const auto name = demangle< Rule >(); ++result.at( name ).failure; if( !stack.empty() ) { ++result.at( stack.back() ).branches.at( name ).failure; } } template< typename Rule, typename ParseInput, typename... States > void raise( const ParseInput& /*unused*/, States&&... /*unused*/ ) { const auto name = demangle< Rule >(); ++result.at( name ).raise; if( !stack.empty() ) { ++result.at( stack.back() ).branches.at( name ).raise; } } template< typename Rule, typename ParseInput, typename... States > void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ ) { stack.pop_back(); const auto name = demangle< Rule >(); ++result.at( name ).unwind; if( !stack.empty() ) { ++result.at( stack.back() ).branches.at( name ).unwind; } } template< typename Rule, typename ParseInput, typename... States > void apply( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename Rule, typename ParseInput, typename... States > void apply0( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} }; } // namespace internal template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > bool coverage( ParseInput&& in, coverage_result& result, States&&... st ) { internal::coverage_state state( result ); visit< Rule, internal::coverage_insert >( state.result ); // Fill map with all sub-rules of the grammar. return parse< Rule, Action, state_control< Control >::template type >( in, st..., state ); } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/forward.hpp000066400000000000000000000006241426407250600225650ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_FORWARD_HPP #define TAO_PEGTL_CONTRIB_FORWARD_HPP #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Name, typename Rule, typename = void > struct analyze_traits; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/function.hpp000066400000000000000000000025771426407250600227570ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_FUNCTION_HPP #define TAO_PEGTL_CONTRIB_FUNCTION_HPP #include "../config.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" #include "../internal/enable_control.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename F, F U > struct function; template< typename ParseInput, typename... States, bool ( *U )( ParseInput&, States... ) > struct function< bool ( * )( ParseInput&, States... ), U > { using rule_t = function; using subs_t = empty_list; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control > [[nodiscard]] static bool match( ParseInput& in, States... st ) noexcept( noexcept( U( in, st... ) ) ) { return U( in, st... ); } }; template< typename F, F U > inline constexpr bool enable_control< function< F, U > > = false; } // namespace internal template< auto F > struct function : internal::function< decltype( F ), F > {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/http.hpp000066400000000000000000000236611426407250600221060ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_HTTP_HPP #define TAO_PEGTL_CONTRIB_HTTP_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/contrib/http.hpp" #else #include "../ascii.hpp" #include "../config.hpp" #include "../nothing.hpp" #include "../rules.hpp" #include "../utf8.hpp" #include "abnf.hpp" #include "forward.hpp" #include "remove_first_state.hpp" #include "uri.hpp" namespace TAO_PEGTL_NAMESPACE::http { // HTTP 1.1 grammar according to RFC 7230. // This grammar is a direct PEG translation of the original HTTP grammar. // It should be considered experimental -- in case of any issues, in particular // missing rules for attached actions, please contact the developers. using OWS = star< abnf::WSP >; // optional whitespace using RWS = plus< abnf::WSP >; // required whitespace using BWS = OWS; // "bad" whitespace using obs_text = not_range< 0x00, 0x7F >; using obs_fold = seq< abnf::CRLF, plus< abnf::WSP > >; // clang-format off struct tchar : sor< abnf::ALPHA, abnf::DIGIT, one< '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~' > > {}; struct token : plus< tchar > {}; struct field_name : token {}; struct field_vchar : sor< abnf::VCHAR, obs_text > {}; struct field_content : list< field_vchar, plus< abnf::WSP > > {}; struct field_value : star< sor< field_content, obs_fold > > {}; struct header_field : seq< field_name, one< ':' >, OWS, field_value, OWS > {}; struct method : token {}; struct absolute_path : plus< one< '/' >, uri::segment > {}; struct origin_form : seq< absolute_path, uri::opt_query > {}; struct absolute_form : uri::absolute_URI {}; struct authority_form : uri::authority {}; struct asterisk_form : one< '*' > {}; struct request_target : sor< origin_form, absolute_form, authority_form, asterisk_form > {}; struct status_code : rep< 3, abnf::DIGIT > {}; struct reason_phrase : star< sor< abnf::VCHAR, obs_text, abnf::WSP > > {}; struct HTTP_version : if_must< string< 'H', 'T', 'T', 'P', '/' >, abnf::DIGIT, one< '.' >, abnf::DIGIT > {}; struct request_line : if_must< method, abnf::SP, request_target, abnf::SP, HTTP_version, abnf::CRLF > {}; struct status_line : if_must< HTTP_version, abnf::SP, status_code, abnf::SP, reason_phrase, abnf::CRLF > {}; struct start_line : sor< status_line, request_line > {}; struct message_body : star< abnf::OCTET > {}; struct HTTP_message : seq< start_line, star< header_field, abnf::CRLF >, abnf::CRLF, opt< message_body > > {}; struct Content_Length : plus< abnf::DIGIT > {}; struct uri_host : uri::host {}; struct port : uri::port {}; struct Host : seq< uri_host, opt< one< ':' >, port > > {}; // PEG are different from CFGs! (this replaces ctext and qdtext) using text = sor< abnf::HTAB, range< 0x20, 0x7E >, obs_text >; struct quoted_pair : if_must< one< '\\' >, sor< abnf::VCHAR, obs_text, abnf::WSP > > {}; struct quoted_string : if_must< abnf::DQUOTE, until< abnf::DQUOTE, sor< quoted_pair, text > > > {}; struct transfer_parameter : seq< token, BWS, one< '=' >, BWS, sor< token, quoted_string > > {}; struct transfer_extension : seq< token, star< OWS, one< ';' >, OWS, transfer_parameter > > {}; struct transfer_coding : sor< istring< 'c', 'h', 'u', 'n', 'k', 'e', 'd' >, istring< 'c', 'o', 'm', 'p', 'r', 'e', 's', 's' >, istring< 'd', 'e', 'f', 'l', 'a', 't', 'e' >, istring< 'g', 'z', 'i', 'p' >, transfer_extension > {}; struct rank : sor< seq< one< '0' >, opt< one< '.' >, rep_opt< 3, abnf::DIGIT > > >, seq< one< '1' >, opt< one< '.' >, rep_opt< 3, one< '0' > > > > > {}; struct t_ranking : seq< OWS, one< ';' >, OWS, one< 'q', 'Q' >, one< '=' >, rank > {}; struct t_codings : sor< istring< 't', 'r', 'a', 'i', 'l', 'e', 'r', 's' >, seq< transfer_coding, opt< t_ranking > > > {}; struct TE : opt< sor< one< ',' >, t_codings >, star< OWS, one< ',' >, opt< OWS, t_codings > > > {}; template< typename T > using make_comma_list = seq< star< one< ',' >, OWS >, T, star< OWS, one< ',' >, opt< OWS, T > > >; struct connection_option : token {}; struct Connection : make_comma_list< connection_option > {}; struct Trailer : make_comma_list< field_name > {}; struct Transfer_Encoding : make_comma_list< transfer_coding > {}; struct protocol_name : token {}; struct protocol_version : token {}; struct protocol : seq< protocol_name, opt< one< '/' >, protocol_version > > {}; struct Upgrade : make_comma_list< protocol > {}; struct pseudonym : token {}; struct received_protocol : seq< opt< protocol_name, one< '/' > >, protocol_version > {}; struct received_by : sor< seq< uri_host, opt< one< ':' >, port > >, pseudonym > {}; struct comment : if_must< one< '(' >, until< one< ')' >, sor< comment, quoted_pair, text > > > {}; struct Via : make_comma_list< seq< received_protocol, RWS, received_by, opt< RWS, comment > > > {}; struct http_URI : if_must< istring< 'h', 't', 't', 'p', ':', '/', '/' >, uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {}; struct https_URI : if_must< istring< 'h', 't', 't', 'p', 's', ':', '/', '/' >, uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {}; struct partial_URI : seq< uri::relative_part, uri::opt_query > {}; // clang-format on struct chunk_size { using rule_t = plus< abnf::HEXDIG >::rule_t; 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, std::size_t& size, States&&... /*unused*/ ) { size = 0; std::size_t i = 0; while( in.size( i + 1 ) >= i + 1 ) { const auto c = in.peek_char( i ); if( ( '0' <= c ) && ( c <= '9' ) ) { size <<= 4; size |= std::size_t( c - '0' ); ++i; continue; } if( ( 'a' <= c ) && ( c <= 'f' ) ) { size <<= 4; size |= std::size_t( c - 'a' + 10 ); ++i; continue; } if( ( 'A' <= c ) && ( c <= 'F' ) ) { size <<= 4; size |= std::size_t( c - 'A' + 10 ); ++i; continue; } break; } in.bump_in_this_line( i ); return i > 0; } }; // clang-format off struct chunk_ext_name : token {}; struct chunk_ext_val : sor< quoted_string, token > {}; struct chunk_ext : star_must< one< ';' >, chunk_ext_name, if_must< one< '=' >, chunk_ext_val > > {}; // clang-format on struct chunk_data { using rule_t = star< abnf::OCTET >::rule_t; 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, const std::size_t size, States&&... /*unused*/ ) { if( in.size( size ) >= size ) { in.bump( size ); return true; } return false; } }; namespace internal::chunk_helper { template< typename Base > struct control; template< template< typename... > class Control, typename Rule > struct control< Control< Rule > > : Control< Rule > { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class, typename ParseInput, typename State, typename... States > [[nodiscard]] static bool match( ParseInput& in, State&& /*unused*/, States&&... st ) { return Control< Rule >::template match< A, M, Action, Control >( in, st... ); } }; template< template< typename... > class Control > struct control< Control< chunk_size > > : remove_first_state< Control< chunk_size > > {}; template< template< typename... > class Control > struct control< Control< chunk_data > > : remove_first_state< Control< chunk_data > > {}; template< template< typename... > class Control > struct bind { template< typename Rule > using type = control< Control< Rule > >; }; } // namespace internal::chunk_helper struct chunk { using impl = seq< chunk_size, chunk_ext, abnf::CRLF, chunk_data, abnf::CRLF >; using rule_t = impl::rule_t; 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 ) { std::size_t size{}; return impl::template match< A, M, Action, internal::chunk_helper::bind< Control >::template type >( in, size, st... ); } }; // clang-format off struct last_chunk : seq< plus< one< '0' > >, not_at< digit >, chunk_ext, abnf::CRLF > {}; struct trailer_part : star< header_field, abnf::CRLF > {}; struct chunked_body : seq< until< last_chunk, chunk >, trailer_part, abnf::CRLF > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::http #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/icu/000077500000000000000000000000001426407250600211665ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl/contrib/icu/internal.hpp000066400000000000000000000055531426407250600235230ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP #define TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP #include #include "../analyze_traits.hpp" #include "../../config.hpp" #include "../../type_list.hpp" #include "../../internal/enable_control.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { namespace icu { template< typename Peek, UProperty P, bool V = true > struct binary_property { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = binary_property; using subs_t = empty_list; [[nodiscard]] static bool test( const data_t c ) noexcept { return u_hasBinaryProperty( c, P ) == V; } template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { in.bump( t.size ); return true; } } return false; } }; template< typename Peek, UProperty P, int V > struct property_value { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = property_value; using subs_t = empty_list; [[nodiscard]] static bool test( const data_t c ) noexcept { return u_getIntPropertyValue( c, P ) == V; } template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { in.bump( t.size ); return true; } } return false; } }; } // namespace icu template< typename Peek, UProperty P, bool V > inline constexpr bool enable_control< icu::binary_property< Peek, P, V > > = false; template< typename Peek, UProperty P, int V > inline constexpr bool enable_control< icu::property_value< Peek, P, V > > = false; } // namespace internal template< typename Name, typename Peek, UProperty P, bool V > struct analyze_traits< Name, internal::icu::binary_property< Peek, P, V > > : analyze_any_traits<> {}; template< typename Name, typename Peek, UProperty P, int V > struct analyze_traits< Name, internal::icu::property_value< Peek, P, V > > : analyze_any_traits<> {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/icu/utf16.hpp000066400000000000000000000311771426407250600226550ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ICU_UTF16_HPP #define TAO_PEGTL_CONTRIB_ICU_UTF16_HPP #include "internal.hpp" #include "../../config.hpp" #include "../utf16.hpp" #include "../internal/peek_utf16.hpp" namespace TAO_PEGTL_NAMESPACE { namespace utf16_be::icu { template< UProperty P, bool V = true > struct binary_property : internal::icu::binary_property< internal::peek_utf16_be, P, V > {}; template< UProperty P, int V > struct property_value : internal::icu::property_value< internal::peek_utf16_be, P, V > {}; // clang-format off struct alphabetic : binary_property< UCHAR_ALPHABETIC > {}; struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {}; struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {}; struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {}; struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {}; struct dash : binary_property< UCHAR_DASH > {}; struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {}; struct deprecated : binary_property< UCHAR_DEPRECATED > {}; struct diacritic : binary_property< UCHAR_DIACRITIC > {}; struct extender : binary_property< UCHAR_EXTENDER > {}; struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {}; struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {}; struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {}; struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {}; struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {}; struct hyphen : binary_property< UCHAR_HYPHEN > {}; struct id_continue : binary_property< UCHAR_ID_CONTINUE > {}; struct id_start : binary_property< UCHAR_ID_START > {}; struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {}; struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {}; struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {}; struct join_control : binary_property< UCHAR_JOIN_CONTROL > {}; struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {}; struct lowercase : binary_property< UCHAR_LOWERCASE > {}; struct math : binary_property< UCHAR_MATH > {}; struct nfc_inert : binary_property< UCHAR_NFC_INERT > {}; struct nfd_inert : binary_property< UCHAR_NFD_INERT > {}; struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {}; struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {}; struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {}; struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {}; struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {}; struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {}; struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {}; struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {}; struct posix_print : binary_property< UCHAR_POSIX_PRINT > {}; struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {}; struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {}; struct radical : binary_property< UCHAR_RADICAL > {}; struct s_term : binary_property< UCHAR_S_TERM > {}; struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {}; struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {}; struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {}; struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {}; struct uppercase : binary_property< UCHAR_UPPERCASE > {}; struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {}; struct white_space : binary_property< UCHAR_WHITE_SPACE > {}; struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {}; struct xid_start : binary_property< UCHAR_XID_START > {}; template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {}; template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {}; template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {}; template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {}; template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {}; template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {}; template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {}; template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {}; template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {}; template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {}; // UNormalizationCheckResult requires an additional header : // template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {}; template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {}; template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {}; template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {}; template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {}; // clang-format on } // namespace utf16_be::icu namespace utf16_le::icu { template< UProperty P, bool V = true > struct binary_property : internal::icu::binary_property< internal::peek_utf16_le, P, V > {}; template< UProperty P, int V > struct property_value : internal::icu::property_value< internal::peek_utf16_le, P, V > {}; // clang-format off struct alphabetic : binary_property< UCHAR_ALPHABETIC > {}; struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {}; struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {}; struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {}; struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {}; struct dash : binary_property< UCHAR_DASH > {}; struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {}; struct deprecated : binary_property< UCHAR_DEPRECATED > {}; struct diacritic : binary_property< UCHAR_DIACRITIC > {}; struct extender : binary_property< UCHAR_EXTENDER > {}; struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {}; struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {}; struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {}; struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {}; struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {}; struct hyphen : binary_property< UCHAR_HYPHEN > {}; struct id_continue : binary_property< UCHAR_ID_CONTINUE > {}; struct id_start : binary_property< UCHAR_ID_START > {}; struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {}; struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {}; struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {}; struct join_control : binary_property< UCHAR_JOIN_CONTROL > {}; struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {}; struct lowercase : binary_property< UCHAR_LOWERCASE > {}; struct math : binary_property< UCHAR_MATH > {}; struct nfc_inert : binary_property< UCHAR_NFC_INERT > {}; struct nfd_inert : binary_property< UCHAR_NFD_INERT > {}; struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {}; struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {}; struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {}; struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {}; struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {}; struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {}; struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {}; struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {}; struct posix_print : binary_property< UCHAR_POSIX_PRINT > {}; struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {}; struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {}; struct radical : binary_property< UCHAR_RADICAL > {}; struct s_term : binary_property< UCHAR_S_TERM > {}; struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {}; struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {}; struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {}; struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {}; struct uppercase : binary_property< UCHAR_UPPERCASE > {}; struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {}; struct white_space : binary_property< UCHAR_WHITE_SPACE > {}; struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {}; struct xid_start : binary_property< UCHAR_XID_START > {}; template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {}; template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {}; template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {}; template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {}; template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {}; template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {}; template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {}; template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {}; template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {}; template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {}; // UNormalizationCheckResult requires an additional header : // template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {}; template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {}; template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {}; template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {}; template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {}; // clang-format on } // namespace utf16_le::icu } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/icu/utf32.hpp000066400000000000000000000311771426407250600226530ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ICU_UTF32_HPP #define TAO_PEGTL_CONTRIB_ICU_UTF32_HPP #include "internal.hpp" #include "../../config.hpp" #include "../utf32.hpp" #include "../internal/peek_utf32.hpp" namespace TAO_PEGTL_NAMESPACE { namespace utf32_be::icu { template< UProperty P, bool V = true > struct binary_property : internal::icu::binary_property< internal::peek_utf32_be, P, V > {}; template< UProperty P, int V > struct property_value : internal::icu::property_value< internal::peek_utf32_be, P, V > {}; // clang-format off struct alphabetic : binary_property< UCHAR_ALPHABETIC > {}; struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {}; struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {}; struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {}; struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {}; struct dash : binary_property< UCHAR_DASH > {}; struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {}; struct deprecated : binary_property< UCHAR_DEPRECATED > {}; struct diacritic : binary_property< UCHAR_DIACRITIC > {}; struct extender : binary_property< UCHAR_EXTENDER > {}; struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {}; struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {}; struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {}; struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {}; struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {}; struct hyphen : binary_property< UCHAR_HYPHEN > {}; struct id_continue : binary_property< UCHAR_ID_CONTINUE > {}; struct id_start : binary_property< UCHAR_ID_START > {}; struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {}; struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {}; struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {}; struct join_control : binary_property< UCHAR_JOIN_CONTROL > {}; struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {}; struct lowercase : binary_property< UCHAR_LOWERCASE > {}; struct math : binary_property< UCHAR_MATH > {}; struct nfc_inert : binary_property< UCHAR_NFC_INERT > {}; struct nfd_inert : binary_property< UCHAR_NFD_INERT > {}; struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {}; struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {}; struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {}; struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {}; struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {}; struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {}; struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {}; struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {}; struct posix_print : binary_property< UCHAR_POSIX_PRINT > {}; struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {}; struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {}; struct radical : binary_property< UCHAR_RADICAL > {}; struct s_term : binary_property< UCHAR_S_TERM > {}; struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {}; struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {}; struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {}; struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {}; struct uppercase : binary_property< UCHAR_UPPERCASE > {}; struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {}; struct white_space : binary_property< UCHAR_WHITE_SPACE > {}; struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {}; struct xid_start : binary_property< UCHAR_XID_START > {}; template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {}; template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {}; template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {}; template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {}; template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {}; template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {}; template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {}; template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {}; template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {}; template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {}; // UNormalizationCheckResult requires an additional header : // template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {}; template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {}; template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {}; template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {}; template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {}; // clang-format on } // namespace utf32_be::icu namespace utf32_le::icu { template< UProperty P, bool V = true > struct binary_property : internal::icu::binary_property< internal::peek_utf32_le, P, V > {}; template< UProperty P, int V > struct property_value : internal::icu::property_value< internal::peek_utf32_le, P, V > {}; // clang-format off struct alphabetic : binary_property< UCHAR_ALPHABETIC > {}; struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {}; struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {}; struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {}; struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {}; struct dash : binary_property< UCHAR_DASH > {}; struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {}; struct deprecated : binary_property< UCHAR_DEPRECATED > {}; struct diacritic : binary_property< UCHAR_DIACRITIC > {}; struct extender : binary_property< UCHAR_EXTENDER > {}; struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {}; struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {}; struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {}; struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {}; struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {}; struct hyphen : binary_property< UCHAR_HYPHEN > {}; struct id_continue : binary_property< UCHAR_ID_CONTINUE > {}; struct id_start : binary_property< UCHAR_ID_START > {}; struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {}; struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {}; struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {}; struct join_control : binary_property< UCHAR_JOIN_CONTROL > {}; struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {}; struct lowercase : binary_property< UCHAR_LOWERCASE > {}; struct math : binary_property< UCHAR_MATH > {}; struct nfc_inert : binary_property< UCHAR_NFC_INERT > {}; struct nfd_inert : binary_property< UCHAR_NFD_INERT > {}; struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {}; struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {}; struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {}; struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {}; struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {}; struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {}; struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {}; struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {}; struct posix_print : binary_property< UCHAR_POSIX_PRINT > {}; struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {}; struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {}; struct radical : binary_property< UCHAR_RADICAL > {}; struct s_term : binary_property< UCHAR_S_TERM > {}; struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {}; struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {}; struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {}; struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {}; struct uppercase : binary_property< UCHAR_UPPERCASE > {}; struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {}; struct white_space : binary_property< UCHAR_WHITE_SPACE > {}; struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {}; struct xid_start : binary_property< UCHAR_XID_START > {}; template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {}; template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {}; template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {}; template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {}; template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {}; template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {}; template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {}; template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {}; template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {}; template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {}; // UNormalizationCheckResult requires an additional header : // template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {}; template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {}; template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {}; template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {}; template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {}; // clang-format on } // namespace utf32_le::icu } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/icu/utf8.hpp000066400000000000000000000143531426407250600225730ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_ICU_UTF8_HPP #define TAO_PEGTL_CONTRIB_ICU_UTF8_HPP #include "internal.hpp" #include "../../config.hpp" #include "../../utf8.hpp" #include "../../internal/peek_utf8.hpp" namespace TAO_PEGTL_NAMESPACE::utf8::icu { template< UProperty P, bool V = true > struct binary_property : internal::icu::binary_property< internal::peek_utf8, P, V > {}; template< UProperty P, int V > struct property_value : internal::icu::property_value< internal::peek_utf8, P, V > {}; // clang-format off struct alphabetic : binary_property< UCHAR_ALPHABETIC > {}; struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {}; struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {}; struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {}; struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {}; struct dash : binary_property< UCHAR_DASH > {}; struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {}; struct deprecated : binary_property< UCHAR_DEPRECATED > {}; struct diacritic : binary_property< UCHAR_DIACRITIC > {}; struct extender : binary_property< UCHAR_EXTENDER > {}; struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {}; struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {}; struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {}; struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {}; struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {}; struct hyphen : binary_property< UCHAR_HYPHEN > {}; struct id_continue : binary_property< UCHAR_ID_CONTINUE > {}; struct id_start : binary_property< UCHAR_ID_START > {}; struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {}; struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {}; struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {}; struct join_control : binary_property< UCHAR_JOIN_CONTROL > {}; struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {}; struct lowercase : binary_property< UCHAR_LOWERCASE > {}; struct math : binary_property< UCHAR_MATH > {}; struct nfc_inert : binary_property< UCHAR_NFC_INERT > {}; struct nfd_inert : binary_property< UCHAR_NFD_INERT > {}; struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {}; struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {}; struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {}; struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {}; struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {}; struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {}; struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {}; struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {}; struct posix_print : binary_property< UCHAR_POSIX_PRINT > {}; struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {}; struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {}; struct radical : binary_property< UCHAR_RADICAL > {}; struct s_term : binary_property< UCHAR_S_TERM > {}; struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {}; struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {}; struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {}; struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {}; struct uppercase : binary_property< UCHAR_UPPERCASE > {}; struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {}; struct white_space : binary_property< UCHAR_WHITE_SPACE > {}; struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {}; struct xid_start : binary_property< UCHAR_XID_START > {}; template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {}; template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {}; template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {}; template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {}; template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {}; template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {}; template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {}; template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {}; template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {}; template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {}; // UNormalizationCheckResult requires an additional header : // template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {}; // template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {}; template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {}; template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {}; template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {}; template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {}; template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::utf8::icu #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/if_then.hpp000066400000000000000000000030521426407250600225330ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_IF_THEN_HPP #define TAO_PEGTL_CONTRIB_IF_THEN_HPP #include #include "../config.hpp" #include "../internal/enable_control.hpp" #include "../internal/failure.hpp" #include "../internal/if_then_else.hpp" #include "../internal/seq.hpp" #include "../internal/success.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Cond, typename Then > struct if_pair {}; template< typename... Pairs > struct if_then; template< typename Cond, typename Then, typename... Pairs > struct if_then< if_pair< Cond, Then >, Pairs... > : if_then_else< Cond, Then, if_then< Pairs... > > { template< typename ElseCond, typename... Thens > using else_if_then = if_then< if_pair< Cond, Then >, Pairs..., if_pair< ElseCond, seq< Thens... > > >; template< typename... Thens > using else_then = if_then_else< Cond, Then, if_then< Pairs..., if_pair< success, seq< Thens... > > > >; }; template<> struct if_then<> : failure {}; template< typename... Pairs > inline constexpr bool enable_control< if_then< Pairs... > > = false; } // namespace internal template< typename Cond, typename... Thens > struct if_then : internal::if_then< internal::if_pair< Cond, internal::seq< Thens... > > > {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/instantiate.hpp000066400000000000000000000020541426407250600234430ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INSTANTIATE_HPP #define TAO_PEGTL_CONTRIB_INSTANTIATE_HPP #include "../config.hpp" #include "../apply_mode.hpp" #include "../match.hpp" #include "../nothing.hpp" #include "../rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename T > struct instantiate : maybe_nothing { template< typename Rule, 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 ) { const T t( static_cast< const ParseInput& >( in ), st... ); return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/integer.hpp000066400000000000000000000371141426407250600225620ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTEGER_HPP #define TAO_PEGTL_CONTRIB_INTEGER_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/contrib/integer.hpp" #else #include #include #include #include #include #include "../ascii.hpp" #include "../parse.hpp" #include "../parse_error.hpp" #include "../rules.hpp" #include "analyze_traits.hpp" namespace TAO_PEGTL_NAMESPACE { struct unsigned_rule_old : plus< digit > { // Pre-3.0 version of this rule. }; struct unsigned_rule_new : if_then_else< one< '0' >, not_at< digit >, plus< digit > > { // New version that does not allow leading zeros. }; struct signed_rule_old : seq< opt< one< '-', '+' > >, plus< digit > > { // Pre-3.0 version of this rule. }; struct signed_rule_new : seq< opt< one< '-', '+' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > > { // New version that does not allow leading zeros. }; struct signed_rule_bis : seq< opt< one< '-' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > > {}; struct signed_rule_ter : seq< one< '-', '+' >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > > {}; namespace internal { [[nodiscard]] constexpr bool is_digit( const char c ) noexcept { // We don't use std::isdigit() because it might // return true for other values on MS platforms. return ( '0' <= c ) && ( c <= '9' ); } template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() > [[nodiscard]] constexpr bool accumulate_digit( Integer& result, const char digit ) noexcept { // Assumes that digit is a digit as per is_digit(); returns false on overflow. static_assert( std::is_integral_v< Integer > ); constexpr Integer cutoff = Maximum / 10; constexpr Integer cutlim = Maximum % 10; const Integer c = digit - '0'; if( ( result > cutoff ) || ( ( result == cutoff ) && ( c > cutlim ) ) ) { return false; } result *= 10; result += c; return true; } template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() > [[nodiscard]] constexpr bool accumulate_digits( Integer& result, const std::string_view input ) noexcept { // Assumes input is a non-empty sequence of digits; returns false on overflow. for( char c : input ) { if( !accumulate_digit< Integer, Maximum >( result, c ) ) { return false; } } return true; } template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() > [[nodiscard]] constexpr bool convert_positive( Integer& result, const std::string_view input ) noexcept { // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow. static_assert( std::is_integral_v< Integer > ); return accumulate_digits< Integer, Maximum >( result, input ); } template< typename Signed > [[nodiscard]] constexpr bool convert_negative( Signed& result, const std::string_view input ) noexcept { // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow. static_assert( std::is_signed_v< Signed > ); using Unsigned = std::make_unsigned_t< Signed >; constexpr Unsigned maximum = static_cast< Unsigned >( ( std::numeric_limits< Signed >::max )() ) + 1; Unsigned temporary = 0; if( accumulate_digits< Unsigned, maximum >( temporary, input ) ) { result = static_cast< Signed >( ~temporary ) + 1; return true; } return false; } template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() > [[nodiscard]] constexpr bool convert_unsigned( Unsigned& result, const std::string_view input ) noexcept { // Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow. static_assert( std::is_unsigned_v< Unsigned > ); return accumulate_digits< Unsigned, Maximum >( result, input ); } template< typename Signed > [[nodiscard]] constexpr bool convert_signed( Signed& result, const std::string_view input ) noexcept { // Assumes result == 0 and that input is an optional sign followed by a non-empty sequence of digits; returns false on overflow. static_assert( std::is_signed_v< Signed > ); if( input[ 0 ] == '-' ) { return convert_negative< Signed >( result, std::string_view( input.data() + 1, input.size() - 1 ) ); } const auto offset = unsigned( input[ 0 ] == '+' ); return convert_positive< Signed >( result, std::string_view( input.data() + offset, input.size() - offset ) ); } template< typename ParseInput > [[nodiscard]] bool match_unsigned( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( !in.empty() ) { const char c = in.peek_char(); if( is_digit( c ) ) { in.bump_in_this_line(); if( c == '0' ) { return in.empty() || ( !is_digit( in.peek_char() ) ); } while( ( !in.empty() ) && is_digit( in.peek_char() ) ) { in.bump_in_this_line(); } return true; } } return false; } template< typename ParseInput, typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() > [[nodiscard]] bool match_and_convert_unsigned_with_maximum_throws( ParseInput& in, Unsigned& st ) { // Assumes st == 0. if( !in.empty() ) { char c = in.peek_char(); if( is_digit( c ) ) { if( c == '0' ) { in.bump_in_this_line(); return in.empty() || ( !is_digit( in.peek_char() ) ); } do { if( !accumulate_digit< Unsigned, Maximum >( st, c ) ) { throw TAO_PEGTL_NAMESPACE::parse_error( "integer overflow", in ); } in.bump_in_this_line(); } while( ( !in.empty() ) && is_digit( c = in.peek_char() ) ); return true; } } return false; } template< typename ParseInput, typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() > [[nodiscard]] bool match_and_convert_unsigned_with_maximum_nothrow( ParseInput& in, Unsigned& st ) { // Assumes st == 0. if( !in.empty() ) { char c = in.peek_char(); if( c == '0' ) { if( ( in.size( 2 ) < 2 ) || ( !is_digit( in.peek_char( 1 ) ) ) ) { in.bump_in_this_line(); return true; } return false; } if( is_digit( c ) ) { unsigned b = 0; do { if( !accumulate_digit< Unsigned, Maximum >( st, c ) ) { return false; } ++b; } while( ( !in.empty() ) && is_digit( c = in.peek_char( b ) ) ); in.bump_in_this_line( b ); return true; } } return false; } } // namespace internal struct unsigned_action { // Assumes that 'in' contains a non-empty sequence of ASCII digits. template< typename ActionInput, typename Unsigned > static void apply( const ActionInput& in, Unsigned& st ) { // This function "only" offers basic exception safety. st = 0; if( !internal::convert_unsigned( st, in.string_view() ) ) { throw parse_error( "unsigned integer overflow", in ); } } }; struct unsigned_rule { using rule_t = unsigned_rule; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { return internal::match_unsigned( in ); // Does not check for any overflow. } }; struct unsigned_rule_with_action { using rule_t = unsigned_rule_with_action; using subs_t = empty_list; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool > { return internal::match_unsigned( in ); // Does not check for any overflow. } template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Unsigned > [[nodiscard]] static auto match( ParseInput& in, Unsigned& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_unsigned_v< Unsigned >, bool > { // This function "only" offers basic exception safety. st = 0; return internal::match_and_convert_unsigned_with_maximum_throws( in, st ); // Throws on overflow. } }; template< typename Unsigned, Unsigned Maximum > struct maximum_action { // Assumes that 'in' contains a non-empty sequence of ASCII digits. static_assert( std::is_unsigned_v< Unsigned > ); template< typename ActionInput, typename Unsigned2 > static void apply( const ActionInput& in, Unsigned2& st ) { // This function "only" offers basic exception safety. st = 0; if( !internal::convert_unsigned< Unsigned, Maximum >( st, in.string_view() ) ) { throw parse_error( "unsigned integer overflow", in ); } } }; template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() > struct maximum_rule { using rule_t = maximum_rule; using subs_t = empty_list; static_assert( std::is_unsigned_v< Unsigned > ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) { Unsigned st = 0; return internal::match_and_convert_unsigned_with_maximum_nothrow< ParseInput, Unsigned, Maximum >( in, st ); } }; template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() > struct maximum_rule_with_action { using rule_t = maximum_rule_with_action; using subs_t = empty_list; static_assert( std::is_unsigned_v< Unsigned > ); template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) -> std::enable_if_t< A == apply_mode::nothing, bool > { Unsigned st = 0; return internal::match_and_convert_unsigned_with_maximum_throws< ParseInput, Unsigned, Maximum >( in, st ); } template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Unsigned2 > [[nodiscard]] static auto match( ParseInput& in, Unsigned2& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_same_v< Unsigned, Unsigned2 >, bool > { // This function "only" offers basic exception safety. st = 0; return internal::match_and_convert_unsigned_with_maximum_throws< ParseInput, Unsigned, Maximum >( in, st ); } }; struct signed_action { // Assumes that 'in' contains a non-empty sequence of ASCII digits, // with optional leading sign; with sign, in.size() must be >= 2. template< typename ActionInput, typename Signed > static void apply( const ActionInput& in, Signed& st ) { // This function "only" offers basic exception safety. st = 0; if( !internal::convert_signed( st, in.string_view() ) ) { throw parse_error( "signed integer overflow", in ); } } }; struct signed_rule { using rule_t = signed_rule; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { return TAO_PEGTL_NAMESPACE::parse< signed_rule_new >( in ); // Does not check for any overflow. } }; namespace internal { template< typename Rule > struct signed_action_action : nothing< Rule > {}; template<> struct signed_action_action< signed_rule_new > : signed_action {}; } // namespace internal struct signed_rule_with_action { using rule_t = signed_rule_with_action; using subs_t = empty_list; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool > { return TAO_PEGTL_NAMESPACE::parse< signed_rule_new >( in ); // Does not check for any overflow. } template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Signed > [[nodiscard]] static auto match( ParseInput& in, Signed& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_signed_v< Signed >, bool > { return TAO_PEGTL_NAMESPACE::parse< signed_rule_new, internal::signed_action_action >( in, st ); // Throws on overflow. } }; template< typename Name > struct analyze_traits< Name, unsigned_rule > : analyze_any_traits<> {}; template< typename Name > struct analyze_traits< Name, unsigned_rule_with_action > : analyze_any_traits<> {}; template< typename Name, typename Integer, Integer Maximum > struct analyze_traits< Name, maximum_rule< Integer, Maximum > > : analyze_any_traits<> {}; template< typename Name, typename Integer, Integer Maximum > struct analyze_traits< Name, maximum_rule_with_action< Integer, Maximum > > : analyze_any_traits<> {}; template< typename Name > struct analyze_traits< Name, signed_rule > : analyze_any_traits<> {}; template< typename Name > struct analyze_traits< Name, signed_rule_with_action > : analyze_any_traits<> {}; } // namespace TAO_PEGTL_NAMESPACE #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/000077500000000000000000000000001426407250600222225ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/endian.hpp000066400000000000000000000032471426407250600241770ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_HPP #include #include #include "../../config.hpp" #if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ ) #include "endian_win.hpp" #else #include "endian_gcc.hpp" #endif namespace TAO_PEGTL_NAMESPACE::internal { enum class endian { #if defined( _WIN32 ) little = 0, big = 1, native = little #elif defined( __BYTE_ORDER__ ) little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ #else #error Unknown endianness. #endif }; template< typename N > [[nodiscard]] N h_to_be( const N n ) noexcept { return N( to_and_from_be< sizeof( N ) >::convert( n ) ); } template< typename N > [[nodiscard]] N be_to_h( const N n ) noexcept { return h_to_be( n ); } template< typename N > [[nodiscard]] N be_to_h( const void* p ) noexcept { N n; std::memcpy( &n, p, sizeof( n ) ); return internal::be_to_h( n ); } template< typename N > [[nodiscard]] N h_to_le( const N n ) noexcept { return N( to_and_from_le< sizeof( N ) >::convert( n ) ); } template< typename N > [[nodiscard]] N le_to_h( const N n ) noexcept { return h_to_le( n ); } template< typename N > [[nodiscard]] N le_to_h( const void* p ) noexcept { N n; std::memcpy( &n, p, sizeof( n ) ); return internal::le_to_h( n ); } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/endian_gcc.hpp000066400000000000000000000114431426407250600250100ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_GCC_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_GCC_HPP #include #include namespace TAO_PEGTL_NAMESPACE::internal { #if !defined( __BYTE_ORDER__ ) #error No byte order defined! #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ template< std::size_t S > struct to_and_from_be { template< typename T > [[nodiscard]] static T convert( const T n ) noexcept { return n; } }; template< std::size_t S > struct to_and_from_le; template<> struct to_and_from_le< 1 > { [[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept { return n; } [[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept { return n; } }; template<> struct to_and_from_le< 2 > { [[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept { return static_cast< std::int16_t >( __builtin_bswap16( static_cast< std::uint16_t >( n ) ) ); } [[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept { return __builtin_bswap16( n ); } }; template<> struct to_and_from_le< 4 > { [[nodiscard]] static float convert( float n ) noexcept { std::uint32_t u; std::memcpy( &u, &n, 4 ); u = convert( u ); std::memcpy( &n, &u, 4 ); return n; } [[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept { return static_cast< std::int32_t >( __builtin_bswap32( static_cast< std::uint32_t >( n ) ) ); } [[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept { return __builtin_bswap32( n ); } }; template<> struct to_and_from_le< 8 > { [[nodiscard]] static double convert( double n ) noexcept { std::uint64_t u; std::memcpy( &u, &n, 8 ); u = convert( u ); std::memcpy( &n, &u, 8 ); return n; } [[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept { return static_cast< std::int64_t >( __builtin_bswap64( static_cast< std::uint64_t >( n ) ) ); } [[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept { return __builtin_bswap64( n ); } }; #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ template< std::size_t S > struct to_and_from_le { template< typename T > [[nodiscard]] static T convert( const T n ) noexcept { return n; } }; template< std::size_t S > struct to_and_from_be; template<> struct to_and_from_be< 1 > { [[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept { return n; } [[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept { return n; } }; template<> struct to_and_from_be< 2 > { [[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept { return static_cast< std::int16_t >( __builtin_bswap16( static_cast< std::uint16_t >( n ) ) ); } [[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept { return __builtin_bswap16( n ); } }; template<> struct to_and_from_be< 4 > { [[nodiscard]] static float convert( float n ) noexcept { std::uint32_t u; std::memcpy( &u, &n, 4 ); u = convert( u ); std::memcpy( &n, &u, 4 ); return n; } [[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept { return static_cast< std::int32_t >( __builtin_bswap32( static_cast< std::uint32_t >( n ) ) ); } [[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept { return __builtin_bswap32( n ); } }; template<> struct to_and_from_be< 8 > { [[nodiscard]] static double convert( double n ) noexcept { std::uint64_t u; std::memcpy( &u, &n, 8 ); u = convert( u ); std::memcpy( &n, &u, 8 ); return n; } [[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept { return static_cast< std::int64_t >( __builtin_bswap64( static_cast< std::uint64_t >( n ) ) ); } [[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept { return __builtin_bswap64( n ); } }; #else #error Unknown host byte order! #endif } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/endian_win.hpp000066400000000000000000000046301426407250600250510ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_WIN_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_WIN_HPP #include #include #include namespace TAO_PEGTL_NAMESPACE::internal { template< std::size_t S > struct to_and_from_le { template< typename T > [[nodiscard]] static T convert( const T t ) noexcept { return t; } }; template< std::size_t S > struct to_and_from_be; template<> struct to_and_from_be< 1 > { [[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept { return n; } [[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept { return n; } }; template<> struct to_and_from_be< 2 > { [[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept { return std::int16_t( _byteswap_ushort( std::uint16_t( n ) ) ); } [[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept { return _byteswap_ushort( n ); } }; template<> struct to_and_from_be< 4 > { [[nodiscard]] static float convert( float n ) noexcept { std::uint32_t u; std::memcpy( &u, &n, 4 ); u = convert( u ); std::memcpy( &n, &u, 4 ); return n; } [[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept { return std::int32_t( _byteswap_ulong( std::uint32_t( n ) ) ); } [[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept { return _byteswap_ulong( n ); } }; template<> struct to_and_from_be< 8 > { [[nodiscard]] static double convert( double n ) noexcept { std::uint64_t u; std::memcpy( &u, &n, 8 ); u = convert( u ); std::memcpy( &n, &u, 8 ); return n; } [[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept { return std::int64_t( _byteswap_uint64( std::uint64_t( n ) ) ); } [[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept { return _byteswap_uint64( n ); } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_mask_uint.hpp000066400000000000000000000031571426407250600257370ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT_HPP #include #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" #include "read_uint.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename R, typename R::type M > struct peek_mask_uint_impl { using data_t = typename R::type; using pair_t = input_pair< data_t >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) ) { if( in.size( sizeof( data_t ) ) < sizeof( data_t ) ) { return { 0, 0 }; } const data_t data = R::read( in.current() ) & M; return { data, sizeof( data_t ) }; } }; template< std::uint16_t M > using peek_mask_uint16_be = peek_mask_uint_impl< read_uint16_be, M >; template< std::uint16_t M > using peek_mask_uint16_le = peek_mask_uint_impl< read_uint16_le, M >; template< std::uint32_t M > using peek_mask_uint32_be = peek_mask_uint_impl< read_uint32_be, M >; template< std::uint32_t M > using peek_mask_uint32_le = peek_mask_uint_impl< read_uint32_le, M >; template< std::uint64_t M > using peek_mask_uint64_be = peek_mask_uint_impl< read_uint64_be, M >; template< std::uint64_t M > using peek_mask_uint64_le = peek_mask_uint_impl< read_uint64_le, M >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_mask_uint8.hpp000066400000000000000000000015601426407250600260230ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT8_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT8_HPP #include #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< std::uint8_t M > struct peek_mask_uint8 { using data_t = std::uint8_t; using pair_t = input_pair< std::uint8_t >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( in.empty() ) { return { 0, 0 }; } return { std::uint8_t( in.peek_uint8() & M ), 1 }; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_uint.hpp000066400000000000000000000024751426407250600247260ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT_HPP #include #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" #include "read_uint.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename R > struct peek_uint_impl { using data_t = typename R::type; using pair_t = input_pair< data_t >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) ) { if( in.size( sizeof( data_t ) ) < sizeof( data_t ) ) { return { 0, 0 }; } const data_t data = R::read( in.current() ); return { data, sizeof( data_t ) }; } }; using peek_uint16_be = peek_uint_impl< read_uint16_be >; using peek_uint16_le = peek_uint_impl< read_uint16_le >; using peek_uint32_be = peek_uint_impl< read_uint32_be >; using peek_uint32_le = peek_uint_impl< read_uint32_le >; using peek_uint64_be = peek_uint_impl< read_uint64_be >; using peek_uint64_le = peek_uint_impl< read_uint64_le >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_uint8.hpp000066400000000000000000000014571426407250600250150ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT8_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT8_HPP #include #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct peek_uint8 { using data_t = std::uint8_t; using pair_t = input_pair< std::uint8_t >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( in.empty() ) { return { 0, 0 }; } return { in.peek_uint8(), 1 }; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_utf16.hpp000066400000000000000000000030741426407250600247100ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF16_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF16_HPP #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" #include "read_uint.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename R > struct peek_utf16_impl { using data_t = char32_t; using pair_t = input_pair< char32_t >; using short_t = std::make_unsigned< char16_t >::type; static_assert( sizeof( short_t ) == 2 ); static_assert( sizeof( char16_t ) == 2 ); template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( 4 ) ) ) { if( in.size( 2 ) < 2 ) { return { 0, 0 }; } const char32_t t = R::read( in.current() ); if( ( t < 0xd800 ) || ( t > 0xdfff ) ) { return { t, 2 }; } if( ( t >= 0xdc00 ) || ( in.size( 4 ) < 4 ) ) { return { 0, 0 }; } const char32_t u = R::read( in.current() + 2 ); if( ( u >= 0xdc00 ) && ( u <= 0xdfff ) ) { const auto cp = ( ( ( t & 0x03ff ) << 10 ) | ( u & 0x03ff ) ) + 0x10000; return { cp, 4 }; } return { 0, 0 }; } }; using peek_utf16_be = peek_utf16_impl< read_uint16_be >; using peek_utf16_le = peek_utf16_impl< read_uint16_le >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/peek_utf32.hpp000066400000000000000000000022241426407250600247020ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF32_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF32_HPP #include #include "../../config.hpp" #include "../../internal/input_pair.hpp" #include "read_uint.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename R > struct peek_utf32_impl { using data_t = char32_t; using pair_t = input_pair< char32_t >; static_assert( sizeof( char32_t ) == 4 ); template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( 4 ) ) ) { if( in.size( 4 ) < 4 ) { return { 0, 0 }; } const char32_t t = R::read( in.current() ); if( ( t <= 0x10ffff ) && !( t >= 0xd800 && t <= 0xdfff ) ) { return { t, 4 }; } return { 0, 0 }; } }; using peek_utf32_be = peek_utf32_impl< read_uint32_be >; using peek_utf32_le = peek_utf32_impl< read_uint32_le >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/read_uint.hpp000066400000000000000000000031561426407250600247120ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_READ_UINT_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_READ_UINT_HPP #include #include "../../config.hpp" #include "endian.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct read_uint16_be { using type = std::uint16_t; [[nodiscard]] static std::uint16_t read( const void* d ) noexcept { return be_to_h< std::uint16_t >( d ); } }; struct read_uint16_le { using type = std::uint16_t; [[nodiscard]] static std::uint16_t read( const void* d ) noexcept { return le_to_h< std::uint16_t >( d ); } }; struct read_uint32_be { using type = std::uint32_t; [[nodiscard]] static std::uint32_t read( const void* d ) noexcept { return be_to_h< std::uint32_t >( d ); } }; struct read_uint32_le { using type = std::uint32_t; [[nodiscard]] static std::uint32_t read( const void* d ) noexcept { return le_to_h< std::uint32_t >( d ); } }; struct read_uint64_be { using type = std::uint64_t; [[nodiscard]] static std::uint64_t read( const void* d ) noexcept { return be_to_h< std::uint64_t >( d ); } }; struct read_uint64_le { using type = std::uint64_t; [[nodiscard]] static std::uint64_t read( const void* d ) noexcept { return le_to_h< std::uint64_t >( d ); } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/set_stack_guard.hpp000066400000000000000000000025741426407250600261050ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_SET_STACK_GUARD_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_SET_STACK_GUARD_HPP #include #include #include "../../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Cs > class [[nodiscard]] set_stack_guard { public: template< typename... Ts > set_stack_guard( std::set< Cs... >& set, Ts&&... ts ) : m_i( set.emplace( std::forward< Ts >( ts )... ) ), m_s( set ) {} set_stack_guard( set_stack_guard&& ) = delete; set_stack_guard( const set_stack_guard& ) = delete; set_stack_guard& operator=( set_stack_guard&& ) = delete; set_stack_guard& operator=( const set_stack_guard& ) = delete; ~set_stack_guard() { if( m_i.second ) { m_s.erase( m_i.first ); } } explicit operator bool() const noexcept { return m_i.second; } private: const std::pair< typename std::set< Cs... >::iterator, bool > m_i; std::set< Cs... >& m_s; }; template< typename... Cs > set_stack_guard( std::set< Cs... >&, const typename std::set< Cs... >::value_type& ) -> set_stack_guard< Cs... >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/internal/vector_stack_guard.hpp000066400000000000000000000023531426407250600266070ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_INTERNAL_VECTOR_STACK_GUARD_HPP #define TAO_PEGTL_CONTRIB_INTERNAL_VECTOR_STACK_GUARD_HPP #include #include #include "../../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Cs > class [[nodiscard]] vector_stack_guard { public: template< typename... Ts > vector_stack_guard( std::vector< Cs... >& vector, Ts&&... ts ) : m_s( vector ) { m_s.emplace_back( std::forward< Ts >( ts )... ); } vector_stack_guard( vector_stack_guard&& ) = delete; vector_stack_guard( const vector_stack_guard& ) = delete; vector_stack_guard& operator=( vector_stack_guard&& ) = delete; vector_stack_guard& operator=( const vector_stack_guard& ) = delete; ~vector_stack_guard() { m_s.pop_back(); } private: std::vector< Cs... >& m_s; }; template< typename... Cs > vector_stack_guard( std::vector< Cs... >&, const typename std::vector< Cs... >::value_type& ) -> vector_stack_guard< Cs... >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/iri.hpp000066400000000000000000000074761426407250600217200ustar00rootroot00000000000000// Copyright (c) 2021 Kelvin Hammond // Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_IRI_HPP #define TAO_PEGTL_CONTRIB_IRI_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/contrib/iri.hpp" #else #include "../config.hpp" #include "../rules.hpp" #include "../utf8.hpp" #include "abnf.hpp" #include "uri.hpp" namespace TAO_PEGTL_NAMESPACE::iri { // IRI grammar according to RFC 3987. // This grammar is a direct PEG translation of the original URI grammar. // It should be considered experimental -- in case of any issues, in particular // missing rules for attached actions, please contact the developers. // Note that this grammar has multiple top-level rules. using uri::scheme; using uri::port; using uri::dslash; using uri::IP_literal; using uri::IPv4address; using uri::pct_encoded; using uri::sub_delims; using uri::colon; // clang-format off struct ucschar : utf8::ranges< 0xA0, 0xD7FF, 0xF900, 0xFDCF, 0xFDF0, 0xFFEF, 0x10000, 0x1FFFD, 0x20000, 0x2FFFD, 0x30000, 0x3FFFD, 0x40000, 0x4FFFD, 0x50000, 0x5FFFD, 0x60000, 0x6FFFD, 0x70000, 0x7FFFD, 0x80000, 0x8FFFD, 0x90000, 0x9FFFD, 0xA0000, 0xAFFFD, 0xB0000, 0xBFFFD, 0xC0000, 0xCFFFD, 0xD0000, 0xDFFFD, 0xE1000, 0xEFFFD > {}; struct iprivate : utf8::ranges< 0xE000, 0xF8FF, 0xF0000, 0xFFFFD, 0x100000, 0x10FFFD > {}; struct iunreserved : sor< abnf::ALPHA, abnf::DIGIT, one< '-', '.', '_', '~' >, ucschar > {}; struct ipchar : sor< iunreserved, pct_encoded, sub_delims, one< ':', '@' > > {}; struct isegment : star< ipchar > {}; struct isegment_nz : plus< ipchar > {}; // non-zero-length segment without any colon ":" struct isegment_nz_nc : plus< sor< iunreserved, pct_encoded, sub_delims, one< '@' > > > {}; struct ipath_abempty : star< one< '/' >, isegment > {}; struct ipath_absolute : seq< one< '/' >, opt< isegment_nz, star< one< '/' >, isegment > > > {}; struct ipath_noscheme : seq< isegment_nz_nc, star< one< '/' >, isegment > > {}; struct ipath_rootless : seq< isegment_nz, star< one< '/' >, isegment > > {}; struct ipath_empty : success {}; struct ipath : sor< ipath_noscheme, // begins with a non-colon segment ipath_rootless, // begins with a segment ipath_absolute, // begins with "/" but not "//" ipath_abempty > // begins with "/" or is empty {}; struct ireg_name : star< sor< iunreserved, pct_encoded, sub_delims > > {}; struct ihost : sor< IP_literal, IPv4address, ireg_name > {}; struct iuserinfo : star< sor< iunreserved, pct_encoded, sub_delims, colon > > {}; struct opt_iuserinfo : opt< iuserinfo, one< '@' > > {}; struct iauthority : seq< opt_iuserinfo, ihost, opt< colon, port > > {}; struct iquery : star< sor< ipchar, iprivate, one< '/', '?' > > > {}; struct ifragment : star< sor< ipchar, one< '/', '?' > > > {}; struct opt_iquery : opt_must< one< '?' >, iquery > {}; struct opt_ifragment : opt_must< one< '#' >, ifragment > {}; struct ihier_part : sor< if_must< dslash, iauthority, ipath_abempty >, ipath_rootless, ipath_absolute, ipath_empty > {}; struct irelative_part : sor< if_must< dslash, iauthority, ipath_abempty >, ipath_noscheme, ipath_absolute, ipath_empty > {}; struct irelative_ref : seq< irelative_part, opt_iquery, opt_ifragment > {}; struct IRI : seq< scheme, one< ':' >, ihier_part, opt_iquery, opt_ifragment > {}; struct IRI_reference : sor< IRI, irelative_ref > {}; struct absolute_IRI : seq< scheme, one< ':' >, ihier_part, opt_iquery > {}; // clang-format off } // namespace TAO_PEGTL_NAMESPACE::iri #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/json.hpp000066400000000000000000000062331426407250600220740ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_JSON_HPP #define TAO_PEGTL_CONTRIB_JSON_HPP #include "../ascii.hpp" #include "../config.hpp" #include "../rules.hpp" #include "../utf8.hpp" namespace TAO_PEGTL_NAMESPACE::json { // JSON grammar according to RFC 8259 // clang-format off struct ws : one< ' ', '\t', '\n', '\r' > {}; template< typename R, typename P = ws > struct padr : seq< R, star< P > > {}; struct begin_array : padr< one< '[' > > {}; struct begin_object : padr< one< '{' > > {}; struct end_array : one< ']' > {}; struct end_object : one< '}' > {}; struct name_separator : pad< one< ':' >, ws > {}; struct value_separator : padr< one< ',' > > {}; struct false_ : string< 'f', 'a', 'l', 's', 'e' > {}; // NOLINT(readability-identifier-naming) struct null : string< 'n', 'u', 'l', 'l' > {}; struct true_ : string< 't', 'r', 'u', 'e' > {}; // NOLINT(readability-identifier-naming) struct digits : plus< digit > {}; struct exp : seq< one< 'e', 'E' >, opt< one< '-', '+'> >, digits > {}; struct frac : seq< one< '.' >, digits > {}; struct int_ : sor< one< '0' >, plus< digit > > {}; // NOLINT(readability-identifier-naming) struct number : seq< opt< one< '-' > >, int_, opt< frac >, opt< exp > > {}; struct xdigit : pegtl::xdigit {}; struct unicode : list< seq< one< 'u' >, rep< 4, xdigit > >, one< '\\' > > {}; struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {}; struct escaped : sor< escaped_char, unicode > {}; struct unescaped : utf8::range< 0x20, 0x10FFFF > {}; struct char_ : if_then_else< one< '\\' >, escaped, unescaped > {}; // NOLINT(readability-identifier-naming) struct string_content : until< at< one< '"' > >, char_ > {}; struct string : seq< one< '"' >, string_content, any > { using content = string_content; }; struct key_content : until< at< one< '"' > >, char_ > {}; struct key : seq< one< '"' >, key_content, any > { using content = key_content; }; struct value; struct array_element; struct next_array_element : seq< array_element > {}; struct array_content : opt< array_element, star< value_separator, next_array_element > > {}; struct array : seq< begin_array, array_content, end_array > { using begin = begin_array; using end = end_array; using element = array_element; using content = array_content; }; struct member_value : padr< value > {}; struct member : seq< key, name_separator, member_value > {}; struct next_member : seq< member > {}; struct object_content : opt< member, star< value_separator, next_member > > {}; struct object : seq< begin_object, object_content, end_object > { using begin = begin_object; using end = end_object; using element = member; using content = object_content; }; struct value : sor< string, number, object, array, false_, true_, null > {}; struct array_element : padr< value > {}; struct text : pad< value, ws > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::json #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/json_pointer.hpp000066400000000000000000000020251426407250600236270ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_JSON_POINTER_HPP #define TAO_PEGTL_CONTRIB_JSON_POINTER_HPP #include "../ascii.hpp" #include "../config.hpp" #include "../rules.hpp" #include "../utf8.hpp" namespace TAO_PEGTL_NAMESPACE::json_pointer { // JSON pointer grammar according to RFC 6901 // clang-format off struct unescaped : utf8::ranges< 0x0, 0x2E, 0x30, 0x7D, 0x7F, 0x10FFFF > {}; struct escaped : seq< one< '~' >, one< '0', '1' > > {}; struct reference_token : star< sor< unescaped, escaped > > {}; struct json_pointer : star< one< '/' >, reference_token > {}; // clang-format on // relative JSON pointer, see ... // clang-format off struct non_negative_integer : sor< one< '0' >, plus< digit > > {}; struct relative_json_pointer : seq< non_negative_integer, sor< one< '#' >, json_pointer > > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::json_pointer #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/limit_bytes.hpp000066400000000000000000000046211426407250600234460ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_LIMIT_BYTES_HPP #define TAO_PEGTL_CONTRIB_LIMIT_BYTES_HPP #include #include "../apply_mode.hpp" #include "../config.hpp" #include "../match.hpp" #include "../nothing.hpp" #include "../rewind_mode.hpp" #if defined( __cpp_exceptions ) #include "../parse_error.hpp" #else #include #include #endif namespace TAO_PEGTL_NAMESPACE { namespace internal { template< std::size_t Maximum, typename MemoryInput > struct [[nodiscard]] bytes_guard { MemoryInput& m_in; const char* m_end; explicit bytes_guard( MemoryInput& in_in ) noexcept : m_in( in_in ), m_end( in_in.end() ) { m_in.private_set_end( m_in.begin() + std::min( m_in.size(), Maximum ) ); } bytes_guard( bytes_guard&& ) = delete; bytes_guard( const bytes_guard& ) = delete; ~bytes_guard() { m_in.private_set_end( m_end ); } bytes_guard& operator=( bytes_guard&& ) = delete; bytes_guard& operator=( const bytes_guard& ) = delete; }; // C++17 does not allow for partial deduction guides. } // namespace internal template< std::size_t Maximum > struct limit_bytes : maybe_nothing { template< typename Rule, 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 ) { internal::bytes_guard< Maximum, ParseInput > bg( in ); if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) { if( in.empty() && ( bg.m_end != in.current() ) ) { #if defined( __cpp_exceptions ) throw TAO_PEGTL_NAMESPACE::parse_error( "maximum allowed rule consumption reached", in ); #else std::fputs( "maximum allowed rule consumption reached\n", stderr ); std::terminate(); #endif } return true; } return false; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/limit_depth.hpp000066400000000000000000000043461426407250600234300ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_LIMIT_DEPTH_HPP #define TAO_PEGTL_CONTRIB_LIMIT_DEPTH_HPP #include "../apply_mode.hpp" #include "../config.hpp" #include "../match.hpp" #include "../nothing.hpp" #include "../rewind_mode.hpp" #if defined( __cpp_exceptions ) #include "../parse_error.hpp" #else #include #include #endif namespace TAO_PEGTL_NAMESPACE { namespace internal { struct [[nodiscard]] depth_guard { std::size_t& m_depth; explicit depth_guard( std::size_t& depth ) noexcept : m_depth( depth ) { ++m_depth; } depth_guard( depth_guard&& ) = delete; depth_guard( const depth_guard& ) = delete; ~depth_guard() { --m_depth; } depth_guard& operator=( depth_guard&& ) = delete; depth_guard& operator=( const depth_guard& ) = delete; }; } // namespace internal template< std::size_t Maximum > struct limit_depth : maybe_nothing { template< typename Rule, 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 ) { if constexpr( Control< Rule >::enable ) { const internal::depth_guard dg( in.private_depth ); if( in.private_depth > Maximum ) { #if defined( __cpp_exceptions ) throw TAO_PEGTL_NAMESPACE::parse_error( "maximum parser rule nesting depth exceeded", in ); #else std::fputs( "maximum parser rule nesting depth exceeded\n", stderr ); std::terminate(); #endif } return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); } else { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); } } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/parse_tree.hpp000066400000000000000000000371351426407250600232610ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_HPP #define TAO_PEGTL_CONTRIB_PARSE_TREE_HPP #include #include #include #include #include #include #include #include #include #include "remove_first_state.hpp" #include "shuffle_states.hpp" #include "../apply_mode.hpp" #include "../config.hpp" #include "../demangle.hpp" #include "../memory_input.hpp" #include "../normal.hpp" #include "../nothing.hpp" #include "../parse.hpp" #include "../rewind_mode.hpp" #include "../internal/enable_control.hpp" #include "../internal/has_unwind.hpp" #include "../internal/iterator.hpp" namespace TAO_PEGTL_NAMESPACE::parse_tree { template< typename T, typename Source = std::string_view > struct basic_node { using node_t = T; using children_t = std::vector< std::unique_ptr< node_t > >; children_t children; std::string_view type; Source source; TAO_PEGTL_NAMESPACE::internal::iterator m_begin; TAO_PEGTL_NAMESPACE::internal::iterator m_end; // each node will be default constructed basic_node() = default; // no copy/move is necessary // (nodes are always owned/handled by a std::unique_ptr) basic_node( const basic_node& ) = delete; basic_node( basic_node&& ) = delete; ~basic_node() = default; // no assignment either basic_node& operator=( const basic_node& ) = delete; basic_node& operator=( basic_node&& ) = delete; [[nodiscard]] bool is_root() const noexcept { return type.empty(); } template< typename U > [[nodiscard]] bool is_type() const noexcept { const auto u = demangle< U >(); return ( ( type.data() == u.data() ) && ( type.size() == u.size() ) ) || ( type == u ); } template< typename U > void set_type() noexcept { type = demangle< U >(); } [[nodiscard]] position begin() const { return position( m_begin, source ); } [[nodiscard]] position end() const { return position( m_end, source ); } [[nodiscard]] bool has_content() const noexcept { return m_end.data != nullptr; } [[nodiscard]] std::string_view string_view() const noexcept { assert( has_content() ); return std::string_view( m_begin.data, m_end.data - m_begin.data ); } [[nodiscard]] std::string string() const { assert( has_content() ); return std::string( m_begin.data, m_end.data ); } template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > [[nodiscard]] memory_input< P, Eol > as_memory_input() const { assert( has_content() ); return { m_begin.data, m_end.data, source, m_begin.byte, m_begin.line, m_begin.column }; } template< typename... States > void remove_content( States&&... /*unused*/ ) noexcept { m_end = TAO_PEGTL_NAMESPACE::internal::iterator(); } // all non-root nodes are initialized by calling this method template< typename Rule, typename ParseInput, typename... States > void start( const ParseInput& in, States&&... /*unused*/ ) { set_type< Rule >(); source = in.source(); m_begin = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() ); } // 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::iterator( in.iterator() ); } // if parsing of the rule failed, this method is called template< typename Rule, typename ParseInput, typename... States > void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} // if parsing succeeded and the (optional) transform call // did not discard the node, it is appended to its parent. // note that "child" is the node whose Rule just succeeded // and "*this" is the parent where the node should be appended. template< typename... States > void emplace_back( std::unique_ptr< node_t >&& child, States&&... /*unused*/ ) { assert( child ); children.emplace_back( std::move( child ) ); } }; struct node : basic_node< node > {}; namespace internal { template< typename Node > struct state { std::vector< std::unique_ptr< Node > > stack; state() { emplace_back(); } void emplace_back() { stack.emplace_back( std::make_unique< Node >() ); } [[nodiscard]] std::unique_ptr< Node >& back() noexcept { assert( !stack.empty() ); return stack.back(); } void pop_back() noexcept { assert( !stack.empty() ); return stack.pop_back(); } }; template< typename Selector, typename... Parameters > void transform( Parameters&&... /*unused*/ ) noexcept {} template< typename Selector, typename ParseInput, typename Node, typename... States > auto transform( const ParseInput& in, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( in, n, st... ) ) ) -> decltype( (void)Selector::transform( in, n, st... ) ) { Selector::transform( in, n, st... ); } template< typename Selector, typename ParseInput, typename Node, typename... States > auto transform( const ParseInput& /*unused*/, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( n, st... ) ) ) -> decltype( (void)Selector::transform( n, st... ) ) { Selector::transform( n, st... ); } template< typename Rule, template< typename... > class Selector > inline constexpr bool is_selected_node = ( TAO_PEGTL_NAMESPACE::internal::enable_control< Rule > && Selector< Rule >::value ); template< unsigned Level, typename Subs, template< typename... > class Selector > inline constexpr bool is_leaf{}; template< typename... Rules, template< typename... > class Selector > inline constexpr bool is_leaf< 0, type_list< Rules... >, Selector > = ( sizeof...( Rules ) == 0 ); template< unsigned Level, typename Rule, template< typename... > class Selector > inline constexpr bool is_unselected_branch = ( !is_selected_node< Rule, Selector > && is_leaf< Level, typename Rule::subs_t, Selector > ); template< unsigned Level, typename... Rules, template< typename... > class Selector > inline constexpr bool is_leaf< Level, type_list< Rules... >, Selector > = ( is_unselected_branch< Level - 1, Rules, Selector > && ... ); template< typename Node, template< typename... > class Selector, template< typename... > class Control > struct make_control { template< typename Rule, bool, bool > struct state_handler; template< typename Rule > using type = rotate_states_right< state_handler< Rule, is_selected_node< Rule, Selector >, is_leaf< 8, typename Rule::subs_t, Selector > > >; }; template< typename, typename, typename... > inline constexpr bool node_has_unwind = false; template< typename Node, typename Rule, typename... States > inline constexpr bool node_has_unwind< Node, Rule, decltype( std::declval< Node >().template unwind< Rule >( std::declval< States >()... ) ), States... > = true; template< typename Control, typename... States > inline constexpr bool control_has_unwind = TAO_PEGTL_NAMESPACE::internal::has_unwind< Control, void, States... >; template< typename Node, template< typename... > class Selector, template< typename... > class Control > template< typename Rule > struct make_control< Node, Selector, Control >::state_handler< Rule, false, true > : remove_first_state< Control< Rule > > {}; template< typename Node, template< typename... > class Selector, template< typename... > class Control > template< typename Rule > struct make_control< Node, Selector, Control >::state_handler< Rule, false, false > : remove_first_state< Control< Rule > > { static constexpr bool enable = true; template< typename ParseInput, typename... States > static void start( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ ) { state.emplace_back(); } template< typename ParseInput, typename... States > static void success( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ ) { auto n = std::move( state.back() ); state.pop_back(); for( auto& c : n->children ) { state.back()->children.emplace_back( std::move( c ) ); } } template< typename ParseInput, typename... States > static void failure( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ ) { state.pop_back(); } template< typename ParseInput, typename... States > static void unwind( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ ) { state.pop_back(); } }; template< typename Node, template< typename... > class Selector, template< typename... > class Control > template< typename Rule, bool B > struct make_control< Node, Selector, Control >::state_handler< Rule, true, B > : remove_first_state< Control< Rule > > { template< typename ParseInput, typename... States > static void start( const ParseInput& in, state< Node >& state, States&&... st ) { Control< Rule >::start( in, st... ); state.emplace_back(); state.back()->template start< Rule >( in, st... ); } template< typename ParseInput, typename... States > static void success( const ParseInput& in, state< Node >& state, States&&... st ) { auto n = std::move( state.back() ); state.pop_back(); n->template success< Rule >( in, st... ); transform< Selector< Rule > >( in, n, st... ); if( n ) { state.back()->emplace_back( std::move( n ), st... ); } Control< Rule >::success( in, st... ); } template< typename ParseInput, typename... States > static void failure( const ParseInput& in, state< Node >& state, States&&... st ) { state.back()->template failure< Rule >( in, st... ); state.pop_back(); Control< Rule >::failure( in, st... ); } template< typename ParseInput, typename... States > static void unwind( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] state< Node >& state, States&&... st ) { if constexpr( node_has_unwind< Node, Rule, void, const ParseInput&, States... > ) { state.back()->template unwind< Rule >( in, st... ); } state.pop_back(); if constexpr( control_has_unwind< Control< Rule >, const ParseInput&, States... > ) { Control< Rule >::unwind( in, st... ); } #if defined( _MSC_VER ) ( (void)st, ... ); #endif } }; template< typename > using store_all = std::true_type; template< typename > struct selector; template< typename T > struct selector< std::tuple< T > > { using type = typename T::type; }; template< typename... Ts > struct selector< std::tuple< Ts... > > { static_assert( sizeof...( Ts ) == 0, "multiple matches found" ); using type = std::false_type; }; template< typename T > using selector_t = typename selector< T >::type; template< typename Rule, typename Collection > using select_tuple = std::conditional_t< Collection::template contains< Rule >, std::tuple< Collection >, std::tuple<> >; } // namespace internal template< typename Rule, typename... Collections > using selector = internal::selector_t< decltype( std::tuple_cat( std::declval< internal::select_tuple< Rule, Collections > >()... ) ) >; template< typename Base > struct apply : std::true_type { template< typename... Rules > struct on { using type = Base; template< typename Rule > static constexpr bool contains = ( std::is_same_v< Rule, Rules > || ... ); }; }; struct store_content : apply< store_content > {}; // some nodes don't need to store their content struct remove_content : apply< remove_content > { template< typename Node, typename... States > static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->Node::remove_content( st... ) ) ) { n->remove_content( st... ); } }; // if a node has only one child, replace the node with its child, otherwise remove content struct fold_one : apply< fold_one > { template< typename Node, typename... States > static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.size(), n->Node::remove_content( st... ) ) ) { if( n->children.size() == 1 ) { n = std::move( n->children.front() ); } else { n->remove_content( st... ); } } }; // if a node has no children, discard the node, otherwise remove content struct discard_empty : apply< discard_empty > { template< typename Node, typename... States > static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( (void)n->children.empty(), n->Node::remove_content( st... ) ) ) { if( n->children.empty() ) { n.reset(); } else { n->remove_content( st... ); } } }; template< typename Rule, typename Node, template< typename... > class Selector = internal::store_all, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > [[nodiscard]] std::unique_ptr< Node > parse( ParseInput&& in, States&&... st ) { internal::state< Node > state; if( !TAO_PEGTL_NAMESPACE::parse< Rule, Action, internal::make_control< Node, Selector, Control >::template type >( in, st..., state ) ) { return nullptr; } assert( state.stack.size() == 1 ); return std::move( state.back() ); } template< typename Rule, template< typename... > class Selector = internal::store_all, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > [[nodiscard]] std::unique_ptr< node > parse( ParseInput&& in, States&&... st ) { return parse< Rule, node, Selector, Action, Control >( in, st... ); } } // namespace TAO_PEGTL_NAMESPACE::parse_tree #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/parse_tree_to_dot.hpp000066400000000000000000000061421426407250600246230ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP #define TAO_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP #include #include #include #include "parse_tree.hpp" namespace TAO_PEGTL_NAMESPACE::parse_tree { namespace internal { inline void escape( std::ostream& os, const std::string_view s ) { static const char* h = "0123456789abcdef"; const char* p = s.data(); const char* l = p; const char* const e = s.data() + s.size(); while( p != e ) { const unsigned char c = *p; if( c == '\\' ) { os.write( l, p - l ); l = ++p; os << "\\\\\\\\"; } else if( c == '"' ) { os.write( l, p - l ); l = ++p; os << "\\\\\\\""; } else if( c < 32 ) { os.write( l, p - l ); l = ++p; switch( c ) { case '\a': os << "\\\\a"; break; case '\b': os << "\\\\b"; break; case '\f': os << "\\\\f"; break; case '\n': os << "\\\\n"; break; case '\r': os << "\\\\r"; break; case '\t': os << "\\\\t"; break; case '\v': os << "\\\\v"; break; default: os << "\\\\u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ]; } } else if( c == 127 ) { os.write( l, p - l ); l = ++p; os << "\\\\u007f"; } else { ++p; } } os.write( l, p - l ); } template< typename Node > void print_dot_node( std::ostream& os, const Node& n, const std::string_view s ) { os << " x" << &n << " [ label=\""; escape( os, s ); if( n.has_content() ) { os << "\\n\\\""; escape( os, n.string_view() ); os << "\\\""; } os << "\" ]\n"; if( !n.children.empty() ) { os << " x" << &n << " -> { "; for( auto& up : n.children ) { os << "x" << up.get() << ( ( up == n.children.back() ) ? " }\n" : ", " ); } for( auto& up : n.children ) { print_dot_node( os, *up, up->type ); } } } } // namespace internal template< typename Node > void print_dot( std::ostream& os, const Node& n ) { os << "digraph parse_tree\n{\n"; internal::print_dot_node( os, n, n.is_root() ? "ROOT" : n.type ); os << "}\n"; } } // namespace TAO_PEGTL_NAMESPACE::parse_tree #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/peg.hpp000066400000000000000000000067341426407250600217040ustar00rootroot00000000000000// Copyright (c) 2021 Daniel Deptford // Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PEG_HPP #define TAO_PEGTL_CONTRIB_PEG_HPP #include namespace TAO_PEGTL_NAMESPACE::peg { // PEG grammar from https://pdos.csail.mit.edu/~baford/packrat/popl04/peg-popl04.pdf namespace grammar { // clang-format off struct AND; struct Char; struct Class; struct CLOSE; struct Comment; struct Definition; struct DOT; struct EndOfFile; struct EndOfLine; struct Expression; struct QUESTION; struct IdentCont; struct Identifier; struct IdentStart; struct LEFTARROW; struct Literal; struct NOT; struct OPEN; struct PLUS; struct Prefix; struct Primary; struct Range; struct Sequence; struct SLASH; struct Space; struct Spacing; struct STAR; struct Suffix; struct Grammar : seq< Spacing, plus< Definition >, EndOfFile > {}; struct Definition : seq< Identifier, LEFTARROW, Expression > {}; struct Expression : list< Sequence, SLASH > {}; struct Sequence : star< Prefix > {}; struct Prefix : seq< opt< sor< AND, NOT > >, Suffix > {}; struct Suffix : seq< Primary, opt< sor< QUESTION, STAR, PLUS > > > {}; struct Primary : sor< seq< Identifier, not_at< LEFTARROW > >, seq< OPEN, Expression, CLOSE >, Literal, Class, DOT > {}; struct Identifier : seq< IdentStart, star< IdentCont >, Spacing > {}; struct IdentStart : identifier_first {}; struct IdentCont : identifier_other {}; struct Literal : sor< seq< one< '\'' >, until< one< '\'' >, Char >, Spacing >, seq< one< '"' >, until< one< '"' >, Char >, Spacing > > {}; struct Class : seq< one< '[' >, until< one< ']' >, Range >, Spacing > {}; struct Range : sor< seq< Char, one< '-' >, Char >, Char > {}; struct Char : sor< seq< one< '\\' >, one< 'n', 'r', 't', '\'', '"', '[', ']', '\\' > >, seq< one< '\\' >, range< '0', '2' >, range< '0', '7' >, range< '0', '7' > >, seq< one< '\\' >, range< '0','7' >, opt< range< '0','7' > > >, seq< not_at< one< '\\' > >, any > > {}; struct LEFTARROW : seq< string< '<','-' >, Spacing > {}; struct SLASH : seq< one< '/' >, Spacing > {}; struct AND : seq< one< '&' >, Spacing > {}; struct NOT : seq< one< '!' >, Spacing > {}; struct QUESTION : seq< one< '?' >, Spacing > {}; struct STAR : seq< one< '*' >, Spacing > {}; struct PLUS : seq< one< '+' >, Spacing > {}; struct OPEN : seq< one< '(' >, Spacing > {}; struct CLOSE : seq< one< ')' >, Spacing > {}; struct DOT : seq< one< '.' >, Spacing > {}; struct Spacing : star< sor< Space, Comment > > {}; struct Comment : seq< one< '#' >, until< EndOfLine > > {}; struct Space : sor< one< ' ', '\t' >, EndOfLine > {}; struct EndOfLine : sor< string< '\r', '\n' >, one< '\n' >, one< '\r' > > {}; struct EndOfFile : eof {}; // clang-format on } // namespace grammar } // namespace TAO_PEGTL_NAMESPACE::peg #endif // TAO_PEGTL_CONTRIB_PEG_HPP tao-pegtl-3.2.7/include/tao/pegtl/contrib/predicates.hpp000066400000000000000000000104141426407250600232420ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PREDICATES_HPP #define TAO_PEGTL_CONTRIB_PREDICATES_HPP #include "../config.hpp" #include "../type_list.hpp" #include "../internal/bump_help.hpp" #include "../internal/dependent_false.hpp" #include "../internal/enable_control.hpp" #include "../internal/failure.hpp" #include "../internal/peek_char.hpp" #include "../internal/peek_utf8.hpp" #include "analyze_traits.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Peek, typename... Ps > struct predicates_and_test { using peek_t = Peek; using data_t = typename Peek::data_t; [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return ( Ps::test( c ) && ... ); // TODO: Static assert that Ps::peek_t is the same as peek_t?! } }; template< typename Peek, typename P > struct predicate_not_test { using peek_t = Peek; using data_t = typename Peek::data_t; [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return !P::test( c ); // TODO: Static assert that P::peek_t is the same as peek_t?! } }; template< typename Peek, typename... Ps > struct predicates_or_test { using peek_t = Peek; using data_t = typename Peek::data_t; [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return ( Ps::test( c ) || ... ); // TODO: Static assert that Ps::peek_t is the same as peek_t?! } }; template< template< typename, typename... > class Test, typename Peek, typename... Ps > struct predicates : private Test< Peek, Ps... > { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = predicates; using subs_t = empty_list; using base_t = Test< Peek, Ps... >; using base_t::test; template< int Eol > static constexpr bool can_match_eol = test( Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { bump_help< predicates >( in, t.size ); return true; } } return false; } }; template< template< typename, typename... > class Test, typename Peek > struct predicates< Test, Peek > { static_assert( dependent_false< Peek >, "Empty predicate list is not allowed!" ); }; template< template< typename, typename... > class Test, typename Peek, typename... Ps > inline constexpr bool enable_control< predicates< Test, Peek, Ps... > > = false; } // namespace internal inline namespace ascii { // clang-format off template< typename... Ps > struct predicates_and : internal::predicates< internal::predicates_and_test, internal::peek_char, Ps... > {}; template< typename P > struct predicate_not : internal::predicates< internal::predicate_not_test, internal::peek_char, P > {}; template< typename... Ps > struct predicates_or : internal::predicates< internal::predicates_or_test, internal::peek_char, Ps... > {}; // clang-format on } // namespace ascii namespace utf8 { // clang-format off template< typename... Ps > struct predicates_and : internal::predicates< internal::predicates_and_test, internal::peek_utf8, Ps... > {}; template< typename P > struct predicate_not : internal::predicates< internal::predicate_not_test, internal::peek_utf8, P > {}; template< typename... Ps > struct predicates_or : internal::predicates< internal::predicates_or_test, internal::peek_utf8, Ps... > {}; // clang-format on } // namespace utf8 template< typename Name, template< typename, typename... > class Test, typename Peek, typename... Ps > struct analyze_traits< Name, internal::predicates< Test, Peek, Ps... > > : analyze_any_traits<> {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/print.hpp000066400000000000000000000033721426407250600222600ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PRINT_HPP #define TAO_PEGTL_CONTRIB_PRINT_HPP #include #include "../config.hpp" #include "../demangle.hpp" #include "../type_list.hpp" #include "../visit.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Name > struct print_names { static void visit( std::ostream& os ) { os << demangle< Name >() << '\n'; } }; template< typename Name > struct print_debug { static void visit( std::ostream& os ) { const auto first = demangle< Name >(); os << first << '\n'; const auto second = demangle< typename Name::rule_t >(); if( first != second ) { os << " (aka) " << second << '\n'; } print_subs( os, typename Name::subs_t() ); os << '\n'; } private: template< typename... Rules > static void print_subs( std::ostream& os, type_list< Rules... > /*unused*/ ) { ( print_sub< Rules >( os ), ... ); } template< typename Rule > static void print_sub( std::ostream& os ) { os << " (sub) " << demangle< Rule >() << '\n'; } }; } // namespace internal template< typename Grammar > void print_names( std::ostream& os ) { visit< Grammar, internal::print_names >( os ); } template< typename Grammar > void print_debug( std::ostream& os ) { visit< Grammar, internal::print_debug >( os ); } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/print_coverage.hpp000066400000000000000000000031471426407250600241330ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PRINT_COVERAGE_HPP #define TAO_PEGTL_CONTRIB_PRINT_COVERAGE_HPP #include #include "coverage.hpp" namespace TAO_PEGTL_NAMESPACE { inline std::ostream& operator<<( std::ostream& os, const coverage_result& result ) { os << "[\n"; bool f = true; for( const auto& [ k, v ] : result ) { if( f ) { f = false; } else { os << ",\n"; } os << " {\n" << " \"rule\": \"" << k << "\",\n" << " \"start\": " << v.start << ", \"success\": " << v.success << ", \"failure\": " << v.failure << ", \"unwind\": " << v.unwind << ", \"raise\": " << v.raise << ",\n"; if( v.branches.empty() ) { os << " \"branches\": []\n"; } else { os << " \"branches\": [\n"; bool f2 = true; for( const auto& [ k2, v2 ] : v.branches ) { if( f2 ) { f2 = false; } else { os << ",\n"; } os << " { \"branch\": \"" << k2 << "\", \"start\": " << v2.start << ", \"success\": " << v2.success << ", \"failure\": " << v2.failure << ", \"unwind\": " << v2.unwind << ", \"raise\": " << v2.raise << " }"; } os << "\n ]\n"; } os << " }"; } os << "\n"; os << "]\n"; return os; } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/proto3.hpp000066400000000000000000000202101426407250600223400ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_PROTO3_HPP #define TAO_PEGTL_CONTRIB_PROTO3_HPP #include "../ascii.hpp" #include "../config.hpp" #include "../rules.hpp" namespace TAO_PEGTL_NAMESPACE::proto3 { // protocol buffer v3 // https://developers.google.com/protocol-buffers/docs/reference/proto3-spec // clang-format off struct comment_sl : seq< two< '/' >, until< eolf > > {}; struct comment_ml : if_must< string< '/', '*' >, until< string< '*', '/' > > > {}; struct sp : sor< space, comment_sl, comment_ml > {}; struct sps : star< sp > {}; struct comma : one< ',' > {}; struct dot : one< '.' > {}; struct equ : one< '=' > {}; struct semi : one< ';' > {}; struct option; struct message; struct extend; struct ident_first : ranges< 'a', 'z', 'A', 'Z' > {}; // NOTE: Yes, no '_'. struct ident_other : ranges< 'a', 'z', 'A', 'Z', '0', '9', '_' > {}; struct ident : seq< ident_first, star< ident_other > > {}; struct full_ident : list_must< ident, dot > {}; struct hex_lit : seq< one< '0' >, one< 'x', 'X' >, plus< xdigit > > {}; struct oct_lit : seq< one< '0' >, plus< odigit > > {}; struct dec_lit : seq< range< '1', '9' >, star< digit > > {}; struct int_lit : sor< hex_lit, oct_lit, dec_lit > {}; struct sign : one< '+', '-' > {}; struct exp : seq< one< 'E', 'e' >, opt< sign >, plus< digit > > {}; struct float_lit : sor< seq< plus< digit >, dot, exp >, seq< plus< digit >, dot, star< digit >, opt< exp > >, seq< dot, plus< digit >, opt< exp > >, keyword< 'i', 'n', 'f' >, keyword< 'n', 'a', 'n' > > {}; struct bool_lit : sor< keyword< 't', 'r', 'u', 'e' >, keyword< 'f', 'a', 'l', 's', 'e' > > {}; struct hex_escape : if_must< one< 'x', 'X' >, xdigit, xdigit > {}; struct oct_escape : if_must< odigit, odigit, odigit > {}; struct char_escape : one< 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"' > {}; struct escape : if_must< one< '\\' >, hex_escape, oct_escape, char_escape > {}; struct char_value : sor< escape, not_one< '\n', '\0' > > {}; // NOTE: No need to exclude '\' from not_one<>, see escape rule. template< char Q > struct str_impl : if_must< one< Q >, until< one< Q >, char_value > > {}; struct str_lit : sor< str_impl< '\'' >, str_impl< '"' > > {}; struct constant : sor< bool_lit, seq< opt< sign >, float_lit >, seq< opt< sign >, int_lit >, str_lit, full_ident > {}; struct option_name : seq< sor< ident, if_must< one< '(' >, full_ident, one< ')' > > >, star_must< dot, ident > > {}; struct option : if_must< keyword< 'o', 'p', 't', 'i', 'o', 'n' >, sps, option_name, sps, equ, sps, constant, sps, semi > {}; struct bool_type : keyword< 'b', 'o', 'o', 'l' > {}; struct bytes_type : keyword< 'b', 'y', 't', 'e', 's' > {}; struct double_type : keyword< 'd', 'o', 'u', 'b', 'l', 'e' > {}; struct float_type : keyword< 'f', 'l', 'o', 'a', 't' > {}; struct string_type : keyword< 's', 't', 'r', 'i', 'n', 'g' > {}; struct int32_type : keyword< 'i', 'n', 't', '3', '2' > {}; struct int64_type : keyword< 'i', 'n', 't', '6', '4' > {}; struct sint32_type : keyword< 's', 'i', 'n', 't', '3', '2' > {}; struct sint64_type : keyword< 's', 'i', 'n', 't', '6', '4' > {}; struct uint32_type : keyword< 'u', 'i', 'n', 't', '3', '2' > {}; struct uint64_type : keyword< 'u', 'i', 'n', 't', '6', '4' > {}; struct fixed32_type : keyword< 'f', 'i', 'x', 'e', 'd', '3', '2' > {}; struct fixed64_type : keyword< 'f', 'i', 'x', 'e', 'd', '6', '4' > {}; struct sfixed32_type : keyword< 's', 'f', 'i', 'x', 'e', 'd', '3', '2' > {}; struct sfixed64_type : keyword< 's', 'f', 'i', 'x', 'e', 'd', '6', '4' > {}; struct builtin_type : sor< bool_type, bytes_type, double_type, float_type, string_type, int32_type, int64_type, sint32_type, sint64_type, uint32_type, uint64_type, fixed32_type, fixed64_type, sfixed32_type, sfixed64_type > {}; struct defined_type : seq< opt< dot >, full_ident > {}; // NOTE: This replaces both message_type and enum_type -- they have the same syntax. struct type : sor< builtin_type, defined_type > {}; struct field_option : if_must< option_name, sps, equ, sps, constant > {}; struct field_options : if_must< one< '[' >, sps, list< field_option, comma, sp >, sps, one< ']' > > {}; struct field_name : ident {}; struct field_number : int_lit {}; struct field : seq< opt< sor< keyword< 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l' >, keyword< 'r', 'e', 'p', 'e', 'a', 't', 'e', 'd' > >, sps >, type, sps, field_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {}; struct oneof_name : ident {}; struct oneof_field : if_must< type, sps, field_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {}; struct oneof_body : sor< oneof_field, semi > {}; struct oneof : if_must< keyword< 'o', 'n', 'e', 'o', 'f' >, sps, oneof_name, sps, one< '{' >, sps, until< one< '}' >, oneof_body, sps >, sps > {}; struct key_type : seq< sor< bool_type, string_type, int32_type, int64_type, sint32_type, sint64_type, uint32_type, uint64_type, fixed32_type, fixed64_type, sfixed32_type, sfixed64_type >, not_at< ident_other > > {}; struct map_name : ident {}; struct map_field : if_must< keyword< 'm', 'a', 'p' >, sps, one< '<' >, sps, key_type, sps, comma, sps, type, sps, one< '>' >, sps, map_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {}; struct range : if_must< int_lit, sps, keyword< 't', 'o' >, sps, sor< int_lit, keyword< 'm', 'a', 'x' > > > {}; struct ranges : list_must< range, comma, sp > {}; struct field_names : list_must< field_name, comma, sp > {}; struct reserved : if_must< keyword< 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd' >, sps, sor< ranges, field_names >, sps, semi > {}; struct enum_name : ident {}; struct enum_value_option : seq< option_name, sps, equ, sps, constant > {}; struct enum_field : seq< ident, sps, equ, sps, int_lit, sps, opt_must< one< '[' >, sps, list_must< enum_value_option, comma, sp >, sps, one< ']' >, sps >, semi > {}; struct enum_body : if_must< one< '{' >, sps, star< sor< option, enum_field, semi >, sps >, one< '}' > > {}; struct enum_def : if_must< keyword< 'e', 'n', 'u', 'm' >, sps, enum_name, sps, enum_body > {}; struct message_thing : sor< field, enum_def, message, option, oneof, map_field, reserved, extend, semi > {}; struct message_body : seq< one<'{'>, sps, star< message_thing, sps >, one<'}'> > {}; struct message : if_must< keyword< 'm', 'e', 's', 's', 'a', 'g', 'e' >, sps, defined_type, sps, message_body > {}; struct extend : if_must< keyword< 'e', 'x', 't', 'e', 'n', 'd' >, sps, defined_type, sps, message_body > {}; struct package : if_must< keyword< 'p', 'a', 'c', 'k', 'a', 'g', 'e' >, sps, full_ident, sps, semi > {}; struct import_option : opt< sor< keyword< 'w', 'e', 'a', 'k' >, keyword< 'p', 'u', 'b', 'l', 'i', 'c' > > > {}; struct import : if_must< keyword< 'i', 'm', 'p', 'o', 'r', 't' >, sps, import_option, sps, str_lit, sps, semi > {}; struct rpc_name : ident {}; struct rpc_type : if_must< one< '(' >, sps, opt< keyword< 's', 't', 'r', 'e', 'a', 'm' >, sps >, defined_type, sps, one< ')' > > {}; struct rpc_options : if_must< one< '{' >, sps, star< sor< option, semi >, sps >, one< '}' > > {}; struct rpc : if_must< keyword< 'r', 'p', 'c' >, sps, rpc_name, sps, rpc_type, sps, keyword< 'r', 'e', 't', 'u', 'r', 'n', 's' >, sps, rpc_type, sps, sor< semi, rpc_options > > {}; struct service_name : ident {}; struct service : if_must< keyword< 's', 'e', 'r', 'v', 'i', 'c', 'e' >, sps, service_name, sps, one< '{' >, sps, star< sor< option, rpc, semi >, sps >, one< '}' > > {}; struct body : sor< import, package, option, message, enum_def, service, extend, semi > {}; struct quote : one< '\'', '"' > {}; struct head : if_must< keyword< 's', 'y', 'n', 't', 'a', 'x' >, sps, equ, sps, quote, string< 'p', 'r', 'o', 't', 'o', '3' >, quote, sps, semi > {}; struct proto : must< sps, head, sps, star< body, sps >, eof > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::proto3 #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/raw_string.hpp000066400000000000000000000204601426407250600233000ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_RAW_STRING_HPP #define TAO_PEGTL_CONTRIB_RAW_STRING_HPP #include #include #include "../apply_mode.hpp" #include "../ascii.hpp" #include "../config.hpp" #include "../rewind_mode.hpp" #include "../rules.hpp" #include "analyze_traits.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< char Open, char Marker > struct raw_string_open { using rule_t = raw_string_open; using subs_t = empty_list; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput > [[nodiscard]] static bool match( ParseInput& in, std::size_t& marker_size ) noexcept( noexcept( in.size( 0 ) ) ) { if( in.empty() || ( in.peek_char( 0 ) != Open ) ) { return false; } for( std::size_t i = 1; i < in.size( i + 1 ); ++i ) { switch( const auto c = in.peek_char( i ) ) { case Open: marker_size = i + 1; in.bump_in_this_line( marker_size ); (void)eol::match( in ); return true; case Marker: break; default: return false; } } return false; } }; template< char Open, char Marker > inline constexpr bool enable_control< raw_string_open< Open, Marker > > = false; template< char Marker, char Close > struct at_raw_string_close { using rule_t = at_raw_string_close; using subs_t = empty_list; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput > [[nodiscard]] static bool match( ParseInput& in, const std::size_t& marker_size ) noexcept( noexcept( in.size( 0 ) ) ) { if( in.size( marker_size ) < marker_size ) { return false; } if( in.peek_char( 0 ) != Close ) { return false; } if( in.peek_char( marker_size - 1 ) != Close ) { return false; } for( std::size_t i = 0; i < ( marker_size - 2 ); ++i ) { if( in.peek_char( i + 1 ) != Marker ) { return false; } } return true; } }; template< char Marker, char Close > inline constexpr bool enable_control< at_raw_string_close< Marker, Close > > = false; template< typename Cond, typename... Rules > struct raw_string_until : raw_string_until< Cond, seq< Rules... > > {}; template< typename Cond > struct raw_string_until< Cond > { using rule_t = raw_string_until; using subs_t = type_list< Cond >; 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, const std::size_t& marker_size, States&&... /*unused*/ ) { auto m = in.template mark< M >(); while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, marker_size ) ) { if( in.empty() ) { return false; } in.bump(); } return m( true ); } }; template< typename Cond, typename Rule > struct raw_string_until< Cond, Rule > { using rule_t = raw_string_until; using subs_t = type_list< Cond, 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, const std::size_t& marker_size, States&&... st ) { auto m = in.template mark< M >(); using m_t = decltype( m ); while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, marker_size ) ) { if( !Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { return false; } } return m( true ); } }; template< typename Cond, typename... Rules > inline constexpr bool enable_control< raw_string_until< Cond, Rules... > > = false; } // namespace internal // raw_string matches Lua-style long literals. // // The following description was taken from the Lua documentation // (see http://www.lua.org/docs.html): // // - An "opening long bracket of level n" is defined as an opening square // bracket followed by n equal signs followed by another opening square // bracket. So, an opening long bracket of level 0 is written as `[[`, // an opening long bracket of level 1 is written as `[=[`, and so on. // - A "closing long bracket" is defined similarly; for instance, a closing // long bracket of level 4 is written as `]====]`. // - A "long literal" starts with an opening long bracket of any level and // ends at the first closing long bracket of the same level. It can // contain any text except a closing bracket of the same level. // - Literals in this bracketed form can run for several lines, do not // interpret any escape sequences, and ignore long brackets of any other // level. // - For convenience, when the opening long bracket is eagerly followed // by a newline, the newline is not included in the string. // // Note that unlike Lua's long literal, a raw_string is customizable to use // other characters than `[`, `=` and `]` for matching. Also note that Lua // introduced newline-specific replacements in Lua 5.2, which we do not // support on the grammar level. template< char Open, char Marker, char Close, typename... Contents > struct raw_string { // This is used for binding the apply()-method and for error-reporting // when a raw string is not closed properly or has invalid content. struct content : internal::raw_string_until< internal::at_raw_string_close< Marker, Close >, Contents... > {}; using rule_t = raw_string; using subs_t = empty_list; // type_list< internal::raw_string_open< Open, Marker >, content >; 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 ) { std::size_t marker_size; if( Control< internal::raw_string_open< Open, Marker > >::template match< A, M, Action, Control >( in, marker_size ) ) { if( Control< content >::template match< A, M, Action, Control >( in, marker_size, st... ) ) { in.bump_in_this_line( marker_size ); return true; } } return false; } }; template< typename Name, char Open, char Marker, char Close > struct analyze_traits< Name, raw_string< Open, Marker, Close > > : analyze_any_traits<> {}; template< typename Name, char Open, char Marker, char Close, typename... Contents > struct analyze_traits< Name, raw_string< Open, Marker, Close, Contents... > > : analyze_traits< Name, typename seq< any, star< Contents... >, any >::rule_t > {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/remove_first_state.hpp000066400000000000000000000057171426407250600250350ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_REMOVE_FIRST_STATE_HPP #define TAO_PEGTL_CONTRIB_REMOVE_FIRST_STATE_HPP #include #include "../config.hpp" #include "../internal/has_unwind.hpp" 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. template< typename Base > struct remove_first_state : Base { template< typename ParseInput, typename State, typename... States > static void start( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::start( in, st... ) ) ) { Base::start( in, st... ); } template< typename ParseInput, typename State, typename... States > static void success( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::success( in, st... ) ) ) { Base::success( in, st... ); } template< typename ParseInput, typename State, typename... States > static void failure( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::failure( in, st... ) ) ) { Base::failure( in, st... ); } template< typename ParseInput, typename State, typename... States > [[noreturn]] static void raise( const ParseInput& in, State&& /*unused*/, States&&... st ) { Base::raise( in, 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... > > { Base::unwind( in, st... ); } template< template< typename... > class Action, typename Iterator, typename ParseInput, typename State, typename... States > static auto apply( const Iterator& 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... ); } template< template< typename... > class Action, typename ParseInput, typename State, typename... States > static auto apply0( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::template apply0< Action >( in, st... ) ) ) -> decltype( Base::template apply0< Action >( in, st... ) ) { return Base::template apply0< Action >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/remove_last_states.hpp000066400000000000000000000143411426407250600250250ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_REMOVE_LAST_STATES_HPP #define TAO_PEGTL_CONTRIB_REMOVE_LAST_STATES_HPP #include #include #include "../config.hpp" #include "../internal/has_unwind.hpp" 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. template< typename Base, std::size_t N > struct remove_last_states : Base { template< typename ParseInput, typename Tuple, std::size_t... Is > static void start_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::start( in, std::get< Is >( t )... ) ) ) { Base::start( in, std::get< Is >( t )... ); } template< typename ParseInput, typename... States > static void start( const ParseInput& in, States&&... st ) noexcept( noexcept( start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) ) { start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ); } template< typename ParseInput, typename Tuple, std::size_t... Is > static void success_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::success( in, std::get< Is >( t )... ) ) ) { Base::success( in, std::get< Is >( t )... ); } template< typename ParseInput, typename... States > static void success( const ParseInput& in, States&&... st ) noexcept( noexcept( success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) ) { success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ); } template< typename ParseInput, typename Tuple, std::size_t... Is > static void failure_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::failure( in, std::get< Is >( t )... ) ) ) { Base::failure( in, std::get< Is >( t )... ); } template< typename ParseInput, typename... States > static void failure( const ParseInput& in, States&&... st ) noexcept( noexcept( failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) ) { failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ); } template< typename ParseInput, typename Tuple, std::size_t... Is > [[noreturn]] static void raise_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) { Base::raise( in, std::get< Is >( t )... ); } template< typename ParseInput, typename... States > [[noreturn]] static void raise( const ParseInput& in, States&&... st ) { raise_impl( in, 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*/ ) -> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, std::tuple_element_t< Is, Tuple >... > > { Base::unwind( in, std::get< Is >( t )... ); } template< typename ParseInput, typename... States > static auto unwind( const ParseInput& in, States&&... st ) -> decltype( unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) { unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ); } template< template< typename... > class Action, typename Iterator, typename ParseInput, typename Tuple, std::size_t... Is > static auto apply_impl( const Iterator& 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 Iterator, typename ParseInput, typename... States > static auto apply( const Iterator& 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 >() ); } template< template< typename... > class Action, typename ParseInput, typename Tuple, std::size_t... Is > static auto apply0_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply0< Action >( in, std::get< Is >( t )... ) ) ) -> decltype( Base::template apply0< Action >( in, std::get< Is >( t )... ) ) { return Base::template apply0< Action >( in, std::get< Is >( t )... ); } template< template< typename... > class Action, typename ParseInput, typename... States > static auto apply0( const ParseInput& in, States&&... st ) noexcept( noexcept( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) ) -> decltype( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) { return apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ); } }; template< typename Base > using remove_last_state = remove_last_states< Base, 1 >; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/rep_one_min_max.hpp000066400000000000000000000053471426407250600242670ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_REP_ONE_MIN_MAX_HPP #define TAO_PEGTL_CONTRIB_REP_ONE_MIN_MAX_HPP #include #include #include "../config.hpp" #include "../type_list.hpp" #include "../internal/bump_help.hpp" #include "../internal/bytes.hpp" #include "../internal/enable_control.hpp" #include "../internal/opt.hpp" #include "analyze_traits.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< unsigned Min, unsigned Max, char C > struct rep_one_min_max { using rule_t = rep_one_min_max; using subs_t = empty_list; static_assert( Min <= Max ); template< int Eol > static constexpr bool can_match_eol = ( C == Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) { const auto size = in.size( Max + 1 ); if( size < Min ) { return false; } std::size_t i = 0; while( ( i < size ) && ( in.peek_char( i ) == C ) ) { ++i; } if( ( Min <= i ) && ( i <= Max ) ) { bump_help< rep_one_min_max >( in, i ); return true; } return false; } }; template< unsigned Max, char C > struct rep_one_min_max< 0, Max, C > { using rule_t = rep_one_min_max; using subs_t = empty_list; template< int Eol > static constexpr bool can_match_eol = ( C == Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) { const auto size = in.size( Max + 1 ); std::size_t i = 0; while( ( i < size ) && ( in.peek_char( i ) == C ) ) { ++i; } if( i <= Max ) { bump_help< rep_one_min_max >( in, i ); return true; } return false; } }; template< unsigned Min, unsigned Max, char C > inline constexpr bool enable_control< rep_one_min_max< Min, Max, C > > = false; } // namespace internal inline namespace ascii { template< unsigned Min, unsigned Max, char C > struct rep_one_min_max : internal::rep_one_min_max< Min, Max, C > {}; } // namespace ascii template< typename Name, unsigned Min, unsigned Max, char C > struct analyze_traits< Name, internal::rep_one_min_max< Min, Max, C > > : std::conditional_t< ( Min != 0 ), analyze_any_traits<>, analyze_opt_traits<> > {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/rep_string.hpp000066400000000000000000000020571426407250600232770ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_REP_STRING_HPP #define TAO_PEGTL_CONTRIB_REP_STRING_HPP #include #include "../config.hpp" #include "../internal/string.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< std::size_t, typename, char... > struct make_rep_string; template< char... Ss, char... Cs > struct make_rep_string< 0, string< Ss... >, Cs... > { using type = string< Ss... >; }; template< std::size_t N, char... Ss, char... Cs > struct make_rep_string< N, string< Ss... >, Cs... > : make_rep_string< N - 1, string< Ss..., Cs... >, Cs... > {}; } // namespace internal inline namespace ascii { template< std::size_t N, char... Cs > struct rep_string : internal::make_rep_string< N, internal::string<>, Cs... >::type {}; } // namespace ascii } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/separated_seq.hpp000066400000000000000000000021301426407250600237330ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_SEPARATED_SEQ_HPP #define TAO_PEGTL_CONTRIB_SEPARATED_SEQ_HPP #include "../config.hpp" #include "../internal/seq.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename... > struct sep; template< typename... Ts, typename S, typename Rule, typename... Rules > struct sep< type_list< Ts... >, S, Rule, Rules... > : sep< type_list< Ts..., Rule, S >, S, Rules... > {}; template< typename... Ts, typename S, typename Rule > struct sep< type_list< Ts... >, S, Rule > { using type = seq< Ts..., Rule >; }; template< typename S > struct sep< type_list<>, S > { using type = seq<>; }; } // namespace internal template< typename S, typename... Rules > struct separated_seq : internal::sep< type_list<>, S, Rules... >::type {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/shuffle_states.hpp000066400000000000000000000223651426407250600241460ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_SHUFFLE_STATES_HPP #define TAO_PEGTL_CONTRIB_SHUFFLE_STATES_HPP #include #include #include #include "../config.hpp" #include "../internal/has_unwind.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< std::size_t N > struct rotate_left { template< std::size_t I, std::size_t S > static constexpr std::size_t value = ( I + N ) % S; }; template< std::size_t N > struct rotate_right { template< std::size_t I, std::size_t S > static constexpr std::size_t value = ( I + S - N ) % S; }; struct reverse { template< std::size_t I, std::size_t S > static constexpr std::size_t value = ( S - 1 ) - I; }; } // namespace internal // Applies 'Shuffle' to the states of start(), success(), failure(), raise(), apply(), and apply0() template< typename Base, typename Shuffle > struct shuffle_states : Base { template< typename ParseInput, typename Tuple, std::size_t... Is > static void start_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::start( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) ) { Base::start( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< typename ParseInput, typename... States > static void start( const ParseInput& in, States&&... st ) noexcept( noexcept( start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) ) { start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< typename ParseInput, typename State > static void start( const ParseInput& in, State&& st ) noexcept( noexcept( Base::start( in, st ) ) ) { Base::start( in, st ); } template< typename ParseInput, typename Tuple, std::size_t... Is > static void success_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::success( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) ) { Base::success( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< typename ParseInput, typename... States > static void success( const ParseInput& in, States&&... st ) noexcept( noexcept( success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) ) { success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< typename ParseInput, typename State > static void success( const ParseInput& in, State&& st ) noexcept( noexcept( Base::success( in, st ) ) ) { Base::success( in, st ); } template< typename ParseInput, typename Tuple, std::size_t... Is > static void failure_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::failure( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) ) { Base::failure( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< typename ParseInput, typename... States > static void failure( const ParseInput& in, States&&... st ) noexcept( noexcept( failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) ) { failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< typename ParseInput, typename State > static void failure( const ParseInput& in, State&& st ) noexcept( noexcept( Base::failure( in, st ) ) ) { Base::failure( in, st ); } template< typename ParseInput, typename Tuple, std::size_t... Is > [[noreturn]] static void raise_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) { Base::raise( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< typename ParseInput, typename... States > [[noreturn]] static void raise( const ParseInput& in, States&&... st ) { raise_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< typename ParseInput, typename State > [[noreturn]] static void raise( const ParseInput& in, State&& st ) { Base::raise( 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 >... > > { Base::unwind( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< typename ParseInput, typename... States > static auto unwind( const ParseInput& in, States&&... st ) -> decltype( unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) { unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< typename ParseInput, typename State > static auto unwind( const ParseInput& in, State&& st ) -> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, State > > { Base::unwind( in, st ); } template< template< typename... > class Action, typename Iterator, typename ParseInput, typename Tuple, std::size_t... Is > static auto apply_impl( const Iterator& 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 Iterator, typename ParseInput, typename... States > static auto apply( const Iterator& 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 Iterator, typename ParseInput, typename State > static auto apply( const Iterator& 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 ); } template< template< typename... > class Action, typename ParseInput, typename Tuple, std::size_t... Is > static auto apply0_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) ) -> decltype( Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) { return Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ); } template< template< typename... > class Action, typename ParseInput, typename... States > static auto apply0( const ParseInput& in, States&&... st ) noexcept( noexcept( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) ) -> decltype( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) { return apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ); } template< template< typename... > class Action, typename ParseInput, typename State > static auto apply0( const ParseInput& in, State&& st ) noexcept( noexcept( Base::template apply0< Action >( in, st ) ) ) -> decltype( Base::template apply0< Action >( in, st ) ) { return Base::template apply0< Action >( in, st ); } }; template< typename Base, std::size_t N = 1 > using rotate_states_left = shuffle_states< Base, internal::rotate_left< N > >; template< typename Base, std::size_t N = 1 > using rotate_states_right = shuffle_states< Base, internal::rotate_right< N > >; template< typename Base > using reverse_states = shuffle_states< Base, internal::reverse >; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/state_control.hpp000066400000000000000000000112341426407250600240000ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_STATE_CONTROL_HPP #define TAO_PEGTL_CONTRIB_STATE_CONTROL_HPP #include #include "shuffle_states.hpp" #include "../config.hpp" #include "../internal/has_unwind.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class Control > struct state_control { template< typename Rule > struct control : Control< Rule > { static constexpr bool enable = true; template< typename ParseInput, typename State, typename... States > static void start( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st ) { if constexpr( Control< Rule >::enable ) { Control< Rule >::start( in, st... ); } if constexpr( State::template enable< Rule > ) { state.template start< Rule >( in, st... ); } #if defined( _MSC_VER ) ( (void)st, ... ); #endif } template< typename ParseInput, typename State, typename... States > static void success( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st ) { if constexpr( State::template enable< Rule > ) { state.template success< Rule >( in, st... ); } if constexpr( Control< Rule >::enable ) { Control< Rule >::success( in, st... ); } #if defined( _MSC_VER ) ( (void)st, ... ); #endif } template< typename ParseInput, typename State, typename... States > static void failure( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st ) { if constexpr( State::template enable< Rule > ) { state.template failure< Rule >( in, st... ); } if constexpr( Control< Rule >::enable ) { Control< Rule >::failure( in, st... ); } #if defined( _MSC_VER ) ( (void)st, ... ); #endif } template< typename ParseInput, typename State, typename... States > [[noreturn]] static void raise( const ParseInput& in, [[maybe_unused]] State& state, States&&... st ) { if constexpr( State::template enable< Rule > ) { state.template raise< Rule >( in, st... ); } Control< Rule >::raise( in, 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... > ) > { if constexpr( State::template enable< Rule > ) { state.template unwind< Rule >( in, st... ); } if constexpr( Control< Rule >::enable && internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) { Control< Rule >::unwind( in, st... ); } #if defined( _MSC_VER ) ( (void)st, ... ); #endif } template< template< typename... > class Action, typename Iterator, typename ParseInput, typename State, typename... States > static auto apply( const Iterator& 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 > ) { state.template apply< Rule >( in, st... ); } return Control< Rule >::template apply< Action >( begin, in, st... ); } template< template< typename... > class Action, typename ParseInput, typename State, typename... States > static auto apply0( const ParseInput& in, [[maybe_unused]] State& state, States&&... st ) -> decltype( Control< Rule >::template apply0< Action >( in, st... ) ) { if constexpr( State::template enable< Rule > ) { state.template apply0< Rule >( in, st... ); } return Control< Rule >::template apply0< Action >( in, st... ); } }; template< typename Rule > using type = rotate_states_right< control< Rule > >; }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/to_string.hpp000066400000000000000000000015231426407250600231300ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_TO_STRING_HPP #define TAO_PEGTL_CONTRIB_TO_STRING_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename > struct to_string; template< template< char... > class X, char... Cs > struct to_string< X< Cs... > > { [[nodiscard]] static std::string get() { const char s[] = { Cs..., 0 }; return std::string( s, sizeof...( Cs ) ); } }; } // namespace internal template< typename T > [[nodiscard]] std::string to_string() { return internal::to_string< T >::get(); } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/trace.hpp000066400000000000000000000212061426407250600222160ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_TRACE_HPP #define TAO_PEGTL_CONTRIB_TRACE_HPP #include #include #include #include #include #include "state_control.hpp" #include "../apply_mode.hpp" #include "../config.hpp" #include "../demangle.hpp" #include "../normal.hpp" #include "../nothing.hpp" #include "../parse.hpp" #include "../rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { template< bool HideInternal = false, bool UseColor = true, std::size_t IndentIncrement = 2, std::size_t InitialIndent = 8 > struct tracer_traits { template< typename Rule > static constexpr bool enable = ( HideInternal ? normal< Rule >::enable : true ); static constexpr std::size_t initial_indent = InitialIndent; static constexpr std::size_t indent_increment = IndentIncrement; static constexpr std::string_view ansi_reset = UseColor ? "\033[m" : ""; static constexpr std::string_view ansi_rule = UseColor ? "\033[36m" : ""; static constexpr std::string_view ansi_hide = UseColor ? "\033[37m" : ""; static constexpr std::string_view ansi_position = UseColor ? "\033[1;34m" : ""; static constexpr std::string_view ansi_success = UseColor ? "\033[32m" : ""; static constexpr std::string_view ansi_failure = UseColor ? "\033[31m" : ""; static constexpr std::string_view ansi_raise = UseColor ? "\033[1;31m" : ""; static constexpr std::string_view ansi_unwind = UseColor ? "\033[31m" : ""; static constexpr std::string_view ansi_apply = UseColor ? "\033[1;36m" : ""; }; using standard_tracer_traits = tracer_traits< true >; using complete_tracer_traits = tracer_traits< false >; template< typename TracerTraits > struct tracer { const std::ios_base::fmtflags m_flags; std::size_t m_count = 0; std::vector< std::size_t > m_stack; position m_position; template< typename Rule > static constexpr bool enable = TracerTraits::template enable< Rule >; template< typename ParseInput > explicit tracer( const ParseInput& in ) : m_flags( std::cerr.flags() ), m_position( in.position() ) { std::cerr << std::left; print_position(); } tracer( const tracer& ) = delete; tracer( tracer&& ) = delete; ~tracer() { std::cerr.flags( m_flags ); } tracer& operator=( const tracer& ) = delete; tracer& operator=( tracer&& ) = delete; [[nodiscard]] std::size_t indent() const noexcept { return TracerTraits::initial_indent + TracerTraits::indent_increment * m_stack.size(); } void print_position() const { std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_position << "position" << TracerTraits::ansi_reset << ' ' << m_position << '\n'; } void update_position( const position& p ) { if( m_position != p ) { m_position = p; print_position(); } } template< typename Rule, typename ParseInput, typename... States > void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) { std::cerr << '#' << std::setw( indent() - 1 ) << ++m_count << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n'; m_stack.push_back( m_count ); } template< typename Rule, typename ParseInput, typename... States > void success( const ParseInput& in, States&&... /*unused*/ ) { const auto prev = m_stack.back(); m_stack.pop_back(); std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_success << "success" << TracerTraits::ansi_reset; if( m_count != prev ) { std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset; } std::cerr << '\n'; update_position( in.position() ); } template< typename Rule, typename ParseInput, typename... States > void failure( const ParseInput& in, States&&... /*unused*/ ) { const auto prev = m_stack.back(); m_stack.pop_back(); std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_failure << "failure" << TracerTraits::ansi_reset; if( m_count != prev ) { std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset; } std::cerr << '\n'; update_position( in.position() ); } template< typename Rule, typename ParseInput, typename... States > void raise( const ParseInput& /*unused*/, States&&... /*unused*/ ) { 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 ParseInput, typename... States > void unwind( const ParseInput& in, States&&... /*unused*/ ) { const auto prev = m_stack.back(); m_stack.pop_back(); std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_unwind << "unwind" << TracerTraits::ansi_reset; if( m_count != prev ) { std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset; } std::cerr << '\n'; update_position( in.position() ); } template< typename Rule, typename ParseInput, typename... States > void apply( const ParseInput& /*unused*/, States&&... /*unused*/ ) { std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply" << TracerTraits::ansi_reset << '\n'; } template< typename Rule, typename ParseInput, typename... States > void apply0( const ParseInput& /*unused*/, States&&... /*unused*/ ) { std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply0" << TracerTraits::ansi_reset << '\n'; } template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > bool parse( ParseInput&& in, States&&... st ) { return TAO_PEGTL_NAMESPACE::parse< Rule, Action, state_control< Control >::template type >( in, st..., *this ); } }; template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > bool standard_trace( ParseInput&& in, States&&... st ) { tracer< standard_tracer_traits > tr( in ); return tr.parse< Rule, Action, Control >( in, st... ); } template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal, typename ParseInput, typename... States > bool complete_trace( ParseInput&& in, States&&... st ) { tracer< complete_tracer_traits > tr( in ); return tr.parse< Rule, Action, Control >( in, st... ); } template< typename Tracer > struct trace : maybe_nothing { template< typename Rule, 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 ) { if constexpr( sizeof...( st ) == 0 ) { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) ); } else if constexpr( !std::is_same_v< std::tuple_element_t< sizeof...( st ) - 1, std::tuple< States... > >, Tracer& > ) { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) ); } else { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); } } }; using trace_standard = trace< tracer< standard_tracer_traits > >; using trace_complete = trace< tracer< complete_tracer_traits > >; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/uint16.hpp000066400000000000000000000111521426407250600222450ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UINT16_HPP #define TAO_PEGTL_CONTRIB_UINT16_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_mask_uint.hpp" #include "internal/peek_uint.hpp" namespace TAO_PEGTL_NAMESPACE { namespace uint16_be { // clang-format off struct any : internal::any< internal::peek_uint16_be > {}; template< std::uint16_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint16_be, Cs... > {}; template< std::uint16_t Lo, std::uint16_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint16_be, Lo, Hi > {}; template< std::uint16_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint16_be, Cs... > {}; template< std::uint16_t Lo, std::uint16_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint16_be, Lo, Hi > {}; template< std::uint16_t... Cs > struct ranges : internal::ranges< internal::peek_uint16_be, Cs... > {}; template< std::uint16_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint16_be, Cs >... > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint16_be< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint16_be< M >, Lo, Hi > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Lo, Hi > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint16_be< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Cs >... > {}; // clang-format on } // namespace uint16_be namespace uint16_le { // clang-format off struct any : internal::any< internal::peek_uint16_le > {}; template< std::uint16_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint16_le, Cs... > {}; template< std::uint16_t Lo, std::uint16_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint16_le, Lo, Hi > {}; template< std::uint16_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint16_le, Cs... > {}; template< std::uint16_t Lo, std::uint16_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint16_le, Lo, Hi > {}; template< std::uint16_t... Cs > struct ranges : internal::ranges< internal::peek_uint16_le, Cs... > {}; template< std::uint16_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint16_le, Cs >... > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint16_le< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint16_le< M >, Lo, Hi > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Lo, Hi > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint16_le< M >, Cs... > {}; template< std::uint16_t M, std::uint16_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Cs >... > {}; // clang-format on } // namespace uint16_le } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/uint32.hpp000066400000000000000000000111521426407250600222430ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UINT32_HPP #define TAO_PEGTL_CONTRIB_UINT32_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_mask_uint.hpp" #include "internal/peek_uint.hpp" namespace TAO_PEGTL_NAMESPACE { namespace uint32_be { // clang-format off struct any : internal::any< internal::peek_uint32_be > {}; template< std::uint32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint32_be, Cs... > {}; template< std::uint32_t Lo, std::uint32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint32_be, Lo, Hi > {}; template< std::uint32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint32_be, Cs... > {}; template< std::uint32_t Lo, std::uint32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint32_be, Lo, Hi > {}; template< std::uint32_t... Cs > struct ranges : internal::ranges< internal::peek_uint32_be, Cs... > {}; template< std::uint32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint32_be, Cs >... > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint32_be< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint32_be< M >, Lo, Hi > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Lo, Hi > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint32_be< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Cs >... > {}; // clang-format on } // namespace uint32_be namespace uint32_le { // clang-format off struct any : internal::any< internal::peek_uint32_le > {}; template< std::uint32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint32_le, Cs... > {}; template< std::uint32_t Lo, std::uint32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint32_le, Lo, Hi > {}; template< std::uint32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint32_le, Cs... > {}; template< std::uint32_t Lo, std::uint32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint32_le, Lo, Hi > {}; template< std::uint32_t... Cs > struct ranges : internal::ranges< internal::peek_uint32_le, Cs... > {}; template< std::uint32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint32_le, Cs >... > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint32_le< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint32_le< M >, Lo, Hi > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Lo, Hi > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint32_le< M >, Cs... > {}; template< std::uint32_t M, std::uint32_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Cs >... > {}; // clang-format on } // namespace uint32_le } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/uint64.hpp000066400000000000000000000111531426407250600222510ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UINT64_HPP #define TAO_PEGTL_CONTRIB_UINT64_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_mask_uint.hpp" #include "internal/peek_uint.hpp" namespace TAO_PEGTL_NAMESPACE { namespace uint64_be { // clang-format off struct any : internal::any< internal::peek_uint64_be > {}; template< std::uint64_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint64_be, Cs... > {}; template< std::uint64_t Lo, std::uint64_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint64_be, Lo, Hi > {}; template< std::uint64_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint64_be, Cs... > {}; template< std::uint64_t Lo, std::uint64_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint64_be, Lo, Hi > {}; template< std::uint64_t... Cs > struct ranges : internal::ranges< internal::peek_uint64_be, Cs... > {}; template< std::uint64_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint64_be, Cs >... > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint64_be< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint64_be< M >, Lo, Hi > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Lo, Hi > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint64_be< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Cs >... > {}; // clang-format on } // namespace uint64_be namespace uint64_le { // clang-format off struct any : internal::any< internal::peek_uint64_le > {}; template< std::uint64_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint64_le, Cs... > {}; template< std::uint64_t Lo, std::uint64_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint64_le, Lo, Hi > {}; template< std::uint64_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint64_le, Cs... > {}; template< std::uint64_t Lo, std::uint64_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint64_le, Lo, Hi > {}; template< std::uint64_t... Cs > struct ranges : internal::ranges< internal::peek_uint64_le, Cs... > {}; template< std::uint64_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint64_le, Cs >... > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint64_le< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint64_le< M >, Lo, Hi > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Lo, Hi > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint64_le< M >, Cs... > {}; template< std::uint64_t M, std::uint64_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Cs >... > {}; // clang-format on } // namespace uint64_le } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/uint8.hpp000066400000000000000000000045721426407250600221760ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UINT8_HPP #define TAO_PEGTL_CONTRIB_UINT8_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_mask_uint8.hpp" #include "internal/peek_uint8.hpp" namespace TAO_PEGTL_NAMESPACE::uint8 { // clang-format off struct any : internal::any< internal::peek_uint8 > {}; template< std::uint8_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint8, Cs... > {}; template< std::uint8_t Lo, std::uint8_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint8, Lo, Hi > {}; template< std::uint8_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint8, Cs... > {}; template< std::uint8_t Lo, std::uint8_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint8, Lo, Hi > {}; template< std::uint8_t... Cs > struct ranges : internal::ranges< internal::peek_uint8, Cs... > {}; template< std::uint8_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint8, Cs >... > {}; template< std::uint8_t M, std::uint8_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint8< M >, Cs... > {}; template< std::uint8_t M, std::uint8_t Lo, std::uint8_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint8< M >, Lo, Hi > {}; template< std::uint8_t M, std::uint8_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint8< M >, Cs... > {}; template< std::uint8_t M, std::uint8_t Lo, std::uint8_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint8< M >, Lo, Hi > {}; template< std::uint8_t M, std::uint8_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint8< M >, Cs... > {}; template< std::uint8_t M, std::uint8_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint8< M >, Cs >... > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::uint8 #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/unescape.hpp000066400000000000000000000155341426407250600227320ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UNESCAPE_HPP #define TAO_PEGTL_CONTRIB_UNESCAPE_HPP #include #include #include #include "../ascii.hpp" #include "../config.hpp" #include "../parse_error.hpp" namespace TAO_PEGTL_NAMESPACE::unescape { // Utility functions for the unescape actions. [[nodiscard]] inline bool utf8_append_utf32( std::string& string, const unsigned utf32 ) { if( utf32 <= 0x7f ) { string += char( utf32 & 0xff ); return true; } if( utf32 <= 0x7ff ) { char tmp[] = { char( ( ( utf32 & 0x7c0 ) >> 6 ) | 0xc0 ), char( ( ( utf32 & 0x03f ) ) | 0x80 ) }; string.append( tmp, sizeof( tmp ) ); return true; } if( utf32 <= 0xffff ) { if( utf32 >= 0xd800 && utf32 <= 0xdfff ) { // nope, this is a UTF-16 surrogate return false; } char tmp[] = { char( ( ( utf32 & 0xf000 ) >> 12 ) | 0xe0 ), char( ( ( utf32 & 0x0fc0 ) >> 6 ) | 0x80 ), char( ( ( utf32 & 0x003f ) ) | 0x80 ) }; string.append( tmp, sizeof( tmp ) ); return true; } if( utf32 <= 0x10ffff ) { char tmp[] = { char( ( ( utf32 & 0x1c0000 ) >> 18 ) | 0xf0 ), char( ( ( utf32 & 0x03f000 ) >> 12 ) | 0x80 ), char( ( ( utf32 & 0x000fc0 ) >> 6 ) | 0x80 ), char( ( ( utf32 & 0x00003f ) ) | 0x80 ) }; string.append( tmp, sizeof( tmp ) ); return true; } return false; } // This function MUST only be called for characters matching TAO_PEGTL_NAMESPACE::ascii::xdigit! template< typename I > [[nodiscard]] I unhex_char( const char c ) { switch( c ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return I( c - '0' ); case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return I( c - 'a' + 10 ); case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': return I( c - 'A' + 10 ); default: // LCOV_EXCL_LINE std::terminate(); // LCOV_EXCL_LINE } } template< typename I > [[nodiscard]] I unhex_string( const char* begin, const char* end ) { I r = 0; while( begin != end ) { r <<= 4; r += unhex_char< I >( *begin++ ); } return r; } // Actions for common unescape situations. struct append_all { template< typename ActionInput > static void apply( const ActionInput& in, std::string& s ) { s.append( in.begin(), in.size() ); } }; // This action MUST be called for a character matching T which MUST be TAO_PEGTL_NAMESPACE::one< ... >. template< typename T, char... Rs > struct unescape_c { template< typename ActionInput > static void apply( const ActionInput& in, std::string& s ) { assert( in.size() == 1 ); s += apply_one( in, static_cast< const T* >( nullptr ) ); } template< typename ActionInput, char... Qs > [[nodiscard]] static char apply_one( const ActionInput& in, const one< Qs... >* /*unused*/ ) { static_assert( sizeof...( Qs ) == sizeof...( Rs ), "size mismatch between escaped characters and their mappings" ); return apply_two( in, { Qs... }, { Rs... } ); } template< typename ActionInput > [[nodiscard]] static char apply_two( const ActionInput& in, const std::initializer_list< char >& q, const std::initializer_list< char >& r ) { const char c = *in.begin(); for( std::size_t i = 0; i < q.size(); ++i ) { if( *( q.begin() + i ) == c ) { return *( r.begin() + i ); } } std::terminate(); // LCOV_EXCL_LINE } }; // See src/example/pegtl/unescape.cpp for why the following two actions // skip the first input character. They also MUST be called // with non-empty matched inputs! struct unescape_u { #if defined( __cpp_exceptions ) template< typename ActionInput > static void apply( const ActionInput& in, std::string& s ) { assert( !in.empty() ); // First character MUST be present, usually 'u' or 'U'. if( !utf8_append_utf32( s, unhex_string< unsigned >( in.begin() + 1, in.end() ) ) ) { throw parse_error( "invalid escaped unicode code point", in ); } } #else template< typename ActionInput > static bool apply( const ActionInput& in, std::string& s ) { assert( !in.empty() ); // First character MUST be present, usually 'u' or 'U'. return utf8_append_utf32( s, unhex_string< unsigned >( in.begin() + 1, in.end() ) ); } #endif }; struct unescape_x { template< typename ActionInput > static void apply( const ActionInput& in, std::string& s ) { assert( !in.empty() ); // First character MUST be present, usually 'x'. s += unhex_string< char >( in.begin() + 1, in.end() ); } }; // The unescape_j action is similar to unescape_u, however unlike // unescape_u it // (a) assumes exactly 4 hexdigits per escape sequence, // (b) accepts multiple consecutive escaped 16-bit values. // When applied to more than one escape sequence, unescape_j // translates UTF-16 surrogate pairs in the input into a single // UTF-8 sequence in s, as required for JSON by RFC 8259. struct unescape_j { template< typename ActionInput > static bool apply( const ActionInput& in, std::string& s ) { assert( ( ( in.size() + 1 ) % 6 ) == 0 ); // Expects multiple "\\u1234", starting with the first "u". for( const char* b = in.begin() + 1; b < in.end(); b += 6 ) { const auto c = unhex_string< unsigned >( b, b + 4 ); if( ( 0xd800 <= c ) && ( c <= 0xdbff ) && ( b + 6 < in.end() ) ) { const auto d = unhex_string< unsigned >( b + 6, b + 10 ); if( ( 0xdc00 <= d ) && ( d <= 0xdfff ) ) { b += 6; (void)utf8_append_utf32( s, ( ( ( c & 0x03ff ) << 10 ) | ( d & 0x03ff ) ) + 0x10000 ); continue; } } if( !utf8_append_utf32( s, c ) ) { #if defined( __cpp_exceptions ) throw parse_error( "invalid escaped unicode code point", in ); #else return false; #endif } } return true; } }; } // namespace TAO_PEGTL_NAMESPACE::unescape #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/uri.hpp000066400000000000000000000120171426407250600217170ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_URI_HPP #define TAO_PEGTL_CONTRIB_URI_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/contrib/uri.hpp" #else #include #include "../ascii.hpp" #include "../config.hpp" #include "../rules.hpp" #include "../utf8.hpp" #include "abnf.hpp" #include "integer.hpp" namespace TAO_PEGTL_NAMESPACE::uri { // URI grammar according to RFC 3986. // This grammar is a direct PEG translation of the original URI grammar. // It should be considered experimental -- in case of any issues, in particular // missing rules for attached actions, please contact the developers. // Note that this grammar has multiple top-level rules. using dot = one< '.' >; using colon = one< ':' >; // clang-format off struct dec_octet : maximum_rule< std::uint8_t > {}; struct IPv4address : seq< dec_octet, dot, dec_octet, dot, dec_octet, dot, dec_octet > {}; struct h16 : rep_min_max< 1, 4, abnf::HEXDIG > {}; struct ls32 : sor< seq< h16, colon, h16 >, IPv4address > {}; struct dcolon : two< ':' > {}; struct IPv6address : sor< seq< rep< 6, h16, colon >, ls32 >, seq< dcolon, rep< 5, h16, colon >, ls32 >, seq< opt< h16 >, dcolon, rep< 4, h16, colon >, ls32 >, seq< opt< h16, opt< colon, h16 > >, dcolon, rep< 3, h16, colon >, ls32 >, seq< opt< h16, rep_opt< 2, colon, h16 > >, dcolon, rep< 2, h16, colon >, ls32 >, seq< opt< h16, rep_opt< 3, colon, h16 > >, dcolon, h16, colon, ls32 >, seq< opt< h16, rep_opt< 4, colon, h16 > >, dcolon, ls32 >, seq< opt< h16, rep_opt< 5, colon, h16 > >, dcolon, h16 >, seq< opt< h16, rep_opt< 6, colon, h16 > >, dcolon > > {}; struct gen_delims : one< ':', '/', '?', '#', '[', ']', '@' > {}; struct sub_delims : one< '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' > {}; struct unreserved : sor< abnf::ALPHA, abnf::DIGIT, one< '-', '.', '_', '~' > > {}; struct reserved : sor< gen_delims, sub_delims > {}; struct IPvFuture : if_must< one< 'v', 'V' >, plus< abnf::HEXDIG >, dot, plus< sor< unreserved, sub_delims, colon > > > {}; struct IP_literal : if_must< one< '[' >, sor< IPvFuture, IPv6address >, one< ']' > > {}; struct pct_encoded : if_must< one< '%' >, abnf::HEXDIG, abnf::HEXDIG > {}; struct pchar : sor< unreserved, pct_encoded, sub_delims, one< ':', '@' > > {}; struct query : star< sor< pchar, one< '/', '?' > > > {}; struct fragment : star< sor< pchar, one< '/', '?' > > > {}; struct segment : star< pchar > {}; struct segment_nz : plus< pchar > {}; struct segment_nz_nc : plus< sor< unreserved, pct_encoded, sub_delims, one< '@' > > > {}; // non-zero-length segment without any colon ":" struct path_abempty : star< one< '/' >, segment > {}; struct path_absolute : seq< one< '/' >, opt< segment_nz, star< one< '/' >, segment > > > {}; struct path_noscheme : seq< segment_nz_nc, star< one< '/' >, segment > > {}; struct path_rootless : seq< segment_nz, star< one< '/' >, segment > > {}; struct path_empty : success {}; struct path : sor< path_noscheme, // begins with a non-colon segment path_rootless, // begins with a segment path_absolute, // begins with "/" but not "//" path_abempty > {}; // begins with "/" or is empty struct reg_name : star< sor< unreserved, pct_encoded, sub_delims > > {}; struct port : star< abnf::DIGIT > {}; struct host : sor< IP_literal, IPv4address, reg_name > {}; struct userinfo : star< sor< unreserved, pct_encoded, sub_delims, colon > > {}; struct opt_userinfo : opt< userinfo, one< '@' > > {}; struct authority : seq< opt_userinfo, host, opt< colon, port > > {}; struct scheme : seq< abnf::ALPHA, star< sor< abnf::ALPHA, abnf::DIGIT, one< '+', '-', '.' > > > > {}; using dslash = two< '/' >; using opt_query = opt_must< one< '?' >, query >; using opt_fragment = opt_must< one< '#' >, fragment >; struct hier_part : sor< if_must< dslash, authority, path_abempty >, path_rootless, path_absolute, path_empty > {}; struct relative_part : sor< if_must< dslash, authority, path_abempty >, path_noscheme, path_absolute, path_empty > {}; struct relative_ref : seq< relative_part, opt_query, opt_fragment > {}; struct URI : seq< scheme, one< ':' >, hier_part, opt_query, opt_fragment > {}; struct URI_reference : sor< URI, relative_ref > {}; struct absolute_URI : seq< scheme, one< ':' >, hier_part, opt_query > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::uri #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/utf16.hpp000066400000000000000000000056061426407250600220730ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UTF16_HPP #define TAO_PEGTL_CONTRIB_UTF16_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_utf16.hpp" namespace TAO_PEGTL_NAMESPACE { namespace utf16_be { // clang-format off struct any : internal::any< internal::peek_utf16_be > {}; struct bom : internal::one< internal::result_on_found::success, internal::peek_utf16_be, 0xfeff > {}; template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf16_be, Cs... > {}; template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf16_be, Lo, Hi > {}; template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf16_be, Cs... > {}; template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf16_be, Lo, Hi > {}; template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf16_be, Cs... > {}; template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf16_be, Cs >... > {}; // clang-format on } // namespace utf16_be namespace utf16_le { // clang-format off struct any : internal::any< internal::peek_utf16_le > {}; struct bom : internal::one< internal::result_on_found::success, internal::peek_utf16_le, 0xfeff > {}; template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf16_le, Cs... > {}; template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf16_le, Lo, Hi > {}; template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf16_le, Cs... > {}; template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf16_le, Lo, Hi > {}; template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf16_le, Cs... > {}; template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf16_le, Cs >... > {}; // clang-format on } // namespace utf16_le #if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ ) namespace utf16 = utf16_le; #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ namespace utf16 = utf16_le; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ namespace utf16 = utf16_be; #else #error Unknown endianness. #endif } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/contrib/utf32.hpp000066400000000000000000000056061426407250600220710ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CONTRIB_UTF32_HPP #define TAO_PEGTL_CONTRIB_UTF32_HPP #include "../config.hpp" #include "../internal/result_on_found.hpp" #include "../internal/rules.hpp" #include "internal/peek_utf32.hpp" namespace TAO_PEGTL_NAMESPACE { namespace utf32_be { // clang-format off struct any : internal::any< internal::peek_utf32_be > {}; struct bom : internal::one< internal::result_on_found::success, internal::peek_utf32_be, 0xfeff > {}; template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf32_be, Cs... > {}; template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf32_be, Lo, Hi > {}; template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf32_be, Cs... > {}; template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf32_be, Lo, Hi > {}; template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf32_be, Cs... > {}; template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf32_be, Cs >... > {}; // clang-format on } // namespace utf32_be namespace utf32_le { // clang-format off struct any : internal::any< internal::peek_utf32_le > {}; struct bom : internal::one< internal::result_on_found::success, internal::peek_utf32_le, 0xfeff > {}; template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf32_le, Cs... > {}; template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf32_le, Lo, Hi > {}; template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf32_le, Cs... > {}; template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf32_le, Lo, Hi > {}; template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf32_le, Cs... > {}; template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf32_le, Cs >... > {}; // clang-format on } // namespace utf32_le #if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ ) namespace utf32 = utf32_le; #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ namespace utf32 = utf32_le; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ namespace utf32 = utf32_be; #else #error Unknown endianness. #endif } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/cstream_input.hpp000066400000000000000000000016441426407250600223410ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_CSTREAM_INPUT_HPP #define TAO_PEGTL_CSTREAM_INPUT_HPP #include #include "buffer_input.hpp" #include "config.hpp" #include "eol.hpp" #include "internal/cstream_reader.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Eol = eol::lf_crlf, std::size_t Chunk = 64 > struct cstream_input : buffer_input< internal::cstream_reader, Eol, std::string, Chunk > { template< typename T > cstream_input( std::FILE* in_stream, const std::size_t in_maximum, T&& in_source ) : buffer_input< internal::cstream_reader, Eol, std::string, Chunk >( std::forward< T >( in_source ), in_maximum, in_stream ) {} }; template< typename... Ts > cstream_input( Ts&&... ) -> cstream_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/demangle.hpp000066400000000000000000000107331426407250600212370ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_DEMANGLE_HPP #define TAO_PEGTL_DEMANGLE_HPP #include #include "config.hpp" // ensure a consistent interface namespace TAO_PEGTL_NAMESPACE { #if !defined( __clang__ ) && defined( __GNUC__ ) && ( __GNUC__ == 7 ) template< typename T > [[nodiscard]] std::string_view demangle() noexcept; #else template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept; #endif } // namespace TAO_PEGTL_NAMESPACE #if defined( __clang__ ) #if defined( _LIBCPP_VERSION ) template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = sv.find( '=' ); static_assert( begin != std::string_view::npos ); return sv.substr( begin + 2, sv.size() - begin - 3 ); } #else namespace TAO_PEGTL_NAMESPACE::internal { // When using libstdc++ with clang, std::string_view::find is not constexpr :( template< char C > constexpr const char* string_view_find( const char* p, std::size_t n ) noexcept { while( n ) { if( *p == C ) { return p; } ++p; --n; } return nullptr; } } // namespace TAO_PEGTL_NAMESPACE::internal template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = internal::string_view_find< '=' >( sv.data(), sv.size() ); static_assert( begin != nullptr ); return { begin + 2, sv.data() + sv.size() - begin - 3 }; } #endif #elif defined( __GNUC__ ) #if( __GNUC__ == 7 ) // GCC 7 wrongly sometimes disallows __PRETTY_FUNCTION__ in constexpr functions, // therefore we drop the 'constexpr' and hope for the best. template< typename T > [[nodiscard]] std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { const std::string_view sv = __PRETTY_FUNCTION__; const auto begin = sv.find( '=' ); const auto tmp = sv.substr( begin + 2 ); const auto end = tmp.rfind( ';' ); return tmp.substr( 0, end ); } #elif( __GNUC__ == 9 ) && ( __GNUC_MINOR__ < 3 ) #if !defined( __cpp_rtti ) #error "RTTI support required for GCC 9.1/9.2" #else #include // GCC 9.1 and 9.2 have a bug that leads to truncated __PRETTY_FUNCTION__ names, // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91155 template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { // fallback: requires RTTI, no demangling return typeid( T ).name(); } #endif #else namespace TAO_PEGTL_NAMESPACE::special { template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = sv.find( '=' ); static_assert( begin != std::string_view::npos ); constexpr auto tmp = sv.substr( begin + 2 ); constexpr auto end = tmp.rfind( ';' ); static_assert( end != std::string_view::npos ); return tmp.substr( 0, end ); } } // namespace TAO_PEGTL_NAMESPACE::special template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { return special::demangle< T >(); } #endif #elif defined( _MSC_VER ) #if( _MSC_VER < 1920 ) template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { const std::string_view sv = __FUNCSIG__; const auto begin = sv.find( "demangle<" ); const auto tmp = sv.substr( begin + 9 ); const auto end = tmp.rfind( '>' ); return tmp.substr( 0, end ); } #else template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { // we can not add static_assert for additional safety, // see issues #296, #301 and #308 constexpr std::string_view sv = __FUNCSIG__; constexpr auto begin = sv.find( "demangle<" ); constexpr auto tmp = sv.substr( begin + 9 ); constexpr auto end = tmp.rfind( '>' ); return tmp.substr( 0, end ); } #endif #else #if !defined( __cpp_rtti ) #error "RTTI support required for unknown compilers" #else #include template< typename T > [[nodiscard]] constexpr std::string_view TAO_PEGTL_NAMESPACE::demangle() noexcept { // fallback: requires RTTI, no demangling return typeid( T ).name(); } #endif #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/disable_action.hpp000066400000000000000000000017101426407250600224160ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_DISABLE_ACTION_HPP #define TAO_PEGTL_DISABLE_ACTION_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { struct disable_action : maybe_nothing { template< typename Rule, 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 ) { return TAO_PEGTL_NAMESPACE::match< Rule, apply_mode::nothing, M, Action, Control >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/discard_input.hpp000066400000000000000000000017571426407250600223210ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_DISCARD_INPUT_HPP #define TAO_PEGTL_DISCARD_INPUT_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { struct discard_input : maybe_nothing { template< typename Rule, 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 ) { const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); in.discard(); return result; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/discard_input_on_failure.hpp000066400000000000000000000020671426407250600245170ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_DISCARD_INPUT_ON_FAILURE_HPP #define TAO_PEGTL_DISCARD_INPUT_ON_FAILURE_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { struct discard_input_on_failure : maybe_nothing { template< typename Rule, 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 ) { const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); if( !result ) { in.discard(); } return result; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/discard_input_on_success.hpp000066400000000000000000000020661426407250600245370ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_DISCARD_INPUT_ON_SUCCESS_HPP #define TAO_PEGTL_DISCARD_INPUT_ON_SUCCESS_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { struct discard_input_on_success : maybe_nothing { template< typename Rule, 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 ) { const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); if( result ) { in.discard(); } return result; } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/enable_action.hpp000066400000000000000000000017041426407250600222440ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_ENABLE_ACTION_HPP #define TAO_PEGTL_ENABLE_ACTION_HPP #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "nothing.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { struct enable_action : maybe_nothing { template< typename Rule, 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 ) { return TAO_PEGTL_NAMESPACE::match< Rule, apply_mode::action, M, Action, Control >( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/eol.hpp000066400000000000000000000016721426407250600202440ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_EOL_HPP #define TAO_PEGTL_EOL_HPP #include "config.hpp" #include "internal/eol.hpp" #include "internal/cr_crlf_eol.hpp" #include "internal/cr_eol.hpp" #include "internal/crlf_eol.hpp" #include "internal/lf_crlf_eol.hpp" #include "internal/lf_eol.hpp" namespace TAO_PEGTL_NAMESPACE { inline namespace ascii { // this is both a rule and a pseudo-namespace for eol::cr, ... struct eol : internal::eol { // clang-format off struct cr : internal::cr_eol {}; struct cr_crlf : internal::cr_crlf_eol {}; struct crlf : internal::crlf_eol {}; struct lf : internal::lf_eol {}; struct lf_crlf : internal::lf_crlf_eol {}; // clang-format on }; } // namespace ascii } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/eol_pair.hpp000066400000000000000000000006071426407250600212540ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_EOL_PAIR_HPP #define TAO_PEGTL_EOL_PAIR_HPP #include #include #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { using eol_pair = std::pair< bool, std::size_t >; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/file_input.hpp000066400000000000000000000021711426407250600216160ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_FILE_INPUT_HPP #define TAO_PEGTL_FILE_INPUT_HPP #include "config.hpp" #include "eol.hpp" #include "tracking_mode.hpp" #if defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) #include // Required for _POSIX_MAPPED_FILES #endif #if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 ) #include "mmap_input.hpp" #else #include "read_input.hpp" #endif namespace TAO_PEGTL_NAMESPACE { #if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 ) template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct file_input : mmap_input< P, Eol > { using mmap_input< P, Eol >::mmap_input; }; #else template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct file_input : read_input< P, Eol > { using read_input< P, Eol >::read_input; }; #endif template< typename... Ts > explicit file_input( Ts&&... ) -> file_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/000077500000000000000000000000001426407250600205625ustar00rootroot00000000000000tao-pegtl-3.2.7/include/tao/pegtl/internal/action.hpp000066400000000000000000000027531426407250600225570ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ACTION_HPP #define TAO_PEGTL_INTERNAL_ACTION_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< template< typename... > class Action, typename... Rules > struct action : action< Action, seq< Rules... > > {}; template< template< typename... > class Action > struct action< Action > : success {}; template< template< typename... > class Action, typename Rule > struct action< Action, Rule > { using rule_t = action; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode M, template< typename... > class, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { return Control< Rule >::template match< A, M, Action, Control >( in, st... ); } }; template< template< typename... > class Action, typename... Rules > inline constexpr bool enable_control< action< Action, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/action_input.hpp000066400000000000000000000051411426407250600237700ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ACTION_INPUT_HPP #define TAO_PEGTL_INTERNAL_ACTION_INPUT_HPP #include #include #include #include #include "iterator.hpp" #include "../config.hpp" #include "../position.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename ParseInput > class action_input { public: using input_t = ParseInput; using iterator_t = typename ParseInput::iterator_t; action_input( const iterator_t& in_begin, const ParseInput& in_input ) noexcept : m_begin( in_begin ), m_input( in_input ) {} action_input( const action_input& ) = delete; action_input( action_input&& ) = delete; ~action_input() = default; action_input& operator=( const action_input& ) = delete; action_input& operator=( action_input&& ) = delete; [[nodiscard]] const iterator_t& iterator() const noexcept { return m_begin; } [[nodiscard]] const ParseInput& input() const noexcept { return m_input; } [[nodiscard]] const char* begin() const noexcept { if constexpr( std::is_same_v< iterator_t, const char* > ) { return iterator(); } else { return iterator().data; } } [[nodiscard]] const char* end() const noexcept { return input().current(); } [[nodiscard]] bool empty() const noexcept { return begin() == end(); } [[nodiscard]] std::size_t size() const noexcept { return std::size_t( end() - begin() ); } [[nodiscard]] std::string string() const { return std::string( begin(), size() ); } [[nodiscard]] std::string_view string_view() const noexcept { return std::string_view( begin(), size() ); } [[nodiscard]] char peek_char( const std::size_t offset = 0 ) const noexcept { return begin()[ offset ]; } [[nodiscard]] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept { return static_cast< std::uint8_t >( peek_char( offset ) ); } [[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const { return input().position( iterator() ); // NOTE: Not efficient with lazy inputs. } protected: const iterator_t m_begin; const ParseInput& m_input; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/any.hpp000066400000000000000000000033371426407250600220700ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ANY_HPP #define TAO_PEGTL_INTERNAL_ANY_HPP #include "../config.hpp" #include "enable_control.hpp" #include "peek_char.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Peek > struct any; template<> struct any< peek_char > { using peek_t = peek_char; using data_t = char; using rule_t = any; using subs_t = empty_list; [[nodiscard]] static bool test( const char /*unused*/ ) noexcept { return true; } template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( !in.empty() ) { in.bump(); return true; } return false; } }; template< typename Peek > struct any { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = any; using subs_t = empty_list; template< int Eol > static constexpr bool can_match_eol = true; [[nodiscard]] static bool test( const data_t /*unused*/ ) noexcept { return true; } template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { in.bump( t.size ); return true; } return false; } }; template< typename Peek > inline constexpr bool enable_control< any< Peek > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/apply.hpp000066400000000000000000000030241426407250600224170ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_APPLY_HPP #define TAO_PEGTL_INTERNAL_APPLY_HPP #include "../config.hpp" #include "apply_single.hpp" #include "enable_control.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Actions > struct apply { using rule_t = apply; using subs_t = empty_list; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( [[maybe_unused]] ParseInput& in, [[maybe_unused]] States&&... st ) { if constexpr( ( A == apply_mode::action ) && ( sizeof...( Actions ) > 0 ) ) { using action_t = typename ParseInput::action_t; const action_t i2( in.iterator(), in ); // No data -- range is from begin to begin. return ( apply_single< Actions >::match( i2, st... ) && ... ); } else { #if defined( _MSC_VER ) ( (void)st, ... ); #endif return true; } } }; template< typename... Actions > inline constexpr bool enable_control< apply< Actions... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/apply0.hpp000066400000000000000000000025151426407250600225030ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_APPLY0_HPP #define TAO_PEGTL_INTERNAL_APPLY0_HPP #include "../config.hpp" #include "apply0_single.hpp" #include "enable_control.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Actions > struct apply0 { using rule_t = apply0; using subs_t = empty_list; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& /*unused*/, [[maybe_unused]] States&&... st ) { if constexpr( A == apply_mode::action ) { return ( apply0_single< Actions >::match( st... ) && ... ); } else { #if defined( _MSC_VER ) ( (void)st, ... ); #endif return true; } } }; template< typename... Actions > inline constexpr bool enable_control< apply0< Actions... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/apply0_single.hpp000066400000000000000000000020311426407250600240350ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_APPLY0_SINGLE_HPP #define TAO_PEGTL_INTERNAL_APPLY0_SINGLE_HPP #include "../config.hpp" #include namespace TAO_PEGTL_NAMESPACE::internal { template< typename Action > struct apply0_single { template< typename... States > [[nodiscard]] static auto match( States&&... st ) noexcept( noexcept( Action::apply0( st... ) ) ) -> std::enable_if_t< std::is_same_v< decltype( Action::apply0( st... ) ), void >, bool > { Action::apply0( st... ); return true; } template< typename... States > [[nodiscard]] static auto match( States&&... st ) noexcept( noexcept( Action::apply0( st... ) ) ) -> std::enable_if_t< std::is_same_v< decltype( Action::apply0( st... ) ), bool >, bool > { return Action::apply0( st... ); } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/apply_single.hpp000066400000000000000000000022021426407250600237550ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_APPLY_SINGLE_HPP #define TAO_PEGTL_INTERNAL_APPLY_SINGLE_HPP #include "../config.hpp" #include namespace TAO_PEGTL_NAMESPACE::internal { template< typename Action > struct apply_single { template< typename ActionInput, typename... States > [[nodiscard]] static auto match( const ActionInput& in, States&&... st ) noexcept( noexcept( Action::apply( in, st... ) ) ) -> std::enable_if_t< std::is_same_v< decltype( Action::apply( in, st... ) ), void >, bool > { Action::apply( in, st... ); return true; } template< typename ActionInput, typename... States > [[nodiscard]] static auto match( const ActionInput& in, States&&... st ) noexcept( noexcept( Action::apply( in, st... ) ) ) -> std::enable_if_t< std::is_same_v< decltype( Action::apply( in, st... ) ), bool >, bool > { return Action::apply( in, st... ); } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/at.hpp000066400000000000000000000025771426407250600217120ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_AT_HPP #define TAO_PEGTL_INTERNAL_AT_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct at : at< seq< Rules... > > {}; template<> struct at<> : success {}; template< typename Rule > struct at< Rule > { using rule_t = at; using subs_t = type_list< Rule >; template< apply_mode, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { const auto m = in.template mark< rewind_mode::required >(); return Control< Rule >::template match< apply_mode::nothing, rewind_mode::active, Action, Control >( in, st... ); } }; template< typename... Rules > inline constexpr bool enable_control< at< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/bof.hpp000066400000000000000000000012721426407250600220430ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_BOF_HPP #define TAO_PEGTL_INTERNAL_BOF_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct bof { using rule_t = bof; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept { return in.byte() == 0; } }; template<> inline constexpr bool enable_control< bof > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/bol.hpp000066400000000000000000000012731426407250600220520ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_BOL_HPP #define TAO_PEGTL_INTERNAL_BOL_HPP #include "../config.hpp" #include "../type_list.hpp" #include "enable_control.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct bol { using rule_t = bol; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept { return in.column() == 1; } }; template<> inline constexpr bool enable_control< bol > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/bump.hpp000066400000000000000000000020761426407250600222430ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_BUMP_HPP #define TAO_PEGTL_INTERNAL_BUMP_HPP #include "../config.hpp" #include "iterator.hpp" namespace TAO_PEGTL_NAMESPACE::internal { inline void bump( iterator& iter, const std::size_t count, const int ch ) noexcept { for( std::size_t i = 0; i < count; ++i ) { if( iter.data[ i ] == ch ) { ++iter.line; iter.column = 1; } else { ++iter.column; } } iter.byte += count; iter.data += count; } inline void bump_in_this_line( iterator& iter, const std::size_t count ) noexcept { iter.data += count; iter.byte += count; iter.column += count; } inline void bump_to_next_line( iterator& iter, const std::size_t count ) noexcept { ++iter.line; iter.byte += count; iter.column = 1; iter.data += count; } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/bump_help.hpp000066400000000000000000000012221426407250600232430ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_BUMP_HELP_HPP #define TAO_PEGTL_INTERNAL_BUMP_HELP_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename ParseInput > void bump_help( ParseInput& in, const std::size_t count ) { if constexpr( Rule::template can_match_eol< ParseInput::eol_t::ch > ) { in.bump( count ); } else { in.bump_in_this_line( count ); } } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/bytes.hpp000066400000000000000000000017011426407250600224200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_BYTES_HPP #define TAO_PEGTL_INTERNAL_BYTES_HPP #include "../config.hpp" #include "enable_control.hpp" #include "success.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Cnt > struct bytes { using rule_t = bytes; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.size( 0 ) ) ) { if( in.size( Cnt ) >= Cnt ) { in.bump( Cnt ); return true; } return false; } }; template<> struct bytes< 0 > : success {}; template< unsigned Cnt > inline constexpr bool enable_control< bytes< Cnt > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/control.hpp000066400000000000000000000027721426407250600227630ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CONTROL_HPP #define TAO_PEGTL_INTERNAL_CONTROL_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< template< typename... > class Control, typename... Rules > struct control : control< Control, seq< Rules... > > {}; template< template< typename... > class Control > struct control< Control > : success {}; template< template< typename... > class Control, typename Rule > struct control< Control, Rule > { using rule_t = control; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { return Control< Rule >::template match< A, M, Action, Control >( in, st... ); } }; template< template< typename... > class Control, typename... Rules > inline constexpr bool enable_control< control< Control, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/cr_crlf_eol.hpp000066400000000000000000000015661426407250600235540ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CR_CRLF_EOL_HPP #define TAO_PEGTL_INTERNAL_CR_CRLF_EOL_HPP #include "../config.hpp" #include "../eol_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct cr_crlf_eol { static constexpr int ch = '\r'; template< typename ParseInput > [[nodiscard]] static eol_pair match( ParseInput& in ) noexcept( noexcept( in.size( 2 ) ) ) { eol_pair p = { false, in.size( 2 ) }; if( p.second ) { if( in.peek_char() == '\r' ) { in.bump_to_next_line( 1 + ( ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) ); p.first = true; } } return p; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/cr_eol.hpp000066400000000000000000000014541426407250600225420ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CR_EOL_HPP #define TAO_PEGTL_INTERNAL_CR_EOL_HPP #include "../config.hpp" #include "../eol_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct cr_eol { static constexpr int ch = '\r'; template< typename ParseInput > [[nodiscard]] static eol_pair match( ParseInput& in ) noexcept( noexcept( in.size( 1 ) ) ) { eol_pair p = { false, in.size( 1 ) }; if( p.second ) { if( in.peek_char() == '\r' ) { in.bump_to_next_line(); p.first = true; } } return p; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/crlf_eol.hpp000066400000000000000000000015361426407250600230650ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CRLF_EOL_HPP #define TAO_PEGTL_INTERNAL_CRLF_EOL_HPP #include "../config.hpp" #include "../eol_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct crlf_eol { static constexpr int ch = '\n'; template< typename ParseInput > [[nodiscard]] static eol_pair match( ParseInput& in ) noexcept( noexcept( in.size( 2 ) ) ) { eol_pair p = { false, in.size( 2 ) }; if( p.second > 1 ) { if( ( in.peek_char() == '\r' ) && ( in.peek_char( 1 ) == '\n' ) ) { in.bump_to_next_line( 2 ); p.first = true; } } return p; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/cstream_reader.hpp000066400000000000000000000027501426407250600242570ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CSTREAM_READER_HPP #define TAO_PEGTL_INTERNAL_CSTREAM_READER_HPP #include #include #include #if defined( __cpp_exceptions ) #include #else #include #endif #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct cstream_reader { explicit cstream_reader( std::FILE* s ) noexcept : m_cstream( s ) { assert( m_cstream != nullptr ); } [[nodiscard]] std::size_t operator()( char* buffer, const std::size_t length ) const { if( const auto r = std::fread( buffer, 1, length, m_cstream ) ) { return r; } if( std::feof( m_cstream ) != 0 ) { return 0; } // Please contact us if you know how to provoke the following exception. // The example on cppreference.com doesn't work, at least not on macOS. // LCOV_EXCL_START #if defined( __cpp_exceptions ) const auto ec = std::ferror( m_cstream ); assert( ec != 0 ); throw std::system_error( ec, std::system_category(), "std::fread() failed" ); #else std::fputs( "std::fread() failed\n", stderr ); std::terminate(); #endif // LCOV_EXCL_STOP } std::FILE* m_cstream; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/cstring_reader.hpp000066400000000000000000000016671426407250600243000ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_CSTRING_READER_HPP #define TAO_PEGTL_INTERNAL_CSTRING_READER_HPP #include #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct cstring_reader { explicit cstring_reader( const char* zero_terminated ) noexcept : m_cstring( zero_terminated ) { assert( m_cstring != nullptr ); } [[nodiscard]] std::size_t operator()( char* buffer, const std::size_t length ) noexcept { std::size_t i = 0; char c; while( ( i < length ) && ( ( c = m_cstring[ i ] ) != 0 ) ) { *buffer++ = c; ++i; } m_cstring += i; return i; } const char* m_cstring; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/dependent_false.hpp000066400000000000000000000006601426407250600244150ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_DEPENDENT_FALSE_HPP #define TAO_PEGTL_INTERNAL_DEPENDENT_FALSE_HPP #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... > inline constexpr bool dependent_false = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/disable.hpp000066400000000000000000000025221426407250600226770ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_DISABLE_HPP #define TAO_PEGTL_INTERNAL_DISABLE_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct disable : disable< seq< Rules... > > {}; template<> struct disable<> : success {}; template< typename Rule > struct disable< Rule > { using rule_t = disable; using subs_t = type_list< Rule >; template< apply_mode, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { return Control< Rule >::template match< apply_mode::nothing, M, Action, Control >( in, st... ); } }; template< typename... Rules > inline constexpr bool enable_control< disable< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/discard.hpp000066400000000000000000000014171426407250600227070ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_DISCARD_HPP #define TAO_PEGTL_INTERNAL_DISCARD_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct discard { using rule_t = discard; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept { static_assert( noexcept( in.discard() ) ); in.discard(); return true; } }; template<> inline constexpr bool enable_control< discard > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/enable.hpp000066400000000000000000000025111426407250600225200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ENABLE_HPP #define TAO_PEGTL_INTERNAL_ENABLE_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct enable : enable< seq< Rules... > > {}; template<> struct enable<> : success {}; template< typename Rule > struct enable< Rule > { using rule_t = enable; using subs_t = type_list< Rule >; template< apply_mode, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { return Control< Rule >::template match< apply_mode::action, M, Action, Control >( in, st... ); } }; template< typename... Rules > inline constexpr bool enable_control< enable< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/enable_control.hpp000066400000000000000000000013551426407250600242650ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ENABLE_CONTROL_HPP #define TAO_PEGTL_INTERNAL_ENABLE_CONTROL_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { // This class is a simple tagging mechanism. // By default, enable_control< Rule > is 'true'. // Each internal (!) rule that should be hidden // from the control and action class' callbacks // simply specializes enable_control<> to return // 'true' for the above expression. template< typename Rule > inline constexpr bool enable_control = true; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/eof.hpp000066400000000000000000000013201426407250600220400ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_EOF_HPP #define TAO_PEGTL_INTERNAL_EOF_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct eof { using rule_t = eof; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { return in.empty(); } }; template<> inline constexpr bool enable_control< eof > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/eol.hpp000066400000000000000000000013761426407250600220610ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_EOL_HPP #define TAO_PEGTL_INTERNAL_EOL_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct eol { using rule_t = eol; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( ParseInput::eol_t::match( in ) ) ) { return ParseInput::eol_t::match( in ).first; } }; template<> inline constexpr bool enable_control< eol > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/eolf.hpp000066400000000000000000000014571426407250600222270ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_EOLF_HPP #define TAO_PEGTL_INTERNAL_EOLF_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct eolf { using rule_t = eolf; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( ParseInput::eol_t::match( in ) ) ) { const auto p = ParseInput::eol_t::match( in ); return p.first || ( !p.second ); } }; template<> inline constexpr bool enable_control< eolf > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/failure.hpp000066400000000000000000000013151426407250600227220ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_FAILURE_HPP #define TAO_PEGTL_INTERNAL_FAILURE_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct failure { using rule_t = failure; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& /*unused*/ ) noexcept { return false; } }; template<> inline constexpr bool enable_control< failure > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/file_mapper_posix.hpp000066400000000000000000000100641426407250600250010ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_FILE_MAPPER_POSIX_HPP #define TAO_PEGTL_INTERNAL_FILE_MAPPER_POSIX_HPP #include #include #include #include #include #if !defined( __cpp_exceptions ) #include #include #endif #include #include "../config.hpp" #include "filesystem.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct file_opener { explicit file_opener( const internal::filesystem::path& path ) // NOLINT(modernize-pass-by-value) : m_path( path ), m_fd( open() ) {} file_opener( const file_opener& ) = delete; file_opener( file_opener&& ) = delete; ~file_opener() { ::close( m_fd ); } file_opener& operator=( const file_opener& ) = delete; file_opener& operator=( file_opener&& ) = delete; [[nodiscard]] std::size_t size() const { struct stat st; errno = 0; if( ::fstat( m_fd, &st ) < 0 ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "fstat() failed", m_path, ec ); #else std::perror( "fstat() failed" ); std::terminate(); #endif // LCOV_EXCL_STOP } return std::size_t( st.st_size ); } const internal::filesystem::path m_path; const int m_fd; private: [[nodiscard]] int open() const { errno = 0; const int fd = ::open( m_path.c_str(), O_RDONLY #if defined( O_CLOEXEC ) | O_CLOEXEC #endif ); if( fd >= 0 ) { return fd; } #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "open() failed", m_path, ec ); #else std::perror( "open() failed" ); std::terminate(); #endif } }; class file_mapper { public: explicit file_mapper( const internal::filesystem::path& path ) : file_mapper( file_opener( path ) ) {} explicit file_mapper( const file_opener& reader ) : m_size( reader.size() ), m_data( static_cast< const char* >( ::mmap( nullptr, m_size, PROT_READ, MAP_PRIVATE, reader.m_fd, 0 ) ) ) { if( ( m_size != 0 ) && ( intptr_t( m_data ) == -1 ) ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "mmap() failed", reader.m_path, ec ); #else std::perror( "mmap() failed" ); std::terminate(); #endif // LCOV_EXCL_STOP } } file_mapper( const file_mapper& ) = delete; file_mapper( file_mapper&& ) = delete; ~file_mapper() { // Legacy C interface requires pointer-to-mutable but does not write through the pointer. ::munmap( const_cast< char* >( m_data ), m_size ); } file_mapper& operator=( const file_mapper& ) = delete; file_mapper& operator=( file_mapper&& ) = delete; [[nodiscard]] bool empty() const noexcept { return m_size == 0; } [[nodiscard]] std::size_t size() const noexcept { return m_size; } using iterator = const char*; using const_iterator = const char*; [[nodiscard]] iterator data() const noexcept { return m_data; } [[nodiscard]] iterator begin() const noexcept { return m_data; } [[nodiscard]] iterator end() const noexcept { return m_data + m_size; } private: const std::size_t m_size; const char* const m_data; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/file_mapper_win32.hpp000066400000000000000000000165771426407250600246200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_FILE_MAPPER_WIN32_HPP #define TAO_PEGTL_INTERNAL_FILE_MAPPER_WIN32_HPP #if !defined( NOMINMAX ) #define NOMINMAX #define TAO_PEGTL_NOMINMAX_WAS_DEFINED #endif #if !defined( WIN32_LEAN_AND_MEAN ) #define WIN32_LEAN_AND_MEAN #define TAO_PEGTL_WIN32_LEAN_AND_MEAN_WAS_DEFINED #endif #include #if defined( TAO_PEGTL_NOMINMAX_WAS_DEFINED ) #undef NOMINMAX #undef TAO_PEGTL_NOMINMAX_WAS_DEFINED #endif #if defined( TAO_PEGTL_WIN32_LEAN_AND_MEAN_WAS_DEFINED ) #undef WIN32_LEAN_AND_MEAN #undef TAO_PEGTL_WIN32_LEAN_AND_MEAN_WAS_DEFINED #endif #include "../config.hpp" #if !defined( __cpp_exceptions ) #include #include #endif #include "filesystem.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct file_opener { explicit file_opener( const internal::filesystem::path& path ) : m_path( path ), m_handle( open() ) {} file_opener( const file_opener& ) = delete; file_opener( file_opener&& ) = delete; ~file_opener() { ::CloseHandle( m_handle ); } file_opener& operator=( const file_opener& ) = delete; file_opener& operator=( file_opener&& ) = delete; [[nodiscard]] std::size_t size() const { 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 ); #else std::perror( "GetFileSizeEx() failed" ); std::terminate(); #endif } return std::size_t( size.QuadPart ); } const internal::filesystem::path m_path; const HANDLE m_handle; private: [[nodiscard]] HANDLE open() const { SetLastError( 0 ); #if( _WIN32_WINNT >= 0x0602 ) const HANDLE handle = ::CreateFile2( m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr ); if( handle != INVALID_HANDLE_VALUE ) { return handle; } #if defined( __cpp_exceptions ) internal::error_code ec( ::GetLastError(), internal::system_category() ); throw internal::filesystem::filesystem_error( "CreateFile2() failed", m_path, ec ); #else std::perror( "CreateFile2() failed" ); std::terminate(); #endif #else const HANDLE handle = ::CreateFileW( m_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ); if( handle != INVALID_HANDLE_VALUE ) { return handle; } #if defined( __cpp_exceptions ) internal::error_code ec( ::GetLastError(), internal::system_category() ); throw internal::filesystem::filesystem_error( "CreateFileW()", m_path, ec ); #else std::perror( "CreateFileW() failed" ); std::terminate(); #endif #endif } }; struct win32_file_mapper { explicit win32_file_mapper( const internal::filesystem::path& path ) : win32_file_mapper( file_opener( path ) ) {} explicit win32_file_mapper( const file_opener& reader ) : m_size( reader.size() ), m_handle( open( reader ) ) {} win32_file_mapper( const win32_file_mapper& ) = delete; win32_file_mapper( win32_file_mapper&& ) = delete; ~win32_file_mapper() { ::CloseHandle( m_handle ); } win32_file_mapper& operator=( const win32_file_mapper& ) = delete; win32_file_mapper& operator=( win32_file_mapper&& ) = delete; const size_t m_size; const HANDLE m_handle; private: [[nodiscard]] HANDLE open( const file_opener& reader ) const { const uint64_t file_size = reader.size(); SetLastError( 0 ); // Use `CreateFileMappingW` because a) we're not specifying a // mapping name, so the character type is of no consequence, and // b) it's defined in `memoryapi.h`, unlike // `CreateFileMappingA`(?!) const HANDLE handle = ::CreateFileMappingW( reader.m_handle, nullptr, PAGE_READONLY, DWORD( file_size >> 32 ), DWORD( file_size & 0xffffffff ), nullptr ); if( handle != NULL || file_size == 0 ) { 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 ); #else std::perror( "CreateFileMappingW() failed" ); std::terminate(); #endif } }; class file_mapper { public: explicit file_mapper( const internal::filesystem::path& path ) : file_mapper( win32_file_mapper( path ) ) {} explicit file_mapper( const win32_file_mapper& mapper ) : m_size( mapper.m_size ), m_data( static_cast< const char* >( ::MapViewOfFile( mapper.m_handle, FILE_MAP_READ, 0, 0, 0 ) ) ) { 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 ); #else std::perror( "MapViewOfFile() failed" ); std::terminate(); #endif } } file_mapper( const file_mapper& ) = delete; file_mapper( file_mapper&& ) = delete; ~file_mapper() { ::UnmapViewOfFile( LPCVOID( m_data ) ); } file_mapper& operator=( const file_mapper& ) = delete; file_mapper& operator=( file_mapper&& ) = delete; [[nodiscard]] bool empty() const noexcept { return m_size == 0; } [[nodiscard]] std::size_t size() const noexcept { return m_size; } using iterator = const char*; using const_iterator = const char*; [[nodiscard]] iterator data() const noexcept { return m_data; } [[nodiscard]] iterator begin() const noexcept { return m_data; } [[nodiscard]] iterator end() const noexcept { return m_data + m_size; } private: const std::size_t m_size; const char* const m_data; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/file_reader.hpp000066400000000000000000000105701426407250600235370ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_FILE_READER_HPP #define TAO_PEGTL_INTERNAL_FILE_READER_HPP #include #include #include #include #if !defined( __cpp_exceptions ) #include #endif #include "../config.hpp" #include "filesystem.hpp" namespace TAO_PEGTL_NAMESPACE::internal { [[nodiscard]] inline std::FILE* file_open( const internal::filesystem::path& path ) { errno = 0; #if defined( _MSC_VER ) std::FILE* file; if( ::_wfopen_s( &file, path.c_str(), L"rb" ) == 0 ) { return file; } #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::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 { return file; } #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "std::fopen() failed", path, ec ); #else std::perror( "std::fopen() failed" ); std::terminate(); #endif #endif } struct file_close { void operator()( FILE* f ) const noexcept { std::fclose( f ); } }; class file_reader { public: explicit file_reader( const internal::filesystem::path& path ) : file_reader( file_open( path ), path ) {} file_reader( FILE* file, const internal::filesystem::path& path ) // NOLINT(modernize-pass-by-value) : m_path( path ), m_file( file ) {} file_reader( const file_reader& ) = delete; file_reader( file_reader&& ) = delete; ~file_reader() = default; file_reader& operator=( const file_reader& ) = delete; file_reader& operator=( file_reader&& ) = delete; [[nodiscard]] std::size_t size() const { errno = 0; if( std::fseek( m_file.get(), 0, SEEK_END ) != 0 ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "std::fseek() failed [SEEK_END]", m_path, ec ); #else std::perror( "std::fseek() failed [SEEK_END]" ); std::terminate(); #endif // LCOV_EXCL_STOP } errno = 0; const auto s = std::ftell( m_file.get() ); if( s < 0 ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "std::ftell() failed", m_path, ec ); #else std::perror( "std::ftell() failed" ); std::terminate(); #endif // LCOV_EXCL_STOP } errno = 0; if( std::fseek( m_file.get(), 0, SEEK_SET ) != 0 ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "std::fseek() failed [SEEK_SET]", m_path, ec ); #else std::perror( "std::fseek() failed [SEEK_SET]" ); std::terminate(); #endif // LCOV_EXCL_STOP } return std::size_t( s ); } [[nodiscard]] std::string read() const { std::string nrv; nrv.resize( size() ); errno = 0; if( !nrv.empty() && ( std::fread( &nrv[ 0 ], nrv.size(), 1, m_file.get() ) != 1 ) ) { // LCOV_EXCL_START #if defined( __cpp_exceptions ) internal::error_code ec( errno, internal::system_category() ); throw internal::filesystem::filesystem_error( "std::fread() failed", m_path, ec ); #else std::perror( "std::fread() failed" ); std::terminate(); #endif // LCOV_EXCL_STOP } return nrv; } private: const internal::filesystem::path m_path; const std::unique_ptr< std::FILE, file_close > m_file; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/filesystem.hpp000066400000000000000000000025251426407250600234630ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #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 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 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 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 tao-pegtl-3.2.7/include/tao/pegtl/internal/has_apply.hpp000066400000000000000000000012661426407250600232600ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_HAS_APPLY_HPP #define TAO_PEGTL_INTERNAL_HAS_APPLY_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename, typename, template< typename... > class, typename... > inline constexpr bool has_apply = false; template< typename C, template< typename... > class Action, typename... S > inline constexpr bool has_apply< C, decltype( C::template apply< Action >( std::declval< S >()... ) ), Action, S... > = true; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/has_apply0.hpp000066400000000000000000000012731426407250600233360ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_HAS_APPLY0_HPP #define TAO_PEGTL_INTERNAL_HAS_APPLY0_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename, typename, template< typename... > class, typename... > inline constexpr bool has_apply0 = false; template< typename C, template< typename... > class Action, typename... S > inline constexpr bool has_apply0< C, decltype( C::template apply0< Action >( std::declval< S >()... ) ), Action, S... > = true; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/has_match.hpp000066400000000000000000000024241426407250600232240ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_HAS_MATCH_HPP #define TAO_PEGTL_INTERNAL_HAS_MATCH_HPP #include #include "../apply_mode.hpp" #include "../config.hpp" #include "../rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename, typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > inline constexpr bool has_match = false; template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > inline constexpr bool has_match< decltype( (void)Action< Rule >::template match< Rule, A, M, Action, Control >( std::declval< ParseInput& >(), std::declval< States&& >()... ), bool() ), Rule, A, M, Action, Control, ParseInput, States... > = true; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/has_unwind.hpp000066400000000000000000000011211426407250600234250ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_HAS_UNWIND_HPP #define TAO_PEGTL_INTERNAL_HAS_UNWIND_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename, typename... > inline constexpr bool has_unwind = false; template< typename C, typename... S > inline constexpr bool has_unwind< C, decltype( C::unwind( std::declval< S >()... ) ), S... > = true; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/identifier.hpp000066400000000000000000000012271426407250600234170ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_IDENTIFIER_HPP #define TAO_PEGTL_INTERNAL_IDENTIFIER_HPP #include "../config.hpp" #include "peek_char.hpp" #include "ranges.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { using identifier_first = ranges< peek_char, 'a', 'z', 'A', 'Z', '_' >; using identifier_other = ranges< peek_char, 'a', 'z', 'A', 'Z', '0', '9', '_' >; using identifier = seq< identifier_first, star< identifier_other > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/if_apply.hpp000066400000000000000000000033641426407250600231040ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_IF_APPLY_HPP #define TAO_PEGTL_INTERNAL_IF_APPLY_HPP #include "../config.hpp" #include "apply_single.hpp" #include "enable_control.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename... Actions > struct if_apply { using rule_t = if_apply; 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 ) { if constexpr( ( A == apply_mode::action ) && ( sizeof...( Actions ) != 0 ) ) { using action_t = typename ParseInput::action_t; auto m = in.template mark< rewind_mode::required >(); if( Control< Rule >::template match< apply_mode::action, rewind_mode::active, Action, Control >( in, st... ) ) { const action_t i2( m.iterator(), in ); return m( ( apply_single< Actions >::match( i2, st... ) && ... ) ); } return false; } else { return Control< Rule >::template match< A, M, Action, Control >( in, st... ); } } }; template< typename Rule, typename... Actions > inline constexpr bool enable_control< if_apply< Rule, Actions... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/if_must.hpp000066400000000000000000000030031426407250600227350ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_IF_MUST_HPP #define TAO_PEGTL_INTERNAL_IF_MUST_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/if_must.hpp" #else #include "../config.hpp" #include "enable_control.hpp" #include "must.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< bool Default, typename Cond, typename... Rules > struct if_must { using rule_t = if_must; using subs_t = type_list< Cond, must< Rules... > >; 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 ) { if( Control< Cond >::template match< A, M, Action, Control >( in, st... ) ) { (void)Control< must< Rules... > >::template match< A, M, Action, Control >( in, st... ); return true; } return Default; } }; template< bool Default, typename Cond, typename... Rules > inline constexpr bool enable_control< if_must< Default, Cond, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/if_must_else.hpp000066400000000000000000000012531426407250600237520ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_IF_MUST_ELSE_HPP #define TAO_PEGTL_INTERNAL_IF_MUST_ELSE_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/if_must_else.hpp" #else #include "../config.hpp" #include "if_then_else.hpp" #include "must.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Cond, typename Then, typename Else > using if_must_else = if_then_else< Cond, must< Then >, must< Else > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/if_then_else.hpp000066400000000000000000000031531426407250600237210ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_IF_THEN_ELSE_HPP #define TAO_PEGTL_INTERNAL_IF_THEN_ELSE_HPP #include "../config.hpp" #include "enable_control.hpp" #include "not_at.hpp" #include "seq.hpp" #include "sor.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Cond, typename Then, typename Else > struct if_then_else { using rule_t = if_then_else; using subs_t = type_list< Cond, Then, Else >; 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 mark< M >(); using m_t = decltype( m ); if( Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { return m( Control< Then >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ); } return m( Control< Else >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ); } }; template< typename Cond, typename Then, typename Else > inline constexpr bool enable_control< if_then_else< Cond, Then, Else > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/input_pair.hpp000066400000000000000000000011111426407250600234370ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_INPUT_PAIR_HPP #define TAO_PEGTL_INTERNAL_INPUT_PAIR_HPP #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Data > struct input_pair { Data data; std::uint8_t size; using data_t = Data; explicit operator bool() const noexcept { return size > 0; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/istream_reader.hpp000066400000000000000000000023241426407250600242620ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ISTREAM_READER_HPP #define TAO_PEGTL_INTERNAL_ISTREAM_READER_HPP #include #if defined( __cpp_exceptions ) #include #else #include #include #endif #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct istream_reader { explicit istream_reader( std::istream& s ) noexcept : m_istream( s ) {} [[nodiscard]] std::size_t operator()( char* buffer, const std::size_t length ) { m_istream.read( buffer, std::streamsize( length ) ); if( const auto r = m_istream.gcount() ) { return std::size_t( r ); } if( m_istream.eof() ) { return 0; } #if defined( __cpp_exceptions ) const auto ec = errno; throw std::system_error( ec, std::system_category(), "std::istream::read() failed" ); #else std::fputs( "std::istream::read() failed\n", stderr ); std::terminate(); #endif } std::istream& m_istream; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/istring.hpp000066400000000000000000000041431426407250600227540ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ISTRING_HPP #define TAO_PEGTL_INTERNAL_ISTRING_HPP #include #include "../config.hpp" #include "bump_help.hpp" #include "enable_control.hpp" #include "one.hpp" #include "result_on_found.hpp" #include "success.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< char C > inline constexpr bool is_alpha = ( ( 'a' <= C ) && ( C <= 'z' ) ) || ( ( 'A' <= C ) && ( C <= 'Z' ) ); template< char C > [[nodiscard]] constexpr bool ichar_equal( const char c ) noexcept { if constexpr( is_alpha< C > ) { return ( C | 0x20 ) == ( c | 0x20 ); } else { return c == C; } } template< char... Cs > [[nodiscard]] constexpr bool istring_equal( const char* r ) noexcept { return ( ichar_equal< Cs >( *r++ ) && ... ); } template< char... Cs > struct istring; template<> struct istring<> : success {}; // template< char C > // struct istring< C > // : std::conditional_t< is_alpha< C >, one< result_on_found::success, peek_char, C | 0x20, C & ~0x20 >, one< result_on_found::success, peek_char, C > > // {}; template< char... Cs > struct istring { using rule_t = istring; using subs_t = empty_list; template< int Eol > static constexpr bool can_match_eol = one< result_on_found::success, peek_char, Cs... >::template can_match_eol< Eol >; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.size( 0 ) ) ) { if( in.size( sizeof...( Cs ) ) >= sizeof...( Cs ) ) { if( istring_equal< Cs... >( in.current() ) ) { bump_help< istring >( in, sizeof...( Cs ) ); return true; } } return false; } }; template< char... Cs > inline constexpr bool enable_control< istring< Cs... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/iterator.hpp000066400000000000000000000022671426407250600231330ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ITERATOR_HPP #define TAO_PEGTL_INTERNAL_ITERATOR_HPP #include #include #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct iterator { iterator() = default; explicit iterator( const char* in_data ) noexcept : data( in_data ) {} iterator( 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 ), column( in_column ) { assert( in_line != 0 ); assert( in_column != 0 ); } iterator( const iterator& ) = default; iterator( iterator&& ) = default; ~iterator() = default; iterator& operator=( const iterator& ) = default; iterator& operator=( iterator&& ) = default; const char* data = nullptr; std::size_t byte = 0; std::size_t line = 1; std::size_t column = 1; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/lf_crlf_eol.hpp000066400000000000000000000020141426407250600235360ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LF_CRLF_EOL_HPP #define TAO_PEGTL_INTERNAL_LF_CRLF_EOL_HPP #include "../config.hpp" #include "../eol_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct lf_crlf_eol { static constexpr int ch = '\n'; template< typename ParseInput > [[nodiscard]] static eol_pair match( ParseInput& in ) noexcept( noexcept( in.size( 2 ) ) ) { eol_pair p = { false, in.size( 2 ) }; if( p.second ) { const auto a = in.peek_char(); if( a == '\n' ) { in.bump_to_next_line(); p.first = true; } else if( ( a == '\r' ) && ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) { in.bump_to_next_line( 2 ); p.first = true; } } return p; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/lf_eol.hpp000066400000000000000000000014541426407250600225370ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LF_EOL_HPP #define TAO_PEGTL_INTERNAL_LF_EOL_HPP #include "../config.hpp" #include "../eol_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct lf_eol { static constexpr int ch = '\n'; template< typename ParseInput > [[nodiscard]] static eol_pair match( ParseInput& in ) noexcept( noexcept( in.size( 1 ) ) ) { eol_pair p = { false, in.size( 1 ) }; if( p.second ) { if( in.peek_char() == '\n' ) { in.bump_to_next_line(); p.first = true; } } return p; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/list.hpp000066400000000000000000000007201426407250600222450ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LIST_HPP #define TAO_PEGTL_INTERNAL_LIST_HPP #include "../config.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Sep > using list = seq< Rule, star< Sep, Rule > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/list_must.hpp000066400000000000000000000011631426407250600233170ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LIST_MUST_HPP #define TAO_PEGTL_INTERNAL_LIST_MUST_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/list_must.hpp" #else #include "../config.hpp" #include "must.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Sep > using list_must = seq< Rule, star< Sep, must< Rule > > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/list_tail.hpp000066400000000000000000000010331426407250600232540ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LIST_TAIL_HPP #define TAO_PEGTL_INTERNAL_LIST_TAIL_HPP #include "../config.hpp" #include "opt.hpp" #include "seq.hpp" #include "star.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Sep > using list_tail = seq< Rule, star< Sep, Rule >, opt< Sep > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/list_tail_pad.hpp000066400000000000000000000011301426407250600240760ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_LIST_TAIL_PAD_HPP #define TAO_PEGTL_INTERNAL_LIST_TAIL_PAD_HPP #include "../config.hpp" #include "list.hpp" #include "opt.hpp" #include "pad.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Sep, typename Pad > using list_tail_pad = seq< Rule, star< pad< Sep, Pad >, Rule >, opt< star< Pad >, Sep > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/marker.hpp000066400000000000000000000035171426407250600225620ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_MARKER_HPP #define TAO_PEGTL_INTERNAL_MARKER_HPP #include "../config.hpp" #include "../rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Iterator, rewind_mode M > class [[nodiscard]] marker { public: static constexpr rewind_mode next_rewind_mode = M; explicit marker( const Iterator& /*unused*/ ) noexcept {} marker( const marker& ) = delete; marker( marker&& ) = delete; ~marker() = default; marker& operator=( const marker& ) = delete; marker& operator=( marker&& ) = delete; [[nodiscard]] bool operator()( const bool result ) const noexcept { return result; } }; template< typename Iterator > class [[nodiscard]] marker< Iterator, rewind_mode::required > { public: static constexpr rewind_mode next_rewind_mode = rewind_mode::active; explicit marker( Iterator& i ) noexcept : m_saved( i ), m_input( &i ) {} marker( const marker& ) = delete; marker( marker&& ) = delete; ~marker() { if( m_input != nullptr ) { ( *m_input ) = m_saved; } } marker& operator=( const marker& ) = delete; marker& operator=( marker&& ) = delete; [[nodiscard]] bool operator()( const bool result ) noexcept { if( result ) { m_input = nullptr; return true; } return false; } [[nodiscard]] const Iterator& iterator() const noexcept { return m_saved; } private: const Iterator m_saved; Iterator* m_input; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/minus.hpp000066400000000000000000000007721426407250600224340ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_MINUS_HPP #define TAO_PEGTL_INTERNAL_MINUS_HPP #include "../config.hpp" #include "eof.hpp" #include "not_at.hpp" #include "rematch.hpp" #include "seq.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename M, typename S > using minus = rematch< M, not_at< S, eof > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/missing_apply.hpp000066400000000000000000000016361426407250600241570ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_MISSING_APPLY_HPP #define TAO_PEGTL_INTERNAL_MISSING_APPLY_HPP #include "../config.hpp" #include "../rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Control, template< typename... > class Action, typename ParseInput, typename... States > void missing_apply( ParseInput& in, States&&... st ) { // 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 mark< rewind_mode::required >(); (void)Control::template apply< Action >( m.iterator(), in, st... ); // LCOV_EXCL_STOP } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/missing_apply0.hpp000066400000000000000000000014721426407250600242350ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_MISSING_APPLY0_HPP #define TAO_PEGTL_INTERNAL_MISSING_APPLY0_HPP #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Control, template< typename... > class Action, typename ParseInput, typename... States > void missing_apply0( ParseInput& in, States&&... st ) { // 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 (void)Control::template apply0< Action >( in, st... ); // LCOV_EXCL_STOP } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/must.hpp000066400000000000000000000035271426407250600222720ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_MUST_HPP #define TAO_PEGTL_INTERNAL_MUST_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/must.hpp" #else #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { // The general case applies must<> to each of the // rules in the 'Rules' parameter pack individually. template< typename... Rules > struct must : seq< must< Rules >... > {}; template<> struct must<> : success {}; // While in theory the implementation for a single rule could // be simplified to must< Rule > = sor< Rule, raise< Rule > >, this // would result in some unnecessary run-time overhead. template< typename Rule > struct must< Rule > { using rule_t = must; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { if( !Control< Rule >::template match< A, rewind_mode::dontcare, Action, Control >( in, st... ) ) { Control< Rule >::raise( static_cast< const ParseInput& >( in ), st... ); } return true; } }; template< typename... Rules > inline constexpr bool enable_control< must< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/not_at.hpp000066400000000000000000000026401426407250600225610ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_NOT_AT_HPP #define TAO_PEGTL_INTERNAL_NOT_AT_HPP #include "../config.hpp" #include "enable_control.hpp" #include "failure.hpp" #include "seq.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct not_at : not_at< seq< Rules... > > {}; template<> struct not_at<> : failure {}; template< typename Rule > struct not_at< Rule > { using rule_t = not_at; using subs_t = type_list< Rule >; template< apply_mode, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { const auto m = in.template mark< rewind_mode::required >(); return !Control< Rule >::template match< apply_mode::nothing, rewind_mode::active, Action, Control >( in, st... ); } }; template< typename... Rules > inline constexpr bool enable_control< not_at< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/one.hpp000066400000000000000000000032271426407250600220600ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_ONE_HPP #define TAO_PEGTL_INTERNAL_ONE_HPP #include #include "../config.hpp" #include "any.hpp" #include "bump_help.hpp" #include "enable_control.hpp" #include "failure.hpp" #include "result_on_found.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< result_on_found R, typename Peek, typename Peek::data_t... Cs > struct one { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = one; using subs_t = empty_list; [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return ( ( c == Cs ) || ... ) == bool( R ); } template< int Eol > static constexpr bool can_match_eol = test( Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { bump_help< one >( in, t.size ); return true; } } return false; } }; template< typename Peek > struct one< result_on_found::success, Peek > : failure {}; template< typename Peek > struct one< result_on_found::failure, Peek > : any< Peek > {}; template< result_on_found R, typename Peek, typename Peek::data_t... Cs > inline constexpr bool enable_control< one< R, Peek, Cs... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/opt.hpp000066400000000000000000000025411426407250600220770ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_OPT_HPP #define TAO_PEGTL_INTERNAL_OPT_HPP #include #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct opt : opt< seq< Rules... > > {}; template<> struct opt<> : success {}; template< typename Rule > struct opt< Rule > { using rule_t = opt; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { (void)Control< Rule >::template match< A, rewind_mode::required, Action, Control >( in, st... ); return true; } }; template< typename... Rules > inline constexpr bool enable_control< opt< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/pad.hpp000066400000000000000000000007551426407250600220460ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PAD_HPP #define TAO_PEGTL_INTERNAL_PAD_HPP #include "../config.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Pad1, typename Pad2 = Pad1 > using pad = seq< star< Pad1 >, Rule, star< Pad2 > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/pad_opt.hpp000066400000000000000000000007721426407250600227270ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PAD_OPT_HPP #define TAO_PEGTL_INTERNAL_PAD_OPT_HPP #include "../config.hpp" #include "opt.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename Pad > using pad_opt = seq< star< Pad >, opt< Rule, star< Pad > > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/path_to_string.hpp000066400000000000000000000013631426407250600243220ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PATH_TO_STRING_HPP #define TAO_PEGTL_INTERNAL_PATH_TO_STRING_HPP #include #include "../config.hpp" #include "filesystem.hpp" namespace TAO_PEGTL_NAMESPACE::internal { [[nodiscard]] inline std::string path_to_string( const internal::filesystem::path& path ) { #if defined( TAO_PEGTL_BOOST_FILESYSTEM ) return path.string(); #elif defined( __cpp_char8_t ) const auto s = path.u8string(); return { reinterpret_cast< const char* >( s.data() ), s.size() }; #else return path.u8string(); #endif } } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/peek_char.hpp000066400000000000000000000013471426407250600232210ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PEEK_CHAR_HPP #define TAO_PEGTL_INTERNAL_PEEK_CHAR_HPP #include #include "../config.hpp" #include "input_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct peek_char { using data_t = char; using pair_t = input_pair< char >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( in.empty() ) { return { 0, 0 }; } return { in.peek_char(), 1 }; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/peek_utf8.hpp000066400000000000000000000054071426407250600231730ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PEEK_UTF8_HPP #define TAO_PEGTL_INTERNAL_PEEK_UTF8_HPP #include "../config.hpp" #include "input_pair.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct peek_utf8 { using data_t = char32_t; using pair_t = input_pair< char32_t >; template< typename ParseInput > [[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) ) { if( in.empty() ) { return { 0, 0 }; } const char32_t c0 = in.peek_uint8(); if( ( c0 & 0x80 ) == 0 ) { return { c0, 1 }; } return peek_impl( in, c0 ); } private: template< typename ParseInput > [[nodiscard]] static pair_t peek_impl( ParseInput& in, char32_t c0 ) noexcept( noexcept( in.size( 4 ) ) ) { if( ( c0 & 0xE0 ) == 0xC0 ) { if( in.size( 2 ) >= 2 ) { const char32_t c1 = in.peek_uint8( 1 ); if( ( c1 & 0xC0 ) == 0x80 ) { c0 &= 0x1F; c0 <<= 6; c0 |= ( c1 & 0x3F ); if( c0 >= 0x80 ) { return { c0, 2 }; } } } } else if( ( c0 & 0xF0 ) == 0xE0 ) { if( in.size( 3 ) >= 3 ) { const char32_t c1 = in.peek_uint8( 1 ); const char32_t c2 = in.peek_uint8( 2 ); if( ( ( c1 & 0xC0 ) == 0x80 ) && ( ( c2 & 0xC0 ) == 0x80 ) ) { c0 &= 0x0F; c0 <<= 6; c0 |= ( c1 & 0x3F ); c0 <<= 6; c0 |= ( c2 & 0x3F ); if( c0 >= 0x800 && !( c0 >= 0xD800 && c0 <= 0xDFFF ) ) { return { c0, 3 }; } } } } else if( ( c0 & 0xF8 ) == 0xF0 ) { if( in.size( 4 ) >= 4 ) { const char32_t c1 = in.peek_uint8( 1 ); const char32_t c2 = in.peek_uint8( 2 ); const char32_t c3 = in.peek_uint8( 3 ); if( ( ( c1 & 0xC0 ) == 0x80 ) && ( ( c2 & 0xC0 ) == 0x80 ) && ( ( c3 & 0xC0 ) == 0x80 ) ) { c0 &= 0x07; c0 <<= 6; c0 |= ( c1 & 0x3F ); c0 <<= 6; c0 |= ( c2 & 0x3F ); c0 <<= 6; c0 |= ( c3 & 0x3F ); if( c0 >= 0x10000 && c0 <= 0x10FFFF ) { return { c0, 4 }; } } } } return { 0, 0 }; } }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/pegtl_string.hpp000066400000000000000000000071761426407250600240070ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PEGTL_STRING_HPP #define TAO_PEGTL_INTERNAL_PEGTL_STRING_HPP #include #include #include "../ascii.hpp" #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { // Inspired by https://github.com/irrequietus/typestring // Rewritten and reduced to what is needed for the PEGTL // and to work with Visual Studio 2015. template< typename, typename, typename, typename, typename, typename, typename, typename > struct string_join; template< template< char... > class S, char... C0s, char... C1s, char... C2s, char... C3s, char... C4s, char... C5s, char... C6s, char... C7s > struct string_join< S< C0s... >, S< C1s... >, S< C2s... >, S< C3s... >, S< C4s... >, S< C5s... >, S< C6s... >, S< C7s... > > { using type = S< C0s..., C1s..., C2s..., C3s..., C4s..., C5s..., C6s..., C7s... >; }; template< template< char... > class S, char, bool > struct string_at { using type = S<>; }; template< template< char... > class S, char C > struct string_at< S, C, true > { using type = S< C >; }; template< typename T, std::size_t S > struct string_max_length { static_assert( S <= 512, "String longer than 512 (excluding terminating \\0)!" ); using type = T; }; } // namespace TAO_PEGTL_NAMESPACE::internal #define TAO_PEGTL_INTERNAL_EMPTY() #define TAO_PEGTL_INTERNAL_DEFER( X ) X TAO_PEGTL_INTERNAL_EMPTY() #define TAO_PEGTL_INTERNAL_EXPAND( ... ) __VA_ARGS__ #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 ) \ 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 ), \ TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##3 ), \ TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##4 ), \ TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##5 ), \ TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##6 ), \ TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##7 ) >::type #define TAO_PEGTL_INTERNAL_STRING_8( S, x, n ) \ TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_AT, S, x, n ) #define TAO_PEGTL_INTERNAL_STRING_64( S, x, n ) \ TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_8, S, x, n ) #define TAO_PEGTL_INTERNAL_STRING_512( S, x, n ) \ TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_64, S, x, n ) #define TAO_PEGTL_INTERNAL_STRING( S, x ) \ TAO_PEGTL_INTERNAL_EXPAND( \ TAO_PEGTL_INTERNAL_EXPAND( \ TAO_PEGTL_INTERNAL_EXPAND( \ TAO_PEGTL_NAMESPACE::internal::string_max_length< TAO_PEGTL_INTERNAL_STRING_512( S, x, ), sizeof( x ) - 1 >::type ) ) ) #define TAO_PEGTL_STRING( x ) \ TAO_PEGTL_INTERNAL_STRING( TAO_PEGTL_NAMESPACE::ascii::string, x ) #define TAO_PEGTL_ISTRING( x ) \ TAO_PEGTL_INTERNAL_STRING( TAO_PEGTL_NAMESPACE::ascii::istring, x ) #define TAO_PEGTL_KEYWORD( x ) \ TAO_PEGTL_INTERNAL_STRING( TAO_PEGTL_NAMESPACE::ascii::keyword, x ) #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/plus.hpp000066400000000000000000000032501426407250600222560ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_PLUS_HPP #define TAO_PEGTL_INTERNAL_PLUS_HPP #include #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { // While plus<> could easily be implemented with // seq< Rule, Rules ..., star< Rule, Rules ... > > we // provide an explicit implementation to optimise away // the otherwise created input mark. template< typename Rule, typename... Rules > struct plus : plus< seq< Rule, Rules... > > {}; template< typename Rule > struct plus< Rule > { using rule_t = plus; 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 ) { if( Control< Rule >::template match< A, M, Action, Control >( in, st... ) ) { while( Control< Rule >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { } return true; } return false; } }; template< typename Rule, typename... Rules > inline constexpr bool enable_control< plus< Rule, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/raise.hpp000066400000000000000000000023231426407250600223760ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_RAISE_HPP #define TAO_PEGTL_INTERNAL_RAISE_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/raise.hpp" #else #include #include "../config.hpp" #include "enable_control.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename T > struct raise { using rule_t = raise; using subs_t = empty_list; template< apply_mode, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[noreturn]] static bool match( ParseInput& in, States&&... st ) { Control< T >::raise( static_cast< const ParseInput& >( in ), st... ); } }; template< typename T > inline constexpr bool enable_control< raise< T > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/range.hpp000066400000000000000000000032371426407250600223740ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_RANGE_HPP #define TAO_PEGTL_INTERNAL_RANGE_HPP #include "../config.hpp" #include "bump_help.hpp" #include "enable_control.hpp" #include "one.hpp" #include "result_on_found.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > struct range { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = range; using subs_t = empty_list; static_assert( Lo < Hi, "invalid range" ); [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return ( ( Lo <= c ) && ( c <= Hi ) ) == bool( R ); } template< int Eol > static constexpr bool can_match_eol = test( Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { bump_help< range >( in, t.size ); return true; } } return false; } }; template< result_on_found R, typename Peek, typename Peek::data_t C > struct range< R, Peek, C, C > : one< R, Peek, C > {}; template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > inline constexpr bool enable_control< range< R, Peek, Lo, Hi > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/ranges.hpp000066400000000000000000000050511426407250600225530ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_RANGES_HPP #define TAO_PEGTL_INTERNAL_RANGES_HPP #include "../config.hpp" #include #include "bump_help.hpp" #include "enable_control.hpp" #include "failure.hpp" #include "one.hpp" #include "range.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Char, Char Lo, Char Hi > constexpr bool validate_range( Char c ) noexcept { static_assert( Lo <= Hi, "invalid range" ); return ( Lo <= c ) && ( c <= Hi ); } template< typename Peek, typename Peek::data_t... Cs > struct ranges { using peek_t = Peek; using data_t = typename Peek::data_t; using rule_t = ranges; using subs_t = empty_list; template< std::size_t... Is > [[nodiscard]] static constexpr bool test( std::index_sequence< Is... > /*unused*/, const data_t c ) noexcept { constexpr const data_t cs[] = { Cs... }; if constexpr( sizeof...( Cs ) % 2 == 0 ) { return ( validate_range< data_t, cs[ 2 * Is ], cs[ 2 * Is + 1 ] >( c ) || ... ); } else { return ( validate_range< data_t, cs[ 2 * Is ], cs[ 2 * Is + 1 ] >( c ) || ... ) || ( c == cs[ sizeof...( Cs ) - 1 ] ); } } [[nodiscard]] static constexpr bool test( const data_t c ) noexcept { return test( std::make_index_sequence< sizeof...( Cs ) / 2 >(), c ); } template< int Eol > static constexpr bool can_match_eol = test( Eol ); template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) ) { if( const auto t = Peek::peek( in ) ) { if( test( t.data ) ) { bump_help< ranges >( in, t.size ); return true; } } return false; } }; template< typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > struct ranges< Peek, Lo, Hi > : range< result_on_found::success, Peek, Lo, Hi > {}; template< typename Peek, typename Peek::data_t C > struct ranges< Peek, C > : one< result_on_found::success, Peek, C > {}; template< typename Peek > struct ranges< Peek > : failure {}; template< typename Peek, typename Peek::data_t... Cs > inline constexpr bool enable_control< ranges< Peek, Cs... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rematch.hpp000066400000000000000000000046101426407250600227170ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REMATCH_HPP #define TAO_PEGTL_INTERNAL_REMATCH_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../apply_mode.hpp" #include "../memory_input.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Head, typename... Rules > struct rematch; template< typename Head > struct rematch< Head > { using rule_t = rematch; using subs_t = type_list< Head >; 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 ) { return Control< Head >::template match< A, M, Action, Control >( in, st... ); } }; template< typename Head, typename Rule, typename... Rules > struct rematch< Head, Rule, Rules... > { using rule_t = rematch; using subs_t = type_list< Head, Rule, Rules... >; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { auto m = in.template mark< 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.iterator(), 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... ) ) ) ); } return false; } }; template< typename Head, typename... Rules > inline constexpr bool enable_control< rematch< Head, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rep.hpp000066400000000000000000000032451426407250600220650ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REP_HPP #define TAO_PEGTL_INTERNAL_REP_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Cnt, typename... Rules > struct rep : rep< Cnt, seq< Rules... > > {}; template< unsigned Cnt > struct rep< Cnt > : success {}; template< typename Rule > struct rep< 0, Rule > : success {}; template< unsigned Cnt, typename Rule > struct rep< Cnt, Rule > { using rule_t = rep; 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 mark< M >(); using m_t = decltype( m ); for( unsigned i = 0; i != Cnt; ++i ) { if( !Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { return false; } } return m( true ); } }; template< unsigned Cnt, typename... Rules > inline constexpr bool enable_control< rep< Cnt, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rep_min.hpp000066400000000000000000000010321426407250600227200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REP_MIN_HPP #define TAO_PEGTL_INTERNAL_REP_MIN_HPP #include "../config.hpp" #include "rep.hpp" #include "seq.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Min, typename Rule, typename... Rules > using rep_min = seq< rep< Min, Rule, Rules... >, star< Rule, Rules... > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rep_min_max.hpp000066400000000000000000000045101426407250600235710ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REP_MIN_MAX_HPP #define TAO_PEGTL_INTERNAL_REP_MIN_MAX_HPP #include #include "../config.hpp" #include "enable_control.hpp" #include "failure.hpp" #include "not_at.hpp" #include "seq.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Min, unsigned Max, typename... Rules > struct rep_min_max : rep_min_max< Min, Max, seq< Rules... > > { static_assert( Min <= Max ); }; template< unsigned Min, unsigned Max > struct rep_min_max< Min, Max > : failure { static_assert( Min <= Max ); }; template< typename Rule > struct rep_min_max< 0, 0, Rule > : not_at< Rule > {}; template< unsigned Min, unsigned Max, typename Rule > struct rep_min_max< Min, Max, Rule > { using rule_t = rep_min_max; using subs_t = type_list< Rule >; static_assert( Min <= Max ); 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 mark< M >(); using m_t = decltype( m ); for( unsigned i = 0; i != Min; ++i ) { if( !Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { return false; } } for( unsigned i = Min; i != Max; ++i ) { if( !Control< Rule >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { return m( true ); } } return m( Control< not_at< Rule > >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ); // NOTE that not_at<> will always rewind. } }; template< unsigned Min, unsigned Max, typename... Rules > inline constexpr bool enable_control< rep_min_max< Min, Max, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rep_opt.hpp000066400000000000000000000031011426407250600227360ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REP_OPT_HPP #define TAO_PEGTL_INTERNAL_REP_OPT_HPP #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Max, typename... Rules > struct rep_opt : rep_opt< Max, seq< Rules... > > {}; template< unsigned Max > struct rep_opt< Max > : success {}; template< typename... Rules > struct rep_opt< 0, Rules... > : success {}; template< unsigned Max, typename Rule > struct rep_opt< Max, Rule > { using rule_t = rep_opt; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { for( unsigned i = 0; ( i != Max ) && Control< Rule >::template match< A, rewind_mode::required, Action, Control >( in, st... ); ++i ) { } return true; } }; template< unsigned Max, typename... Rules > inline constexpr bool enable_control< rep_opt< Max, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/require.hpp000066400000000000000000000016701426407250600227530ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_REQUIRE_HPP #define TAO_PEGTL_INTERNAL_REQUIRE_HPP #include "../config.hpp" #include "enable_control.hpp" #include "success.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< unsigned Amount > struct require; template<> struct require< 0 > : success {}; template< unsigned Amount > struct require { using rule_t = require; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.size( 0 ) ) ) { return in.size( Amount ) >= Amount; } }; template< unsigned Amount > inline constexpr bool enable_control< require< Amount > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/result_on_found.hpp000066400000000000000000000006771426407250600245120ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_RESULT_ON_FOUND_HPP #define TAO_PEGTL_INTERNAL_RESULT_ON_FOUND_HPP #include "../config.hpp" namespace TAO_PEGTL_NAMESPACE::internal { enum class result_on_found : bool { success = true, failure = false }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/rules.hpp000066400000000000000000000026371426407250600224350ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_RULES_HPP #define TAO_PEGTL_INTERNAL_RULES_HPP #include "action.hpp" #include "any.hpp" #include "apply.hpp" #include "apply0.hpp" #include "at.hpp" #include "bof.hpp" #include "bol.hpp" #include "bytes.hpp" #include "control.hpp" #include "disable.hpp" #include "discard.hpp" #include "enable.hpp" #include "enable_control.hpp" #include "eof.hpp" #include "eol.hpp" #include "eolf.hpp" #include "failure.hpp" #include "identifier.hpp" #include "if_apply.hpp" #include "if_then_else.hpp" #include "istring.hpp" #include "list.hpp" #include "list_tail.hpp" #include "list_tail_pad.hpp" #include "minus.hpp" #include "not_at.hpp" #include "one.hpp" #include "opt.hpp" #include "pad.hpp" #include "pad_opt.hpp" #include "plus.hpp" #include "range.hpp" #include "ranges.hpp" #include "rematch.hpp" #include "rep.hpp" #include "rep_min.hpp" #include "rep_min_max.hpp" #include "rep_opt.hpp" #include "require.hpp" #include "seq.hpp" #include "sor.hpp" #include "star.hpp" #include "state.hpp" #include "string.hpp" #include "success.hpp" #include "until.hpp" #if defined( __cpp_exceptions ) #include "if_must.hpp" #include "if_must_else.hpp" #include "list_must.hpp" #include "must.hpp" #include "raise.hpp" #include "star_must.hpp" #include "try_catch_type.hpp" #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/seq.hpp000066400000000000000000000030361426407250600220650ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_SEQ_HPP #define TAO_PEGTL_INTERNAL_SEQ_HPP #include "../config.hpp" #include "enable_control.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct seq; template<> struct seq<> : success {}; template< typename... Rules > struct seq { using rule_t = seq; using subs_t = type_list< Rules... >; 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 ) { if constexpr( sizeof...( Rules ) == 1 ) { return Control< Rules... >::template match< A, M, Action, Control >( in, st... ); } else { auto m = in.template mark< M >(); using m_t = decltype( m ); return m( ( Control< Rules >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) && ... ) ); } } }; template< typename... Rules > inline constexpr bool enable_control< seq< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/sor.hpp000066400000000000000000000035711426407250600221040ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_SOR_HPP #define TAO_PEGTL_INTERNAL_SOR_HPP #include #include "../config.hpp" #include "enable_control.hpp" #include "failure.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename... Rules > struct sor; template<> struct sor<> : failure {}; template< typename... Rules > struct sor { using rule_t = sor; using subs_t = type_list< Rules... >; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, std::size_t... Indices, typename ParseInput, typename... States > [[nodiscard]] static bool match( std::index_sequence< Indices... > /*unused*/, ParseInput& in, States&&... st ) { return ( Control< Rules >::template match< A, ( ( Indices == ( sizeof...( Rules ) - 1 ) ) ? M : rewind_mode::required ), Action, Control >( in, st... ) || ... ); } 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 ) { return match< A, M, Action, Control >( std::index_sequence_for< Rules... >(), in, st... ); } }; template< typename... Rules > inline constexpr bool enable_control< sor< Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/star.hpp000066400000000000000000000025241426407250600222470ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_STAR_HPP #define TAO_PEGTL_INTERNAL_STAR_HPP #include #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Rule, typename... Rules > struct star : star< seq< Rule, Rules... > > {}; template< typename Rule > struct star< Rule > { using rule_t = star; using subs_t = type_list< Rule >; template< apply_mode A, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static bool match( ParseInput& in, States&&... st ) { while( Control< Rule >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { } return true; } }; template< typename Rule, typename... Rules > inline constexpr bool enable_control< star< Rule, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/star_must.hpp000066400000000000000000000011521426407250600233130ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_STAR_MUST_HPP #define TAO_PEGTL_INTERNAL_STAR_MUST_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/star_must.hpp" #else #include "../config.hpp" #include "if_must.hpp" #include "star.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Cond, typename... Rules > using star_must = star< if_must< false, Cond, Rules... > >; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/state.hpp000066400000000000000000000043621426407250600224200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_STATE_HPP #define TAO_PEGTL_INTERNAL_STATE_HPP #include "../config.hpp" #include #include "dependent_false.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename NewState, typename... Rules > struct state : state< NewState, seq< Rules... > > {}; template< typename NewState > struct state< NewState > : success {}; template< typename NewState, typename Rule > struct state< NewState, Rule > { using rule_t = state; 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 ) { if constexpr( std::is_constructible_v< NewState, const ParseInput&, States... > ) { NewState s( static_cast< const ParseInput& >( in ), st... ); if( Control< Rule >::template match< A, M, Action, Control >( in, s ) ) { s.success( static_cast< const ParseInput& >( in ), st... ); return true; } return false; } else if constexpr( std::is_default_constructible_v< NewState > ) { NewState s; if( Control< Rule >::template match< A, M, Action, Control >( in, s ) ) { s.success( static_cast< const ParseInput& >( in ), st... ); return true; } return false; } else { static_assert( internal::dependent_false< NewState >, "unable to instantiate new state" ); } } }; template< typename NewState, typename... Rules > inline constexpr bool enable_control< state< NewState, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/string.hpp000066400000000000000000000031761426407250600226100ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_STRING_HPP #define TAO_PEGTL_INTERNAL_STRING_HPP #include #include #include "../config.hpp" #include "bump_help.hpp" #include "enable_control.hpp" #include "one.hpp" #include "result_on_found.hpp" #include "success.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { [[nodiscard]] inline bool unsafe_equals( const char* s, const std::initializer_list< char >& l ) noexcept { return std::memcmp( s, &*l.begin(), l.size() ) == 0; } template< char... Cs > struct string; template<> struct string<> : success {}; // template< char C > // struct string // : one< C > // {}; template< char... Cs > struct string { using rule_t = string; using subs_t = empty_list; template< int Eol > static constexpr bool can_match_eol = one< result_on_found::success, peek_char, Cs... >::template can_match_eol< Eol >; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.size( 0 ) ) ) { if( in.size( sizeof...( Cs ) ) >= sizeof...( Cs ) ) { if( unsafe_equals( in.current(), { Cs... } ) ) { bump_help< string >( in, sizeof...( Cs ) ); return true; } } return false; } }; template< char... Cs > inline constexpr bool enable_control< string< Cs... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/success.hpp000066400000000000000000000013141426407250600227420ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_SUCCESS_HPP #define TAO_PEGTL_INTERNAL_SUCCESS_HPP #include "../config.hpp" #include "enable_control.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { struct success { using rule_t = success; using subs_t = empty_list; template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& /*unused*/ ) noexcept { return true; } }; template<> inline constexpr bool enable_control< success > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/try_catch_type.hpp000066400000000000000000000035331426407250600243200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_TRY_CATCH_TYPE_HPP #define TAO_PEGTL_INTERNAL_TRY_CATCH_TYPE_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/try_catch_type.hpp" #else #include #include "../config.hpp" #include "enable_control.hpp" #include "seq.hpp" #include "success.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Exception, typename... Rules > struct try_catch_type : try_catch_type< Exception, seq< Rules... > > {}; template< typename Exception > struct try_catch_type< Exception > : success {}; template< typename Exception, typename Rule > struct try_catch_type< Exception, Rule > { using rule_t = try_catch_type; 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 mark< M >(); 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& ) { return false; } } }; template< typename Exception, typename... Rules > inline constexpr bool enable_control< try_catch_type< Exception, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/until.hpp000066400000000000000000000046661426407250600224420ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_UNTIL_HPP #define TAO_PEGTL_INTERNAL_UNTIL_HPP #include "../config.hpp" #include "bytes.hpp" #include "enable_control.hpp" #include "eof.hpp" #include "not_at.hpp" #include "seq.hpp" #include "star.hpp" #include "../apply_mode.hpp" #include "../rewind_mode.hpp" #include "../type_list.hpp" namespace TAO_PEGTL_NAMESPACE::internal { template< typename Cond, typename... Rules > struct until : until< Cond, seq< Rules... > > {}; template< typename Cond > struct until< Cond > { using rule_t = until; using subs_t = type_list< Cond >; 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 mark< M >(); while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { if( in.empty() ) { return false; } in.bump(); } return m( true ); } }; template< typename Cond, typename Rule > struct until< Cond, Rule > { using rule_t = until; using subs_t = type_list< Cond, 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 mark< M >(); using m_t = decltype( m ); while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, st... ) ) { if( !Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { return false; } } return m( true ); } }; template< typename Cond, typename... Rules > inline constexpr bool enable_control< until< Cond, Rules... > > = false; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/internal/unwind_guard.hpp000066400000000000000000000016551426407250600237700ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_INTERNAL_UNWIND_GUARD_HPP #define TAO_PEGTL_INTERNAL_UNWIND_GUARD_HPP #include "../config.hpp" #include #include namespace TAO_PEGTL_NAMESPACE::internal { template< typename Unwind > struct unwind_guard { explicit unwind_guard( Unwind&& unwind_impl ) : unwind( std::move( unwind_impl ) ) {} ~unwind_guard() { if( unwind ) { ( *unwind )(); } } unwind_guard( const unwind_guard& ) = delete; unwind_guard( unwind_guard&& ) noexcept = delete; unwind_guard& operator=( const unwind_guard& ) = delete; unwind_guard& operator=( unwind_guard&& ) noexcept = delete; std::optional< Unwind > unwind; }; } // namespace TAO_PEGTL_NAMESPACE::internal #endif tao-pegtl-3.2.7/include/tao/pegtl/istream_input.hpp000066400000000000000000000016501426407250600223440ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_ISTREAM_INPUT_HPP #define TAO_PEGTL_ISTREAM_INPUT_HPP #include #include "buffer_input.hpp" #include "config.hpp" #include "eol.hpp" #include "internal/istream_reader.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Eol = eol::lf_crlf, std::size_t Chunk = 64 > struct istream_input : buffer_input< internal::istream_reader, Eol, std::string, Chunk > { template< typename T > istream_input( std::istream& in_stream, const std::size_t in_maximum, T&& in_source ) : buffer_input< internal::istream_reader, Eol, std::string, Chunk >( std::forward< T >( in_source ), in_maximum, in_stream ) {} }; template< typename... Ts > istream_input( Ts&&... ) -> istream_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/match.hpp000066400000000000000000000154221426407250600205570ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_MATCH_HPP #define TAO_PEGTL_MATCH_HPP #include #include "apply_mode.hpp" #include "config.hpp" #include "nothing.hpp" #include "require_apply.hpp" #include "require_apply0.hpp" #include "rewind_mode.hpp" #include "internal/has_apply.hpp" #include "internal/has_apply0.hpp" #include "internal/has_unwind.hpp" #include "internal/marker.hpp" #include "internal/missing_apply.hpp" #include "internal/missing_apply0.hpp" #include "internal/unwind_guard.hpp" #if defined( _MSC_VER ) #pragma warning( push ) #pragma warning( disable : 4702 ) #endif namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static auto match_no_control( ParseInput& in, States&&... st ) -> decltype( Rule::template match< A, M, Action, Control >( in, st... ) ) { return Rule::template match< A, M, Action, Control >( in, st... ); } template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] static auto match_no_control( ParseInput& in, States&&... /*unused*/ ) -> decltype( Rule::match( in ) ) { return Rule::match( in ); } template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] auto match_control_unwind( ParseInput& in, States&&... st ) { #if defined( __cpp_exceptions ) if constexpr( has_unwind< Control< Rule >, void, const ParseInput&, States... > ) { unwind_guard ug( [ & ] { Control< Rule >::unwind( static_cast< const ParseInput& >( in ), st... ); } ); const auto result = match_no_control< Rule, A, M, Action, Control >( in, st... ); ug.unwind.reset(); return result; } else { return match_no_control< Rule, A, M, Action, Control >( in, st... ); } #else return match_no_control< Rule, A, M, Action, Control >( in, st... ); #endif } } // namespace internal template< typename Rule, apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > [[nodiscard]] auto match( ParseInput& in, States&&... st ) { if constexpr( !Control< Rule >::enable ) { return internal::match_no_control< Rule, A, M, Action, Control >( in, st... ); } else { constexpr bool enable_action = ( A == apply_mode::action ); using iterator_t = typename ParseInput::iterator_t; constexpr bool has_apply_void = enable_action && internal::has_apply< Control< Rule >, void, Action, const iterator_t&, const ParseInput&, States... >; constexpr bool has_apply_bool = enable_action && internal::has_apply< Control< Rule >, bool, Action, const iterator_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... >; constexpr bool has_apply0_bool = enable_action && internal::has_apply0< Control< Rule >, bool, Action, const ParseInput&, States... >; constexpr bool has_apply0 = has_apply0_void || has_apply0_bool; static_assert( !( has_apply && has_apply0 ), "both apply() and apply0() defined" ); constexpr bool is_nothing = std::is_base_of_v< nothing< Rule >, Action< Rule > >; static_assert( !( has_apply && is_nothing ), "unexpected apply() defined" ); static_assert( !( has_apply0 && is_nothing ), "unexpected apply0() defined" ); if constexpr( !has_apply && std::is_base_of_v< require_apply, Action< Rule > > ) { internal::missing_apply< Control< Rule >, Action >( in, st... ); } if constexpr( !has_apply0 && std::is_base_of_v< require_apply0, Action< Rule > > ) { internal::missing_apply0< Control< Rule >, Action >( in, st... ); } constexpr bool validate_nothing = std::is_base_of_v< maybe_nothing, Action< void > >; constexpr bool is_maybe_nothing = std::is_base_of_v< maybe_nothing, Action< Rule > >; static_assert( !enable_action || !validate_nothing || is_nothing || is_maybe_nothing || has_apply || has_apply0, "either apply() or apply0() must be defined" ); constexpr bool use_marker = has_apply || has_apply0_bool; auto m = in.template mark< ( use_marker ? rewind_mode::required : rewind_mode::dontcare ) >(); Control< Rule >::start( static_cast< const ParseInput& >( in ), st... ); auto result = internal::match_control_unwind< Rule, A, ( use_marker ? rewind_mode::active : M ), Action, Control >( in, st... ); if( result ) { if constexpr( has_apply_void ) { Control< Rule >::template apply< Action >( m.iterator(), static_cast< const ParseInput& >( in ), st... ); } else if constexpr( has_apply_bool ) { result = Control< Rule >::template apply< Action >( m.iterator(), static_cast< const ParseInput& >( in ), st... ); } else if constexpr( has_apply0_void ) { Control< Rule >::template apply0< Action >( static_cast< const ParseInput& >( in ), st... ); } else if constexpr( has_apply0_bool ) { result = Control< Rule >::template apply0< Action >( static_cast< const ParseInput& >( in ), st... ); } } if( result ) { Control< Rule >::success( static_cast< const ParseInput& >( in ), st... ); } else { Control< Rule >::failure( static_cast< const ParseInput& >( in ), st... ); } (void)m( result ); return result; } } } // namespace TAO_PEGTL_NAMESPACE #if defined( _MSC_VER ) #pragma warning( pop ) #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/memory_input.hpp000066400000000000000000000274051426407250600222160ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_MEMORY_INPUT_HPP #define TAO_PEGTL_MEMORY_INPUT_HPP #include #include #include #include #include #include #include #include #include "config.hpp" #include "eol.hpp" #include "normal.hpp" #include "nothing.hpp" #include "position.hpp" #include "tracking_mode.hpp" #include "internal/action_input.hpp" #include "internal/at.hpp" #include "internal/bump.hpp" #include "internal/eolf.hpp" #include "internal/iterator.hpp" #include "internal/marker.hpp" #include "internal/until.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< tracking_mode, typename Eol, typename Source > class memory_input_base; template< typename Eol, typename Source > class memory_input_base< tracking_mode::eager, Eol, Source > { public: using iterator_t = internal::iterator; template< typename T > memory_input_base( const iterator_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 ), m_source( std::forward< T >( in_source ) ) {} template< typename T > memory_input_base( const char* 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 ), m_end( in_end ), m_source( std::forward< T >( in_source ) ) {} memory_input_base( const memory_input_base& ) = delete; memory_input_base( memory_input_base&& ) = delete; ~memory_input_base() = default; memory_input_base& operator=( const memory_input_base& ) = delete; memory_input_base& operator=( memory_input_base&& ) = delete; [[nodiscard]] const char* current() const noexcept { return m_current.data; } [[nodiscard]] const char* begin() const noexcept { return m_begin; } [[nodiscard]] const char* end( const std::size_t /*unused*/ = 0 ) const noexcept { return m_end; } [[nodiscard]] std::size_t byte() const noexcept { return m_current.byte; } [[nodiscard]] std::size_t line() const noexcept { return m_current.line; } [[nodiscard]] std::size_t column() const noexcept { return m_current.column; } void bump( const std::size_t in_count = 1 ) noexcept { internal::bump( m_current, in_count, Eol::ch ); } void bump_in_this_line( const std::size_t in_count = 1 ) noexcept { internal::bump_in_this_line( m_current, in_count ); } void bump_to_next_line( const std::size_t in_count = 1 ) noexcept { internal::bump_to_next_line( m_current, in_count ); } [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const { return TAO_PEGTL_NAMESPACE::position( it, m_source ); } void restart( const std::size_t in_byte = 0, const std::size_t in_line = 1, const std::size_t in_column = 1 ) { assert( in_line != 0 ); assert( in_column != 0 ); m_current.data = m_begin; m_current.byte = in_byte; m_current.line = in_line; m_current.column = in_column; private_depth = 0; } protected: const char* const m_begin; iterator_t m_current; const char* m_end; const Source m_source; public: std::size_t private_depth = 0; }; template< typename Eol, typename Source > class memory_input_base< tracking_mode::lazy, Eol, Source > { public: using iterator_t = const char*; template< typename T > memory_input_base( const internal::iterator& 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 ), m_source( std::forward< T >( in_source ) ) {} template< typename T > memory_input_base( const char* 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 ), m_end( in_end ), m_source( std::forward< T >( in_source ) ) {} memory_input_base( const memory_input_base& ) = delete; memory_input_base( memory_input_base&& ) = delete; ~memory_input_base() = default; memory_input_base& operator=( const memory_input_base& ) = delete; memory_input_base& operator=( memory_input_base&& ) = delete; [[nodiscard]] const char* current() const noexcept { return m_current; } [[nodiscard]] const char* begin() const noexcept { return m_begin.data; } [[nodiscard]] const char* end( const std::size_t /*unused*/ = 0 ) const noexcept { return m_end; } [[nodiscard]] std::size_t byte() const noexcept { return std::size_t( current() - m_begin.data ); } void bump( const std::size_t in_count = 1 ) noexcept { m_current += in_count; } void bump_in_this_line( const std::size_t in_count = 1 ) noexcept { m_current += in_count; } void bump_to_next_line( const std::size_t in_count = 1 ) noexcept { m_current += in_count; } [[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const iterator_t it ) const { internal::iterator c( m_begin ); internal::bump( c, std::size_t( it - m_begin.data ), Eol::ch ); return TAO_PEGTL_NAMESPACE::position( c, m_source ); } void restart() { m_current = m_begin.data; private_depth = 0; } protected: const internal::iterator m_begin; iterator_t m_current; const char* m_end; const Source m_source; public: std::size_t private_depth = 0; }; } // namespace internal template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf, typename Source = std::string > class memory_input : public internal::memory_input_base< P, Eol, Source > { public: static constexpr tracking_mode tracking_mode_v = P; using eol_t = Eol; using source_t = Source; using typename internal::memory_input_base< P, Eol, Source >::iterator_t; using action_t = internal::action_input< memory_input >; using internal::memory_input_base< P, Eol, Source >::memory_input_base; template< typename T > memory_input( const char* in_begin, const std::size_t in_size, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > ) : memory_input( in_begin, in_begin + in_size, std::forward< T >( in_source ) ) {} template< typename T > memory_input( const std::string& in_string, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > ) : memory_input( in_string.data(), in_string.size(), std::forward< T >( in_source ) ) {} template< typename T > memory_input( const std::string_view in_string, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > ) : memory_input( in_string.data(), in_string.size(), std::forward< T >( in_source ) ) {} template< typename T > memory_input( std::string&&, T&& ) = delete; template< typename T > memory_input( const char* in_begin, T&& in_source ) noexcept( std::is_nothrow_constructible_v< Source, T&& > ) : memory_input( in_begin, std::strlen( in_begin ), std::forward< T >( in_source ) ) {} template< typename T > memory_input( const char* in_begin, const char* in_end, T&& in_source, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_column ) noexcept( std::is_nothrow_constructible_v< Source, T&& > ) : memory_input( { in_begin, in_byte, in_line, in_column }, in_end, std::forward< T >( in_source ) ) {} memory_input( const memory_input& ) = delete; memory_input( memory_input&& ) = delete; ~memory_input() = default; memory_input& operator=( const memory_input& ) = delete; memory_input& operator=( memory_input&& ) = delete; [[nodiscard]] const Source& source() const noexcept { return this->m_source; } [[nodiscard]] bool empty() const noexcept { return this->current() == this->end(); } [[nodiscard]] std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept { return std::size_t( this->end() - this->current() ); } [[nodiscard]] char peek_char( const std::size_t offset = 0 ) const noexcept { return this->current()[ offset ]; } [[nodiscard]] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept { return static_cast< std::uint8_t >( peek_char( offset ) ); } [[nodiscard]] iterator_t& iterator() noexcept { return this->m_current; } [[nodiscard]] const iterator_t& iterator() const noexcept { return this->m_current; } using internal::memory_input_base< P, Eol, Source >::restart; template< rewind_mode M > void restart( const internal::marker< iterator_t, M >& m ) noexcept { iterator() = m.iterator(); } using internal::memory_input_base< P, Eol, Source >::position; [[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const { return position( iterator() ); } void discard() const noexcept {} void require( const std::size_t /*unused*/ ) const noexcept {} template< rewind_mode M > [[nodiscard]] internal::marker< iterator_t, M > mark() noexcept { return internal::marker< iterator_t, M >( iterator() ); } [[nodiscard]] const char* at( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept { return this->begin() + p.byte; } [[nodiscard]] const char* begin_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept { return at( p ) - ( p.column - 1 ); } [[nodiscard]] const char* end_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept { 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 ); return in.current(); } [[nodiscard]] std::string_view line_at( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept { const char* b = begin_of_line( p ); return std::string_view( b, static_cast< std::size_t >( end_of_line( p ) - b ) ); } void private_set_end( const char* new_end ) noexcept { this->m_end = new_end; } }; template< typename... Ts > memory_input( Ts&&... ) -> memory_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/mmap_input.hpp000066400000000000000000000041321426407250600216300ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_MMAP_INPUT_HPP #define TAO_PEGTL_MMAP_INPUT_HPP #include #include "config.hpp" #include "eol.hpp" #include "memory_input.hpp" #include "tracking_mode.hpp" #include "internal/filesystem.hpp" #include "internal/path_to_string.hpp" #if defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) #include // Required for _POSIX_MAPPED_FILES #endif #if defined( _POSIX_MAPPED_FILES ) #include "internal/file_mapper_posix.hpp" #elif defined( _WIN32 ) #include "internal/file_mapper_win32.hpp" #else #endif namespace TAO_PEGTL_NAMESPACE { namespace internal { struct mmap_holder { const file_mapper data; explicit mmap_holder( const internal::filesystem::path& path ) : data( path ) {} mmap_holder( const mmap_holder& ) = delete; mmap_holder( mmap_holder&& ) = delete; ~mmap_holder() = default; mmap_holder& operator=( const mmap_holder& ) = delete; mmap_holder& operator=( mmap_holder&& ) = delete; }; } // namespace internal template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct mmap_input : private internal::mmap_holder, public memory_input< P, Eol > { mmap_input( const internal::filesystem::path& path, const std::string& source ) : internal::mmap_holder( path ), memory_input< P, Eol >( data.begin(), data.end(), source ) {} explicit mmap_input( const internal::filesystem::path& path ) : mmap_input( path, internal::path_to_string( path ) ) {} mmap_input( const mmap_input& ) = delete; mmap_input( mmap_input&& ) = delete; ~mmap_input() = default; mmap_input& operator=( const mmap_input& ) = delete; mmap_input& operator=( mmap_input&& ) = delete; }; template< typename... Ts > explicit mmap_input( Ts&&... ) -> mmap_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/must_if.hpp000066400000000000000000000043311426407250600211260ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_MUST_IF_HPP #define TAO_PEGTL_MUST_IF_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for tao/pegtl/internal/must.hpp" #else #include #include "config.hpp" #include "normal.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Errors, typename Rule, typename = void > inline constexpr bool raise_on_failure = ( Errors::template message< Rule > != nullptr ); template< typename Errors, typename Rule > inline constexpr bool raise_on_failure< Errors, Rule, std::void_t< decltype( Errors::template raise_on_failure< Rule > ) > > = Errors::template raise_on_failure< Rule >; } // namespace internal template< typename Errors, template< typename... > class Base = normal, bool RequireMessage = true > struct must_if { template< typename Rule > struct control : Base< Rule > { template< typename ParseInput, typename... States > static void failure( const ParseInput& in, States&&... st ) noexcept( noexcept( Base< Rule >::failure( in, st... ) ) && !internal::raise_on_failure< Errors, Rule > ) { if constexpr( internal::raise_on_failure< Errors, Rule > ) { raise( in, st... ); } else { Base< Rule >::failure( in, st... ); } } template< typename ParseInput, typename... States > [[noreturn]] static void raise( const ParseInput& in, [[maybe_unused]] States&&... st ) { if constexpr( RequireMessage ) { static_assert( Errors::template message< Rule > != nullptr ); } if constexpr( Errors::template message< Rule > != nullptr ) { constexpr const char* p = Errors::template message< Rule >; throw parse_error( p, in ); #if defined( _MSC_VER ) ( (void)st, ... ); #endif } else { Base< Rule >::raise( in, st... ); } } }; }; } // namespace TAO_PEGTL_NAMESPACE #endif #endif tao-pegtl-3.2.7/include/tao/pegtl/normal.hpp000066400000000000000000000065451426407250600207610ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_NORMAL_HPP #define TAO_PEGTL_NORMAL_HPP #include #include #include #include "apply_mode.hpp" #include "config.hpp" #include "match.hpp" #include "parse_error.hpp" #include "rewind_mode.hpp" #include "internal/enable_control.hpp" #include "internal/has_match.hpp" #if defined( __cpp_exceptions ) #include "demangle.hpp" #else #include "internal/dependent_false.hpp" #include #endif namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct normal { static constexpr bool enable = internal::enable_control< Rule >; template< typename ParseInput, typename... States > static void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename ParseInput, typename... States > static void success( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename ParseInput, typename... States > static void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept {} template< typename ParseInput, typename... States > [[noreturn]] static void raise( const ParseInput& in, States&&... /*unused*/ ) { #if defined( __cpp_exceptions ) throw parse_error( "parse error matching " + std::string( demangle< Rule >() ), in ); #else static_assert( internal::dependent_false< Rule >, "exception support required for normal< Rule >::raise()" ); (void)in; std::terminate(); #endif } template< template< typename... > class Action, typename Iterator, typename ParseInput, typename... States > static auto apply( const Iterator& 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 ); return Action< Rule >::apply( action_input, st... ); } template< template< typename... > class Action, typename ParseInput, typename... States > static auto apply0( const ParseInput& /*unused*/, States&&... st ) noexcept( noexcept( Action< Rule >::apply0( st... ) ) ) -> decltype( Action< Rule >::apply0( st... ) ) { return Action< Rule >::apply0( st... ); } 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 ) { if constexpr( internal::has_match< bool, Rule, A, M, Action, Control, ParseInput, States... > ) { return Action< Rule >::template match< Rule, A, M, Action, Control >( in, st... ); } else { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ); } } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/nothing.hpp000066400000000000000000000006131426407250600211250ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_NOTHING_HPP #define TAO_PEGTL_NOTHING_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct nothing {}; using maybe_nothing = nothing< void >; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/parse.hpp000066400000000000000000000040661426407250600205770ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_PARSE_HPP #define TAO_PEGTL_PARSE_HPP #include #include "apply_mode.hpp" #include "config.hpp" #include "normal.hpp" #include "nothing.hpp" #include "parse_error.hpp" #include "position.hpp" #include "rewind_mode.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { [[nodiscard]] inline auto get_position( const position& p ) noexcept( std::is_nothrow_copy_constructible_v< position > ) { return p; } template< typename ParseInput > [[nodiscard]] position get_position( const ParseInput& in ) noexcept( noexcept( position( in.position() ) ) ) { return in.position(); } } // namespace internal 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 ParseInput, typename... States > auto parse( ParseInput&& in, States&&... st ) { return Control< Rule >::template match< A, M, Action, Control >( in, 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 Outer, typename ParseInput, typename... States > auto parse_nested( const Outer& o, 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; } #else (void)o; return parse< Rule, Action, Control, A, M >( in, st... ); #endif } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/parse_error.hpp000066400000000000000000000056051426407250600220100ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_PARSE_ERROR_HPP #define TAO_PEGTL_PARSE_ERROR_HPP #include #include #include #include #include #include #include #include "config.hpp" #include "position.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { 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 class parse_error : public std::runtime_error { 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 ) ) {} template< typename ParseInput > parse_error( const char* msg, const ParseInput& in ) : parse_error( msg, in.position() ) {} template< typename ParseInput > parse_error( const std::string& msg, const ParseInput& in ) : parse_error( msg, in.position() ) {} [[nodiscard]] const char* what() const noexcept override { return m_impl->what(); } [[nodiscard]] std::string_view message() const noexcept { return m_impl->message(); } [[nodiscard]] const std::vector< position >& positions() const noexcept { return m_impl->positions(); } 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 ) ); } void add_position( const position& p ) { add_position( position( p ) ); } }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/position.hpp000066400000000000000000000046261426407250600213330ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_POSITION_HPP #define TAO_PEGTL_POSITION_HPP #include #include #include #include #include #include "config.hpp" #include "internal/iterator.hpp" namespace TAO_PEGTL_NAMESPACE { struct position { position() = delete; #if defined( __GNUC__ ) && !defined( __clang__ ) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif position( position&& p ) noexcept : byte( p.byte ), line( p.line ), column( p.column ), source( std::move( p.source ) ) {} #if defined( __GNUC__ ) && !defined( __clang__ ) #pragma GCC diagnostic pop #endif position( const position& ) = default; position& operator=( position&& p ) noexcept { byte = p.byte; line = p.line; column = p.column; source = std::move( p.source ); return *this; } position& operator=( const position& ) = default; template< typename T > position( const internal::iterator& in_iter, T&& in_source ) : byte( in_iter.byte ), line( in_iter.line ), column( in_iter.column ), source( std::forward< T >( in_source ) ) {} template< typename T > position( const std::size_t in_byte, const std::size_t in_line, const std::size_t in_column, T&& in_source ) : byte( in_byte ), line( in_line ), column( in_column ), source( in_source ) {} ~position() = default; std::size_t byte; std::size_t line; std::size_t column; std::string source; }; inline bool operator==( const position& lhs, const position& rhs ) noexcept { return ( lhs.byte == rhs.byte ) && ( lhs.source == rhs.source ); } inline bool operator!=( const position& lhs, const position& rhs ) noexcept { return !( lhs == rhs ); } inline std::ostream& operator<<( std::ostream& os, const position& p ) { 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 tao-pegtl-3.2.7/include/tao/pegtl/read_input.hpp000066400000000000000000000031521426407250600216120ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_READ_INPUT_HPP #define TAO_PEGTL_READ_INPUT_HPP #include #include "config.hpp" #include "eol.hpp" #include "string_input.hpp" #include "tracking_mode.hpp" #include "internal/file_reader.hpp" #include "internal/filesystem.hpp" #include "internal/path_to_string.hpp" namespace TAO_PEGTL_NAMESPACE { template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct read_input : string_input< P, Eol > { read_input( const internal::filesystem::path& path, const std::string& source ) : string_input< P, Eol >( internal::file_reader( path ).read(), source ) {} explicit read_input( const internal::filesystem::path& path ) : read_input( path, internal::path_to_string( path ) ) {} read_input( FILE* file, const internal::filesystem::path& path, const std::string& source ) : string_input< P, Eol >( internal::file_reader( file, path ).read(), source ) {} read_input( FILE* file, const internal::filesystem::path& path ) : read_input( file, path, internal::path_to_string( path ) ) {} read_input( const read_input& ) = delete; read_input( read_input&& ) = delete; ~read_input() = default; read_input& operator=( const read_input& ) = delete; read_input& operator=( read_input&& ) = delete; }; template< typename... Ts > explicit read_input( Ts&&... ) -> read_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/require_apply.hpp000066400000000000000000000005251426407250600223420ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_REQUIRE_APPLY_HPP #define TAO_PEGTL_REQUIRE_APPLY_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { struct require_apply {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/require_apply0.hpp000066400000000000000000000005301426407250600224160ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_REQUIRE_APPLY0_HPP #define TAO_PEGTL_REQUIRE_APPLY0_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { struct require_apply0 {}; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/rewind_mode.hpp000066400000000000000000000006131426407250600217530ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_REWIND_MODE_HPP #define TAO_PEGTL_REWIND_MODE_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { enum class rewind_mode : char { active, required, dontcare }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/rules.hpp000066400000000000000000000116741426407250600206220ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_RULES_HPP #define TAO_PEGTL_RULES_HPP #include "config.hpp" #include "parse_error.hpp" #include "internal/rules.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off template< template< typename... > class Action, typename... Rules > struct action : internal::action< Action, Rules... > {}; template< typename... Actions > struct apply : internal::apply< Actions... > {}; template< typename... Actions > struct apply0 : internal::apply0< Actions... > {}; template< typename... Rules > struct at : internal::at< Rules... > {}; struct bof : internal::bof {}; struct bol : internal::bol {}; template< unsigned Num > struct bytes : internal::bytes< Num > {}; template< template< typename... > class Control, typename... Rules > struct control : internal::control< Control, Rules... > {}; template< typename... Rules > struct disable : internal::disable< Rules... > {}; struct discard : internal::discard {}; template< typename... Rules > struct enable : internal::enable< Rules... > {}; struct eof : internal::eof {}; struct eolf : internal::eolf {}; struct failure : internal::failure {}; template< typename Rule, typename... Actions > struct if_apply : internal::if_apply< Rule, Actions... > {}; template< typename Cond, typename Then, typename Else > struct if_then_else : internal::if_then_else< Cond, Then, Else > {}; template< typename Rule, typename Sep, typename Pad = void > struct list : internal::list< Rule, internal::pad< Sep, Pad > > {}; template< typename Rule, typename Sep > struct list< Rule, Sep, void > : internal::list< Rule, Sep > {}; template< typename Rule, typename Sep, typename Pad = void > struct list_tail : internal::list_tail_pad< Rule, Sep, Pad > {}; template< typename Rule, typename Sep > struct list_tail< Rule, Sep, void > : internal::list_tail< Rule, Sep > {}; template< typename M, typename S > struct minus : internal::minus< M, S > {}; template< typename... Rules > struct not_at : internal::not_at< Rules... > {}; template< typename... Rules > struct opt : internal::opt< Rules... > {}; template< typename Rule, typename Pad1, typename Pad2 = Pad1 > struct pad : internal::pad< Rule, Pad1, Pad2 > {}; template< typename Rule, typename Pad > struct pad_opt : internal::pad_opt< Rule, Pad > {}; template< typename Rule, typename... Rules > struct plus : internal::plus< Rule, Rules... > {}; template< typename Head, typename... Rules > struct rematch : internal::rematch< Head, Rules... > {}; template< unsigned Num, typename... Rules > struct rep : internal::rep< Num, Rules... > {}; template< unsigned Max, typename... Rules > struct rep_max : internal::rep_min_max< 0, Max, Rules... > {}; template< unsigned Min, typename Rule, typename... Rules > struct rep_min : internal::rep_min< Min, Rule, Rules... > {}; template< unsigned Min, unsigned Max, typename... Rules > struct rep_min_max : internal::rep_min_max< Min, Max, Rules... > {}; template< unsigned Max, typename... Rules > struct rep_opt : internal::rep_opt< Max, Rules... > {}; template< unsigned Amount > struct require : internal::require< Amount > {}; template< typename... Rules > struct seq : internal::seq< Rules... > {}; template< typename... Rules > struct sor : internal::sor< Rules... > {}; template< typename Rule, typename... Rules > struct star : internal::star< Rule, Rules... > {}; template< typename State, typename... Rules > struct state : internal::state< State, Rules... > {}; struct success : internal::success {}; template< typename Cond, typename... Rules > struct until : internal::until< Cond, Rules... > {}; #if defined( __cpp_exceptions ) template< typename Cond, typename... Thens > struct if_must : internal::if_must< false, Cond, Thens... > {}; template< typename Cond, typename Then, typename Else > struct if_must_else : internal::if_must_else< Cond, Then, Else > {}; template< typename Rule, typename Sep, typename Pad = void > struct list_must : internal::list_must< Rule, internal::pad< Sep, Pad > > {}; template< typename Rule, typename Sep > struct list_must< Rule, Sep, void > : internal::list_must< Rule, Sep > {}; template< typename... Rules > struct must : internal::must< Rules... > {}; template< typename Cond, typename... Rules > struct opt_must : internal::if_must< true, Cond, Rules... > {}; template< typename Exception > struct raise : internal::raise< Exception > {}; 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... > > {}; #endif // clang-format on } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/string_input.hpp000066400000000000000000000035431426407250600222110ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_STRING_INPUT_HPP #define TAO_PEGTL_STRING_INPUT_HPP #include #include #include "config.hpp" #include "eol.hpp" #include "memory_input.hpp" #include "tracking_mode.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { struct string_holder { const std::string data; template< typename T > explicit string_holder( T&& in_data ) : data( std::forward< T >( in_data ) ) {} string_holder( const string_holder& ) = delete; string_holder( string_holder&& ) = delete; ~string_holder() = default; string_holder& operator=( const string_holder& ) = delete; string_holder& operator=( string_holder&& ) = delete; }; } // namespace internal template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf, typename Source = std::string > struct string_input : private internal::string_holder, public memory_input< P, Eol, Source > { template< typename V, typename T, typename... Ts > explicit string_input( V&& in_data, T&& in_source, Ts&&... ts ) : internal::string_holder( std::forward< V >( in_data ) ), memory_input< P, Eol, Source >( data.data(), data.size(), std::forward< T >( in_source ), std::forward< Ts >( ts )... ) {} string_input( const string_input& ) = delete; string_input( string_input&& ) = delete; ~string_input() = default; string_input& operator=( const string_input& ) = delete; string_input& operator=( string_input&& ) = delete; }; template< typename... Ts > explicit string_input( Ts&&... ) -> string_input<>; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/tracking_mode.hpp000066400000000000000000000005741426407250600222730ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_TRACKING_MODE_HPP #define TAO_PEGTL_TRACKING_MODE_HPP #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { enum class tracking_mode : bool { eager, lazy }; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/type_list.hpp000066400000000000000000000020521426407250600214720ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_TYPE_LIST_HPP #define TAO_PEGTL_TYPE_LIST_HPP #include #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... Ts > struct type_list { static constexpr std::size_t size = sizeof...( Ts ); }; using empty_list = type_list<>; template< typename... > struct type_list_concat; template<> struct type_list_concat<> { using type = empty_list; }; template< typename... Ts > struct type_list_concat< type_list< Ts... > > { using type = type_list< Ts... >; }; template< typename... T0s, typename... T1s, typename... Ts > struct type_list_concat< type_list< T0s... >, type_list< T1s... >, Ts... > : type_list_concat< type_list< T0s..., T1s... >, Ts... > {}; template< typename... Ts > using type_list_concat_t = typename type_list_concat< Ts... >::type; } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/include/tao/pegtl/utf8.hpp000066400000000000000000000026131426407250600203470ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_UTF8_HPP #define TAO_PEGTL_UTF8_HPP #include "config.hpp" #include "internal/peek_utf8.hpp" #include "internal/result_on_found.hpp" #include "internal/rules.hpp" namespace TAO_PEGTL_NAMESPACE::utf8 { // clang-format off struct any : internal::any< internal::peek_utf8 > {}; struct bom : internal::one< internal::result_on_found::success, internal::peek_utf8, 0xfeff > {}; // Lemon curry? template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf8, Cs... > {}; template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf8, Lo, Hi > {}; template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf8, Cs... > {}; template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf8, Lo, Hi > {}; template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf8, Cs... > {}; template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf8, Cs >... > {}; // clang-format on } // namespace TAO_PEGTL_NAMESPACE::utf8 #endif tao-pegtl-3.2.7/include/tao/pegtl/version.hpp000066400000000000000000000005271426407250600211500ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_VERSION_HPP #define TAO_PEGTL_VERSION_HPP #define TAO_PEGTL_VERSION "3.2.7" #define TAO_PEGTL_VERSION_MAJOR 3 #define TAO_PEGTL_VERSION_MINOR 2 #define TAO_PEGTL_VERSION_PATCH 7 #endif tao-pegtl-3.2.7/include/tao/pegtl/visit.hpp000066400000000000000000000053271426407250600206240ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_VISIT_HPP #define TAO_PEGTL_VISIT_HPP #include #include "config.hpp" #include "type_list.hpp" namespace TAO_PEGTL_NAMESPACE { namespace internal { template< typename Type, typename... Types > inline constexpr bool contains_v = ( std::is_same_v< Type, Types > || ... ); template< typename Type, typename... Types > struct contains : std::bool_constant< contains_v< Type, Types... > > {}; template< typename Type, typename... Types > struct contains< Type, type_list< Types... > > : contains< Type, Types... > {}; template< typename Rules, typename Todo, typename Done > struct filter { using type = Todo; }; template< typename Rule, typename... Rules, typename... Todo, typename... Done > struct filter< type_list< Rule, Rules... >, type_list< Todo... >, type_list< Done... > > : filter< type_list< Rules... >, std::conditional_t< contains_v< Rule, Todo..., Done... >, type_list< Todo... >, type_list< Rule, Todo... > >, type_list< Done... > > {}; template< typename Rules, typename Todo, typename Done > using filter_t = typename filter< Rules, Todo, Done >::type; template< typename Done, typename... Rules > struct visit_list { using NextDone = type_list_concat_t< type_list< Rules... >, Done >; using NextSubs = type_list_concat_t< typename Rules::subs_t... >; using NextTodo = filter_t< NextSubs, empty_list, NextDone >; using type = typename std::conditional_t< std::is_same_v< NextTodo, empty_list >, type_list_concat< NextDone >, visit_list< NextDone, NextTodo > >::type; }; template< typename Done, typename... Rules > struct visit_list< Done, type_list< Rules... > > : visit_list< Done, Rules... > {}; template< template< typename... > class Func, typename... Args, typename... Rules > void visit( type_list< Rules... > /*unused*/, Args&&... args ) { ( Func< Rules >::visit( args... ), ... ); } } // namespace internal template< typename Grammar > using rule_list_t = typename internal::visit_list< empty_list, Grammar >::type; template< typename Grammar, typename Rule > inline constexpr bool contains_v = internal::contains< Rule, rule_list_t< Grammar > >::value; template< typename Rule, template< typename... > class Func, typename... Args > void visit( Args&&... args ) { internal::visit< Func >( rule_list_t< Rule >(), args... ); } } // namespace TAO_PEGTL_NAMESPACE #endif tao-pegtl-3.2.7/src/000077500000000000000000000000001426407250600142145ustar00rootroot00000000000000tao-pegtl-3.2.7/src/example/000077500000000000000000000000001426407250600156475ustar00rootroot00000000000000tao-pegtl-3.2.7/src/example/pegtl/000077500000000000000000000000001426407250600167625ustar00rootroot00000000000000tao-pegtl-3.2.7/src/example/pegtl/CMakeLists.txt000066400000000000000000000034261426407250600215270ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.8...3.19) set(example_sources abnf2pegtl.cpp analyze.cpp calculator.cpp chomsky_hierarchy.cpp csv1.cpp csv2.cpp dynamic_match.cpp expression.cpp hello_world.cpp indent_aware.cpp iri.cpp json_analyze.cpp json_ast.cpp json_build.cpp json_count.cpp json_coverage.cpp json_parse.cpp json_print_debug.cpp json_print_names.cpp json_trace.cpp lua53_analyze.cpp lua53_parse.cpp modulus_match.cpp parse_tree.cpp parse_tree_user_state.cpp peg2pegtl.cpp proto3.cpp recover.cpp s_expression.cpp sum.cpp symbol_table.cpp token_input.cpp unescape.cpp uri.cpp uri_print_debug.cpp uri_print_names.cpp uri_trace.cpp ) # file(GLOB ...) is used to validate the above list of test_sources file(GLOB glob_example_sources RELATIVE ${CMAKE_CURRENT_LIST_DIR} *.cpp) foreach(examplesourcefile ${example_sources}) if(${examplesourcefile} IN_LIST glob_example_sources) list(REMOVE_ITEM glob_example_sources ${examplesourcefile}) else() message(SEND_ERROR "File ${examplesourcefile} is missing from src/example/pegtl") endif() get_filename_component(exename pegtl-example-${examplesourcefile} NAME_WE) add_executable(${exename} ${examplesourcefile}) target_link_libraries(${exename} PRIVATE taocpp::pegtl) set_target_properties(${exename} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) if(MSVC) target_compile_options(${exename} PRIVATE /W4 /WX /utf-8) else() target_compile_options(${exename} PRIVATE -pedantic -Wall -Wextra -Wshadow -Werror) endif() endforeach() if(glob_example_sources) foreach(ignored_source_file ${glob_example_sources}) message(SEND_ERROR "File ${ignored_source_file} in src/example/pegtl is ignored") endforeach() endif() tao-pegtl-3.2.7/src/example/pegtl/abnf.abnf000066400000000000000000000044121426407250600205210ustar00rootroot00000000000000; grammar for ABNFs taken from RFC 5234 + RFC 7405, ; slightly adapted and extended to PEGs rulelist = 1*( rule / (*c-wsp c-nl) ) rule = rulename defined-as elements c-nl ; continues if next line starts ; with white space rulename = ALPHA *(ALPHA / DIGIT / "-") defined-as = *c-wsp ("=/" / "=") *c-wsp ; basic rules definition and ; incremental alternatives ; different order due to PEG elements = alternation *c-wsp c-wsp = WSP / (c-nl WSP) c-nl = comment / CRLF ; comment or newline comment = ";" *(WSP / VCHAR) CRLF alternation = concatenation *(*c-wsp "/" *c-wsp concatenation) concatenation = predicate *(1*c-wsp predicate) predicate = ["&" / "!"] repetition ; extension for PEGs repetition = [repeat] element repeat = (*DIGIT "*" *DIGIT) / 1*DIGIT ; different order due to PEG element = rulename / group / option / char-val / num-val / prose-val group = "(" *c-wsp alternation *c-wsp ")" option = "[" *c-wsp alternation *c-wsp "]" char-val = case-insensitive-string / case-sensitive-string case-insensitive-string = [ "%i" ] quoted-string case-sensitive-string = "%s" quoted-string quoted-string = DQUOTE *(%x20-21 / %x23-7E) DQUOTE ; quoted string of SP and VCHAR ; without DQUOTE num-val = "%" (bin-val / dec-val / hex-val) bin-val = "b" 1*BIT [ 1*("." 1*BIT) / ("-" 1*BIT) ] ; series of concatenated bit values ; or single ONEOF range dec-val = "d" 1*DIGIT [ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ] hex-val = "x" 1*HEXDIG [ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ] prose-val = "<" *(%x20-3D / %x3F-7E) ">" ; bracketed string of SP and VCHAR ; without angles ; prose description, to be used as ; last resort tao-pegtl-3.2.7/src/example/pegtl/abnf2pegtl.cpp000066400000000000000000000723411426407250600215210ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined( _MSC_VER ) #include #define TAO_PEGTL_STRCASECMP _stricmp #else #include #define TAO_PEGTL_STRCASECMP strcasecmp #endif #include #include #include namespace TAO_PEGTL_NAMESPACE { namespace abnf { using node_ptr = std::unique_ptr< parse_tree::node >; namespace { std::string prefix = "tao::pegtl::"; std::set< std::string > keywords = { "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class", "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue", "co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "requires", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" }; using rules_t = std::vector< std::string >; rules_t rules_defined; rules_t rules; // clang-format off struct one_tag {}; struct string_tag {}; struct istring_tag {}; // clang-format on rules_t::reverse_iterator find_rule( rules_t& r, const std::string& v, const rules_t::reverse_iterator& rbegin ) { return std::find_if( rbegin, r.rend(), [ & ]( const rules_t::value_type& p ) { return TAO_PEGTL_STRCASECMP( p.c_str(), v.c_str() ) == 0; } ); } rules_t::reverse_iterator find_rule( rules_t& r, const std::string& v ) { return find_rule( r, v, r.rbegin() ); } bool append_char( std::string& s, const char c ) { if( !s.empty() ) { s += ", "; } s += '\''; if( c == '\'' || c == '\\' ) { s += '\\'; } s += c; s += '\''; return std::isalpha( c ) != 0; } std::string remove_leading_zeroes( const std::string& v ) { const auto pos = v.find_first_not_of( '0' ); if( pos == std::string::npos ) { return ""; } return v.substr( pos ); } void shift( internal::iterator& it, int delta ) { it.data += delta; it.byte += delta; it.column += delta; } } // namespace namespace grammar { // ABNF grammar according to RFC 5234, updated by RFC 7405, with // the following differences: // // To form a C++ identifier from a rulename, all minuses are // replaced with underscores. // // As C++ identifiers are case-sensitive, we remember the "correct" // spelling from the first occurrence of a rulename, all other // occurrences are automatically changed to that. // // Certain rulenames are reserved as their equivalent C++ identifier is // reserved as a keyword, an alternative token, by the standard or // for other, special reasons. // // When using numerical values (num-val, repeat), the values // must be in the range of the corresponding C++ data type. // // Remember we are defining a PEG, not a CFG. Simply copying some // ABNF from somewhere might lead to surprising results as the // alternations are now sequential, using the sor<> rule. // // PEGs also require two extensions: The and-predicate and the // not-predicate. They are expressed by '&' and '!' respectively, // being allowed (optionally, only one of them) before the // repetition. You can use braces for more complex expressions. // // Finally, instead of the pre-defined CRLF sequence, we accept // any type of line ending as a convenience extension. // clang-format off struct CRLF : sor< abnf::CRLF, CR, LF > {}; struct comment_cont : until< CRLF, sor< WSP, VCHAR > > {}; struct comment : seq< one< ';' >, comment_cont > {}; struct c_nl : sor< comment, CRLF > {}; struct req_c_nl : c_nl {}; struct c_wsp : sor< WSP, seq< c_nl, WSP > > {}; struct rulename : seq< ALPHA, star< ranges< 'a', 'z', 'A', 'Z', '0', '9', '-' > > > {}; struct quoted_string_cont : until< DQUOTE, print > {}; struct quoted_string : seq< DQUOTE, quoted_string_cont > {}; struct case_insensitive_string : seq< opt< istring< '%', 'i' > >, quoted_string > {}; struct case_sensitive_string : seq< istring< '%', 's' >, quoted_string > {}; struct char_val : sor< case_insensitive_string, case_sensitive_string > {}; struct prose_val_cont : until< one< '>' >, print > {}; struct prose_val : seq< one< '<' >, prose_val_cont > {}; template< char First, typename Digit > struct gen_val { struct value : plus< Digit > {}; struct range : seq< one< '-' >, value > {}; struct next_value : seq< value > {}; struct type : seq< istring< First >, value, sor< range, star< one< '.' >, next_value > > > {}; }; using hex_val = gen_val< 'x', HEXDIG >; using dec_val = gen_val< 'd', DIGIT >; using bin_val = gen_val< 'b', BIT >; struct num_val_choice : sor< bin_val::type, dec_val::type, hex_val::type > {}; struct num_val : seq< one< '%' >, num_val_choice > {}; struct alternation; struct option_close : one< ']' > {}; struct option : seq< one< '[' >, pad< alternation, c_wsp >, option_close > {}; struct group_close : one< ')' > {}; struct group : seq< one< '(' >, pad< alternation, c_wsp >, group_close > {}; struct element : sor< rulename, group, option, char_val, num_val, prose_val > {}; struct repeat : sor< seq< star< DIGIT >, one< '*' >, star< DIGIT > >, plus< DIGIT > > {}; struct repetition : seq< opt< repeat >, element > {}; struct req_repetition : seq< repetition > {}; struct and_predicate : seq< one< '&' >, req_repetition > {}; struct not_predicate : seq< one< '!' >, req_repetition > {}; struct predicate : sor< and_predicate, not_predicate, repetition > {}; struct concatenation : list< predicate, plus< c_wsp > > {}; struct alternation : list< concatenation, pad< one< '/' >, c_wsp > > {}; struct defined_as_op : sor< string< '=', '/' >, one< '=' > > {}; struct defined_as : pad< defined_as_op, c_wsp > {}; struct rule : seq< seq< rulename, defined_as, alternation >, star< c_wsp >, req_c_nl > {}; struct rulelist : until< eof, sor< seq< star< c_wsp >, c_nl >, rule > > {}; // clang-format on } // namespace grammar #if defined( __cpp_exceptions ) // Using must_if<> we define a control class which is used for // the parsing run instead of the default control class. // // This improves the errors reported to the user. // // The following turns local errors into global errors, i.e. // if one of the rules for which a custom error message is // defined fails, it throws a parse_error exception (aka global // failure) instead of returning false (aka local failure). // clang-format off template< typename > inline constexpr const char* error_message = nullptr; template<> inline constexpr auto error_message< abnf::grammar::comment_cont > = "unterminated comment"; template<> inline constexpr auto error_message< abnf::grammar::quoted_string_cont > = "unterminated string (missing '\"')"; template<> inline constexpr auto error_message< abnf::grammar::prose_val_cont > = "unterminated prose description (missing '>')"; template<> inline constexpr auto error_message< abnf::grammar::hex_val::value > = "expected hexadecimal value"; template<> inline constexpr auto error_message< abnf::grammar::dec_val::value > = "expected decimal value"; template<> inline constexpr auto error_message< abnf::grammar::bin_val::value > = "expected binary value"; template<> inline constexpr auto error_message< abnf::grammar::num_val_choice > = "expected base specifier (one of 'bBdDxX')"; template<> inline constexpr auto error_message< abnf::grammar::option_close > = "unterminated option (missing ']')"; template<> inline constexpr auto error_message< abnf::grammar::group_close > = "unterminated group (missing ')')"; template<> inline constexpr auto error_message< abnf::grammar::req_repetition > = "expected element"; template<> inline constexpr auto error_message< abnf::grammar::concatenation > = "expected element"; template<> inline constexpr auto error_message< abnf::grammar::alternation > = "expected element"; template<> inline constexpr auto error_message< abnf::grammar::defined_as > = "expected '=' or '=/'"; template<> inline constexpr auto error_message< abnf::grammar::req_c_nl > = "unterminated rule"; template<> inline constexpr auto error_message< abnf::grammar::rule > = "expected rule"; // clang-format on struct error { template< typename Rule > static constexpr auto message = error_message< Rule >; }; template< typename Rule > using control = must_if< error >::control< Rule >; #else template< typename Rule > using control = normal< Rule >; #endif // Since we are going to generate a parse tree, we define a // selector that decides which rules will be included in our // parse tree, which rules will be omitted from the parse tree, // and which of the nodes will store the matched content. // Additionally, some nodes will fold when they have exactly // one child node. (see fold_one below) template< typename Rule > struct selector : parse_tree::selector< Rule, parse_tree::store_content::on< grammar::rulename, grammar::prose_val, grammar::hex_val::value, grammar::dec_val::value, grammar::bin_val::value, grammar::hex_val::range, grammar::dec_val::range, grammar::bin_val::range, grammar::hex_val::type, grammar::dec_val::type, grammar::bin_val::type, grammar::repeat, grammar::defined_as_op >, parse_tree::remove_content::on< grammar::option, grammar::and_predicate, grammar::not_predicate, grammar::rule >, parse_tree::fold_one::on< grammar::alternation, grammar::group, grammar::repetition, grammar::concatenation > > {}; // Besides the above "simple" list of selected rules, // we also provide special handling to some nodes. // When they are inserted into the parse tree, the // transform method allows additional tree transformations // in order to improve the generated tree. template<> struct selector< grammar::quoted_string > : std::true_type { template< typename... States > static void transform( node_ptr& n ) { shift( n->m_begin, 1 ); shift( n->m_end, -1 ); const auto content = n->string_view(); for( const auto c : content ) { if( std::isalpha( c ) != 0 ) { n->set_type< istring_tag >(); return; } } if( content.size() == 1 ) { n->set_type< one_tag >(); } else { n->set_type< string_tag >(); } } }; template<> struct selector< grammar::case_sensitive_string > : std::true_type { template< typename... States > static void transform( node_ptr& n ) { n = std::move( n->children.back() ); if( n->string_view().size() == 1 ) { n->set_type< one_tag >(); } else { n->set_type< string_tag >(); } } }; std::string to_string( const node_ptr& n ); std::string to_string( const std::vector< node_ptr >& v ); std::string to_string_unwrap_seq( const node_ptr& n ) { if( n->is_type< grammar::group >() || n->is_type< grammar::concatenation >() ) { return to_string( n->children ); } return to_string( n ); } namespace { std::string get_rulename( const node_ptr& n ) { assert( n->is_type< grammar::rulename >() ); std::string v = n->string(); std::replace( v.begin(), v.end(), '-', '_' ); return v; } std::string get_rulename( const node_ptr& n, const bool print_forward_declarations ) { std::string v = get_rulename( n ); const auto it = find_rule( rules, v ); if( it != rules.rend() ) { return *it; } if( keywords.count( v ) != 0 || v.find( "__" ) != std::string::npos ) { #if defined( __cpp_exceptions ) throw parse_error( '\'' + n->string() + "' is a reserved rulename", n->begin() ); #else std::cerr << '\'' + n->string() + "' is a reserved rulename" << std::endl; std::terminate(); #endif } if( print_forward_declarations && find_rule( rules_defined, v ) != rules_defined.rend() ) { std::cout << "struct " << v << ";\n"; } rules.push_back( v ); return v; } template< typename T > std::string gen_val( const node_ptr& n ) { if( n->children.size() == 2 ) { if( n->children.back()->is_type< T >() ) { return prefix + "range< " + to_string( n->children.front() ) + ", " + to_string( n->children.back()->children.front() ) + " >"; } } if( n->children.size() == 1 ) { return prefix + "one< " + to_string( n->children ) + " >"; } return prefix + "string< " + to_string( n->children ) + " >"; } struct ccmp { bool operator()( const std::string& lhs, const std::string& rhs ) const noexcept { return TAO_PEGTL_STRCASECMP( lhs.c_str(), rhs.c_str() ) < 0; } }; std::map< std::string, parse_tree::node*, ccmp > previous_rules; } // namespace template<> struct selector< grammar::rule > : std::true_type { template< typename... States > static void transform( node_ptr& n ) { const auto rname = get_rulename( n->children.front() ); assert( n->children.at( 1 )->is_type< grammar::defined_as_op >() ); const auto op = n->children.at( 1 )->string(); // when we insert a normal rule, we need to check for duplicates if( op == "=" ) { if( !previous_rules.try_emplace( rname, n.get() ).second ) { #if defined( __cpp_exceptions ) throw parse_error( "rule '" + rname + "' is already defined", n->begin() ); #else std::cerr << "rule '" + rname + "' is already defined" << std::endl; std::terminate(); #endif } } // if it is an "incremental alternation", we need to consolidate the assigned alternations else if( op == "=/" ) { 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() ); #else std::cerr << "incremental alternation '" + rname + "' without previous rule definition" << std::endl; std::terminate(); #endif } auto& previous = p->second->children.back(); // if the previous rule does not assign an alternation, create an intermediate alternation and move its assignee into it. if( !previous->is_type< abnf::grammar::alternation >() ) { auto s = std::make_unique< parse_tree::node >(); s->set_type< abnf::grammar::alternation >(); s->source = previous->source; s->m_begin = previous->m_begin; s->m_end = previous->m_end; s->children.emplace_back( std::move( previous ) ); previous = std::move( s ); } // append all new options to the previous rule's assignee (which always is an alternation now) previous->m_end = n->children.back()->m_end; // if the new rule itself contains an alternation, append the individual entries... if( n->children.back()->is_type< abnf::grammar::alternation >() ) { for( auto& e : n->children.back()->children ) { previous->children.emplace_back( std::move( e ) ); } } // ...otherwise add the node itself as another option. else { previous->children.emplace_back( std::move( n->children.back() ) ); } n.reset(); } else { #if defined( __cpp_exceptions ) throw parse_error( "invalid operator '" + op + "', this should not happen!", n->begin() ); #else std::cerr << "invalid operator '" + op + "', this should not happen!" << std::endl; std::terminate(); #endif } } }; // Finally, the generated parse tree for each node is converted to // a C++ source code string. struct stringifier { using function_t = std::string ( * )( const node_ptr& n ); function_t default_ = nullptr; std::map< std::string_view, function_t > map_; template< typename T > void add( const function_t& f ) { map_.try_emplace( demangle< T >(), f ); } std::string operator()( const node_ptr& n ) const { const auto it = map_.find( n->type ); if( it != map_.end() ) { return it->second( n ); } return default_( n ); } }; stringifier make_stringifier() { stringifier nrv; nrv.default_ = []( const node_ptr& n ) -> std::string { #if defined( __cpp_exceptions ) throw parse_error( "missing to_string() for " + std::string( n->type ), n->begin() ); #else std::cerr << "missing to_string() for " + std::string( n->type ) << std::endl; std::terminate(); #endif }; nrv.add< grammar::rulename >( []( const node_ptr& n ) { return get_rulename( n, true ); } ); nrv.add< grammar::rule >( []( const node_ptr& n ) { return "struct " + get_rulename( n->children.front(), false ) + " : " + to_string( n->children.back() ) + " {};"; } ); nrv.add< string_tag >( []( const node_ptr& n ) { const auto content = n->string_view(); std::string s; for( const auto c : content ) { append_char( s, c ); } return prefix + "string< " + s + " >"; } ); nrv.add< istring_tag >( []( const node_ptr& n ) { const auto content = n->string_view(); std::string s; for( const auto c : content ) { append_char( s, c ); } return prefix + "istring< " + s + " >"; } ); nrv.add< one_tag >( []( const node_ptr& n ) { const auto content = n->string_view(); std::string s; for( const auto c : content ) { append_char( s, c ); } return prefix + "one< " + s + " >"; } ); nrv.add< grammar::hex_val::value >( []( const node_ptr& n ) { return "0x" + n->string(); } ); nrv.add< grammar::dec_val::value >( []( const node_ptr& n ) { return n->string(); } ); nrv.add< grammar::bin_val::value >( []( const node_ptr& n ) { unsigned long long v = 0; const char* p = n->m_begin.data; // TODO: Detect overflow do { v <<= 1; v |= ( *p++ & 1 ); } while( p != n->m_end.data ); std::ostringstream oss; oss << v; return std::move( oss ).str(); } ); nrv.add< grammar::hex_val::type >( []( const node_ptr& n ) { return gen_val< grammar::hex_val::range >( n ); } ); nrv.add< grammar::dec_val::type >( []( const node_ptr& n ) { return gen_val< grammar::dec_val::range >( n ); } ); nrv.add< grammar::bin_val::type >( []( const node_ptr& n ) { return gen_val< grammar::bin_val::range >( n ); } ); nrv.add< grammar::alternation >( []( const node_ptr& n ) { return prefix + "sor< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::option >( []( const node_ptr& n ) { return prefix + "opt< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::group >( []( const node_ptr& n ) { return prefix + "seq< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::prose_val >( []( const node_ptr& n ) { return "/* " + n->string() + " */"; } ); nrv.add< grammar::and_predicate >( []( const node_ptr& n ) { assert( n->children.size() == 1 ); return prefix + "at< " + to_string_unwrap_seq( n->children.front() ) + " >"; } ); nrv.add< grammar::not_predicate >( []( const node_ptr& n ) { assert( n->children.size() == 1 ); return prefix + "not_at< " + to_string_unwrap_seq( n->children.front() ) + " >"; } ); nrv.add< grammar::concatenation >( []( const node_ptr& n ) { assert( !n->children.empty() ); return prefix + "seq< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::repetition >( []( const node_ptr& n ) -> std::string { assert( n->children.size() == 2 ); const auto content = to_string_unwrap_seq( n->children.back() ); const auto rep = n->children.front()->string(); const auto star = rep.find( '*' ); if( star == std::string::npos ) { const auto v = remove_leading_zeroes( rep ); if( v.empty() ) { #if defined( __cpp_exceptions ) throw parse_error( "repetition of zero not allowed", n->begin() ); #else std::cerr << "repetition of zero not allowed" << std::endl; std::terminate(); #endif } return prefix + "rep< " + v + ", " + content + " >"; } const auto min = remove_leading_zeroes( rep.substr( 0, star ) ); const auto max = remove_leading_zeroes( rep.substr( star + 1 ) ); if( ( star != rep.size() - 1 ) && max.empty() ) { #if defined( __cpp_exceptions ) throw parse_error( "repetition maximum of zero not allowed", n->begin() ); #else std::cerr << "repetition maximum of zero not allowed" << std::endl; std::terminate(); #endif } if( min.empty() && max.empty() ) { return prefix + "star< " + content + " >"; } if( !min.empty() && max.empty() ) { if( min == "1" ) { return prefix + "plus< " + content + " >"; } return prefix + "rep_min< " + min + ", " + content + " >"; } if( min.empty() && !max.empty() ) { if( max == "1" ) { return prefix + "opt< " + content + " >"; } return prefix + "rep_max< " + max + ", " + content + " >"; } unsigned long long min_val; unsigned long long max_val; { std::stringstream s; s.str( min ); s >> min_val; s.clear(); s.str( max ); s >> max_val; } if( min_val > max_val ) { #if defined( __cpp_exceptions ) throw parse_error( "repetition minimum which is greater than the repetition maximum not allowed", n->begin() ); #else std::cerr << "repetition minimum which is greater than the repetition maximum not allowed" << std::endl; std::terminate(); #endif } if( ( min_val == 1 ) && ( max_val == 1 ) ) { // note: content can not be used here! return to_string( n->children.back() ); } auto min_element = ( min_val == 1 ) ? content : ( prefix + "rep< " + min + ", " + content + " >" ); if( min_val == max_val ) { return min_element; } std::ostringstream oss; oss << ( max_val - min_val ); const auto max_element = prefix + ( ( max_val - min_val == 1 ) ? "opt< " : ( "rep_opt< " + std::move( oss ).str() + ", " ) ) + content + " >"; return prefix + "seq< " + min_element + ", " + max_element + " >"; } ); return nrv; } std::string to_string( const node_ptr& n ) { static stringifier s = make_stringifier(); return s( n ); } std::string to_string( const std::vector< node_ptr >& v ) { std::string result; for( const auto& c : v ) { if( !result.empty() ) { result += ", "; } result += to_string( c ); } return result; } } // namespace abnf } // namespace TAO_PEGTL_NAMESPACE int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { using namespace TAO_PEGTL_NAMESPACE; if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " SOURCE\n"; return 1; } file_input in( argv[ 1 ] ); #if defined( __cpp_exceptions ) try { const auto root = parse_tree::parse< abnf::grammar::rulelist, abnf::selector, nothing, abnf::control >( in ); for( const auto& rule : root->children ) { abnf::rules_defined.push_back( abnf::get_rulename( rule->children.front() ) ); } for( const auto& rule : root->children ) { std::cout << abnf::to_string( rule ) << '\n'; } } catch( const parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << '\n'; } #else if( const auto root = parse_tree::parse< abnf::grammar::rulelist, abnf::selector, nothing, abnf::control >( in ) ) { for( const auto& rule : root->children ) { abnf::rules_defined.push_back( abnf::get_rulename( rule->children.front() ) ); } for( const auto& rule : root->children ) { std::cout << abnf::to_string( rule ) << '\n'; } } else { std::cerr << "error occurred" << std::endl; return 1; } #endif return 0; } tao-pegtl-3.2.7/src/example/pegtl/analyze.cpp000066400000000000000000000010241426407250600211260ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include using namespace TAO_PEGTL_NAMESPACE; struct bar; struct foo : sor< digit, bar > {}; struct bar : plus< foo > // seq< foo, opt< bar > > {}; int main() // NOLINT(bugprone-exception-escape) { if( analyze< foo >( 1 ) != 0 ) { std::cerr << "there are problems" << std::endl; return 1; } return 0; } tao-pegtl-3.2.7/src/example/pegtl/calculator.cpp000066400000000000000000000251011426407250600216160ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include // Include the analyze function that checks // a grammar for possible infinite cycles. #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace calculator { // This enum is used for the order in which the operators are // evaluated, i.e. the priority of the operators; a higher // number indicates a lower priority. enum class order : int { }; // For each binary operator known to the calculator we need an // instance of the following data structure with the priority, // and a function that performs the calculation. All operators // are left-associative. struct op { order p; std::function< long( long, long ) > f; }; // Class that takes care of an operand and an operator stack for // shift-reduce style handling of operator priority; in a // reduce-step it calls on the functions contained in the op // instances to perform the calculation. struct stack { void push( const op& b ) { while( ( !m_o.empty() ) && ( m_o.back().p <= b.p ) ) { reduce(); } m_o.push_back( b ); } void push( const long l ) { m_l.push_back( l ); } long finish() { while( !m_o.empty() ) { reduce(); } assert( m_l.size() == 1 ); const auto r = m_l.back(); m_l.clear(); return r; } private: std::vector< op > m_o; std::vector< long > m_l; void reduce() { assert( !m_o.empty() ); assert( m_l.size() > 1 ); const auto r = m_l.back(); m_l.pop_back(); const auto l = m_l.back(); m_l.pop_back(); const auto o = m_o.back(); m_o.pop_back(); m_l.push_back( o.f( l, r ) ); } }; // Additional layer, a "stack of stacks", to clearly show how bracketed // sub-expressions can be easily processed by giving them a stack of // their own. Once a bracketed sub-expression has finished evaluation on // its stack, the result is pushed onto the next higher stack, and the // sub-expression's temporary stack is discarded. The top-level calculation // is handled just like a bracketed sub-expression, on the first stack pushed // by the constructor. struct stacks { stacks() { open(); } void open() { m_v.emplace_back(); } template< typename T > void push( const T& t ) { assert( !m_v.empty() ); m_v.back().push( t ); } void close() { assert( m_v.size() > 1 ); const auto r = m_v.back().finish(); m_v.pop_back(); m_v.back().push( r ); } long finish() { assert( m_v.size() == 1 ); return m_v.back().finish(); } private: std::vector< stack > m_v; }; // A wrapper around the data structures that contain the binary // operators for the calculator. struct operators { operators() { // By default we initialise with all binary operators from the C language that can be // used on integers, all with their usual priority. insert( "*", order( 5 ), []( const long l, const long r ) { return l * r; } ); insert( "/", order( 5 ), []( const long l, const long r ) { return l / r; } ); insert( "%", order( 5 ), []( const long l, const long r ) { return l % r; } ); insert( "+", order( 6 ), []( const long l, const long r ) { return l + r; } ); insert( "-", order( 6 ), []( const long l, const long r ) { return l - r; } ); insert( "<<", order( 7 ), []( const long l, const long r ) { return l << r; } ); insert( ">>", order( 7 ), []( const long l, const long r ) { return l >> r; } ); insert( "<", order( 8 ), []( const long l, const long r ) { return l < r; } ); insert( ">", order( 8 ), []( const long l, const long r ) { return l > r; } ); insert( "<=", order( 8 ), []( const long l, const long r ) { return l <= r; } ); insert( ">=", order( 8 ), []( const long l, const long r ) { return l >= r; } ); insert( "==", order( 9 ), []( const long l, const long r ) { return l == r; } ); insert( "!=", order( 9 ), []( const long l, const long r ) { return l != r; } ); insert( "&", order( 10 ), []( const long l, const long r ) { return l & r; } ); insert( "^", order( 11 ), []( const long l, const long r ) { return l ^ r; } ); insert( "|", order( 12 ), []( const long l, const long r ) { return l | r; } ); insert( "&&", order( 13 ), []( const long l, const long r ) { return ( ( l != 0 ) && ( r != 0 ) ) ? 1 : 0; } ); insert( "||", order( 14 ), []( const long l, const long r ) { return ( ( l != 0 ) || ( r != 0 ) ) ? 1 : 0; } ); } // Arbitrary user-defined operators can be added at runtime. void insert( const std::string& name, const order p, const std::function< long( long, long ) >& f ) { assert( !name.empty() ); m_ops.try_emplace( name, op{ p, f } ); } [[nodiscard]] const std::map< std::string, op >& ops() const noexcept { return m_ops; } private: std::map< std::string, op > m_ops; }; // Here the actual grammar starts. using namespace tao::pegtl; // Comments are introduced by a '#' and proceed to the end-of-line/file. struct comment : seq< one< '#' >, until< eolf > > {}; // The calculator ignores all spaces and comments; space is a pegtl rule // that matches the usual ascii characters ' ', '\t', '\n' etc. In other // words, everything that is space or a comment is ignored. struct ignored : sor< space, comment > {}; // Since the binary operators are taken from a runtime data structure // (rather than hard-coding them into the grammar), we need a custom // rule that attempts to match the input against the current map of // operators. struct infix { using rule_t = ascii::any::rule_t; template< apply_mode, rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, const operators& b, stacks& s, States&&... /*unused*/ ) { // Look for the longest match of the input against the operators in the operator map. return match( in, b, s, std::string() ); } private: template< typename ParseInput > static bool match( ParseInput& in, const operators& b, stacks& s, std::string t ) { if( in.size( t.size() + 1 ) > t.size() ) { t += in.peek_char( t.size() ); const auto i = b.ops().lower_bound( t ); if( i != b.ops().end() ) { if( match( in, b, s, t ) ) { return true; } if( i->first == t ) { // While we are at it, this rule also performs the task of what would // usually be an associated action: To push the matched operator onto // the operator stack. s.push( i->second ); in.bump( t.size() ); return true; } } } return false; } }; // A number is a non-empty sequence of digits preceded by an optional sign. struct number : seq< opt< one< '+', '-' > >, plus< digit > > {}; struct expression; // A bracketed expression is introduced by a '(' and, in this grammar, must // proceed with an expression and a ')'. struct bracket : seq< one< '(' >, expression, one< ')' > > {}; // An atomic expression, i.e. one without operators, is either a number or // a bracketed expression. struct atomic : sor< number, bracket > {}; // An expression is a non-empty list of atomic expressions where each pair // of atomic expressions is separated by an infix operator and we allow // the rule ignored as padding (before and after every single expression). struct expression : list< atomic, infix, ignored > {}; // The top-level grammar allows one expression and then expects eof. struct grammar : seq< expression, eof > {}; // After the grammar we proceed with the additional actions that are // required to let our calculator actually do something. // The base-case of the class template for the actions, does nothing. template< typename Rule > struct action {}; // This action will be called when the number rule matches; it converts the // matched portion of the input to a long and pushes it onto the operand // stack. template<> struct action< number > { template< typename ActionInput > static void apply( const ActionInput& in, const operators& /*unused*/, stacks& s ) { std::stringstream ss( in.string() ); long v; ss >> v; s.push( v ); } }; // The actions for the brackets call functions that create, and collect // a temporary additional stack for evaluating the bracketed expression. template<> struct action< one< '(' > > { static void apply0( const operators& /*unused*/, stacks& s ) { s.open(); } }; template<> struct action< one< ')' > > { static void apply0( const operators& /*unused*/, stacks& s ) { s.close(); } }; } // namespace calculator int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { // Check the grammar for some possible issues. if( pegtl::analyze< calculator::grammar >() != 0 ) { return 1; } // The objects required as state by the actions. calculator::stacks s; calculator::operators b; for( int i = 1; i < argc; ++i ) { // Parse and process the command-line arguments as calculator expressions... pegtl::argv_input in( argv, i ); if( pegtl::parse< calculator::grammar, calculator::action >( in, b, s ) ) { // ...and print the respective results to std::cout. std::cout << s.finish() << std::endl; } else { std::cerr << "parse error for: " << argv[ i ] << std::endl; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/chomsky_hierarchy.cpp000066400000000000000000000073261426407250600232110ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { // Examples for grammars on all levels of the Chomsky hierarchy. // Type 3 - Regular Languages // The regular language (ab+)* implemented in a straight-forward fashion. struct type_3 : pegtl::star< pegtl::one< 'a' >, pegtl::plus< pegtl::one< 'b' > > > {}; // Type 2 - Context Free Languages // The context-free, but not regular, language a^n b^n. // Implementation that implicitly uses the C++ call stack. struct type_2_recursive : pegtl::sor< pegtl::string< 'a', 'b' >, pegtl::seq< pegtl::one< 'a' >, type_2_recursive, pegtl::one< 'b' > > > {}; // Implementation that uses state instead of recursion, an // action to set the state, and a custom rule to use it. template< char C > struct match_n { template< pegtl::apply_mode, pegtl::rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, std::size_t& count, States&&... /*unused*/ ) { if( in.size( count ) >= count ) { for( std::size_t i = 0; i < count; ++i ) { if( in.peek_char( i ) != C ) { return false; } } in.bump_in_this_line( count ); return true; } return false; } }; struct type_2_with_state : pegtl::seq< pegtl::star< pegtl::one< 'a' > >, match_n< 'b' > > {}; template< typename Rule > struct action_2_with_state {}; template<> struct action_2_with_state< pegtl::star< pegtl::one< 'a' > > > { template< typename ActionInput > static void apply( const ActionInput& in, std::size_t& count ) { count = in.size(); } }; // Type 1 - Context Sensitive Languages // The context-sensitive, but not context-free, language a^n b^n c^n. // Here only the implementation that uses state can be used. // Both the match_n<> rule and the action are the same as in // the previous non-recursive implementation of a^n b^n. struct type_1 : pegtl::seq< pegtl::star< pegtl::one< 'a' > >, match_n< 'b' >, match_n< 'c' > > {}; template< typename Rule > struct action_1 : action_2_with_state< Rule > {}; // Type 0 - Recursively Enumerable Languages // We can use the entire Turing-complete C++ language in custom rules, // so we can pretty much do everything if we decide to (pun intended), // including recursive and recursively enumerable languages ... within // the limits of time and space that we are able to dedicate. } // namespace example int main( int argc, char** argv ) { for( int i = 1; i < argc; ++i ) { pegtl::argv_input in( argv, i ); const auto r3 = pegtl::parse< pegtl::seq< example::type_3, pegtl::eof > >( in ); in.restart(); const auto r2r = pegtl::parse< pegtl::seq< example::type_2_recursive, pegtl::eof > >( in ); in.restart(); std::size_t count = 0; const auto r2s = pegtl::parse< pegtl::seq< example::type_2_with_state, pegtl::eof >, example::action_2_with_state >( in, count ); in.restart(); const auto r1 = pegtl::parse< pegtl::seq< example::type_1, pegtl::eof >, example::action_1 >( in, count ); std::cout << r3 << r2r << r2s << r1 << std::endl; assert( r2r == r2s ); } return 0; } tao-pegtl-3.2.7/src/example/pegtl/csv1.cpp000066400000000000000000000061561426407250600203520ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace csv1 { // Simple CSV-file format for an unknown-at-compile-time number of values per // line, the values are space/tab-padded integers, comment lines start with // a hash and are ignored; neither the grammar nor the included actions make // sure that the number of values per line is always the same; last line can // end with an LF or CR+LF but doesn't have to. // Example file contents parsed by this grammar (excluding C++ comment intro): // # This is a comment // 123 , 124,41,1 // 1,2,3,4 // 1 // 1,2 // clang-format off struct value : pegtl::plus< pegtl::digit > {}; struct value_item : pegtl::pad< value, pegtl::blank > {}; struct value_list : pegtl::list< value_item, pegtl::one< ',' > > {}; struct value_line : pegtl::seq< value_list, pegtl::eolf > {}; struct comment_line : pegtl::seq< pegtl::one< '#' >, pegtl::until< pegtl::eolf > > {}; struct line : pegtl::sor< comment_line, value_line > {}; struct file : pegtl::until< pegtl::eof, line > {}; // clang-format on // Data structure to store the result of a parsing run: using result_data = std::vector< std::vector< unsigned long > >; // Action and control classes to fill in the above data structure: template< typename Rule > struct action {}; template<> struct action< value > { template< typename ActionInput > static void apply( const ActionInput& in, result_data& data ) { assert( !data.empty() ); std::stringstream ss( in.string() ); unsigned long v; ss >> v; data.back().push_back( v ); } }; template< typename Rule > struct control : pegtl::normal< Rule > {}; template<> struct control< value_line > : pegtl::normal< value_line > { template< typename ParseInput > static void start( ParseInput& /*unused*/, result_data& data ) { data.emplace_back(); } template< typename ParseInput > static void failure( ParseInput& /*unused*/, result_data& data ) { assert( !data.empty() ); data.pop_back(); } }; } // namespace csv1 int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { pegtl::file_input in( argv[ i ] ); csv1::result_data data; if( !pegtl::parse< pegtl::seq< csv1::file >, csv1::action, csv1::control >( in, data ) ) { std::cerr << "parse error" << std::endl; return 1; } for( const auto& line : data ) { assert( !line.empty() ); // The grammar doesn't allow empty lines. std::cout << line.front(); for( std::size_t j = 1; j < line.size(); ++j ) { std::cout << ", " << line[ j ]; } std::cout << std::endl; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/csv2.cpp000066400000000000000000000123331426407250600203450ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace csv2 { // Simple CSV-file format for a known-at-compile-time number of values per // line, the values are strings that can use quotes when they contain commas, // if quotes are used they have to be the first character (of the line or // after the comma); quoted strings can't contain quotes, no string can have // LF or CR; last line has to end with an LF or CR+LF. // Example file contents parsed by this grammar (excluding C++ comment intro): // a,b,c // "foo","bar","baz" // ",,,",13,42 // aha """,yes, this works // clang-format off template< char C > struct string_without : pegtl::star< pegtl::not_one< C, 10, 13 > > {}; struct plain_value : string_without< ',' > {}; struct quoted_value : pegtl::seq< pegtl::one< '"' >, string_without< '"' >, pegtl::one< '"' > > {}; struct value : pegtl::sor< quoted_value, plain_value > {}; template< unsigned N > struct line : pegtl::seq< value, pegtl::rep< N - 1, pegtl::one< ',' >, value >, pegtl::eol > {}; template< unsigned N > struct file : pegtl::until< pegtl::eof, line< N > > { static_assert( N != 0 ); }; // clang-format on // Meta-programming helper: template< unsigned N, typename T > struct tuple_help; template< unsigned N, typename... S > struct tuple_help< N, std::tuple< S... > > { using tuple_t = typename tuple_help< N - 1, std::tuple< std::string, S... > >::tuple_t; }; template< typename... S > struct tuple_help< 0, std::tuple< S... > > { using tuple_t = std::tuple< S... >; }; // Ad-hoc helper to initialise a tuple from a vector: template< unsigned I > struct tuple_init { template< typename... S > static void init( std::tuple< S... >& t, std::vector< std::string >& v ) { std::get< I >( t ) = std::move( v[ I ] ); tuple_init< I - 1 >::init( t, v ); } }; template<> struct tuple_init< 0 > { template< typename... S > static void init( std::tuple< S... >& t, std::vector< std::string >& v ) { std::get< 0 >( t ) = std::move( v[ 0 ] ); } }; // Data structure to store the result of a parsing run: template< unsigned N > struct result_data { using tuple_t = typename tuple_help< N, std::tuple<> >::tuple_t; std::vector< std::string > temp; std::vector< tuple_t > result; }; // Action class to fill in the above data structure: template< typename Rule > struct action {}; template<> struct action< plain_value > { template< typename ActionInput, unsigned N > static void apply( const ActionInput& in, result_data< N >& data ) { data.temp.push_back( in.string() ); } }; template<> struct action< string_without< '"' > > : action< plain_value > {}; template< unsigned N > struct action< line< N > > { using tuple_t = typename tuple_help< N, std::tuple<> >::tuple_t; template< typename ActionInput > static void apply( const ActionInput& in, result_data< N >& data ) { if( data.temp.size() != N ) { std::cerr << "column count mismatch " << in.position() << std::endl; std::terminate(); } tuple_t temp; tuple_init< N - 1 >::init( temp, data.temp ); data.result.emplace_back( std::move( temp ) ); data.temp.clear(); } }; // Another helper to print tuples of arbitrary sizes: inline void print_string( const std::string& s ) { // Needs more elaborate escaping in practice... if( s.find( ',' ) != std::string::npos ) { std::cout << '"' << s << '"'; } else { std::cout << s; } } template< unsigned I > struct print_help { template< typename... S > static void print( const std::tuple< S... >& t ) { print_help< I - 1 >::print( t ); std::cout << ','; print_string( std::get< I >( t ) ); } }; template<> struct print_help< 0 > { template< typename... S > static void print( const std::tuple< S... >& t ) { print_string( std::get< 0 >( t ) ); } }; template< typename... S > void print_tuple( const std::tuple< S... >& t ) { constexpr unsigned size = sizeof...( S ); static_assert( size, "empty tuple doesn't work here" ); print_help< size - 1 >::print( t ); std::cout << std::endl; } } // namespace csv2 int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { pegtl::file_input in( argv[ i ] ); constexpr unsigned number_of_columns = 3; csv2::result_data< number_of_columns > data; if( pegtl::parse< pegtl::seq< csv2::file< number_of_columns > >, csv2::action >( in, data ) ) { for( const auto& line : data.result ) { csv2::print_tuple( line ); } } else { std::cerr << "parse error" << std::endl; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/double.hpp000066400000000000000000000027151426407250600207520ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_DOUBLE_HPP #define TAO_PEGTL_SRC_EXAMPLES_PEGTL_DOUBLE_HPP #include namespace double_ { // A grammar for doubles suitable for std::stod without locale support. // See also: http://en.cppreference.com/w/cpp/string/basic_string/stof using namespace TAO_PEGTL_NAMESPACE; // clang-format off struct plus_minus : opt< one< '+', '-' > > {}; struct dot : one< '.' > {}; struct inf : seq< istring< 'i', 'n', 'f' >, opt< istring< 'i', 'n', 'i', 't', 'y' > > > {}; struct nan : seq< istring< 'n', 'a', 'n' >, opt< one< '(' >, plus< alnum >, one< ')' > > > {}; template< typename D > struct number : if_then_else< dot, plus< D >, seq< plus< D >, opt< dot, star< D > > > > {}; struct e : one< 'e', 'E' > {}; struct p : one< 'p', 'P' > {}; struct exponent : seq< plus_minus, plus< digit > > {}; struct decimal : seq< number< digit >, opt< e, exponent > > {}; struct hexadecimal : seq< one< '0' >, one< 'x', 'X' >, number< xdigit >, opt< p, exponent > > {}; struct grammar : seq< plus_minus, sor< hexadecimal, decimal, inf, nan > > {}; // clang-format on } // namespace double_ #endif tao-pegtl-3.2.7/src/example/pegtl/dynamic_match.cpp000066400000000000000000000057141426407250600222750ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace dynamic { struct long_literal_id : pegtl::plus< pegtl::not_one< '[' > > {}; struct long_literal_open : pegtl::seq< pegtl::one< '[' >, long_literal_id, pegtl::one< '[' > > {}; struct long_literal_mark { using rule_t = long_literal_mark; template< pegtl::apply_mode, pegtl::rewind_mode, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, const std::string& id, const std::string& /*unused*/, States&&... /*unused*/ ) { if( in.size( id.size() ) >= id.size() ) { if( std::memcmp( in.current(), id.data(), id.size() ) == 0 ) { in.bump( id.size() ); return true; } } return false; } }; struct long_literal_close : pegtl::seq< pegtl::one< ']' >, long_literal_mark, pegtl::one< ']' > > {}; struct long_literal_body : pegtl::any {}; struct grammar : pegtl::seq< long_literal_open, pegtl::until< long_literal_close, long_literal_body >, pegtl::eof > {}; template< typename Rule > struct action {}; template<> struct action< long_literal_id > { template< typename ActionInput > static void apply( const ActionInput& in, std::string& id, const std::string& /*unused*/ ) { id = in.string(); } }; template<> struct action< long_literal_body > { template< typename ActionInput > static void apply( const ActionInput& in, const std::string& /*unused*/, std::string& body ) { body += in.string(); } }; } // namespace dynamic namespace TAO_PEGTL_NAMESPACE { template< typename Name > struct analyze_traits< Name, dynamic::long_literal_mark > : analyze_any_traits<> {}; } // namespace TAO_PEGTL_NAMESPACE int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( pegtl::analyze< dynamic::grammar >() != 0 ) { std::cerr << "cycles without progress detected!" << std::endl; return 1; } if( argc > 1 ) { std::string id; std::string body; pegtl::argv_input in( argv, 1 ); if( pegtl::parse< dynamic::grammar, dynamic::action >( in, id, body ) ) { std::cout << "long literal id was: " << id << std::endl; std::cout << "long literal body was: " << body << std::endl; } else { std::cerr << "parse error for: " << argv[ 1 ] << std::endl; return 1; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/expression.cpp000066400000000000000000000506051426407250600216730ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include #include #include #include #include #include namespace TAO_PEGTL_NAMESPACE::expression { // Expression parsing with prefix, postfix and infix operators, ternary // operator and a couple of other special cases supported. // The handling of operator precedences with left and right binding power is // based on https://github.com/matklad/minipratt/blob/master/src/bin/pratt.rs // It correctly recognises all operators with their precedence and associativity, // however is still very much work-in-progress regarding a lot of details... // TODO: Fix missing whitespace-skip before infix/postfix operators. // TODO: Decide whether to use must everywhere or nowhere? // TODO: Decide whether to suppress actions for sub-rules. // TODO: Finalise the event-style interface or change to fake actions or actions with ops? // TODO: Decide on where to use config vs. where to use grammar template parameters. // TODO: Choose customisation points vs. copy-n-paste customisation. // TODO: Constexpr-ify where possible with C++20. namespace internal { struct prefix_info { prefix_info( const std::string_view n, const unsigned pbp ) noexcept : name( n ), prefix_binding_power( pbp ) { assert( pbp ); } std::string name; unsigned prefix_binding_power; }; struct infix_postfix_info { infix_postfix_info( const std::string_view n, const unsigned lbp, const unsigned rbp = 0 ) noexcept : 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 : name( n ), other( o ), left_binding_power( lbp ), right_binding_power( rbp ) { if( right_binding_power > 0 ) { assert( std::min( left_binding_power, right_binding_power ) & 1 ); assert( 2 * std::min( left_binding_power, right_binding_power ) + 1 == left_binding_power + right_binding_power ); } assert( left_binding_power > 0 ); } [[nodiscard]] bool is_infix() const noexcept { return right_binding_power != 0; } [[nodiscard]] bool is_postfix() const noexcept { return right_binding_power == 0; } std::string name; std::string other; // Used for the ':' of the ternary operator etc. unsigned left_binding_power; unsigned right_binding_power; }; template< typename ParseInput > [[nodiscard]] bool match_string_view( ParseInput& in, const std::string_view sv ) { if( in.size( sv.size() ) >= sv.size() ) { if( std::memcmp( in.current(), sv.data(), sv.size() ) == 0 ) { in.bump( sv.size() ); return true; } } return false; } template< typename ParseInput, typename OperatorInfo > [[nodiscard]] const OperatorInfo* match_prefix( ParseInput& in, const std::size_t max_length, const std::vector< OperatorInfo >& ops ) { const std::size_t max = std::min( max_length, in.size( max_length ) ); for( std::string op( in.current(), max ); !op.empty(); op.pop_back() ) { if( const auto i = std::find_if( ops.begin(), ops.end(), [ = ]( const OperatorInfo& info ) { return info.name == op; } ); i != ops.end() ) { in.bump( op.size() ); return &*i; } } return nullptr; } template< typename ParseInput, typename OperatorInfo > [[nodiscard]] const OperatorInfo* match_infix_postfix( ParseInput& in, const std::size_t max_length, const std::vector< OperatorInfo >& ops, const unsigned min_precedence ) { const std::size_t max = std::min( max_length, in.size( max_length ) ); for( std::string op( in.current(), max ); !op.empty(); op.pop_back() ) { if( const auto i = std::find_if( ops.begin(), ops.end(), [ = ]( const OperatorInfo& info ) { return info.name == op; } ); ( i != ops.end() ) && ( i->left_binding_power >= min_precedence ) ) { in.bump( op.size() ); return &*i; } } return nullptr; } template< typename T > [[nodiscard]] std::vector< T > sorted_operator_vector( const std::initializer_list< T >& t ) { std::vector< T > v{ t }; const auto less = []( const auto& l, const auto& r ) { return l.name < r.name; }; std::sort( v.begin(), v.end(), less ); return v; } struct operator_maps { operator_maps() : prefix( sorted_operator_vector( { prefix_info( "!", 80 ), prefix_info( "+", 80 ), prefix_info( "-", 80 ), prefix_info( "~", 80 ), prefix_info( "*", 80 ), prefix_info( "&", 80 ), prefix_info( "++", 80 ), prefix_info( "--", 80 ) } ) ), infix_postfix( sorted_operator_vector( { infix_postfix_info( "::", 99, 100 ), // Special: Followed by identifier (or template-space-identifer, which we don't support yet). infix_postfix_info( ".*", 37, 38 ), infix_postfix_info( "->*", 37, 38 ), infix_postfix_info( "*", 35, 36 ), infix_postfix_info( "/", 35, 36 ), infix_postfix_info( "%", 35, 36 ), infix_postfix_info( "+", 33, 34 ), infix_postfix_info( "-", 33, 34 ), infix_postfix_info( "<<", 31, 32 ), infix_postfix_info( ">>", 31, 32 ), infix_postfix_info( "<=>", 29, 30 ), infix_postfix_info( "<", 27, 28 ), infix_postfix_info( "<=", 27, 28 ), infix_postfix_info( ">", 27, 28 ), infix_postfix_info( ">=", 27, 28 ), infix_postfix_info( "==", 25, 26 ), infix_postfix_info( "!=", 25, 26 ), infix_postfix_info( "&", 23, 24 ), infix_postfix_info( "^", 21, 22 ), infix_postfix_info( "|", 19, 20 ), infix_postfix_info( "&&", 17, 18 ), infix_postfix_info( "||", 15, 16 ), infix_postfix_info( "?", ":", 14, 13 ), // Special: Ternary operator. infix_postfix_info( "=", 12, 11 ), infix_postfix_info( "+=", 12, 11 ), infix_postfix_info( "-=", 12, 11 ), infix_postfix_info( "*=", 12, 11 ), infix_postfix_info( "/=", 12, 11 ), infix_postfix_info( "%=", 12, 11 ), infix_postfix_info( "<<=", 12, 11 ), infix_postfix_info( ">>=", 12, 11 ), infix_postfix_info( "&=", 12, 11 ), infix_postfix_info( "^=", 12, 11 ), infix_postfix_info( "|=", 12, 11 ), // infix_postfix_info( ",", 9, 10 ), // TODO: Enable, but forbid in function argument list. infix_postfix_info( "[", "]", 90 ), // Special: Argument list. infix_postfix_info( "(", ")", 90 ), // Special: Argument list. infix_postfix_info( ".", 90 ), // Special: Followed by identifier. infix_postfix_info( "->", 90 ), // Special: Followed by identifier. infix_postfix_info( "++", 90 ), infix_postfix_info( "--", 90 ) } ) ), max_prefix_length( std::max_element( prefix.begin(), prefix.end(), []( const auto& l, const auto& r ) { return l.name.size() < r.name.size(); } )->name.size() ), max_infix_postfix_length( std::max_element( infix_postfix.begin(), infix_postfix.end(), []( const auto& l, const auto& r ) { return l.name.size() < r.name.size(); } )->name.size() ) { // These are C++20 operators with the correct associativity and relative precedence, however some are still missing: // TODO: Compound literal (C99), _Alignof (C11), Functional cast, sizeof, co_await, co_yield, throw, new, new[], delete, delete[], C-style casts. } const std::vector< prefix_info > prefix; const std::vector< infix_postfix_info > infix_postfix; const std::size_t max_prefix_length; const std::size_t max_infix_postfix_length; }; struct string_view_rule { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput > [[nodiscard]] static bool match( ParseInput& in, const std::string_view sv ) noexcept( noexcept( match_string_view( in, sv ) ) ) { return match_string_view( in, sv ); } }; struct comment : seq< one< '#' >, until< eolf > > {}; struct ignored : sor< space, comment > {}; template< typename Literal, typename Identifier > struct expression; template< typename Literal, typename Identifier > struct bracket_expression { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Result, typename Config > [[nodiscard]] static bool match( ParseInput& in, Result& res, const Config& cfg, const unsigned /*unused*/ ) { return Control< if_must< one< '(' >, star< ignored >, expression< Literal, Identifier >, star< ignored >, one< ')' > > >::template match< A, M, Action, Control >( in, res, cfg, 0 ); } }; template< typename Literal, typename Identifier > struct prefix_expression { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Result, typename Config > [[nodiscard]] static bool match( ParseInput& in, Result& res, const Config& cfg, const unsigned /*unused*/ ) { if( const auto* info = match_prefix( in, cfg.max_prefix_length, cfg.prefix ) ) { (void)Control< must< star< ignored >, expression< Literal, Identifier > > >::template match< A, M, Action, Control >( in, res, cfg, info->prefix_binding_power ); if constexpr( A == apply_mode::action ) { res.prefix( info->name ); } return true; } return false; } }; template< typename Literal, typename Identifier > struct infix_postfix_expression { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Result, typename Config > [[nodiscard]] static bool match( ParseInput& in, Result& res, const Config& cfg, const unsigned min ) { if( const auto* info = match_infix_postfix( in, cfg.max_infix_postfix_length, cfg.infix_postfix, min ) ) { if( info->name == "?" ) { (void)Control< must< star< ignored >, expression< Literal, Identifier > > >::template match< A, M, Action, Control >( in, res, cfg, 0 ); (void)Control< must< star< ignored >, string_view_rule > >::template match< A, M, Action, Control >( in, info->other ); (void)Control< must< star< ignored >, expression< Literal, Identifier > > >::template match< A, M, Action, Control >( in, res, cfg, info->right_binding_power ); if constexpr( A == apply_mode::action ) { res.ternary( info->name, info->other ); } return true; } if( ( info->name == "." ) || ( info->name == "::" ) || ( info->name == "->" ) ) { (void)Control< must< star< ignored >, Identifier > >::template match< A, M, Action, Control >( in, res, cfg, 0 ); if constexpr( A == apply_mode::action ) { res.infix( info->name ); } return true; } if( ( info->name == "(" ) || ( info->name == "[" ) ) { const std::size_t size = res.string_stack.size(); // TODO: Determine number of arguments without relying on res!!! (void)Control< must< star< ignored >, opt< list_must< expression< Literal, Identifier >, one< ',' >, ignored > > > >::template match< A, M, Action, Control >( in, res, cfg, 0 ); (void)Control< must< star< ignored >, string_view_rule > >::template match< A, M, Action, Control >( in, info->other ); if constexpr( A == apply_mode::action ) { res.call( info->name, info->other, res.string_stack.size() - size ); } return true; } if( info->is_infix() ) { (void)Control< must< star< ignored >, expression< Literal, Identifier > > >::template match< A, M, Action, Control >( in, res, cfg, info->right_binding_power ); if constexpr( A == apply_mode::action ) { res.infix( info->name ); } return true; } if( info->is_postfix() ) { if constexpr( A == apply_mode::action ) { res.postfix( info->name ); } return true; } } return false; } }; template< typename Literal, typename Identifier > struct first_expression : sor< Literal, Identifier, bracket_expression< Literal, Identifier >, prefix_expression< Literal, Identifier > > {}; template< typename Literal, typename Identifier > struct expression : seq< first_expression< Literal, Identifier >, star< infix_postfix_expression< Literal, Identifier > > > {}; } // namespace internal template< typename Literal, typename Identifier > struct grammar { using rule_t = grammar; using subs_t = type_list< internal::expression< Literal, Identifier > >; template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Result > [[nodiscard]] static bool match( ParseInput& in, Result& res ) { const internal::operator_maps cfg; return match< A, M, Action, Control >( in, res, cfg ); } template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename Result, typename Config > [[nodiscard]] static bool match( ParseInput& in, Result& res, const Config& cfg ) { return Control< internal::expression< Literal, Identifier > >::template match< A, M, Action, Control >( in, res, cfg, 0 ); } }; } // namespace TAO_PEGTL_NAMESPACE::expression namespace application { namespace pegtl = TAO_PEGTL_NAMESPACE; [[nodiscard]] inline std::string operator+( const char* l, const std::string_view r ) { return std::string( l ) + " '" + std::string( r ) + "'"; } struct result { void infix( const std::string_view op ) { assert( string_stack.size() >= 2 ); std::string tmp = "( " + string_stack.at( string_stack.size() - 2 ) + " " + std::string( op ) + " " + string_stack.at( string_stack.size() - 1 ) + " )"; string_stack.pop_back(); string_stack.back() = std::move( tmp ); } void prefix( const std::string_view op ) { assert( string_stack.size() >= 1 ); // NOLINT(readability-container-size-empty) std::string tmp = std::string( op ) + "( " + string_stack.at( string_stack.size() - 1 ) + " )"; string_stack.back() = std::move( tmp ); } void postfix( const std::string_view op ) { assert( string_stack.size() >= 1 ); // NOLINT(readability-container-size-empty) std::string tmp = "( " + string_stack.at( string_stack.size() - 1 ) + " )" + std::string( op ); string_stack.back() = std::move( tmp ); } void ternary( const std::string_view op, const std::string_view o2 ) { assert( string_stack.size() >= 2 ); std::string tmp = "( " + string_stack.at( string_stack.size() - 3 ) + " " + std::string( op ) + " " + string_stack.at( string_stack.size() - 2 ) + " " + std::string( o2 ) + " " + string_stack.at( string_stack.size() - 1 ) + " )"; string_stack.pop_back(); string_stack.pop_back(); string_stack.back() = std::move( tmp ); } void call( const std::string_view op, const std::string_view o2, const std::size_t args ) { assert( string_stack.size() > args ); std::string tmp = *( string_stack.end() - 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 += " " + std::string( o2 ); string_stack.resize( string_stack.size() - args ); string_stack.back() = std::move( tmp ); } void number( const std::int64_t l ) { string_stack.emplace_back( std::to_string( l ) ); } void identifier( const std::string& id ) { string_stack.emplace_back( id ); } std::vector< std::string > string_stack; }; struct literal : pegtl::plus< pegtl::digit > {}; struct grammar : pegtl::must< pegtl::expression::grammar< literal, pegtl::identifier >, pegtl::eof > {}; template< typename Rule > struct action : pegtl::nothing< Rule > {}; template<> struct action< literal > { template< typename Input, typename... States > static void apply( const Input& in, result& res, States&&... /*unused*/ ) { res.number( std::stoll( in.string() ) ); } }; template<> struct action< pegtl::identifier > { template< typename Input, typename... States > static void apply( const Input& in, result& res, States&&... /*unused*/ ) { res.identifier( in.string() ); } }; } // namespace application int main( int argc, char** argv ) { // if( TAO_PEGTL_NAMESPACE::analyze< application::grammar >() != 0 ) { // return 1; // } for( int i = 1; i < argc; ++i ) { TAO_PEGTL_NAMESPACE::argv_input in( argv, i ); try { application::result res; TAO_PEGTL_NAMESPACE::parse< application::grammar, application::action >( in, res ); std::cout << "Input: " << argv[ i ] << std::endl; assert( res.string_stack.size() == 1 ); std::cout << "Result: " << res.string_stack.at( 0 ) << std::endl; } catch( const TAO_PEGTL_NAMESPACE::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << '\n'; } } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/hello_world.cpp000066400000000000000000000022251426407250600220010ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace hello { // clang-format off struct prefix : pegtl::string< 'H', 'e', 'l', 'l', 'o', ',', ' ' > {}; struct name : pegtl::plus< pegtl::alpha > {}; struct grammar : pegtl::seq< prefix, name, pegtl::one< '!' >, pegtl::eof > {}; // clang-format on template< typename Rule > struct action {}; template<> struct action< name > { template< typename ActionInput > static void apply( const ActionInput& in, std::string& v ) { v = in.string(); } }; } // namespace hello int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc > 1 ) { std::string name; pegtl::argv_input in( argv, 1 ); if( pegtl::parse< hello::grammar, hello::action >( in, name ) ) { std::cout << "Good bye, " << name << "!" << std::endl; } else { std::cerr << "I don't understand." << std::endl; } } } tao-pegtl-3.2.7/src/example/pegtl/indent_aware.cpp000066400000000000000000000131611426407250600221300ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; /* # Example input for Python-esque # indentation aware grammar example. a = 1 # foo def a(): a = 1 if 1: # bar if 2: a = 1 else: a = 1 def b(): a = 1 */ namespace example { // clang-format off struct eq : pegtl::one< '=' > {}; struct co : pegtl::one< ':' > {}; struct hs : pegtl::one< '#' > {}; struct ba : pegtl::one< '(' > {}; struct bz : pegtl::one< ')' > {}; struct sa : pegtl::star< pegtl::any > {}; struct s0 : pegtl::star< pegtl::one< ' ' > > {}; struct s1 : pegtl::plus< pegtl::one< ' ' > > {}; struct name : pegtl::plus< pegtl::alpha > {}; struct expression : pegtl::plus< pegtl::digit > {}; // Simplified; this example is about indentation. struct space_line : pegtl::seq< s1, pegtl::eolf > {}; struct hash_line : pegtl::seq< s0, hs, pegtl::until< pegtl::eolf > > {}; struct trailer : pegtl::must< s0, pegtl::opt< hs, pegtl::until< pegtl::at< pegtl::eolf > > >, pegtl::eolf > {}; struct def_line : pegtl::if_must< pegtl::string< 'd', 'e', 'f' >, s1, name, s0, ba, s0, bz, s0, co, trailer > {}; struct if_line : pegtl::if_must< pegtl::string< 'i', 'f' >, s1, expression, s0, co, trailer > {}; struct else_line : pegtl::if_must< pegtl::string< 'e', 'l', 's', 'e' >, s0, co, trailer > {}; struct let_line : pegtl::if_must< name, s0, eq, s0, expression, trailer > {}; struct indent : pegtl::star< pegtl::one< ' ' > > {}; struct indented : pegtl::must< indent, pegtl::sor< def_line, if_line, else_line, let_line > > {}; struct something : pegtl::sor< space_line, hash_line, indented > {}; struct nothing : pegtl::eolf {}; struct line : pegtl::sor< nothing, something > {}; struct grammar : pegtl::until< pegtl::eof, pegtl::must< line > > {}; // clang-format on enum class type { def, if_, else_, let }; struct entry { entry( const std::size_t i, const example::type t ) : indent( i ), type( t ) {} std::size_t indent; example::type type; }; struct state { std::size_t current_indent = 0; // Temporary value, the indentation of the current line. std::size_t minimum_indent = 0; // Set to non-zero when the next line needs a greater indent. std::vector< entry > stack; // Follows the nesting of the indented blocks. }; template< typename Rule > struct action {}; template<> struct action< co > { static void apply0( state& s ) { s.minimum_indent = s.current_indent + 1; } }; template<> struct action< def_line > { static void apply0( state& s ) { s.stack.emplace_back( s.current_indent, type::def ); } }; template<> struct action< if_line > { static void apply0( state& s ) { s.stack.emplace_back( s.current_indent, type::if_ ); } }; template<> struct action< else_line > { template< typename ActionInput > static void apply( const ActionInput& in, state& s ) { assert( !s.stack.empty() ); if( ( s.stack.back().type != type::if_ ) || ( s.stack.back().indent != s.current_indent ) ) { throw pegtl::parse_error( "expected previous 'if' on same indent as current 'else'", in ); } s.stack.back().type = type::else_; } }; template<> struct action< let_line > { static void apply0( state& s ) { s.stack.emplace_back( s.current_indent, type::let ); } }; template<> struct action< nothing > { template< typename ActionInput > static void apply( const ActionInput& in, state& s ) { if( s.minimum_indent > 0 ) { throw pegtl::parse_error( "expected indented block instead of empty line", in ); } s.stack.clear(); } }; template<> struct action< indent > { template< typename ActionInput > static void apply( const ActionInput& in, state& s ) { s.current_indent = in.size(); if( s.current_indent != 0 ) { while( ( !s.stack.empty() ) && ( s.stack.back().indent > s.current_indent ) ) { s.stack.pop_back(); } } if( s.minimum_indent > 0 ) { if( s.current_indent < s.minimum_indent ) { throw pegtl::parse_error( "expected indented block with more indent", in ); } s.minimum_indent = 0; } else if( ( !s.stack.empty() ) && ( s.current_indent != s.stack.back().indent ) ) { throw pegtl::parse_error( "indentation mismatch", in ); } } }; template<> struct action< grammar > { template< typename ActionInput > static void apply( const ActionInput& in, state& s ) { if( s.minimum_indent > 0 ) { throw pegtl::parse_error( "expected indented block instead of eof", in ); } } }; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { pegtl::file_input in( argv[ i ] ); example::state is; pegtl::parse< example::grammar, example::action >( in, is ); } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/iri.cpp000066400000000000000000000057601426407250600202610ustar00rootroot00000000000000// Copyright (c) 2021 Kelvin Hammond // Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; struct IRI { std::string scheme; std::string authority; std::string userinfo; std::string host; std::string port; std::string path; std::string query; std::string fragment; explicit IRI( const std::string& iri ); }; namespace iri { template< std::string IRI::*Field > struct bind { template< typename ActionInput > static void apply( const ActionInput& in, IRI& iri ) { iri.*Field = in.string(); } }; // clang-format off template< typename Rule > struct action {}; template<> struct action< pegtl::iri::scheme > : bind< &IRI::scheme > {}; template<> struct action< pegtl::iri::iauthority > : bind< &IRI::authority > {}; // userinfo: see below template<> struct action< pegtl::iri::ihost > : bind< &IRI::host > {}; template<> struct action< pegtl::iri::port > : bind< &IRI::port > {}; template<> struct action< pegtl::iri::ipath_noscheme > : bind< &IRI::path > {}; template<> struct action< pegtl::iri::ipath_rootless > : bind< &IRI::path > {}; template<> struct action< pegtl::iri::ipath_absolute > : bind< &IRI::path > {}; template<> struct action< pegtl::iri::ipath_abempty > : bind< &IRI::path > {}; template<> struct action< pegtl::iri::iquery > : bind< &IRI::query > {}; template<> struct action< pegtl::iri::ifragment > : bind< &IRI::fragment > {}; // clang-format on template<> struct action< pegtl::iri::opt_iuserinfo > { template< typename ActionInput > static void apply( const ActionInput& in, IRI& iri ) { if( !in.empty() ) { iri.userinfo = std::string( in.begin(), in.size() - 1 ); } } }; } // namespace iri IRI::IRI( const std::string& iri ) { using grammar = pegtl::must< pegtl::iri::IRI >; pegtl::memory_input input( iri, "iri" ); pegtl::parse< grammar, iri::action >( input, *this ); } 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; } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/json_analyze.cpp000066400000000000000000000011561426407250600221650ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; } // namespace example int main() // NOLINT(bugprone-exception-escape) { if( pegtl::analyze< example::grammar >() != 0 ) { std::cerr << "cycles without progress detected!" << std::endl; return 1; } return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_ast.cpp000066400000000000000000000041301426407250600213040ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include "json_errors.hpp" namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; template< typename Rule > using selector = pegtl::parse_tree::selector< Rule, pegtl::parse_tree::remove_content::on< pegtl::json::null, pegtl::json::true_, pegtl::json::false_, pegtl::json::array, pegtl::json::object, pegtl::json::member >, pegtl::parse_tree::store_content::on< pegtl::json::number, pegtl::json::string, pegtl::json::key > >; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " JSON\n" << "Generate a 'dot' file from the JSON text.\n\n" << "Example: " << argv[ 0 ] << " '{\"foo\":[42,null]}' | dot -Tpng -o parse_tree.png\n"; return 1; } pegtl::argv_input in( argv, 1 ); #if defined( __cpp_exceptions ) try { const auto root = pegtl::parse_tree::parse< example::grammar, example::selector, pegtl::nothing, example::control >( in ); pegtl::parse_tree::print_dot( std::cout, *root ); } catch( const pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << std::endl << in.line_at( p ) << std::endl << std::setw( p.column ) << '^' << std::endl; return 1; } #else if( const auto root = pegtl::parse_tree::parse< example::grammar, example::selector, pegtl::nothing, example::control >( in ) ) { pegtl::parse_tree::print_dot( std::cout, *root ); } else { std::cerr << "error occurred" << std::endl; return 1; } #endif return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_build.cpp000066400000000000000000000117501426407250600216220ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include #include "json_classes.hpp" #include "json_errors.hpp" #include "json_unescape.hpp" namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { // State class that stores the result of a JSON parsing run -- a single JSON object. // The other members are used temporarily, at the end of a (successful) parsing run. // They are expected to be empty. struct json_state { std::shared_ptr< json_base > result; std::vector< std::string > keys; std::vector< std::shared_ptr< array_json > > arrays; std::vector< std::shared_ptr< object_json > > objects; }; // Action class template< typename Rule > struct action {}; template<> struct action< pegtl::json::null > { static void apply0( json_state& state ) { state.result = std::make_shared< null_json >(); } }; template<> struct action< pegtl::json::true_ > { static void apply0( json_state& state ) { state.result = std::make_shared< boolean_json >( true ); } }; template<> struct action< pegtl::json::false_ > { static void apply0( json_state& state ) { state.result = std::make_shared< boolean_json >( false ); } }; template<> struct action< pegtl::json::number > { template< typename ActionInput > static void apply( const ActionInput& in, json_state& state ) { std::stringstream ss( in.string() ); long double v; ss >> v; // NOTE: not quite correct for JSON but we'll use it for this simple example. state.result = std::make_shared< number_json >( v ); } }; template<> struct action< pegtl::json::string::content > : json_unescape { template< typename ParseInput > static void success( const ParseInput& /*unused*/, std::string& s, json_state& state ) { state.result = std::make_shared< string_json >( std::move( s ) ); } }; template<> struct action< pegtl::json::array::begin > { static void apply0( json_state& state ) { state.arrays.push_back( std::make_shared< array_json >() ); } }; template<> struct action< pegtl::json::array::element > { static void apply0( json_state& state ) { state.arrays.back()->data.push_back( std::move( state.result ) ); } }; template<> struct action< pegtl::json::array::end > { static void apply0( json_state& state ) { state.result = std::move( state.arrays.back() ); state.arrays.pop_back(); } }; template<> struct action< pegtl::json::object::begin > { static void apply0( json_state& state ) { state.objects.push_back( std::make_shared< object_json >() ); } }; // To parse a key, we change the state to decouple string parsing/unescaping template<> struct action< pegtl::json::key::content > : json_unescape { template< typename ParseInput > static void success( const ParseInput& /*unused*/, std::string& s, json_state& state ) { state.keys.push_back( std::move( s ) ); } }; template<> struct action< pegtl::json::object::element > { static void apply0( json_state& state ) { state.objects.back()->data[ std::move( state.keys.back() ) ] = std::move( state.result ); state.keys.pop_back(); } }; template<> struct action< pegtl::json::object::end > { static void apply0( json_state& state ) { state.result = std::move( state.objects.back() ); state.objects.pop_back(); } }; using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc != 2 ) { std::cerr << "usage: " << argv[ 0 ] << " \n"; } else { example::json_state state; pegtl::file_input in( argv[ 1 ] ); #if defined( __cpp_exceptions ) try { pegtl::parse< example::grammar, example::action, example::control >( in, state ); } catch( const pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; return 1; } #else if( !pegtl::parse< example::grammar, example::action, example::control >( in, state ) ) { std::cerr << "error occurred" << std::endl; return 1; } #endif assert( state.keys.empty() ); assert( state.arrays.empty() ); assert( state.objects.empty() ); std::cout << state.result << std::endl; } return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_classes.hpp000066400000000000000000000111471426407250600221650ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_CLASSES_HPP #define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_CLASSES_HPP #include #include #include #include #include namespace example { enum class json_type { array, boolean, null, number, object, string }; class json_base { protected: explicit json_base( const json_type in_type ) : type( in_type ) {} virtual ~json_base() = default; public: json_base( const json_base& ) = delete; json_base( json_base&& ) = delete; json_base& operator=( const json_base& ) = delete; json_base& operator=( json_base&& ) = delete; virtual void stream( std::ostream& ) const = 0; const json_type type; }; inline std::ostream& operator<<( std::ostream& o, const json_base& j ) { j.stream( o ); return o; } inline std::ostream& operator<<( std::ostream& o, const std::shared_ptr< json_base >& j ) { return j ? ( o << *j ) : ( o << "NULL" ); } struct array_json : public json_base { array_json() : json_base( json_type::array ) {} std::vector< std::shared_ptr< json_base > > data; void stream( std::ostream& o ) const override { o << '['; if( !data.empty() ) { auto iter = data.begin(); o << *iter; while( ++iter != data.end() ) { o << ',' << *iter; } } o << ']'; } }; struct boolean_json : public json_base { explicit boolean_json( const bool in_data ) : json_base( json_type::boolean ), data( in_data ) {} bool data; void stream( std::ostream& o ) const override { o << ( data ? "true" : "false" ); } }; struct null_json : public json_base { null_json() : json_base( json_type::null ) {} void stream( std::ostream& o ) const override { o << "null"; } }; struct number_json : public json_base { explicit number_json( const long double in_data ) : json_base( json_type::number ), data( in_data ) {} long double data; void stream( std::ostream& o ) const override { o << data; } }; inline std::string json_escape( const std::string& data ) { std::string r = "\""; r.reserve( data.size() + 4 ); static const char* h = "0123456789abcdef"; const auto* d = reinterpret_cast< const unsigned char* >( data.data() ); for( std::size_t i = 0; i < data.size(); ++i ) { switch( const auto c = d[ i ] ) { case '\b': r += "\\b"; break; case '\f': r += "\\f"; break; case '\n': r += "\\n"; break; case '\r': r += "\\r"; break; case '\t': r += "\\t"; break; case '\\': r += "\\\\"; break; case '\"': r += "\\\""; break; default: if( ( c < 32 ) || ( c == 127 ) ) { r += "\\u00"; r += h[ ( c & 0xf0 ) >> 4 ]; r += h[ c & 0x0f ]; continue; } r += c; // Assume valid UTF-8. break; } } r += '"'; return r; } struct string_json : public json_base { explicit string_json( const std::string& in_data ) : json_base( json_type::string ), data( in_data ) {} std::string data; void stream( std::ostream& o ) const override { o << json_escape( data ); } }; struct object_json : public json_base { object_json() : json_base( json_type::object ) {} std::map< std::string, std::shared_ptr< json_base > > data; void stream( std::ostream& o ) const override { o << '{'; if( !data.empty() ) { auto iter = data.begin(); o << json_escape( iter->first ) << ':' << iter->second; while( ++iter != data.end() ) { o << ',' << json_escape( iter->first ) << ':' << iter->second; } } o << '}'; } }; } // namespace example #endif tao-pegtl-3.2.7/src/example/pegtl/json_count.cpp000066400000000000000000000035271426407250600216560ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include namespace TAO_PEGTL_NAMESPACE { struct counter_data { std::size_t start = 0; std::size_t success = 0; std::size_t failure = 0; }; struct counter_state { std::map< std::string_view, counter_data > counts; }; template< typename Rule > struct counter : normal< Rule > { template< typename Input > static void start( const Input& /*unused*/, counter_state& ts ) { ++ts.counts[ demangle< Rule >() ].start; } template< typename Input > static void success( const Input& /*unused*/, counter_state& ts ) { ++ts.counts[ demangle< Rule >() ].success; } template< typename Input > static void failure( const Input& /*unused*/, counter_state& ts ) { ++ts.counts[ demangle< Rule >() ].failure; } }; } // namespace TAO_PEGTL_NAMESPACE using namespace TAO_PEGTL_NAMESPACE; using grammar = seq< json::text, eof >; int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { counter_state cs; for( int i = 1; i < argc; ++i ) { file_input in( argv[ i ] ); parse< grammar, nothing, counter >( in, cs ); } std::cout << std::right << std::setw( 72 ) << "RULE NAME" << std::left << " START SUCCESS FAILURE" << std::endl; for( const auto& j : cs.counts ) { std::cout << std::right << std::setw( 72 ) << j.first << " " << std::setw( 8 ) << j.second.start << " " << std::setw( 8 ) << j.second.success << " " << std::setw( 8 ) << j.second.failure << std::endl; } return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_coverage.cpp000066400000000000000000000026311426407250600223140ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include "json_errors.hpp" namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " FILE\n" << "Print coverage of parsing FILE as JSON." << std::endl; return 1; } pegtl::file_input in( argv[ 1 ] ); pegtl::coverage_result result; #if defined( __cpp_exceptions ) try { pegtl::coverage< example::grammar, pegtl::nothing, example::control >( in, result ); } catch( const pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; return 1; } #else if( !pegtl::coverage< example::grammar, pegtl::nothing, example::control >( in, result ) ) { std::cerr << "error occurred" << std::endl; return 1; } #endif std::cout << result; return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_errors.hpp000066400000000000000000000047301426407250600220440ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_ERRORS_HPP #define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_ERRORS_HPP #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { // This file shows how to throw exceptions with // custom error messages for parse errors. #if defined( __cpp_exceptions ) // clang-format off template< typename > inline constexpr const char* error_message = nullptr; template<> inline constexpr auto error_message< pegtl::json::text > = "no valid JSON"; template<> inline constexpr auto error_message< pegtl::json::next_array_element > = "expected value"; template<> inline constexpr auto error_message< pegtl::json::end_array > = "incomplete array, expected ']'"; template<> inline constexpr auto error_message< pegtl::json::name_separator > = "expected ':'"; template<> inline constexpr auto error_message< pegtl::json::member_value > = "expected value"; template<> inline constexpr auto error_message< pegtl::json::next_member > = "expected member"; template<> inline constexpr auto error_message< pegtl::json::end_object > = "incomplete object, expected '}'"; template<> inline constexpr auto error_message< pegtl::json::digits > = "expected at least one digit"; template<> inline constexpr auto error_message< pegtl::json::xdigit > = "incomplete universal character name"; template<> inline constexpr auto error_message< pegtl::json::escaped > = "unknown escape sequence"; template<> inline constexpr auto error_message< pegtl::json::char_ > = "invalid character in string"; template<> inline constexpr auto error_message< pegtl::json::string::content > = "unterminated string"; template<> inline constexpr auto error_message< pegtl::json::key::content > = "unterminated key"; template<> inline constexpr auto error_message< pegtl::eof > = "unexpected character after JSON value"; // clang-format on // As must_if<> can not take error_message as a template parameter directly, we need to wrap it. struct error { template< typename Rule > static constexpr auto message = error_message< Rule >; }; template< typename Rule > using control = pegtl::must_if< error >::control< Rule >; #else template< typename Rule > using control = pegtl::normal< Rule >; #endif } // namespace example #endif tao-pegtl-3.2.7/src/example/pegtl/json_parse.cpp000066400000000000000000000030111426407250600216240ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include "json_errors.hpp" namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; template< typename > struct action {}; template<> struct action< pegtl::json::value > : pegtl::limit_depth< 42 > {}; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " JSON\n" << "Parse a JSON text.\n\n" << "Example: " << argv[ 0 ] << " '{\"foo\":[42,null]}'" << std::endl; return 1; } pegtl::argv_input in( argv, 1 ); #if defined( __cpp_exceptions ) try { pegtl::parse< example::grammar, example::action, example::control >( in ); } catch( const pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; return 1; } #else if( !pegtl::parse< example::grammar, example::action, example::control >( in ) ) { std::cerr << "error occurred" << std::endl; return 1; } #endif return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_print_debug.cpp000066400000000000000000000005611426407250600230230ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include int main() // NOLINT(bugprone-exception-escape) { tao::pegtl::print_debug< tao::pegtl::json::text >( std::cout ); return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_print_names.cpp000066400000000000000000000005611426407250600230400ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include int main() // NOLINT(bugprone-exception-escape) { tao::pegtl::print_names< tao::pegtl::json::text >( std::cout ); return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_trace.cpp000066400000000000000000000025451426407250600216230ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include "json_errors.hpp" namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { using grammar = pegtl::seq< pegtl::json::text, pegtl::eof >; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " JSON\n" << "Trace parsing a JSON text.\n\n" << "Example: " << argv[ 0 ] << " '{\"foo\":[42,null]}'" << std::endl; return 1; } pegtl::argv_input in( argv, 1 ); #if defined( __cpp_exceptions ) try { pegtl::standard_trace< example::grammar, pegtl::nothing, example::control >( in ); } catch( const pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << std::endl; return 1; } #else if( !pegtl::standard_trace< example::grammar, pegtl::nothing, example::control >( in ) ) { std::cerr << "error occurred" << std::endl; return 1; } #endif return 0; } tao-pegtl-3.2.7/src/example/pegtl/json_unescape.hpp000066400000000000000000000023311426407250600223260ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_UNESCAPE_HPP #define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_UNESCAPE_HPP #include #include #include #include namespace example { // Action class for parsing literal strings, uses the PEGTL unescape utilities, cf. unescape.cpp. // clang-format off template< typename Rule > struct json_unescape_action {}; template<> struct json_unescape_action< TAO_PEGTL_NAMESPACE::json::unicode > : TAO_PEGTL_NAMESPACE::unescape::unescape_j {}; template<> struct json_unescape_action< TAO_PEGTL_NAMESPACE::json::escaped_char > : TAO_PEGTL_NAMESPACE::unescape::unescape_c< TAO_PEGTL_NAMESPACE::json::escaped_char, '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' > {}; template<> struct json_unescape_action< TAO_PEGTL_NAMESPACE::json::unescaped > : TAO_PEGTL_NAMESPACE::unescape::append_all {}; // clang-format on using json_unescape = tao::pegtl::change_action_and_states< json_unescape_action, std::string >; } // namespace example #endif tao-pegtl-3.2.7/src/example/pegtl/lua53.hpp000066400000000000000000000465271426407250600204420ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_EXAMPLES_PEGTL_LUA53_HPP #define TAO_PEGTL_SRC_EXAMPLES_PEGTL_LUA53_HPP #if !defined( __cpp_exceptions ) #error "Exception support required for lua53.hpp" #else #include #include namespace lua53 { // PEGTL grammar for the Lua 5.3.0 lexer and parser. // // The grammar here is not very similar to the grammar // in the Lua reference documentation on which it is based // which is due to multiple causes. // // The main difference is that this grammar includes really // "everything", not just the structural parts from the // reference documentation: // - The PEG-approach combines lexer and parser; this grammar // handles comments and tokenisation. // - The operator precedence and associativity are reflected // in the structure of this grammar. // - All details for all types of literals are included, with // escape-sequences for literal strings, and long literals. // // The second necessary difference is that all left-recursion // had to be eliminated. // // In some places the grammar was optimised to require as little // back-tracking as possible, most prominently for expressions. // The original grammar contains the following production rules: // // prefixexp ::= var | functioncall | ‘(’ exp ‘)’ // functioncall ::= prefixexp args | prefixexp ‘:’ Name args // var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name // // We need to eliminate the left-recursion, and we also want to // remove the ambiguity between function calls and variables, // i.e. the fact that we can have expressions like // // ( a * b ).c()[ d ].e:f() // // where only the last element decides between function call and // variable, making it necessary to parse the whole thing again // if we chose wrong at the beginning. // First we eliminate prefixexp and obtain: // // functioncall ::= ( var | functioncall | ‘(’ exp ‘)’ ) ( args | ‘:’ Name args ) // var ::= Name | ( var | functioncall | ‘(’ exp ‘)’ ) ( ‘[’ exp ‘]’ | ‘.’ Name ) // // Next we split function_call and variable into a first part, // a "head", or how they can start, and a second part, the "tail", // which, in a sequence like above, is the final deciding part: // // vartail ::= '[' exp ']' | '.' Name // varhead ::= Name | '(' exp ')' vartail // functail ::= args | ':' Name args // funchead ::= Name | '(' exp ')' // // This allows us to rewrite var and function_call as follows. // // var ::= varhead { { functail } vartail } // function_call ::= funchead [ { vartail } functail ] // // Finally we can define a single expression that takes care // of var, function_call, and expressions in a bracket: // // chead ::= '(' exp ')' | Name // combined ::= chead { functail | vartail } // // Such a combined expression starts with a bracketed // expression or a name, and continues with an arbitrary // number of functail and/or vartail parts, all in a one // grammar rule without back-tracking. // // The rule expr_thirteen below implements "combined". // // Another issue of interest when writing a PEG is how to // manage the separators, the white-space and comments that // can occur in many places; in the classical two-stage // lexer-parser approach the lexer would have taken care of // this, but here we use the PEG approach that combines both. // // In the following grammar most rules adopt the convention // that they take care of "internal padding", i.e. spaces // and comments that can occur within the rule, but not // "external padding", i.e. they don't start or end with // a rule that "eats up" all extra padding (spaces and // comments). In some places, where it is more efficient, // right padding is used. // clang-format off struct short_comment : tao::pegtl::until< tao::pegtl::eolf > {}; struct long_string : tao::pegtl::raw_string< '[', '=', ']' > {}; struct comment : tao::pegtl::disable< tao::pegtl::two< '-' >, tao::pegtl::sor< long_string, short_comment > > {}; struct sep : tao::pegtl::sor< tao::pegtl::ascii::space, comment > {}; struct seps : tao::pegtl::star< sep > {}; struct str_and : TAO_PEGTL_STRING( "and" ) {}; struct str_break : TAO_PEGTL_STRING( "break" ) {}; struct str_do : TAO_PEGTL_STRING( "do" ) {}; struct str_else : TAO_PEGTL_STRING( "else" ) {}; struct str_elseif : TAO_PEGTL_STRING( "elseif" ) {}; struct str_end : TAO_PEGTL_STRING( "end" ) {}; struct str_false : TAO_PEGTL_STRING( "false" ) {}; struct str_for : TAO_PEGTL_STRING( "for" ) {}; struct str_function : TAO_PEGTL_STRING( "function" ) {}; struct str_goto : TAO_PEGTL_STRING( "goto" ) {}; struct str_if : TAO_PEGTL_STRING( "if" ) {}; struct str_in : TAO_PEGTL_STRING( "in" ) {}; struct str_local : TAO_PEGTL_STRING( "local" ) {}; struct str_nil : TAO_PEGTL_STRING( "nil" ) {}; struct str_not : TAO_PEGTL_STRING( "not" ) {}; struct str_or : TAO_PEGTL_STRING( "or" ) {}; struct str_repeat : TAO_PEGTL_STRING( "repeat" ) {}; struct str_return : TAO_PEGTL_STRING( "return" ) {}; struct str_then : TAO_PEGTL_STRING( "then" ) {}; struct str_true : TAO_PEGTL_STRING( "true" ) {}; struct str_until : TAO_PEGTL_STRING( "until" ) {}; struct str_while : TAO_PEGTL_STRING( "while" ) {}; // Note that 'elseif' precedes 'else' in order to prevent only matching // the "else" part of an "elseif" and running into an error in the // 'keyword' rule. template< typename Key > struct key : tao::pegtl::seq< Key, tao::pegtl::not_at< tao::pegtl::identifier_other > > {}; struct sor_keyword : tao::pegtl::sor< str_and, str_break, str_do, str_elseif, str_else, str_end, str_false, str_for, str_function, str_goto, str_if, str_in, str_local, str_nil, str_not, str_repeat, str_return, str_then, str_true, str_until, str_while > {}; struct key_and : key< str_and > {}; struct key_break : key< str_break > {}; struct key_do : key< str_do > {}; struct key_else : key< str_else > {}; struct key_elseif : key< str_elseif > {}; struct key_end : key< str_end > {}; struct key_false : key< str_false > {}; struct key_for : key< str_for > {}; struct key_function : key< str_function > {}; struct key_goto : key< str_goto > {}; struct key_if : key< str_if > {}; struct key_in : key< str_in > {}; struct key_local : key< str_local > {}; struct key_nil : key< str_nil > {}; struct key_not : key< str_not > {}; struct key_or : key< str_or > {}; struct key_repeat : key< str_repeat > {}; struct key_return : key< str_return > {}; struct key_then : key< str_then > {}; struct key_true : key< str_true > {}; struct key_until : key< str_until > {}; struct key_while : key< str_while > {}; struct keyword : key< sor_keyword > {}; template< typename R > struct pad : tao::pegtl::pad< R, sep > {}; struct name : tao::pegtl::seq< tao::pegtl::not_at< keyword >, tao::pegtl::identifier > {}; struct single : tao::pegtl::one< 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"', '\'', '0', '\n' > {}; struct spaces : tao::pegtl::seq< tao::pegtl::one< 'z' >, tao::pegtl::star< tao::pegtl::space > > {}; struct hexbyte : tao::pegtl::if_must< tao::pegtl::one< 'x' >, tao::pegtl::xdigit, tao::pegtl::xdigit > {}; struct decbyte : tao::pegtl::if_must< tao::pegtl::digit, tao::pegtl::rep_opt< 2, tao::pegtl::digit > > {}; struct unichar : tao::pegtl::if_must< tao::pegtl::one< 'u' >, tao::pegtl::one< '{' >, tao::pegtl::plus< tao::pegtl::xdigit >, tao::pegtl::one< '}' > > {}; struct escaped : tao::pegtl::if_must< tao::pegtl::one< '\\' >, tao::pegtl::sor< hexbyte, decbyte, unichar, single, spaces > > {}; struct regular : tao::pegtl::not_one< '\r', '\n' > {}; struct character : tao::pegtl::sor< escaped, regular > {}; template< char Q > struct short_string : tao::pegtl::if_must< tao::pegtl::one< Q >, tao::pegtl::until< tao::pegtl::one< Q >, character > > {}; struct literal_string : tao::pegtl::sor< short_string< '"' >, short_string< '\'' >, long_string > {}; template< typename E > struct exponent : tao::pegtl::opt_must< E, tao::pegtl::opt< tao::pegtl::one< '+', '-' > >, tao::pegtl::plus< tao::pegtl::digit > > {}; template< typename D, typename E > struct numeral_three : tao::pegtl::seq< tao::pegtl::if_must< tao::pegtl::one< '.' >, tao::pegtl::plus< D > >, exponent< E > > {}; template< typename D, typename E > struct numeral_two : tao::pegtl::seq< tao::pegtl::plus< D >, tao::pegtl::opt< tao::pegtl::one< '.' >, tao::pegtl::star< D > >, exponent< E > > {}; template< typename D, typename E > struct numeral_one : tao::pegtl::sor< numeral_two< D, E >, numeral_three< D, E > > {}; struct decimal : numeral_one< tao::pegtl::digit, tao::pegtl::one< 'e', 'E' > > {}; struct hexadecimal : tao::pegtl::if_must< tao::pegtl::istring< '0', 'x' >, numeral_one< tao::pegtl::xdigit, tao::pegtl::one< 'p', 'P' > > > {}; struct numeral : tao::pegtl::sor< hexadecimal, decimal > {}; struct label_statement : tao::pegtl::if_must< tao::pegtl::two< ':' >, seps, name, seps, tao::pegtl::two< ':' > > {}; struct goto_statement : tao::pegtl::if_must< key_goto, seps, name > {}; struct statement; struct expression; struct name_list : tao::pegtl::list< name, tao::pegtl::one< ',' >, sep > {}; struct name_list_must : tao::pegtl::list_must< name, tao::pegtl::one< ',' >, sep > {}; struct expr_list_must : tao::pegtl::list_must< expression, tao::pegtl::one< ',' >, sep > {}; struct statement_return : tao::pegtl::seq< tao::pegtl::pad_opt< expr_list_must, sep >, tao::pegtl::opt< tao::pegtl::one< ';' >, seps > > {}; template< typename E > struct statement_list : tao::pegtl::seq< seps, tao::pegtl::until< tao::pegtl::sor< E, tao::pegtl::if_must< key_return, statement_return, E > >, statement, seps > > {}; template< char O, char... N > struct op_one : tao::pegtl::seq< tao::pegtl::one< O >, tao::pegtl::at< tao::pegtl::not_one< N... > > > {}; template< char O, char P, char... N > struct op_two : tao::pegtl::seq< tao::pegtl::string< O, P >, tao::pegtl::at< tao::pegtl::not_one< N... > > > {}; struct table_field_one : tao::pegtl::if_must< tao::pegtl::one< '[' >, seps, expression, seps, tao::pegtl::one< ']' >, seps, tao::pegtl::one< '=' >, seps, expression > {}; struct table_field_two : tao::pegtl::if_must< tao::pegtl::seq< name, seps, op_one< '=', '=' > >, seps, expression > {}; struct table_field : tao::pegtl::sor< table_field_one, table_field_two, expression > {}; struct table_field_list : tao::pegtl::list_tail< table_field, tao::pegtl::one< ',', ';' >, sep > {}; struct table_constructor : tao::pegtl::if_must< tao::pegtl::one< '{' >, tao::pegtl::pad_opt< table_field_list, sep >, tao::pegtl::one< '}' > > {}; struct parameter_list_one : tao::pegtl::seq< name_list, tao::pegtl::opt_must< pad< tao::pegtl::one< ',' > >, tao::pegtl::ellipsis > > {}; struct parameter_list : tao::pegtl::sor< tao::pegtl::ellipsis, parameter_list_one > {}; struct function_body : tao::pegtl::seq< tao::pegtl::one< '(' >, tao::pegtl::pad_opt< parameter_list, sep >, tao::pegtl::one< ')' >, seps, statement_list< key_end > > {}; struct function_literal : tao::pegtl::if_must< key_function, seps, function_body > {}; struct bracket_expr : tao::pegtl::if_must< tao::pegtl::one< '(' >, seps, expression, seps, tao::pegtl::one< ')' > > {}; struct function_args_one : tao::pegtl::if_must< tao::pegtl::one< '(' >, tao::pegtl::pad_opt< expr_list_must, sep >, tao::pegtl::one< ')' > > {}; struct function_args : tao::pegtl::sor< function_args_one, table_constructor, literal_string > {}; struct variable_tail_one : tao::pegtl::if_must< tao::pegtl::one< '[' >, seps, expression, seps, tao::pegtl::one< ']' > > {}; struct variable_tail_two : tao::pegtl::if_must< tao::pegtl::seq< tao::pegtl::not_at< tao::pegtl::two< '.' > >, tao::pegtl::one< '.' > >, seps, name > {}; struct variable_tail : tao::pegtl::sor< variable_tail_one, variable_tail_two > {}; struct function_call_tail_one : tao::pegtl::if_must< tao::pegtl::seq< tao::pegtl::not_at< tao::pegtl::two< ':' > >, tao::pegtl::one< ':' > >, seps, name, seps, function_args > {}; struct function_call_tail : tao::pegtl::sor< function_args, function_call_tail_one > {}; struct variable_head_one : tao::pegtl::seq< bracket_expr, seps, variable_tail > {}; struct variable_head : tao::pegtl::sor< name, variable_head_one > {}; struct function_call_head : tao::pegtl::sor< name, bracket_expr > {}; struct variable : tao::pegtl::seq< variable_head, tao::pegtl::star< tao::pegtl::star< seps, function_call_tail >, seps, variable_tail > > {}; struct function_call : tao::pegtl::seq< function_call_head, tao::pegtl::plus< tao::pegtl::until< tao::pegtl::seq< seps, function_call_tail >, seps, variable_tail > > > {}; template< typename S, typename O > struct left_assoc : tao::pegtl::seq< S, seps, tao::pegtl::star_must< O, seps, S, seps > > {}; template< typename S, typename O > struct right_assoc : tao::pegtl::seq< S, seps, tao::pegtl::opt_must< O, seps, right_assoc< S, O > > > {}; struct unary_operators : tao::pegtl::sor< tao::pegtl::one< '-' >, tao::pegtl::one< '#' >, op_one< '~', '=' >, key_not > {}; struct expr_ten; struct expr_thirteen : tao::pegtl::seq< tao::pegtl::sor< bracket_expr, name >, tao::pegtl::star< seps, tao::pegtl::sor< function_call_tail, variable_tail > > > {}; struct expr_twelve : tao::pegtl::sor< key_nil, key_true, key_false, tao::pegtl::ellipsis, numeral, literal_string, function_literal, expr_thirteen, table_constructor > {}; struct expr_eleven : tao::pegtl::seq< expr_twelve, seps, tao::pegtl::opt< tao::pegtl::one< '^' >, seps, expr_ten, seps > > {}; struct unary_apply : tao::pegtl::if_must< unary_operators, seps, expr_ten, seps > {}; struct expr_ten : tao::pegtl::sor< unary_apply, expr_eleven > {}; struct operators_nine : tao::pegtl::sor< tao::pegtl::two< '/' >, tao::pegtl::one< '/' >, tao::pegtl::one< '*' >, tao::pegtl::one< '%' > > {}; struct expr_nine : left_assoc< expr_ten, operators_nine > {}; struct operators_eight : tao::pegtl::sor< tao::pegtl::one< '+' >, tao::pegtl::one< '-' > > {}; struct expr_eight : left_assoc< expr_nine, operators_eight > {}; struct expr_seven : right_assoc< expr_eight, op_two< '.', '.', '.' > > {}; struct operators_six : tao::pegtl::sor< tao::pegtl::two< '<' >, tao::pegtl::two< '>' > > {}; struct expr_six : left_assoc< expr_seven, operators_six > {}; struct expr_five : left_assoc< expr_six, tao::pegtl::one< '&' > > {}; struct expr_four : left_assoc< expr_five, op_one< '~', '=' > > {}; struct expr_three : left_assoc< expr_four, tao::pegtl::one< '|' > > {}; struct operators_two : tao::pegtl::sor< tao::pegtl::two< '=' >, tao::pegtl::string< '<', '=' >, tao::pegtl::string< '>', '=' >, op_one< '<', '<' >, op_one< '>', '>' >, tao::pegtl::string< '~', '=' > > {}; struct expr_two : left_assoc< expr_three, operators_two > {}; struct expr_one : left_assoc< expr_two, key_and > {}; struct expression : left_assoc< expr_one, key_or > {}; struct do_statement : tao::pegtl::if_must< key_do, statement_list< key_end > > {}; struct while_statement : tao::pegtl::if_must< key_while, seps, expression, seps, key_do, statement_list< key_end > > {}; struct repeat_statement : tao::pegtl::if_must< key_repeat, statement_list< key_until >, seps, expression > {}; struct at_elseif_else_end : tao::pegtl::sor< tao::pegtl::at< key_elseif >, tao::pegtl::at< key_else >, tao::pegtl::at< key_end > > {}; struct elseif_statement : tao::pegtl::if_must< key_elseif, seps, expression, seps, key_then, statement_list< at_elseif_else_end > > {}; struct else_statement : tao::pegtl::if_must< key_else, statement_list< key_end > > {}; struct if_statement : tao::pegtl::if_must< key_if, seps, expression, seps, key_then, statement_list< at_elseif_else_end >, seps, tao::pegtl::until< tao::pegtl::sor< else_statement, key_end >, elseif_statement, seps > > {}; struct for_statement_one : tao::pegtl::seq< tao::pegtl::one< '=' >, seps, expression, seps, tao::pegtl::one< ',' >, seps, expression, tao::pegtl::pad_opt< tao::pegtl::if_must< tao::pegtl::one< ',' >, seps, expression >, sep > > {}; struct for_statement_two : tao::pegtl::seq< tao::pegtl::opt_must< tao::pegtl::one< ',' >, seps, name_list_must, seps >, key_in, seps, expr_list_must, seps > {}; struct for_statement : tao::pegtl::if_must< key_for, seps, name, seps, tao::pegtl::sor< for_statement_one, for_statement_two >, key_do, statement_list< key_end > > {}; struct assignment_variable_list : tao::pegtl::list_must< variable, tao::pegtl::one< ',' >, sep > {}; struct assignments_one : tao::pegtl::if_must< tao::pegtl::one< '=' >, seps, expr_list_must > {}; struct assignments : tao::pegtl::seq< assignment_variable_list, seps, assignments_one > {}; struct function_name : tao::pegtl::seq< tao::pegtl::list< name, tao::pegtl::one< '.' >, sep >, seps, tao::pegtl::opt_must< tao::pegtl::one< ':' >, seps, name, seps > > {}; struct function_definition : tao::pegtl::if_must< key_function, seps, function_name, function_body > {}; struct local_function : tao::pegtl::if_must< key_function, seps, name, seps, function_body > {}; struct local_variables : tao::pegtl::if_must< name_list_must, seps, tao::pegtl::opt< assignments_one > > {}; struct local_statement : tao::pegtl::if_must< key_local, seps, tao::pegtl::sor< local_function, local_variables > > {}; struct semicolon : tao::pegtl::one< ';' > {}; struct statement : tao::pegtl::sor< semicolon, assignments, function_call, label_statement, key_break, goto_statement, do_statement, while_statement, repeat_statement, if_statement, for_statement, function_definition, local_statement > {}; struct grammar : tao::pegtl::must< tao::pegtl::opt< tao::pegtl::shebang >, statement_list< tao::pegtl::eof > > {}; // clang-format on } // namespace lua53 #endif #endif tao-pegtl-3.2.7/src/example/pegtl/lua53_analyze.cpp000066400000000000000000000011671426407250600221470ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include "lua53.hpp" int main() // NOLINT(bugprone-exception-escape) { if( const auto problems = TAO_PEGTL_NAMESPACE::analyze< lua53::grammar >() != 0 ) { std::cout << "problems: " << problems << std::endl; return 1; } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/lua53_parse.cpp000066400000000000000000000012371426407250600216140ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include "lua53.hpp" int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { TAO_PEGTL_NAMESPACE::file_input in( argv[ i ] ); const auto r = TAO_PEGTL_NAMESPACE::parse< lua53::grammar >( in ); std::cout << argv[ i ] << " " << r << std::endl; } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/modulus_match.cpp000066400000000000000000000017671426407250600223450ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include using namespace TAO_PEGTL_NAMESPACE; namespace modulus { template< unsigned M, unsigned R = 0 > struct my_rule { static_assert( M > 1, "Modulus must be greater than 1" ); static_assert( R < M, "Remainder must be less than modulus" ); template< typename ParseInput > static bool match( ParseInput& in ) { if( !in.empty() ) { if( ( ( *in.current() ) % M ) == R ) { in.bump( 1 ); return true; } } return false; } }; struct grammar : until< eolf, my_rule< 3 > > {}; } // namespace modulus int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( argc > 1 ) { argv_input in( argv, 1 ); if( !parse< modulus::grammar >( in ) ) { return 1; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/parse_tree.cpp000066400000000000000000000124461426407250600216260ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include #include using namespace TAO_PEGTL_NAMESPACE; namespace example { // the grammar // clang-format off struct integer : plus< digit > {}; struct variable : identifier {}; struct plus : pad< one< '+' >, space > {}; struct minus : pad< one< '-' >, space > {}; struct multiply : pad< one< '*' >, space > {}; struct divide : pad< one< '/' >, space > {}; struct open_bracket : seq< one< '(' >, star< space > > {}; struct close_bracket : seq< star< space >, one< ')' > > {}; struct expression; struct bracketed : seq< open_bracket, expression, close_bracket > {}; struct value : sor< integer, variable, bracketed >{}; struct product : list< value, sor< multiply, divide > > {}; struct expression : list< product, sor< plus, minus > > {}; struct grammar : seq< expression, eof > {}; // clang-format on // after a node is stored successfully, you can add an optional transformer like this: struct rearrange : parse_tree::apply< rearrange > // allows bulk selection, see selector<...> { // recursively rearrange nodes. the basic principle is: // // from: PROD/EXPR // / | \ (LHS... may be one or more children, followed by OP,) // LHS... OP RHS (which is one operator, and RHS, which is a single child) // // to: OP // / \ (OP now has two children, the original PROD/EXPR and RHS) // PROD/EXPR RHS (Note that PROD/EXPR has two fewer children now) // | // LHS... // // if only one child is left for LHS..., replace the PROD/EXPR with the child directly. // otherwise, perform the above transformation, then apply it recursively until LHS... // becomes a single child, which then replaces the parent node and the recursion ends. template< typename Node, typename... States > static void transform( std::unique_ptr< Node >& n, States&&... st ) { if( n->children.size() == 1 ) { n = std::move( n->children.back() ); } else { n->remove_content(); auto& c = n->children; auto r = std::move( c.back() ); c.pop_back(); auto o = std::move( c.back() ); c.pop_back(); o->children.emplace_back( std::move( n ) ); o->children.emplace_back( std::move( r ) ); n = std::move( o ); transform( n->children.front(), st... ); } } }; // select which rules in the grammar will produce parse tree nodes: template< typename Rule > using selector = parse_tree::selector< Rule, parse_tree::store_content::on< integer, variable >, parse_tree::remove_content::on< plus, minus, multiply, divide >, rearrange::on< product, expression > >; namespace internal { // a non-thread-safe allocation cache, assuming that the size (sz) is always the same! template< std::size_t N > struct cache { std::size_t pos = 0; std::array< void*, N > data; cache() = default; cache( const cache& ) = delete; cache( cache&& ) = delete; ~cache() { while( pos != 0 ) { ::operator delete( data[ --pos ] ); } } cache& operator=( const cache& ) = delete; cache& operator=( cache&& ) = delete; void* get( std::size_t sz ) { if( pos != 0 ) { return data[ --pos ]; } return ::operator new( sz ); } void put( void* p ) { if( pos < N ) { data[ pos++ ] = p; } else { ::operator delete( p ); } } }; static cache< 32 > the_cache; } // namespace internal // this is not necessary for the example, but serves as a demonstration for an additional optimization. struct node : parse_tree::basic_node< node > { void* operator new( std::size_t sz ) { assert( sz == sizeof( node ) ); return internal::the_cache.get( sz ); } void operator delete( void* p ) { internal::the_cache.put( p ); } }; } // namespace example int main( int argc, char** argv ) { if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " EXPR\n" << "Generate a 'dot' file from expression.\n\n" << "Example: " << argv[ 0 ] << " \"(2*a + 3*b) / (4*n)\" | dot -Tpng -o parse_tree.png\n"; return 1; } argv_input in( argv, 1 ); if( const auto root = parse_tree::parse< example::grammar, example::node, example::selector >( in ) ) { parse_tree::print_dot( std::cout, *root ); return 0; } std::cerr << "parse error" << std::endl; return 1; } tao-pegtl-3.2.7/src/example/pegtl/parse_tree_user_state.cpp000066400000000000000000000013141426407250600240540ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include using namespace TAO_PEGTL_NAMESPACE; template< typename > using selector = std::true_type; struct user_state {}; template< typename Rule > struct work {}; template<> struct work< success > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, user_state& /*unused*/ ) {} }; int main() { memory_input input( "", "dummy" ); user_state state; auto root = parse_tree::parse< success, selector, work >( input, state ); return 0; } tao-pegtl-3.2.7/src/example/pegtl/peg.peg000066400000000000000000000021631426407250600202340ustar00rootroot00000000000000# Parsing Expression Grammar (PEG) taken from # https://pdos.csail.mit.edu/~baford/packrat/popl04/peg-popl04.pdf # Hierarchical syntax Grammar <- Spacing Definition+ EndOfFile Definition <- Identifier LEFTARROW Expression Expression <- Sequence (SLASH Sequence)* Sequence <- Prefix* Prefix <- (AND / NOT)? Suffix Suffix <- Primary (QUESTION / STAR / PLUS)? Primary <- Identifier !LEFTARROW / OPEN Expression CLOSE / Literal / Class / DOT # Lexical syntax Identifier <- IdentStart IdentCont* Spacing IdentStart <- [a-zA-Z_] IdentCont <- IdentStart / [0-9] Literal <- ['] (!['] Char)* ['] Spacing / ["] (!["] Char)* ["] Spacing Class <- '[' (!']' Range)* ']' Spacing Range <- Char '-' Char / Char Char <- '\\' [nrt'"\[\]\\] / '\\' [0-2][0-7][0-7] / '\\' [0-7][0-7]? / !'\\' . LEFTARROW <- '<-' Spacing SLASH <- '/' Spacing AND <- '&' Spacing NOT <- '!' Spacing QUESTION <- '?' Spacing STAR <- '*' Spacing PLUS <- '+' Spacing OPEN <- '(' Spacing CLOSE <- ')' Spacing DOT <- '.' Spacing Spacing <- (Space / Comment)* Comment <- '#' (!EndOfLine .)* EndOfLine Space <- ' ' / '\t' / EndOfLine EndOfLine <- '\r\n' / '\n' / '\r' EndOfFile <- !.tao-pegtl-3.2.7/src/example/pegtl/peg2pegtl.cpp000066400000000000000000000405201426407250600213600ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Copyright (c) 2021 Daniel Deptford // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined( _MSC_VER ) #include #define TAO_PEGTL_STRCASECMP _stricmp #else #include #define TAO_PEGTL_STRCASECMP strcasecmp #endif #include #include #include namespace TAO_PEGTL_NAMESPACE { namespace peg { using node_ptr = std::unique_ptr< parse_tree::node >; namespace { std::string prefix = "tao::pegtl::"; std::unordered_set< std::string > keywords = { "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class", "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue", "co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "requires", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" }; using identifiers_t = std::vector< std::string >; identifiers_t identifiers_defined; identifiers_t identifiers; identifiers_t::reverse_iterator find_identifier( identifiers_t& r, const std::string& v, const identifiers_t::reverse_iterator& rbegin ) { return std::find_if( rbegin, r.rend(), [ & ]( const identifiers_t::value_type& p ) { return TAO_PEGTL_STRCASECMP( p.c_str(), v.c_str() ) == 0; } ); } identifiers_t::reverse_iterator find_identifier( identifiers_t& r, const std::string& v ) { return find_identifier( r, v, r.rbegin() ); } char char_node_to_char( const node_ptr& n ) { const char ch = n->string_view().at( 0 ); if( ch == '\\' ) { static const std::unordered_map< char, char > mappings( { { 'n', '\n' }, { 'r', '\r' }, { 't', '\t' }, { '\'', '\'' }, { '\"', '\"' }, { '[', '[' }, { ']', ']' }, { '\\', '\\' }, } ); auto iter = mappings.find( n->string_view().at( 1 ) ); if( iter != std::end( mappings ) ) { return iter->second; } return static_cast< char >( std::stoi( n->string().substr( 1 ) ) ); } return ch; } void append_char_node( std::string& s, const node_ptr& n ) { if( !s.empty() ) { s += ", "; } s += '\''; const char c = char_node_to_char( n ); static const std::unordered_map< char, std::string > escapes( { { '\b', "b" }, { '\f', "f" }, { '\n', "n" }, { '\r', "r" }, { '\t', "t" }, { '\v', "v" }, { '\\', "\\" }, { '\'', "\'" }, } ); auto iter = escapes.find( c ); if( iter != std::end( escapes ) ) { s += '\\'; s += iter->second; } else { s += c; } s += '\''; } } // namespace #if defined( __cpp_exceptions ) // Using must_if<> we define a control class which is used for // the parsing run instead of the default control class. // // This improves the errors reported to the user. // // The following turns local errors into global errors, i.e. // if one of the rules for which a custom error message is // defined fails, it throws a parse_error exception (aka global // failure) instead of returning false (aka local failure). // clang-format off template< typename > inline constexpr const char* error_message = nullptr; template<> inline constexpr auto error_message< peg::grammar::Char > = "unterminated character literal"; template<> inline constexpr auto error_message< peg::grammar::Expression > = "unterminated expression"; template<> inline constexpr auto error_message< peg::grammar::Grammar > = "unterminated grammar"; template<> inline constexpr auto error_message< peg::grammar::Range > = "unterminated range"; // clang-format on struct error { template< typename Rule > static constexpr auto message = error_message< Rule >; }; template< typename Rule > using control = must_if< error >::control< Rule >; #else template< typename Rule > using control = normal< Rule >; #endif // Since we are going to generate a parse tree, we define a // selector that decides which rules will be included in our // parse tree, which rules will be omitted from the parse tree, // and which of the nodes will store the matched content. // Additionally, some nodes will fold when they have exactly // one child node. (see fold_one below) template< typename Rule > struct selector : pegtl::parse_tree::selector< Rule, pegtl::parse_tree::store_content::on< grammar::Definition, grammar::Prefix, grammar::Suffix, grammar::Sequence, grammar::Expression, grammar::Class, grammar::Literal, grammar::Identifier, grammar::IdentStart, grammar::Range, grammar::Char, grammar::AND, grammar::NOT, grammar::QUESTION, grammar::STAR, grammar::PLUS, grammar::DOT >, pegtl::parse_tree::fold_one::on< grammar::IdentCont > > { template< typename... States > static void transform( node_ptr& n ) { // As we use the PEG grammar taken directly from the original PEG // paper, some nodes may have excess content from nodes not included // in the parse tree (e.g. Comment, Space, etc). if( !n->children.empty() ) { n->m_end = n->children.back()->m_end; } } }; std::string to_string( const node_ptr& n ); std::string to_string( const std::vector< node_ptr >& v ); namespace { std::string get_identifier( const node_ptr& n ) { assert( n->is_type< grammar::Identifier >() ); std::string v = n->string(); std::replace( v.begin(), v.end(), '-', '_' ); return v; } std::string get_identifier( const node_ptr& n, const bool print_forward_declarations ) { std::string v = get_identifier( n ); const auto it = find_identifier( identifiers, v ); if( it != identifiers.rend() ) { return *it; } if( keywords.count( v ) != 0 || v.find( "__" ) != std::string::npos ) { #if defined( __cpp_exceptions ) throw parse_error( '\'' + n->string() + "' is a reserved identifier", n->begin() ); #else std::cerr << '\'' + n->string() + "' is a reserved identifier" << std::endl; std::terminate(); #endif } if( print_forward_declarations && find_identifier( identifiers_defined, v ) != identifiers_defined.rend() ) { std::cout << "struct " << v << ";\n"; } identifiers.push_back( v ); return v; } std::unordered_map< std::string, parse_tree::node* > previous_identifiers; } // namespace template<> struct selector< grammar::Definition > : std::true_type { template< typename... States > static void transform( node_ptr& n ) { const auto idname = get_identifier( n->children.front() ); assert( n->children.back()->is_type< grammar::Expression >() ); if( !previous_identifiers.try_emplace( idname, n.get() ).second ) { #if defined( __cpp_exceptions ) throw parse_error( "identifier '" + idname + "' is already defined", n->begin() ); #else std::cerr << "identifier '" + idname + "' is already defined" << std::endl; std::terminate(); #endif } } }; // Finally, the generated parse tree for each node is converted to // a C++ source code string. struct stringifier { using function_t = std::string ( * )( const node_ptr& n ); function_t default_ = nullptr; std::unordered_map< std::string_view, function_t > map_; template< typename T > void add( const function_t& f ) { map_.try_emplace( demangle< T >(), f ); } std::string operator()( const node_ptr& n ) const { const auto it = map_.find( n->type ); if( it != map_.end() ) { return it->second( n ); } return default_( n ); } }; stringifier make_stringifier() { stringifier nrv; nrv.default_ = []( const node_ptr& n ) -> std::string { #if defined( __cpp_exceptions ) throw parse_error( "missing to_string() for " + std::string( n->type ), n->begin() ); #else std::cerr << "missing to_string() for " + std::string( n->type ) << std::endl; std::terminate(); #endif }; nrv.add< grammar::Identifier >( []( const node_ptr& n ) { return get_identifier( n, true ); } ); nrv.add< grammar::Definition >( []( const node_ptr& n ) { return "struct " + get_identifier( n->children.front(), false ) + " : " + to_string( n->children.back() ) + " {};"; } ); nrv.add< grammar::Char >( []( const node_ptr& n ) { std::string s; append_char_node( s, n ); return s; } ); nrv.add< grammar::Sequence >( []( const node_ptr& n ) { if( n->children.size() == 1 ) { return to_string( n->children.front() ); } return prefix + "seq< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::Expression >( []( const node_ptr& n ) { if( n->children.size() == 1 ) { return to_string( n->children.front() ); } return prefix + "sor< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::Range >( []( const node_ptr& n ) { if( n->children.size() == 1 ) { return prefix + "one< " + to_string( n->children.front() ) + " >"; } return prefix + "range< " + to_string( n->children.front() ) + ", " + to_string( n->children.back() ) + " >"; } ); nrv.add< grammar::Class >( []( const node_ptr& n ) { if( n->children.size() == 1 ) { return to_string( n->children.front() ); } return prefix + "sor < " + to_string( n->children ) + " >"; } ); nrv.add< grammar::Literal >( []( const node_ptr& n ) { if( n->children.size() == 1 ) { return prefix + "one< " + to_string( n->children.front() ) + " >"; } return prefix + "string< " + to_string( n->children ) + " >"; } ); nrv.add< grammar::Prefix >( []( const node_ptr& n ) { auto sub = to_string( n->children.back() ); if( n->children.front()->is_type< grammar::AND >() ) { return prefix + "at< " + sub + " >"; } if( n->children.front()->is_type< grammar::NOT >() ) { return prefix + "not_at< " + sub + " >"; } assert( n->children.size() == 1 ); return sub; } ); nrv.add< grammar::Suffix >( []( const node_ptr& n ) { auto sub = to_string( n->children.front() ); if( n->children.back()->is_type< grammar::QUESTION >() ) { return prefix + "opt< " + sub + " >"; } if( n->children.back()->is_type< grammar::STAR >() ) { return prefix + "star< " + sub + " >"; } if( n->children.back()->is_type< grammar::PLUS >() ) { return prefix + "plus< " + sub + " >"; } assert( n->children.size() == 1 ); return sub; } ); nrv.add< grammar::DOT >( []( const node_ptr& /*unused*/ ) { return prefix + "any"; } ); return nrv; } std::string to_string( const node_ptr& n ) { static stringifier s = make_stringifier(); return s( n ); } std::string to_string( const std::vector< node_ptr >& v ) { std::string result; for( const auto& c : v ) { if( !result.empty() ) { result += ", "; } result += to_string( c ); } return result; } } // namespace peg } // namespace TAO_PEGTL_NAMESPACE int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { using namespace TAO_PEGTL_NAMESPACE; if( argc != 2 ) { std::cerr << "Usage: " << argv[ 0 ] << " SOURCE\n"; return 1; } file_input in( argv[ 1 ] ); #if defined( __cpp_exceptions ) try { const auto root = parse_tree::parse< peg::grammar::Grammar, peg::selector, nothing, peg::control >( in ); for( const auto& definition : root->children ) { peg::identifiers_defined.push_back( peg::get_identifier( definition->children.front() ) ); } for( const auto& rule : root->children ) { std::cout << peg::to_string( rule ) << '\n'; } } catch( const parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << '\n'; } #else if( const auto root = parse_tree::parse< peg::grammar::Grammar, peg::selector, nothing, peg::control >( in ) ) { for( const auto& definition : root->children ) { peg::identifiers_defined.push_back( peg::get_identifier( definition->children.front() ) ); } for( const auto& rule : root->children ) { std::cout << peg::to_string( rule ) << '\n'; } } else { std::cerr << "error occurred" << std::endl; return 1; } #endif return 0; } tao-pegtl-3.2.7/src/example/pegtl/proto3.cpp000066400000000000000000000017611426407250600207210ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { using namespace TAO_PEGTL_NAMESPACE; if( analyze< proto3::proto >() != 0 ) { return 1; } for( int i = 1; i < argc; ++i ) { file_input in( argv[ i ] ); try { parse< proto3::proto >( in ); } catch( const parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << '\n'; } } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/recover.cpp000066400000000000000000000072601426407250600211400ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ // This is a small experiment with a grammar that can recover from errors. // // Triggered by https://github.com/taocpp/PEGTL/issues/55 // // The grammar will recognise simple expressions terminated by semicolons. // When an expression fails to parse, it skips to the next expression // by looking for the terminator. // // Try: build/src/example/pegtl/recover '1+2*3;1+2*(3-)-4;-5;6/;7*(8+9)' #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include using namespace TAO_PEGTL_NAMESPACE; // clang-format off template< typename T > struct skipping : until< T > {}; template< typename R, typename T > struct recoverable : sor< try_catch< must< R >, T >, skipping< T > > {}; struct expr_sum; struct expr_identifier : identifier {}; struct expr_number : plus< digit > {}; struct expr_braced : if_must< one< '(' >, pad< expr_sum, space >, one< ')' > > {}; struct expr_value : sor< expr_identifier, expr_number, expr_braced > {}; struct expr_power : list< must< expr_value >, one< '^' >, space > {}; struct expr_prod : list_must< expr_power, one< '*', '/', '%' >, space > {}; struct expr_sum : list_must< expr_prod, one< '+', '-' >, space > {}; struct term : sor< one< ';' >, eof > {}; struct expr : pad< expr_sum, space > {}; struct recoverable_expr : recoverable< expr, term > {}; struct my_grammar : star< not_at< eof >, recoverable_expr > {}; // clang-format on template< typename Rule > struct my_action {}; template< typename T > struct my_action< skipping< T > > { template< typename ActionInput > static void apply( const ActionInput& in, bool& error ) { if( !error ) { std::cout << in.position() << ": Invalid expression \"" << in.string() << "\"" << std::endl; } error = true; } }; template< typename R > struct found { template< typename ActionInput > static void apply( const ActionInput& in, bool& error ) { if( !error ) { std::cout << in.position() << ": Found " << demangle< R >() << ": \"" << in.string() << "\"" << std::endl; } } }; // clang-format off // template<> struct my_action< expr_identifier > : found< expr_identifier > {}; // template<> struct my_action< expr_number > : found< expr_number > {}; // template<> struct my_action< expr_braced > : found< expr_braced > {}; // template<> struct my_action< expr_value > : found< expr_value > {}; // template<> struct my_action< expr_power > : found< expr_power > {}; // template<> struct my_action< expr_prod > : found< expr_prod > {}; // template<> struct my_action< expr_sum > : found< expr_sum > {}; template<> struct my_action< expr > : found< expr > {}; // clang-format on template<> struct my_action< recoverable_expr > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, bool& error ) { error = false; std::cout << std::string( 79, '-' ) << std::endl; } }; template< typename Rule > struct my_control : normal< Rule > { template< typename ParseInput, typename... States > [[noreturn]] static void raise( const ParseInput& in, States&&... st ) { std::cout << in.position() << ": Parse error matching " << demangle< Rule >() << std::endl; normal< Rule >::raise( in, st... ); } }; int main( int argc, char** argv ) { for( int i = 1; i < argc; ++i ) { argv_input in( argv, i ); bool error = false; parse< my_grammar, my_action, my_control >( in, error ); } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/s_expression.cpp000066400000000000000000000063241426407250600222140ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include namespace sexpr { // clang-format off struct hash_comment : tao::pegtl::until< tao::pegtl::eolf > {}; struct list; struct list_comment : tao::pegtl::if_must< tao::pegtl::at< tao::pegtl::one< '(' > >, tao::pegtl::disable< list > > {}; struct read_include : tao::pegtl::seq< tao::pegtl::one< ' ' >, tao::pegtl::one< '"' >, tao::pegtl::plus< tao::pegtl::not_one< '"' > >, tao::pegtl::one< '"' > > {}; struct hash_include : tao::pegtl::if_must< tao::pegtl::string< 'i', 'n', 'c', 'l', 'u', 'd', 'e' >, read_include > {}; struct hashed : tao::pegtl::if_must< tao::pegtl::one< '#' >, tao::pegtl::sor< hash_include, list_comment, hash_comment > > {}; struct number : tao::pegtl::plus< tao::pegtl::digit > {}; struct symbol : tao::pegtl::identifier {}; struct atom : tao::pegtl::sor< number, symbol > {}; struct anything; struct list : tao::pegtl::if_must< tao::pegtl::one< '(' >, tao::pegtl::until< tao::pegtl::one< ')' >, anything > > {}; struct normal : tao::pegtl::sor< atom, list > {}; struct anything : tao::pegtl::sor< tao::pegtl::space, hashed, normal > {}; struct main : tao::pegtl::until< tao::pegtl::eof, tao::pegtl::must< anything > > {}; // clang-format on template< typename Rule > struct action {}; template<> struct action< tao::pegtl::plus< tao::pegtl::not_one< '"' > > > { template< typename ActionInput > static void apply( const ActionInput& in, std::string& fn ) { fn = in.string(); } }; template<> struct action< hash_include > { template< typename ActionInput > static void apply( const ActionInput& in, std::string& fn ) { std::string f2; // Here f2 is the state argument for the nested parsing // run (to store the value of the string literal like in // the upper-level parsing run), fn is the value of the // last string literal that we use as filename here, and // the input is passed on for chained error messages (as // in "error in line x file foo included from file bar...) tao::pegtl::file_input i2( fn ); tao::pegtl::parse_nested< main, sexpr::action >( in, i2, f2 ); } }; } // namespace sexpr int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { if( tao::pegtl::analyze< sexpr::main >() != 0 ) { return 1; } for( int i = 1; i < argc; ++i ) { std::string fn; tao::pegtl::argv_input in( argv, i ); try { tao::pegtl::parse< sexpr::main, sexpr::action >( in, fn ); } catch( const tao::pegtl::parse_error& e ) { const auto p = e.positions().front(); std::cerr << e.what() << '\n' << in.line_at( p ) << '\n' << std::setw( p.column ) << '^' << '\n'; } } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/sum.cpp000066400000000000000000000030151426407250600202710ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include using namespace TAO_PEGTL_NAMESPACE; #include "double.hpp" namespace sum { struct padded_double : pad< double_::grammar, space > {}; struct double_list : list< padded_double, one< ',' > > {}; struct grammar : seq< double_list, eof > {}; template< typename Rule > struct action {}; template<> struct action< double_::grammar > { template< typename ActionInput > static void apply( const ActionInput& in, double& sum ) { // assume all values will fit into a C++ double std::stringstream ss( in.string() ); double v; ss >> v; sum += v; } }; } // namespace sum int main() { std::cout << "Give me a comma separated list of numbers.\n"; std::cout << "The numbers are added using the PEGTL.\n"; std::cout << "Type [q or Q] to quit\n\n"; std::string str; while( !std::getline( std::cin, str ).fail() ) { if( str.empty() || str[ 0 ] == 'q' || str[ 0 ] == 'Q' ) { break; } double d = 0.0; memory_input in( str, "std::cin" ); if( parse< sum::grammar, sum::action >( in, d ) ) { std::cout << "parsing OK; sum = " << d << std::endl; } else { std::cout << "parsing failed" << std::endl; } } } tao-pegtl-3.2.7/src/example/pegtl/symbol_table.cpp000066400000000000000000000064321426407250600221470ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; namespace example { // Simple example for parsing with a symbol table; here the custom // logic is in the semantic actions and an exception is thrown on // error -- other possibilities are to let the actions' apply() // function return a bool instead, or to use a custom rule for the // matching of name within assignment that uses the symbol table // in its match() function. struct state { unsigned converted = 0; std::string temporary; std::map< std::string, unsigned > symbol_table; }; // clang-format off struct semi : pegtl::one< ';' > {}; struct blank0 : pegtl::star< pegtl::blank > {}; struct blanks : pegtl::plus< pegtl::blank > {}; struct name : pegtl::plus< pegtl::alpha > {}; struct value : pegtl::plus< pegtl::digit > {}; struct equals : pegtl::pad< pegtl::one< '=' >, pegtl::blank > {}; struct definition : pegtl::if_must< pegtl::string< 'd', 'e', 'f' >, blanks, name, blank0, semi > {}; struct assignment : pegtl::if_must< name, equals, value, blank0, semi > {}; struct something : pegtl::sor< pegtl::space, definition, assignment > {}; struct grammar : pegtl::until< pegtl::eof, pegtl::must< something > > {}; // clang-format on template< typename Rule > struct action {}; template<> struct action< value > { template< typename ActionInput > static void apply( const ActionInput& in, state& st ) { pegtl::unsigned_action::apply( in, st.converted ); } }; template<> struct action< name > { template< typename ActionInput > static void apply( const ActionInput& in, state& st ) { st.temporary = in.string(); } }; template<> struct action< definition > { template< typename ActionInput > static void apply( const ActionInput& in, state& st ) { if( !st.symbol_table.try_emplace( st.temporary, 0 ).second ) { throw pegtl::parse_error( "duplicate symbol " + st.temporary, in ); } } }; template<> struct action< assignment > { template< typename ActionInput > static void apply( const ActionInput& in, state& st ) { const auto i = st.symbol_table.find( st.temporary ); if( i == st.symbol_table.end() ) { throw pegtl::parse_error( "unknown symbol " + st.temporary, in ); } i->second = st.converted; } }; } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { pegtl::file_input in( argv[ i ] ); example::state st; pegtl::parse< example::grammar, example::action >( in, st ); for( const auto& j : st.symbol_table ) { std::cout << j.first << " = " << j.second << std::endl; } } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/token_input.cpp000066400000000000000000000150461426407250600220330ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include #include #include // This file contains some experiments towards generalising inputs to // represent sequences of arbitrary objects; it's not very complete, but // it does get a minimal example up-and-running. One main limitation is // that nothing that throws a parse_error can be used because positions // aren't supported by the token_parse_input. namespace TAO_PEGTL_NAMESPACE { template< typename ParseInput > class token_action_input { public: using input_t = ParseInput; using value_t = typename ParseInput::value_t; using iterator_t = typename ParseInput::iterator_t; token_action_input( const iterator_t& in_begin, const ParseInput& in_input ) noexcept : m_begin( in_begin ), m_input( in_input ) {} token_action_input( const token_action_input& ) = delete; token_action_input( token_action_input&& ) = delete; ~token_action_input() = default; token_action_input& operator=( const token_action_input& ) = delete; token_action_input& operator=( token_action_input&& ) = delete; [[nodiscard]] const iterator_t& iterator() const noexcept { return m_begin; } [[nodiscard]] const ParseInput& input() const noexcept { return m_input; } [[nodiscard]] iterator_t begin() const noexcept { return m_begin; } [[nodiscard]] iterator_t end() const noexcept { return m_input.current(); } [[nodiscard]] bool empty() const noexcept { return begin() == end(); } [[nodiscard]] std::size_t size() const noexcept { return std::size_t( end() - begin() ); } protected: const iterator_t m_begin; const ParseInput& m_input; }; template< typename T, typename Source = std::string > class token_parse_input { public: using value_t = T; using source_t = Source; using iterator_t = const T*; using action_t = token_action_input< token_parse_input >; template< typename S > token_parse_input( const iterator_t in_begin, const iterator_t in_end, S&& in_source ) : m_begin( in_begin ), m_current( in_begin ), m_end( in_end ), m_source( std::forward< S >( in_source ) ) {} template< typename S > token_parse_input( const std::vector< T >& in_vector, S&& in_source ) : token_parse_input( in_vector.data(), in_vector.data() + in_vector.size(), std::forward< S >( in_source ) ) {} token_parse_input( const token_parse_input& ) = delete; token_parse_input( token_parse_input&& ) = delete; ~token_parse_input() = default; token_parse_input& operator=( const token_parse_input& ) = delete; token_parse_input& operator=( token_parse_input&& ) = delete; void discard() const noexcept {} void require( const std::size_t /*unused*/ ) const noexcept {} [[nodiscard]] iterator_t current() const noexcept { return m_current; } [[nodiscard]] iterator_t begin() const noexcept { return m_begin; } [[nodiscard]] iterator_t end( const std::size_t /*unused*/ = 0 ) const noexcept { return m_end; } [[nodiscard]] std::size_t byte() const noexcept { return std::size_t( m_current - m_begin ); // We don't return the byte offset even if this function is still called 'byte'. } template< rewind_mode M > [[nodiscard]] internal::marker< iterator_t, M > mark() noexcept { return internal::marker< iterator_t, M >( iterator() ); } void bump( const std::size_t in_count = 1 ) noexcept { std::advance( m_current, in_count ); } void restart() { m_current = m_begin; } [[nodiscard]] const Source& source() const noexcept { return this->m_source; } [[nodiscard]] bool empty() const noexcept { return this->current() == this->end(); } [[nodiscard]] std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept { return std::size_t( this->end() - this->current() ); } [[nodiscard]] T peek_token( const std::size_t offset = 0 ) const noexcept { return this->current()[ offset ]; } [[nodiscard]] iterator_t& iterator() noexcept { return this->m_current; } [[nodiscard]] const iterator_t& iterator() const noexcept { return this->m_current; } private: const iterator_t m_begin; iterator_t m_current; const iterator_t m_end; const Source m_source; }; namespace internal { template< typename Type, Type Value > struct token_type { using rule_t = token_type; using subs_t = empty_list; template< typename ParseInput > static bool match( ParseInput& in ) { if( ( !in.empty() ) && ( in.peek_token().type == Value ) ) { in.bump( 1 ); return true; } return false; } }; } // namespace internal template< auto Value > using token_type = internal::token_type< decltype( Value ), Value >; template< typename Name, typename Type, Type Value > struct analyze_traits< Name, internal::token_type< Type, Value > > : analyze_any_traits<> {}; } // namespace TAO_PEGTL_NAMESPACE using namespace TAO_PEGTL_NAMESPACE; enum my_type { a, b, c, d, e, f }; struct my_token { my_type type; std::string data; }; template< typename Rule > struct my_action : nothing< Rule > {}; template<> struct my_action< eof > { static void apply0() { std::cout << "We have eof!" << std::endl; } }; template<> struct my_action< token_type< my_type::b > > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/ ) { std::cout << "We have a token of type 'b'!" << std::endl; } }; struct my_grammar : seq< plus< token_type< my_type::b > >, eof > {}; int main() { const std::vector< my_token > v{ { my_type::b, "" }, { my_type::b, "" } }; token_parse_input< my_token > in( v, __FUNCTION__ ); if( !parse< my_grammar, my_action >( in ) ) { return 1; } return 0; } tao-pegtl-3.2.7/src/example/pegtl/unescape.cpp000066400000000000000000000046621426407250600213010ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include #include using namespace TAO_PEGTL_NAMESPACE; namespace example { // Grammar for string literals with some escape sequences from the C language: // - \x followed by two hex-digits to insert any byte value. // - \u followed by four hex-digits to insert a Unicode code point. // - \U followed by eight hex-digits to insert any Unicode code points. // - A backslash followed by one of the characters listed in the grammar below. // clang-format off struct escaped_x : seq< one< 'x' >, rep< 2, xdigit > > {}; struct escaped_u : seq< one< 'u' >, rep< 4, xdigit > > {}; struct escaped_U : seq< one< 'U' >, rep< 8, xdigit > > {}; struct escaped_c : one< '\'', '"', '?', '\\', 'a', 'b', 'f', 'n', 'r', 't', 'v' > {}; struct escaped : sor< escaped_x, escaped_u, escaped_U, escaped_c > {}; struct character : if_then_else< one< '\\' >, escaped, utf8::range< 0x20, 0x10FFFF > > {}; struct literal : seq< one< '"' >, until< one< '"' >, character > > {}; struct padded : seq< pad< literal, blank >, eof > {}; // Action class that uses the actions from tao/pegtl/contrib/unescape.hpp to // produce a UTF-8 encoded result string where all escape sequences are // replaced with their intended meaning. template< typename Rule > struct action {}; template<> struct action< utf8::range< 0x20, 0x10FFFF > > : unescape::append_all {}; template<> struct action< escaped_x > : unescape::unescape_x {}; template<> struct action< escaped_u > : unescape::unescape_u {}; template<> struct action< escaped_U > : unescape::unescape_u {}; template<> struct action< escaped_c > : unescape::unescape_c< escaped_c, '\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v' > {}; // clang-format on } // namespace example int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { std::string s; argv_input in( argv, i ); if( parse< example::padded, example::action >( in, s ) ) { std::cout << "argv[ " << i << " ] = " << s << std::endl; } else { std::cerr << "error parsing: " << argv[ i ] << std::endl; } } return 0; } tao-pegtl-3.2.7/src/example/pegtl/uri.cpp000066400000000000000000000057021426407250600202710ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; struct URI { std::string scheme; std::string authority; std::string userinfo; std::string host; std::string port; std::string path; std::string query; std::string fragment; explicit URI( const std::string& uri ); }; namespace uri { template< std::string URI::*Field > struct bind { template< typename ActionInput > static void apply( const ActionInput& in, URI& uri ) { uri.*Field = in.string(); } }; // clang-format off template< typename Rule > struct action {}; template<> struct action< pegtl::uri::scheme > : bind< &URI::scheme > {}; template<> struct action< pegtl::uri::authority > : bind< &URI::authority > {}; // userinfo: see below template<> struct action< pegtl::uri::host > : bind< &URI::host > {}; template<> struct action< pegtl::uri::port > : bind< &URI::port > {}; template<> struct action< pegtl::uri::path_noscheme > : bind< &URI::path > {}; template<> struct action< pegtl::uri::path_rootless > : bind< &URI::path > {}; template<> struct action< pegtl::uri::path_absolute > : bind< &URI::path > {}; template<> struct action< pegtl::uri::path_abempty > : bind< &URI::path > {}; template<> struct action< pegtl::uri::query > : bind< &URI::query > {}; template<> struct action< pegtl::uri::fragment > : bind< &URI::fragment > {}; // clang-format on template<> struct action< pegtl::uri::opt_userinfo > { template< typename ActionInput > static void apply( const ActionInput& in, URI& uri ) { if( !in.empty() ) { uri.userinfo = std::string( in.begin(), in.size() - 1 ); } } }; } // namespace uri URI::URI( const std::string& uri ) { using grammar = pegtl::must< pegtl::uri::URI >; pegtl::memory_input input( uri, "uri" ); pegtl::parse< grammar, uri::action >( input, *this ); } 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; } return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/uri_print_debug.cpp000066400000000000000000000010371426407250600226500ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include int main() // NOLINT(bugprone-exception-escape) { tao::pegtl::print_debug< tao::pegtl::uri::URI >( std::cout ); return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/uri_print_names.cpp000066400000000000000000000010371426407250600226650ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include int main() // NOLINT(bugprone-exception-escape) { tao::pegtl::print_names< tao::pegtl::uri::URI >( std::cout ); return 0; } #endif tao-pegtl-3.2.7/src/example/pegtl/uri_trace.cpp000066400000000000000000000014371426407250600214500ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cerr << "Exception support required, example unavailable." << std::endl; return 1; } #else #include #include #include #include namespace pegtl = TAO_PEGTL_NAMESPACE; using grammar = pegtl::must< pegtl::uri::URI >; int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape) { for( int i = 1; i < argc; ++i ) { std::cout << "Parsing " << argv[ i ] << std::endl; pegtl::argv_input in( argv, i ); pegtl::complete_trace< grammar >( in ); } return 0; } #endif tao-pegtl-3.2.7/src/test/000077500000000000000000000000001426407250600151735ustar00rootroot00000000000000tao-pegtl-3.2.7/src/test/pegtl/000077500000000000000000000000001426407250600163065ustar00rootroot00000000000000tao-pegtl-3.2.7/src/test/pegtl/CMakeLists.txt000066400000000000000000000100541426407250600210460ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.8...3.19) set(test_sources action_enable.cpp action_match.cpp actions_one.cpp actions_three.cpp actions_two.cpp argv_input.cpp ascii_classes.cpp ascii_eol.cpp ascii_eolf.cpp ascii_forty_two.cpp ascii_identifier.cpp ascii_istring.cpp ascii_keyword.cpp ascii_shebang.cpp ascii_string.cpp ascii_three.cpp ascii_two.cpp buffer_input.cpp change_action_and_state.cpp change_action_and_states.cpp change_state.cpp change_states.cpp check_bytes.cpp contains.cpp contrib_alphabet.cpp contrib_analyze.cpp contrib_control_action.cpp contrib_coverage.cpp contrib_function.cpp contrib_http.cpp contrib_if_then.cpp contrib_instantiate.cpp contrib_integer.cpp contrib_iri.cpp contrib_json.cpp contrib_parse_tree.cpp contrib_parse_tree_to_dot.cpp contrib_partial_trace.cpp contrib_predicates.cpp contrib_print.cpp contrib_raw_string.cpp contrib_remove_first_state.cpp contrib_remove_last_states.cpp contrib_rep_one_min_max.cpp contrib_rep_string.cpp contrib_separated_seq.cpp contrib_state_control.cpp contrib_to_string.cpp contrib_trace1.cpp contrib_trace2.cpp contrib_unescape.cpp contrib_uri.cpp control_unwind.cpp data_cstring.cpp demangle.cpp discard_input.cpp enable_control.cpp error_message.cpp file_cstream.cpp file_file.cpp file_istream.cpp file_mmap.cpp file_read.cpp icu_general.cpp internal_endian.cpp internal_file_mapper.cpp internal_file_opener.cpp limit_bytes.cpp limit_depth.cpp parse_error.cpp pegtl_string_t.cpp position.cpp restart_input.cpp rule_action.cpp rule_apply0.cpp rule_apply.cpp rule_at.cpp rule_bof.cpp rule_bol.cpp rule_bytes.cpp rule_control.cpp rule_disable.cpp rule_discard.cpp rule_enable.cpp rule_eof.cpp rule_failure.cpp rule_if_apply.cpp rule_if_must.cpp rule_if_must_else.cpp rule_if_then_else.cpp rule_list.cpp rule_list_must.cpp rule_list_tail.cpp rule_minus.cpp rule_must.cpp rule_not_at.cpp rule_opt.cpp rule_opt_must.cpp rule_pad.cpp rule_pad_opt.cpp rule_plus.cpp rule_raise.cpp rule_rematch.cpp rule_rep.cpp rule_rep_max.cpp rule_rep_min.cpp rule_rep_min_max.cpp rule_rep_opt.cpp rule_require.cpp rule_seq.cpp rule_sor.cpp rule_star.cpp rule_star_must.cpp rule_state.cpp rule_success.cpp rule_try_catch.cpp rule_until.cpp test_empty.cpp test_result.cpp test_setup.cpp uint16_general.cpp uint32_general.cpp uint64_general.cpp uint8_general.cpp utf16_general.cpp utf32_general.cpp utf8_general.cpp visit.cpp ) # file(GLOB ...) is used to validate the above list of test_sources file(GLOB glob_test_sources RELATIVE ${CMAKE_CURRENT_LIST_DIR} *.cpp) foreach(testsourcefile ${test_sources}) if(${testsourcefile} IN_LIST glob_test_sources) list(REMOVE_ITEM glob_test_sources ${testsourcefile}) else() message(SEND_ERROR "File ${testsourcefile} is missing from src/test/pegtl") endif() get_filename_component(exename pegtl-test-${testsourcefile} NAME_WE) add_executable(${exename} ${testsourcefile}) target_link_libraries(${exename} PRIVATE taocpp::pegtl) set_target_properties(${exename} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) if(MSVC) target_compile_options(${exename} PRIVATE /W4 /WX /utf-8) else() target_compile_options(${exename} PRIVATE -pedantic -Wall -Wextra -Wshadow -Werror) endif() 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() add_test(NAME ${exename} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${exename}) endif() endforeach() if(glob_test_sources) foreach(ignored_source_file ${glob_test_sources}) message(SEND_ERROR "File ${ignored_source_file} in src/test/pegtl is ignored") endforeach() endif() tao-pegtl-3.2.7/src/test/pegtl/ExecuteOnAndroid.cmake000066400000000000000000000042571426407250600225200ustar00rootroot00000000000000 if("${ANDROID_NDK}" STREQUAL "") message(FATAL_ERROR "cmake parameter ANDROID_NDK is not set!") endif() if(NOT EXISTS "${ANDROID_NDK}/../platform-tools/adb") message(FATAL_ERROR "adb is not found in ${ANDROID_NDK}/../platform-tools") endif() get_filename_component(UNITTEST_FILENAME ${UNITTEST} NAME) message(STATUS "Cleanup /data/local/tmp ...") execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb shell "rm -r /data/local/tmp/*" OUTPUT_QUIET) foreach(_TEST_DATA IN ITEMS ${TEST_RESOURCES}) get_filename_component(_DIR ${_TEST_DATA} DIRECTORY) message(STATUS "Create /data/local/tmp/${_DIR} directory structure on android ...") execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb shell "mkdir -p /data/local/tmp/${_DIR}" OUTPUT_QUIET) message(STATUS "Push ${_TEST_DATA} from ${TEST_RESOURCES_DIR} to android ...") execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb push ${_TEST_DATA} /data/local/tmp/${_DIR} OUTPUT_QUIET WORKING_DIRECTORY ${TEST_RESOURCES_DIR}) endforeach() if(LIBRARY_DIR) message(STATUS "Push ${LIBRARY_DIR} to android ...") execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb push ${LIBRARY_DIR} /data/local/tmp/ OUTPUT_QUIET) endif() message(STATUS "Push ${UNITTEST} to android ...") if(NOT EXISTS "${UNITTEST}") message(FATAL_ERROR "${UNITTEST} is not found!") endif() execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb push ${UNITTEST} /data/local/tmp/ OUTPUT_QUIET) message(STATUS "Execute ${UNITTEST_FILENAME} on android ...") execute_process( COMMAND ${ANDROID_NDK}/../platform-tools/adb shell "cd /data/local/tmp;su root sh -c 'LD_LIBRARY_PATH=/data/local/tmp/lib TMPDIR=/data/local/tmp HOME=/data/local/tmp ./${UNITTEST_FILENAME};echo exit code $?'" RESULT_VARIABLE _RESULT OUTPUT_VARIABLE _OUT ERROR_VARIABLE _ERR ) if(_RESULT) message(FATAL_ERROR "Execution of ${UNITTEST_FILENAME} failed") else() string(REGEX MATCH "exit code ([0-9]+)" _EXIT_CODE ${_OUT}) if(NOT "${CMAKE_MATCH_1}" EQUAL 0) string(REGEX REPLACE "exit code [0-9]+" "" _PRINT_OUT ${_OUT}) message(FATAL_ERROR "${UNITTEST_FILENAME} execution error: ${_PRINT_OUT} ${_ERR}") endif() endif() tao-pegtl-3.2.7/src/test/pegtl/action_enable.cpp000066400000000000000000000024451426407250600216020ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct C : one< 'c' > {}; struct BCB : seq< B, C, B > {}; struct ABCBA : seq< A, BCB, A > {}; // clang-format on template< typename > struct my_action {}; template<> struct my_action< A > { static void apply0( int& a, int& /*b*/, int& /*c*/ ) { ++a; } }; template<> struct my_action< B > : disable_action { static void apply0( int& /*a*/, int& b, int& /*c*/ ) { ++b; } }; template<> struct my_action< C > : enable_action { static void apply0( int& /*a*/, int& /*b*/, int& c ) { ++c; } }; void unit_test() { memory_input<> in( "abcba", "" ); int a = 0; int b = 0; int c = 0; const auto result = parse< ABCBA, my_action >( in, a, b, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( a == 2 ); TAO_PEGTL_TEST_ASSERT( b == 0 ); TAO_PEGTL_TEST_ASSERT( c == 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/action_match.cpp000066400000000000000000000056231426407250600214510ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct remove_state { template< typename Rule, 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&&... /*unused*/ ) { return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in ); } }; // further generic helpers could be build, e.g. // // - change_control // - remove prefix/suffix from input (e.g. remove surrounding quotes) // - replace the input completely? // - append states // - prepend states // - ... std::size_t global_state = 0; struct state_one { std::size_t byte_in_line_a; std::size_t byte_in_line_b; }; // clang-format off struct grammar_inner : one< 'a' > {}; struct grammar_one_c : seq< grammar_inner > {}; struct grammar_one_b : seq< grammar_inner, grammar_one_c > {}; struct grammar_one_a : seq< grammar_inner, grammar_one_b, eof > {}; // clang-format on template< typename Rule > struct action_one_b {}; template< typename Rule > struct action_one_t {}; template< typename Rule > struct action_one_a {}; template<> struct action_one_b< grammar_one_c > : remove_state {}; template<> struct action_one_b< grammar_inner > { // used inside of remove_state template< typename ActionInput > static void apply( const ActionInput& /*unused*/ ) { ++global_state; } // used outside of remove_state template< typename ActionInput > static void apply( const ActionInput& in, state_one& state ) { state.byte_in_line_b += in.input().byte(); } }; template<> struct action_one_t< grammar_one_b > : change_action< action_one_b > {}; template<> struct action_one_a< grammar_one_b > : change_action< action_one_t > {}; template<> struct action_one_a< grammar_inner > { template< typename ActionInput > static void apply( const ActionInput& in, state_one& state ) { state.byte_in_line_a += in.input().byte(); } }; void unit_test() { state_one state{ 0, 0 }; bool parse_result = parse< grammar_one_a, action_one_a >( memory_input( "aaa", __FUNCTION__ ), state ); TAO_PEGTL_TEST_ASSERT( parse_result ); TAO_PEGTL_TEST_ASSERT( state.byte_in_line_a == 1 ); TAO_PEGTL_TEST_ASSERT( state.byte_in_line_b == 2 ); TAO_PEGTL_TEST_ASSERT( global_state == 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/actions_one.cpp000066400000000000000000000063421426407250600213200ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include #include #include namespace TAO_PEGTL_NAMESPACE { std::vector< std::pair< std::string, std::string > > applied; namespace test1 { struct fiz : seq< at< one< 'a' > >, two< 'a' > > {}; struct foo : sor< fiz, one< 'b' > > {}; struct bar : until< eof, foo > {}; void test_result() { TAO_PEGTL_TEST_ASSERT( applied.size() == 10 ); TAO_PEGTL_TEST_ASSERT( applied[ 0 ].first == demangle< one< 'b' > >() ); TAO_PEGTL_TEST_ASSERT( applied[ 1 ].first == demangle< foo >() ); TAO_PEGTL_TEST_ASSERT( applied[ 2 ].first == demangle< at< one< 'a' > > >() ); TAO_PEGTL_TEST_ASSERT( applied[ 3 ].first == demangle< two< 'a' > >() ); TAO_PEGTL_TEST_ASSERT( applied[ 4 ].first == demangle< fiz >() ); TAO_PEGTL_TEST_ASSERT( applied[ 5 ].first == demangle< foo >() ); TAO_PEGTL_TEST_ASSERT( applied[ 6 ].first == demangle< one< 'b' > >() ); TAO_PEGTL_TEST_ASSERT( applied[ 7 ].first == demangle< foo >() ); TAO_PEGTL_TEST_ASSERT( applied[ 8 ].first == demangle< eof >() ); TAO_PEGTL_TEST_ASSERT( applied[ 9 ].first == demangle< bar >() ); TAO_PEGTL_TEST_ASSERT( applied[ 0 ].second == "b" ); TAO_PEGTL_TEST_ASSERT( applied[ 1 ].second == "b" ); TAO_PEGTL_TEST_ASSERT( applied[ 2 ].second.empty() ); TAO_PEGTL_TEST_ASSERT( applied[ 3 ].second == "aa" ); TAO_PEGTL_TEST_ASSERT( applied[ 4 ].second == "aa" ); TAO_PEGTL_TEST_ASSERT( applied[ 5 ].second == "aa" ); TAO_PEGTL_TEST_ASSERT( applied[ 6 ].second == "b" ); TAO_PEGTL_TEST_ASSERT( applied[ 7 ].second == "b" ); TAO_PEGTL_TEST_ASSERT( applied[ 8 ].second.empty() ); TAO_PEGTL_TEST_ASSERT( applied[ 9 ].second == "baab" ); } } // namespace test1 template< typename Rule > struct test_action { template< typename ActionInput > static void apply( const ActionInput& in ) { applied.emplace_back( demangle< Rule >(), in.string() ); } }; void unit_test() { parse< disable< test1::bar >, test_action >( memory_input( "baab", __FUNCTION__ ) ); TAO_PEGTL_TEST_ASSERT( applied.size() == 1 ); TAO_PEGTL_TEST_ASSERT( applied[ 0 ].first == demangle< disable< test1::bar > >() ); TAO_PEGTL_TEST_ASSERT( applied[ 0 ].second == "baab" ); applied.clear(); parse< at< action< test_action, test1::bar > > >( memory_input( "baab", __FUNCTION__ ) ); TAO_PEGTL_TEST_ASSERT( applied.empty() ); applied.clear(); parse< test1::bar, test_action >( memory_input( "baab", __FUNCTION__ ) ); test1::test_result(); applied.clear(); parse< action< test_action, test1::bar > >( memory_input( "baab", __FUNCTION__ ) ); test1::test_result(); applied.clear(); parse< disable< enable< action< test_action, test1::bar > > > >( memory_input( "baab", __FUNCTION__ ) ); test1::test_result(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/actions_three.cpp000066400000000000000000000062561426407250600216520ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { template< unsigned Size, apply_mode B, rewind_mode N, typename... Rules > struct test_rule { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& in, States&&... st ) { static_assert( A == B, "unexpected apply mode" ); static_assert( M == N, "unexpected rewind mode" ); TAO_PEGTL_TEST_ASSERT( in.size() == Size ); return seq< Rules... >::template match< A, M, Action, Control >( in, st... ); } }; namespace test1 { bool apply_result; struct grammar : test_rule< 2, apply_mode::action, rewind_mode::active, any > {}; template< typename Rule > struct apply_bool_action {}; template<> struct apply_bool_action< grammar > { template< typename ActionInput > static bool apply( const ActionInput& /*unused*/ ) { return apply_result; } }; void apply_bool_true() { apply_result = true; memory_input in( "ab", __FUNCTION__ ); const auto result = parse< grammar, apply_bool_action >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( in.size() == 1 ); TAO_PEGTL_TEST_ASSERT( in.peek_char() == 'b' ); } void apply_bool_false() { apply_result = false; memory_input in( "ab", __FUNCTION__ ); const auto result = parse< grammar, apply_bool_action >( in ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( in.size() == 2 ); TAO_PEGTL_TEST_ASSERT( in.peek_char() == 'a' ); } template< typename Rule > struct apply0_bool_action {}; template<> struct apply0_bool_action< grammar > { static bool apply0() { return apply_result; } }; void apply0_bool_true() { apply_result = true; memory_input in( "ab", __FUNCTION__ ); const auto result = parse< grammar, apply0_bool_action >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( in.size() == 1 ); TAO_PEGTL_TEST_ASSERT( in.peek_char() == 'b' ); } void apply0_bool_false() { apply_result = false; memory_input in( "ab", __FUNCTION__ ); const auto result = parse< grammar, apply0_bool_action >( in ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( in.size() == 2 ); TAO_PEGTL_TEST_ASSERT( in.peek_char() == 'a' ); } } // namespace test1 void unit_test() { test1::apply_bool_true(); test1::apply_bool_false(); test1::apply0_bool_true(); test1::apply0_bool_false(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/actions_two.cpp000066400000000000000000000065031426407250600213470ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { namespace test1 { struct state1 { char c; template< typename ParseInput > state1( const ParseInput& /*unused*/, std::string& /*unused*/ ) : c() {} template< typename ParseInput > void success( const ParseInput& /*unused*/, std::string& s ) const { s += c; } }; struct fobble : sor< state< state1, alpha >, digit > {}; struct fibble : until< eof, fobble > {}; template< typename Rule > struct action1 {}; template<> struct action1< alpha > { template< typename ActionInput > static void apply( const ActionInput& in, state1& s ) { assert( in.size() == 1 ); s.c = in.begin()[ 0 ]; } }; void state_test() { std::string result; memory_input in( "dk41sk41xk3", __FUNCTION__ ); parse< fibble, action1 >( in, result ); TAO_PEGTL_TEST_ASSERT( result == "dkskxk" ); } template< typename Rule > struct action0 {}; static int i0 = 0; template<> struct action0< alpha > { static void apply0() { ++i0; } }; template<> struct action0< digit > { static void apply0( std::string& s ) { s += '0'; } }; void apply0_test() { memory_input ina( "abcdefgh", __FUNCTION__ ); parse< star< alpha >, action0 >( ina ); TAO_PEGTL_TEST_ASSERT( i0 == 8 ); std::string s0; memory_input ind( "12345678", __FUNCTION__ ); parse< star< digit >, action0 >( ind, s0 ); TAO_PEGTL_TEST_ASSERT( s0 == "00000000" ); } const std::size_t count_byte = 12345; const std::size_t count_line = 42; const std::size_t count_column = 12; const char* count_source = "count_source"; template< typename Rule > struct count_action { template< typename ActionInput > static void apply( const ActionInput& in ) { TAO_PEGTL_TEST_ASSERT( in.iterator().byte == count_byte ); TAO_PEGTL_TEST_ASSERT( in.iterator().line == count_line ); TAO_PEGTL_TEST_ASSERT( in.iterator().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() ); TAO_PEGTL_TEST_ASSERT( in.peek_char() == 'f' ); TAO_PEGTL_TEST_ASSERT( in.peek_uint8() == static_cast< unsigned char >( 'f' ) ); } }; void count_test() { const char* foo = "f"; memory_input in( foo, foo + 1, count_source, count_byte, count_line, count_column ); TAO_PEGTL_TEST_ASSERT( parse< alpha, count_action >( in ) ); } } // namespace test1 void unit_test() { test1::state_test(); test1::apply0_test(); test1::count_test(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/argv_input.cpp000066400000000000000000000011461426407250600211720ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { char data[ 12 ]; std::memcpy( data, "foo\0bar\0baz", 12 ); char* argv[] = { data, data + 4, data + 8 }; argv_input in( argv, 1 ); TAO_PEGTL_TEST_ASSERT( in.source() == "argv[1]" ); const auto result = parse< string< 'b', 'a', 'r' > >( in ); TAO_PEGTL_TEST_ASSERT( result ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_classes.cpp000066400000000000000000000153361426407250600216270ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< alnum >( __LINE__, __FILE__, true, false ); verify_analyze< alpha >( __LINE__, __FILE__, true, false ); verify_analyze< any >( __LINE__, __FILE__, true, false ); verify_analyze< blank >( __LINE__, __FILE__, true, false ); verify_analyze< digit >( __LINE__, __FILE__, true, false ); verify_analyze< eol >( __LINE__, __FILE__, true, false ); verify_analyze< identifier_first >( __LINE__, __FILE__, true, false ); verify_analyze< identifier_other >( __LINE__, __FILE__, true, false ); verify_analyze< lower >( __LINE__, __FILE__, true, false ); verify_analyze< nul >( __LINE__, __FILE__, true, false ); verify_analyze< print >( __LINE__, __FILE__, true, false ); verify_analyze< seven >( __LINE__, __FILE__, true, false ); verify_analyze< space >( __LINE__, __FILE__, true, false ); verify_analyze< upper >( __LINE__, __FILE__, true, false ); verify_analyze< xdigit >( __LINE__, __FILE__, true, false ); verify_analyze< not_one< 'a' > >( __LINE__, __FILE__, true, false ); verify_analyze< not_one< 'a', 'z' > >( __LINE__, __FILE__, true, false ); verify_analyze< not_range< 'a', 'z' > >( __LINE__, __FILE__, true, false ); verify_analyze< one< 'a' > >( __LINE__, __FILE__, true, false ); verify_analyze< one< 'a', 'z' > >( __LINE__, __FILE__, true, false ); verify_analyze< range< 'a', 'z' > >( __LINE__, __FILE__, true, false ); verify_analyze< ranges< 'a', 'z' > >( __LINE__, __FILE__, true, false ); verify_analyze< ranges< 'a', 'z', '4' > >( __LINE__, __FILE__, true, false ); verify_rule< alnum >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< alpha >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< blank >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< digit >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< eol >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< identifier_first >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< identifier_other >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< lower >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< nul >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< print >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< seven >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< space >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< upper >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< xdigit >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< not_one< 'a' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< not_one< 'a', 'z' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< not_range< 'a', 'z' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< one< 'a' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< one< 'a', 'z' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< range< 'a', 'z' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< ranges< 'a', 'z' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< ranges< 'a', 'z', '4' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); for( int i = -100; i < 200; ++i ) { const auto c = char( i ); const bool is_blank = ( c == ' ' ) || ( c == '\t' ); const bool is_digit = ( '0' <= c ) && ( c <= '9' ); const bool is_lower = ( 'a' <= c ) && ( c <= 'z' ); const bool is_print = ( ( ' ' <= c ) && ( c <= 126 ) ); const bool is_seven = ( ( i >= 0 ) && ( i <= 127 ) ); const bool is_space = ( c == '\n' ) || ( c == '\r' ) || ( c == '\v' ) || ( c == '\f' ); const bool is_upper = ( 'A' <= c ) && ( c <= 'Z' ); const bool is_xalpha = ( ( 'a' <= c ) && ( c <= 'f' ) ) || ( ( 'A' <= c ) && ( c <= 'F' ) ); const bool is_newline = ( c == '\n' ); const bool is_ident_first = ( c == '_' ) || is_lower || is_upper; const bool is_ident_other = is_ident_first || is_digit; verify_char< alnum >( __LINE__, __FILE__, c, is_lower || is_upper || is_digit ); verify_char< alpha >( __LINE__, __FILE__, c, is_lower || is_upper ); verify_char< any >( __LINE__, __FILE__, c, true ); verify_char< blank >( __LINE__, __FILE__, c, is_blank ); verify_char< digit >( __LINE__, __FILE__, c, is_digit ); verify_char< eol >( __LINE__, __FILE__, c, is_newline ); verify_char< identifier_first >( __LINE__, __FILE__, c, is_ident_first ); verify_char< identifier_other >( __LINE__, __FILE__, c, is_ident_other ); verify_char< lower >( __LINE__, __FILE__, c, is_lower ); verify_char< nul >( __LINE__, __FILE__, c, c == 0 ); verify_char< print >( __LINE__, __FILE__, c, is_print ); verify_char< seven >( __LINE__, __FILE__, c, is_seven ); verify_char< space >( __LINE__, __FILE__, c, is_blank || is_space ); verify_char< upper >( __LINE__, __FILE__, c, is_upper ); verify_char< xdigit >( __LINE__, __FILE__, c, is_digit || is_xalpha ); const bool is_one = ( c == '#' ) || ( c == 'a' ) || ( c == ' ' ); const bool is_range = ( 20 <= c ) && ( c <= 120 ); const bool is_ranges = is_range || ( c == 3 ); verify_char< not_one< 'P' > >( __LINE__, __FILE__, c, c != 'P' ); verify_char< not_one< 'a', '#', ' ' > >( __LINE__, __FILE__, c, !is_one ); verify_char< not_range< 20, 120 > >( __LINE__, __FILE__, c, !is_range ); verify_char< one< 'T' > >( __LINE__, __FILE__, c, c == 'T' ); verify_char< one< 'a', '#', ' ' > >( __LINE__, __FILE__, c, is_one ); verify_char< range< 20, 120 > >( __LINE__, __FILE__, c, is_range ); verify_char< ranges< 20, 120 > >( __LINE__, __FILE__, c, is_range ); verify_char< ranges< 20, 120, 3 > >( __LINE__, __FILE__, c, is_ranges ); verify_char< eolf >( __LINE__, __FILE__, c, is_newline ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_eol.cpp000066400000000000000000000144051426407250600207450ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< eol >( __LINE__, __FILE__, true, false ); verify_rule< eol >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); for( char i = 1; i < 127; ++i ) { verify_char< eol >( __LINE__, __FILE__, i, ( i == '\n' ) ? result_type::success : result_type::local_failure ); } verify_rule< eol, eol::lf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\n", result_type::success, 0 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\r\n", result_type::local_failure, 2 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\n\r", result_type::success, 1 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\n\r\n", result_type::success, 2 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\n\r\r", result_type::success, 2 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\na", result_type::success, 1 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\r\na", result_type::local_failure, 3 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\r\n\r", result_type::local_failure, 3 ); verify_rule< eol, eol::lf >( __LINE__, __FILE__, "\r\n\n", result_type::local_failure, 3 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\r", result_type::success, 0 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\r\n", result_type::success, 1 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\ra", result_type::success, 1 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\r\na", result_type::success, 2 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\r\n\r", result_type::success, 2 ); verify_rule< eol, eol::cr >( __LINE__, __FILE__, "\r\n\n", result_type::success, 2 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eol, eol::crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\n", result_type::success, 0 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\n\r", result_type::success, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\n\r\n", result_type::success, 2 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\n\r\r", result_type::success, 2 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\na", result_type::success, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eol, eol::lf_crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\r", result_type::success, 0 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\ra", result_type::success, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eol, eol::cr_crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_eolf.cpp000066400000000000000000000144771426407250600211240ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< eolf >( __LINE__, __FILE__, false, false ); verify_rule< eolf >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { verify_char< eolf >( __LINE__, __FILE__, i, ( i == '\n' ) ? result_type::success : result_type::local_failure ); } verify_rule< eolf, eol::lf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\n", result_type::success, 0 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\r\n", result_type::local_failure, 2 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\n\r", result_type::success, 1 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\n\r\n", result_type::success, 2 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\n\r\r", result_type::success, 2 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\na", result_type::success, 1 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\r\na", result_type::local_failure, 3 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\r\n\r", result_type::local_failure, 3 ); verify_rule< eolf, eol::lf >( __LINE__, __FILE__, "\r\n\n", result_type::local_failure, 3 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\r", result_type::success, 0 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\r\n", result_type::success, 1 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\ra", result_type::success, 1 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\r\na", result_type::success, 2 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\r\n\r", result_type::success, 2 ); verify_rule< eolf, eol::cr >( __LINE__, __FILE__, "\r\n\n", result_type::success, 2 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eolf, eol::crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\r", result_type::local_failure, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\n", result_type::success, 0 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\n\r", result_type::success, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\n\r\n", result_type::success, 2 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\n\r\r", result_type::success, 2 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\na", result_type::success, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\ra", result_type::local_failure, 2 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eolf, eol::lf_crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\r", result_type::success, 0 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\n", result_type::local_failure, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\r\n", result_type::success, 0 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\n\r", result_type::local_failure, 2 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\n\r\n", result_type::local_failure, 3 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\n\r\r", result_type::local_failure, 3 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\na", result_type::local_failure, 2 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\ra", result_type::success, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\r\na", result_type::success, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\r\n\r", result_type::success, 1 ); verify_rule< eolf, eol::cr_crlf >( __LINE__, __FILE__, "\r\n\n", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_forty_two.cpp000066400000000000000000000032351426407250600222210ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< forty_two< 'a' > >( __LINE__, __FILE__, true, false ); verify_analyze< forty_two< 'a', 'z' > >( __LINE__, __FILE__, true, false ); for( std::size_t i = 0; i < 42; ++i ) { verify_rule< forty_two< 'a' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::local_failure ); } for( std::size_t i = 42; i < 100; ++i ) { verify_rule< forty_two< 'a' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, int( i - 42 ) ); } for( std::size_t i = 0; i < 42; ++i ) { verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::local_failure ); } for( std::size_t i = 42; i < 100; ++i ) { verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'a' ), result_type::success, int( i - 42 ) ); } for( std::size_t i = 0; i < 42; ++i ) { verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'z' ), result_type::local_failure ); } for( std::size_t i = 42; i < 100; ++i ) { verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, std::string( i, 'z' ), result_type::success, int( i - 42 ) ); } verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, "azzaazaazaaazzzaaaazzaaazzaazazzzaazzazaza", result_type::success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_identifier.cpp000066400000000000000000000030331426407250600223030ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< identifier >( __LINE__, __FILE__, true, false ); verify_rule< identifier >( __LINE__, __FILE__, "_", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_a", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_1", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_123", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_1a", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_a1", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "_fro_bble", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "f_o_o42", result_type::success, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< identifier >( __LINE__, __FILE__, "1", result_type::local_failure, 1 ); verify_rule< identifier >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< identifier >( __LINE__, __FILE__, " _", result_type::local_failure, 2 ); verify_rule< identifier >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_istring.cpp000066400000000000000000000051661426407250600216510ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< istring<> >( __LINE__, __FILE__, false, false ); verify_analyze< istring< 1 > >( __LINE__, __FILE__, true, false ); verify_analyze< istring< 1, 2 > >( __LINE__, __FILE__, true, false ); verify_analyze< istring< 1, 2, 3, 4 > >( __LINE__, __FILE__, true, false ); verify_analyze< istring< 1, 2, 3, 4, 5, 6, 7 > >( __LINE__, __FILE__, true, false ); verify_rule< istring<> >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "c", result_type::local_failure, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aB", result_type::success, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "AB", result_type::success, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "Ab", result_type::success, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "ac", result_type::local_failure, 2 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "ba", result_type::local_failure, 2 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aab", result_type::local_failure, 3 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aab", result_type::local_failure, 3 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "Abb", result_type::success, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "abc", result_type::success, 1 ); verify_rule< istring< 'a', 'b' > >( __LINE__, __FILE__, "aBab", result_type::success, 2 ); verify_rule< istring< 'a', '0' > >( __LINE__, __FILE__, "a0A0", result_type::success, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_keyword.cpp000066400000000000000000000030541426407250600216500ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, true, false ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "foo", result_type::success, 0 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "foo ", result_type::success, 1 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "foo foo", result_type::success, 4 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "FOO", result_type::local_failure, 3 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "f", result_type::local_failure, 1 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "fo", result_type::local_failure, 2 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, " foo", result_type::local_failure, 4 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "foo_", result_type::local_failure, 4 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "foo1", result_type::local_failure, 4 ); verify_rule< keyword< 'f', 'o', 'o' > >( __LINE__, __FILE__, "fooa", result_type::local_failure, 4 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_shebang.cpp000066400000000000000000000033071426407250600215740ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< shebang >( __LINE__, __FILE__, true, false ); verify_rule< shebang >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#", result_type::local_failure, 1 ); verify_rule< shebang >( __LINE__, __FILE__, "!", result_type::local_failure, 1 ); verify_rule< shebang >( __LINE__, __FILE__, "!#", result_type::local_failure, 2 ); verify_rule< shebang >( __LINE__, __FILE__, "# ", result_type::local_failure, 3 ); verify_rule< shebang >( __LINE__, __FILE__, "! ", result_type::local_failure, 3 ); verify_rule< shebang >( __LINE__, __FILE__, "## ", result_type::local_failure, 3 ); verify_rule< shebang >( __LINE__, __FILE__, "!! ", result_type::local_failure, 3 ); verify_rule< shebang >( __LINE__, __FILE__, "#!", result_type::success, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#! ", result_type::success, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#!/bin/bash", result_type::success, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#!/bin/bash\n", result_type::success, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#!/bin/bash\n#!/b", result_type::success, 4 ); verify_rule< shebang >( __LINE__, __FILE__, "#!\n", result_type::success, 0 ); verify_rule< shebang >( __LINE__, __FILE__, "#!\n ", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_string.cpp000066400000000000000000000050171426407250600214730ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< string<> >( __LINE__, __FILE__, false, false ); verify_analyze< string< 1 > >( __LINE__, __FILE__, true, false ); verify_analyze< string< 1, 2 > >( __LINE__, __FILE__, true, false ); verify_analyze< string< 1, 2, 3, 4 > >( __LINE__, __FILE__, true, false ); verify_analyze< string< 1, 2, 3, 4, 5, 6, 7 > >( __LINE__, __FILE__, true, false ); verify_rule< string<> >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "c", result_type::local_failure, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "aB", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "AB", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "Ab", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "ac", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "ba", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "aab", result_type::local_failure, 3 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "aab", result_type::local_failure, 3 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "abc", result_type::success, 1 ); verify_rule< string< 'a', 'b' > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_three.cpp000066400000000000000000000023021426407250600212660ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< three< 'a' > >( __LINE__, __FILE__, true, false ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "a", result_type::local_failure ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aa", result_type::local_failure ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aab", result_type::local_failure ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aaa", result_type::success ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aaaa", result_type::success, 1 ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aaaaa", result_type::success, 2 ); verify_rule< three< 'a' > >( __LINE__, __FILE__, "aaaaaa", result_type::success, 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/ascii_two.cpp000066400000000000000000000016361426407250600210010ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< two< 'a' > >( __LINE__, __FILE__, true, false ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "a", result_type::local_failure ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "aa", result_type::success ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "aaa", result_type::success, 1 ); verify_rule< two< 'a' > >( __LINE__, __FILE__, "aaaa", result_type::success, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/buffer_input.cpp000066400000000000000000000050611426407250600215040ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { template< typename Rule, template< typename... > class Action = nothing > bool parse_cstring( const char* string, const char* source, const std::size_t maximum ) { buffer_input< internal::cstring_reader > in( source, maximum, string ); return parse< Rule, Action >( in ); } void unit_test() { static constexpr std::size_t chunk_size = buffer_input< internal::cstring_reader >::chunk_size; static_assert( chunk_size >= 2 ); TAO_PEGTL_TEST_ASSERT( parse_cstring< seq< string< 'a', 'b', 'c' >, eof > >( "abc", TAO_TEST_LINE, 1 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< seq< string< 'a', 'b', 'c' >, eof > >( "abc", TAO_TEST_LINE, 128 ) ); // We need one extra byte in the buffer so that eof calling in.empty() calling in.require( 1 ) does not throw a "require beyond end of buffer" exception. #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< seq< rep< chunk_size + 2, one< 'a' > >, eof > >( std::string( std::size_t( chunk_size + 2 ), 'a' ).c_str(), TAO_TEST_LINE, 2 ) ); #endif TAO_PEGTL_TEST_ASSERT( parse_cstring< seq< rep< chunk_size + 2, one< 'a' > >, eof > >( std::string( std::size_t( chunk_size + 2 ), 'a' ).c_str(), TAO_TEST_LINE, 3 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< chunk_size + 9, one< 'a' > > >( std::string( std::size_t( chunk_size + 9 ), 'a' ).c_str(), TAO_TEST_LINE, 9 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< chunk_size + 9, one< 'a' > > >( std::string( std::size_t( chunk_size + 10 ), 'a' ).c_str(), TAO_TEST_LINE, 9 ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< rep< chunk_size + 10, one< 'a' > > >( std::string( std::size_t( chunk_size + 10 ), 'a' ).c_str(), TAO_TEST_LINE, 9 ) ); TAO_PEGTL_TEST_THROWS( parse_cstring< rep< chunk_size + 10, one< 'a' > > >( std::string( std::size_t( chunk_size + 11 ), 'a' ).c_str(), TAO_TEST_LINE, 9 ) ); TAO_PEGTL_TEST_THROWS( parse_cstring< seq< rep< chunk_size + 10, one< 'a' > >, eof > >( std::string( std::size_t( chunk_size + 10 ), 'a' ).c_str(), TAO_TEST_LINE, 9 ) ); TAO_PEGTL_TEST_THROWS( parse_cstring< seq< rep< chunk_size + 10, one< 'a' > >, eof > >( std::string( std::size_t( chunk_size + 10 ), 'a' ).c_str(), TAO_TEST_LINE, 10 ) ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/change_action_and_state.cpp000066400000000000000000000046321426407250600236230ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct AB : seq< A, B > {}; // clang-format on template< typename > struct my_action_1 {}; template< typename > struct my_action_2 {}; template<> struct my_action_1< A > { static void apply0( int& c ) { TAO_PEGTL_TEST_ASSERT( c == 0 ); c = 1; } }; struct S { int v = 0; template< typename ParseInput > explicit S( const ParseInput& /*unused*/, int& c ) { if( c == 5 ) { v = 6; } else { TAO_PEGTL_TEST_ASSERT( c == 1 ); v = 2; } } template< typename ParseInput > void success( const ParseInput& /*unused*/, int& c ) { TAO_PEGTL_TEST_ASSERT( v == 3 ); c = 4; } }; template<> struct my_action_1< B > : change_action_and_state< my_action_2, S > {}; template<> struct my_action_2< A > { static void apply0( S& /*s*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } }; template<> struct my_action_2< B > { static void apply0( S& s ) { TAO_PEGTL_TEST_ASSERT( s.v == 2 ); s.v = 3; } }; void unit_test() { { memory_input in( "ab", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 4 ); } { memory_input in( "a", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 1 ); } { memory_input in( "b", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 0 ); } { memory_input in( "ab", "" ); int c = 5; const auto result = parse< disable< AB >, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 5 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/change_action_and_states.cpp000066400000000000000000000044761426407250600240140ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct AB : seq< A, B > {}; // clang-format on template< typename > struct my_action_1 {}; template< typename > struct my_action_2 {}; template<> struct my_action_1< A > { static void apply0( int& c ) { TAO_PEGTL_TEST_ASSERT( c == 0 ); c = 1; } }; template<> struct my_action_1< B > : change_action_and_states< my_action_2, int > { // not called because my_action_2 is active static void apply0( int& /*v*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } template< typename ParseInput > static void success( const ParseInput& /*unused*/, int& v, int& c ) { TAO_PEGTL_TEST_ASSERT( v == 2 ); TAO_PEGTL_TEST_ASSERT( c == 1 ); c = 3; } }; template<> struct my_action_2< A > { static void apply0( int& /*c*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } }; template<> struct my_action_2< B > { static void apply0( int& v ) { TAO_PEGTL_TEST_ASSERT( v == 0 ); v = 2; } }; void unit_test() { { memory_input in( "ab", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 3 ); } { memory_input in( "a", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 1 ); } { memory_input in( "b", "" ); int c = 0; const auto result = parse< AB, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 0 ); } { memory_input in( "ab", "" ); int c = 5; const auto result = parse< disable< AB >, my_action_1 >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 5 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/change_state.cpp000066400000000000000000000041761426407250600214470ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct AB : seq< A, B > {}; // clang-format on template< typename > struct my_action {}; template<> struct my_action< A > { static void apply0( int& c ) { TAO_PEGTL_TEST_ASSERT( c == 0 ); c = 1; } }; struct S { int v = 0; template< typename ParseInput > explicit S( const ParseInput& /*unused*/, int& c ) { if( c == 5 ) { v = 6; } else { TAO_PEGTL_TEST_ASSERT( c == 1 ); v = 2; } } template< typename ParseInput > void success( const ParseInput& /*unused*/, int& c ) { TAO_PEGTL_TEST_ASSERT( v == 3 ); c = 4; } }; template<> struct my_action< B > : change_state< S > { static void apply0( S& s ) { TAO_PEGTL_TEST_ASSERT( s.v == 2 ); s.v = 3; } }; void unit_test() { { memory_input in( "ab", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 4 ); } { memory_input in( "a", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 1 ); } { memory_input in( "b", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 0 ); } { memory_input in( "ab", "" ); int c = 5; const auto result = parse< disable< AB >, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 5 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/change_states.cpp000066400000000000000000000036161426407250600216300ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct AB : seq< A, B > {}; // clang-format on template< typename > struct my_action {}; template<> struct my_action< A > { static void apply0( int& c ) { TAO_PEGTL_TEST_ASSERT( c == 0 ); c = 1; } }; template<> struct my_action< B > : change_states< int > { static void apply0( int& v ) { TAO_PEGTL_TEST_ASSERT( v == 0 ); v = 2; } template< typename ParseInput > static void success( const ParseInput& /*unused*/, int& v, int& c ) { TAO_PEGTL_TEST_ASSERT( v == 2 ); TAO_PEGTL_TEST_ASSERT( c == 1 ); c = 3; } }; void unit_test() { { memory_input in( "ab", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 3 ); } { memory_input in( "a", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 1 ); } { memory_input in( "b", "" ); int c = 0; const auto result = parse< AB, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( !result ); TAO_PEGTL_TEST_ASSERT( c == 0 ); } { memory_input in( "ab", "" ); int c = 5; const auto result = parse< disable< AB >, my_action >( in, c ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( c == 5 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/check_bytes.cpp000066400000000000000000000023061426407250600212760ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct test_rule : star< alpha > {}; struct test_grammar : seq< test_rule, eof > {}; template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< test_rule > : check_bytes< 5 > {}; void unit_test() { memory_input<> i1( "aaa", __FUNCTION__ ); const auto r1 = pegtl::parse< test_grammar >( i1 ); TAO_PEGTL_TEST_ASSERT( r1 ); memory_input<> i2( "aaaaaaaaaaa", __FUNCTION__ ); const auto r2 = pegtl::parse< test_grammar >( i2 ); TAO_PEGTL_TEST_ASSERT( r2 ); memory_input<> i3( "aaa", __FUNCTION__ ); const auto r3 = pegtl::parse< test_grammar, test_action >( i3 ); TAO_PEGTL_TEST_ASSERT( r3 ); #if defined( __cpp_exceptions ) memory_input<> i4( "aaaaaaaaaaa", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( pegtl::parse< test_grammar, test_action >( i4 ) ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contains.cpp000066400000000000000000000011071426407250600206270ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : plus< alpha, opt< A > > {}; struct B : star< sor< space, digit, A > > {}; struct grammar : seq< A, B > {}; // clang-format on void unit_test() { static_assert( contains_v< grammar, digit > ); static_assert( !contains_v< grammar, xdigit > ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_alphabet.cpp000066400000000000000000000047761426407250600223300ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { static_assert( alphabet::a == 'a' ); static_assert( alphabet::b == 'b' ); static_assert( alphabet::c == 'c' ); static_assert( alphabet::d == 'd' ); static_assert( alphabet::e == 'e' ); static_assert( alphabet::f == 'f' ); static_assert( alphabet::g == 'g' ); static_assert( alphabet::h == 'h' ); static_assert( alphabet::i == 'i' ); static_assert( alphabet::j == 'j' ); static_assert( alphabet::k == 'k' ); static_assert( alphabet::l == 'l' ); static_assert( alphabet::m == 'm' ); static_assert( alphabet::n == 'n' ); static_assert( alphabet::o == 'o' ); static_assert( alphabet::p == 'p' ); static_assert( alphabet::q == 'q' ); static_assert( alphabet::r == 'r' ); static_assert( alphabet::s == 's' ); static_assert( alphabet::t == 't' ); static_assert( alphabet::u == 'u' ); static_assert( alphabet::v == 'v' ); static_assert( alphabet::w == 'w' ); static_assert( alphabet::x == 'x' ); static_assert( alphabet::y == 'y' ); static_assert( alphabet::z == 'z' ); static_assert( alphabet::A == 'A' ); static_assert( alphabet::B == 'B' ); static_assert( alphabet::C == 'C' ); static_assert( alphabet::D == 'D' ); static_assert( alphabet::E == 'E' ); static_assert( alphabet::F == 'F' ); static_assert( alphabet::G == 'G' ); static_assert( alphabet::H == 'H' ); static_assert( alphabet::I == 'I' ); static_assert( alphabet::J == 'J' ); static_assert( alphabet::K == 'K' ); static_assert( alphabet::L == 'L' ); static_assert( alphabet::M == 'M' ); static_assert( alphabet::N == 'N' ); static_assert( alphabet::O == 'O' ); static_assert( alphabet::P == 'P' ); static_assert( alphabet::Q == 'Q' ); static_assert( alphabet::R == 'R' ); static_assert( alphabet::S == 'S' ); static_assert( alphabet::T == 'T' ); static_assert( alphabet::U == 'U' ); static_assert( alphabet::V == 'V' ); static_assert( alphabet::W == 'W' ); static_assert( alphabet::X == 'X' ); static_assert( alphabet::Y == 'Y' ); static_assert( alphabet::Z == 'Z' ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_analyze.cpp000066400000000000000000000175171426407250600222100ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... Rules > struct strange { using rule_t = strange; using subs_t = type_list< Rules... >; static_assert( sizeof...( Rules ) > 1 ); // Pretend to be a rule that consumes on success by itself _and_ has sub-rules, // to test a supported combination even though it is not frequently encountered. }; template< typename Name, typename... Rules > struct analyze_traits< Name, strange< Rules... > > : analyze_any_traits< Rules... > {}; void unit_test() { verify_analyze< strange< alpha, digit > >( __LINE__, __FILE__, true, false ); verify_analyze< strange< opt< alpha >, opt< digit > > >( __LINE__, __FILE__, true, false ); verify_analyze< strange< star< star< alpha > >, digit > >( __LINE__, __FILE__, true, true ); verify_analyze< strange< digit, star< star< alpha > > > >( __LINE__, __FILE__, true, true ); verify_analyze< eof >( __LINE__, __FILE__, false, false ); verify_analyze< eolf >( __LINE__, __FILE__, false, false ); verify_analyze< success >( __LINE__, __FILE__, false, false ); verify_analyze< failure >( __LINE__, __FILE__, true, false ); // clang-format off { struct tst : star< tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : plus< tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : seq< eof, at< digit >, tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); // This is a false positive. } { struct tst : sor< digit, seq< at< digit >, tst > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); // This is a false positive. } { struct tst : sor< digit, seq< opt< digit >, tst > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : sor< digit, tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : at< any > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : at< tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : at< any, tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : not_at< any > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : opt< tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : opt< any, tst > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct rec : sor< seq< rec, alpha >, alpha > {}; verify_analyze< rec >( __LINE__, __FILE__, true, true ); } { struct bar; struct foo : seq< digit, bar > {}; struct bar : plus< foo > {}; verify_analyze< seq< any, bar > >( __LINE__, __FILE__, true, false ); } { struct bar; struct foo : seq< bar, digit > {}; struct bar : plus< foo > {}; verify_analyze< seq< bar, any > >( __LINE__, __FILE__, true, true ); } { struct bar; struct foo : sor< digit, bar > {}; struct bar : plus< foo > {}; verify_analyze< bar >( __LINE__, __FILE__, false, true ); verify_analyze< foo >( __LINE__, __FILE__, false, true ); verify_analyze< sor< any, bar > >( __LINE__, __FILE__, false, true ); } { // Excerpt from the Lua 5.3 grammar: // prefixexp ::= var | functioncall | ‘(’ exp ‘)’ // functioncall ::= prefixexp args | prefixexp ‘:’ Name args // var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name // Simplified version, equivalent regarding consumption of input: struct var; struct fun; struct exp : sor< var, fun, seq< any, exp, any > > {}; struct fun : seq< exp, any > {}; struct var : sor< any, seq< exp, any, exp >, seq< exp, any > > {}; verify_analyze< exp >( __LINE__, __FILE__, true, true ); verify_analyze< fun >( __LINE__, __FILE__, true, true ); verify_analyze< var >( __LINE__, __FILE__, true, true ); } { struct exp : sor< exp, seq< any, exp > > {}; verify_analyze< exp >( __LINE__, __FILE__, false, true ); } { struct tst : until< any > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : until< star< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : until< any, star< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, true, true ); } { struct tst : until< star< any >, star< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : until< any, any > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : until< star< any >, any > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : plus< plus< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : star< star< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : plus< star< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : plus< opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : star< opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : star< plus< opt< any > > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : list< any, any > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : list< star< any >, any > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : list< any, opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : list< star< any >, opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } #if defined( __cpp_exceptions ) { struct tst : list_must< any, any > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : list_must< star< any >, any > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : list_must< any, opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, true, false ); } { struct tst : list_must< star< any >, opt< any > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } #endif { struct tst : plus< pad_opt< alpha, digit > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } { struct tst : rep< 42, opt< alpha > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, false ); } { struct tst : rep_min< 42, opt< alpha > > {}; verify_analyze< tst >( __LINE__, __FILE__, false, true ); } // clang-format on } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_control_action.cpp000066400000000000000000000071271426407250600235560ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct test_action : nothing< Rule > {}; struct first_rule : sor< alpha, digit > {}; #if defined( __cpp_exceptions ) struct second_rule : must< alnum > {}; #endif std::string story; template<> struct test_action< first_rule > : control_action { template< typename ParseInput > static void start( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'a'; } template< typename ParseInput > static void success( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'b'; } // LCOV_EXCL_START template< typename ParseInput > static void failure( const ParseInput& /*unused*/, int /*unused*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } // LCOV_EXCL_STOP }; template<> struct test_action< alpha > : control_action { template< typename ParseInput > static void start( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'd'; } // LCOV_EXCL_START template< typename ParseInput > static void success( const ParseInput& /*unused*/, int /*unused*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } // LCOV_EXCL_STOP template< typename ParseInput > static void failure( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'f'; } }; template<> struct test_action< digit > : control_action { template< typename ParseInput > static void start( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'g'; } template< typename ParseInput > static void success( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'h'; } // LCOV_EXCL_START template< typename ParseInput > static void failure( const ParseInput& /*unused*/, int /*unused*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } // LCOV_EXCL_STOP }; #if defined( __cpp_exceptions ) template<> struct test_action< second_rule > : control_action { template< typename ParseInput > static void start( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'j'; } // LCOV_EXCL_START template< typename ParseInput > static void success( const ParseInput& /*unused*/, int /*unused*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } template< typename ParseInput > static void failure( const ParseInput& /*unused*/, int /*unused*/ ) { TAO_PEGTL_TEST_UNREACHABLE; } // LCOV_EXCL_STOP template< typename ParseInput > static void unwind( const ParseInput& /*unused*/, int /*unused*/ ) { story += 'm'; } }; #endif void unit_test() { { memory_input in( "0", __FUNCTION__ ); const auto b = parse< first_rule, test_action >( in, 42 ); TAO_PEGTL_TEST_ASSERT( b ); TAO_PEGTL_TEST_ASSERT( story == "adfghb" ); } #if defined( __cpp_exceptions ) story.clear(); { memory_input in( "*", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< second_rule, test_action >( in, 42 ) ); TAO_PEGTL_TEST_ASSERT( story == "jm" ); } #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_coverage.cpp000066400000000000000000000060731426407250600223330ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" #include #include namespace TAO_PEGTL_NAMESPACE { [[nodiscard]] inline bool operator==( const coverage_info& l, const coverage_info& r ) noexcept { return ( l.start == r.start ) && ( l.success == r.success ) && ( l.failure == r.failure ) && ( l.unwind == r.unwind ) && ( l.raise == r.raise ); } template< typename Rule > [[nodiscard]] bool equals( const coverage_result& result, const coverage_info& i ) { const coverage_entry m = result.at( demangle< Rule >() ); // Slice return i == m; } #if defined( __cpp_exceptions ) using grammar = seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >; void unit_test() { const std::string data = "F"; coverage_result result; memory_input in( data, __FILE__ ); const bool success = coverage< grammar >( in, result ); std::cout << result; // To manually see that printing does the right thing, too. TAO_PEGTL_TEST_ASSERT( success ); TAO_PEGTL_TEST_ASSERT( result.size() == 7 ); TAO_PEGTL_TEST_ASSERT( equals< grammar >( result, coverage_info{ 1, 1, 0, 0, 0 } ) ); 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< 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 } ) ); } #else using grammar = seq< sor< one< 'a' >, one< 'F' > >, eof >; void unit_test() { const std::string data = "F"; coverage_result result; memory_input in( data, __FILE__ ); const bool success = coverage< grammar >( in, result ); std::cout << result; // To manually see that printing does the right thing, too. TAO_PEGTL_TEST_ASSERT( success ); TAO_PEGTL_TEST_ASSERT( result.size() == 5 ); TAO_PEGTL_TEST_ASSERT( equals< grammar >( result, coverage_info{ 1, 1, 0, 0, 0 } ) ); TAO_PEGTL_TEST_ASSERT( equals< one< 'a' > >( result, coverage_info{ 1, 0, 1, 0, 0 } ) ); // 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< sor< one< 'a' >, one< 'F' > > >( result, coverage_info{ 1, 1, 0, 0, 0 } ) ); } #endif } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_function.cpp000066400000000000000000000014231426407250600223570ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { bool call1 = false; [[nodiscard]] bool func1( memory_input<>& /*unused*/, int /*unused*/, char*& /*unused*/, const double& /*unused*/ ) { call1 = true; return true; } struct rule1 : TAO_PEGTL_NAMESPACE::function< func1 > {}; void unit_test() { int i = 42; char c = 'a'; double d = 42.0; memory_input in( "foo", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< rule1 >( in, i, &c, d ) ); TAO_PEGTL_TEST_ASSERT( call1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_http.cpp000066400000000000000000000051661426407250600215210ustar00rootroot00000000000000// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include namespace TAO_PEGTL_NAMESPACE { void test_header() { // TODO. } template< typename Rule > struct chunked_action : nothing< Rule > {}; template<> struct chunked_action< http::chunk_ext > { static void apply0( std::string& s ) { s += 'a'; } }; template<> struct chunked_action< http::chunk_data > { static void apply0( std::string& s ) { s += 'b'; } }; void test_chunked() { using GRAMMAR = must< http::chunked_body, eof >; verify_analyze< GRAMMAR >( __LINE__, __FILE__, true, false ); { string_input in( "0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( in ) ); } { std::string dummy; string_input in( "0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( in, dummy ) ); } { std::string state; string_input in( "0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR, chunked_action >( in, state ) ); TAO_PEGTL_TEST_ASSERT( state == "a" ); } { std::string state; string_input in( "\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< GRAMMAR, chunked_action >( in, state ) ); } { std::string state; string_input in( "1\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< GRAMMAR, chunked_action >( in, state ) ); } { string_input in( "01\r\nX\r\n1a\r\nabcdefghijklmnopqrstuvwxyz\r\n0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( in ) ); } { std::string dummy; string_input in( "01\r\nX\r\n1a\r\nabcdefghijklmnopqrstuvwxyz\r\n0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( in, dummy ) ); } { std::string state; string_input in( "01\r\nX\r\n1A\r\nabcdefghijklmnopqrstuvwxyz\r\n0\r\n\r\n", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR, chunked_action >( in, state ) ); TAO_PEGTL_TEST_ASSERT( state == "ababa" ); } } void unit_test() { test_header(); test_chunked(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/contrib_if_then.cpp000066400000000000000000000016061426407250600221510ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { // clang-format off using grammar = if_then< one< 'a' >, one< 'b' >, one< 'c' > >:: else_if_then< one< 'a' >, one< 'b' > >:: else_then< one< 'c' > >; // clang-format on verify_rule< grammar >( __LINE__, __FILE__, "abc", result_type::success, 0 ); verify_rule< grammar >( __LINE__, __FILE__, "abcd", result_type::success, 1 ); verify_rule< grammar >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_rule< grammar >( __LINE__, __FILE__, "c", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_instantiate.cpp000066400000000000000000000031301426407250600230520ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { bool ctor = false; bool dtor = false; struct test_class { template< typename ParseInput > test_class( const ParseInput& /*unused*/ ) { TAO_PEGTL_TEST_ASSERT( ctor == false ); TAO_PEGTL_TEST_ASSERT( dtor == false ); ctor = true; } test_class( test_class&& ) = delete; test_class( const test_class& ) = delete; ~test_class() { TAO_PEGTL_TEST_ASSERT( ctor == true ); TAO_PEGTL_TEST_ASSERT( dtor == false ); dtor = true; } test_class& operator=( test_class&& ) = delete; test_class& operator=( const test_class& ) = delete; }; using test_grammar = sor< alpha, digit >; template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< alpha > { static void apply0() { TAO_PEGTL_TEST_ASSERT( ctor == true ); TAO_PEGTL_TEST_ASSERT( dtor == false ); } }; template<> struct test_action< sor< alpha, digit > > : instantiate< test_class > {}; void unit_test() { memory_input in( "a", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< test_grammar, test_action >( in ) ); TAO_PEGTL_TEST_ASSERT( ctor == true ); TAO_PEGTL_TEST_ASSERT( dtor == true ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_integer.cpp000066400000000000000000000263231426407250600221750ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include #include #include #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct int_action : nothing< Rule > {}; template<> struct int_action< signed_rule > : signed_action {}; template<> struct int_action< unsigned_rule > : unsigned_action {}; template< typename S > void test_signed( const std::string& i, const S s ) { { S st = -123; memory_input in( i, __FUNCTION__ ); parse< must< signed_rule, eof >, int_action >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } { S st = -123; memory_input in( i, __FUNCTION__ ); parse< must< signed_rule_with_action, eof > >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } } template< typename S > void test_signed( const std::string& i ) { S st; memory_input in( i, __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< must< signed_rule, eof >, int_action >( in, st ) ); } template< typename S > std::string lexical_cast( const S s ) { std::ostringstream oss; oss << s; return std::move( oss ).str(); } template< typename S > void test_signed( const S s ) { S st; const auto i = lexical_cast( s ); memory_input in( i, __FUNCTION__ ); parse< must< signed_rule, eof >, int_action >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } template< typename S > void test_unsigned( const std::string& i, const S s ) { { S st = 123; memory_input in( i, __FUNCTION__ ); parse< must< unsigned_rule, eof >, int_action >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } { S st = 123; memory_input in( i, __FUNCTION__ ); parse< must< unsigned_rule_with_action, eof > >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } } template< typename S > void test_unsigned( const std::string& i ) { S st = 123; memory_input in( i, __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< must< unsigned_rule, eof >, int_action >( in, st ) ); } template< typename S > void test_unsigned( const S s ) { S st = 123; const auto i = lexical_cast( s ); memory_input in( i, __FUNCTION__ ); parse< must< unsigned_rule, eof >, int_action >( in, st ); TAO_PEGTL_TEST_ASSERT( st == s ); } template< auto M > using max_seq_rule = seq< one< 'a' >, maximum_rule< std::uint64_t, M >, one< 'b' >, eof >; void unit_test() { test_signed< signed char >( "" ); test_signed< signed char >( "-" ); test_signed< signed char >( "+" ); test_signed< signed char >( "a" ); test_signed< signed char >( "--0" ); test_signed< signed char >( "++0" ); test_signed< signed char >( "-+0" ); test_signed< signed char >( "0", 0 ); test_signed< signed char >( "+0", 0 ); test_signed< signed char >( "-0", 0 ); test_signed< signed char >( "000" ); test_signed< signed char >( "+000" ); test_signed< signed char >( "-000" ); test_signed< signed char >( "127", 127 ); test_signed< signed char >( "0127" ); test_signed< signed char >( "-1", -1 ); test_signed< signed char >( "-01" ); test_signed< signed char >( "-001" ); test_signed< signed char >( "-127", -127 ); test_signed< signed char >( "-128", -128 ); test_signed< signed char >( "128" ); test_signed< signed char >( "-129" ); test_signed< signed char >( "0128" ); test_signed< signed char >( "00128" ); test_signed< signed char >( "-0129" ); test_signed< signed char >( "-00129" ); test_unsigned< unsigned char >( "" ); test_unsigned< unsigned char >( "-" ); test_unsigned< unsigned char >( "+" ); test_unsigned< unsigned char >( "a" ); test_unsigned< unsigned char >( "-0" ); test_unsigned< unsigned char >( "+1" ); test_unsigned< unsigned char >( "0", 0 ); test_unsigned< unsigned char >( "000" ); test_unsigned< unsigned char >( "0", 0 ); test_unsigned< unsigned char >( "255", 255 ); test_unsigned< unsigned char >( "0255" ); test_unsigned< unsigned char >( "000255" ); test_unsigned< unsigned char >( "256" ); test_unsigned< unsigned char >( "0256" ); test_unsigned< unsigned char >( "000256" ); test_signed< signed long long >( "0", 0 ); test_signed< signed long long >( ( std::numeric_limits< signed long long >::max )() ); test_signed< signed long long >( ( std::numeric_limits< signed long long >::min )() ); test_unsigned< unsigned long long >( "0", 0 ); test_unsigned< unsigned long long >( ( std::numeric_limits< unsigned long long >::max )() ); verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a1b", result_type::local_failure ); verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a9b", result_type::local_failure ); verify_rule< max_seq_rule< 0 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a1b", result_type::success ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a2b", result_type::local_failure ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a9b", result_type::local_failure ); verify_rule< max_seq_rule< 1 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a1b", result_type::success ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a2b", result_type::success ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a3b", result_type::local_failure ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a9b", result_type::local_failure ); verify_rule< max_seq_rule< 2 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a3b", result_type::success ); verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a4b", result_type::local_failure ); verify_rule< max_seq_rule< 3 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 4 > >( __LINE__, __FILE__, "a5b", result_type::local_failure ); verify_rule< max_seq_rule< 4 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a9b", result_type::success ); verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a10b", result_type::local_failure ); verify_rule< max_seq_rule< 9 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a9b", result_type::success ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a10b", result_type::success ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a11b", result_type::local_failure ); verify_rule< max_seq_rule< 10 > >( __LINE__, __FILE__, "a19b", result_type::local_failure ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a9b", result_type::success ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a10b", result_type::success ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a11b", result_type::success ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a12b", result_type::local_failure ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a13b", result_type::local_failure ); verify_rule< max_seq_rule< 11 > >( __LINE__, __FILE__, "a111b", result_type::local_failure ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a0b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a1b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a9b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a10b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a11b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a12b", result_type::success ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "ab", result_type::local_failure ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a13b", result_type::local_failure ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a19b", result_type::local_failure ); verify_rule< max_seq_rule< 12 > >( __LINE__, __FILE__, "a111b", result_type::local_failure ); verify_rule< max_seq_rule< 18446744073709551614ULL > >( __LINE__, __FILE__, "a18446744073709551614b", result_type::success ); verify_rule< max_seq_rule< 18446744073709551614ULL > >( __LINE__, __FILE__, "a18446744073709551615b", result_type::local_failure ); verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a18446744073709551615b", result_type::success ); verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a18446744073709551616b", result_type::local_failure ); verify_rule< max_seq_rule< 18446744073709551615ULL > >( __LINE__, __FILE__, "a98446744073709551614b", result_type::local_failure ); verify_analyze< unsigned_rule >( __LINE__, __FILE__, true, false ); verify_analyze< unsigned_rule_with_action >( __LINE__, __FILE__, true, false ); verify_analyze< signed_rule >( __LINE__, __FILE__, true, false ); verify_analyze< signed_rule_with_action >( __LINE__, __FILE__, true, false ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/contrib_iri.cpp000066400000000000000000000064721426407250600213260ustar00rootroot00000000000000// Copyright (c) 2021 Kelvin Hammond // Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { using GRAMMAR = must< iri::IRI, eof >; void unit_test() { verify_analyze< GRAMMAR >( __LINE__, __FILE__, true, false ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "https://en.wiktionary.org/wiki/%E1%BF%AC%CF%8C%CE%B4%CE%BF%CF%82", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "https://en.wiktionary.org/wiki/Ῥόδος", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "https://www.myfictionαlbank.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ftp://ftp.is.co.za/rfc/rfc1808.txt", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///C:/Users/Benutzer/Desktop/Uniform%20Resource%20Identifier.html", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///etc/fstab", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "geo:48.33,14.122;u=22.5", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ldap://[2001:db8::7]/c=GB?objectClass?one", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "gopher://gopher.floodgap.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "mailto:John.Doe@example.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "sip:911@pbx.mycompany.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "news:comp.infosystems.www.servers.unix", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "data:text/plain;charset=iso-8859-7,%be%fa%be", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "tel:+1-816-555-1212", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "telnet://192.0.2.16:80/", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "git://github.com/rails/rails.git", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "crid://broadcaster.com/movies/BestActionMovieEver", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "http://nobody:password@example.org:8080/cgi-bin/script.php?action=submit&pageid=86392001#section_2", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "quake://480fps.com:26000/", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ftp://300.300.300.300/foo", result_type::success ); // 300.300.300.300 is a valid hostname! TAO_PEGTL_TEST_THROWS( parse< GRAMMAR >( memory_input( "", "" ) ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/contrib_json.cpp000066400000000000000000000232671426407250600215150ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { using GRAMMAR = seq< json::text, eof >; void unit_test() { verify_analyze< GRAMMAR >( __LINE__, __FILE__, true, false ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "{}", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, " [ ] ", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, " { } ", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, " [ ] ", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, " { } ", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[[{}],[],{}]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[ null, true, false, 0, 1, 2, 123, 1.23, 0.12, -1, -0, -1.23, \"\", \"abc\" ]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\b\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\f\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\n\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\r\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\t\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\/\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\\\\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\\"\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\u002C\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\u002c\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"ab\\u002Ccd\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"ab\\u002ccd\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\uD834\\uDD1E\"]", result_type::success, 0 ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\uD834\"]", result_type::success, 0 ); // unfortunately, this is valid for the grammar... verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\\uDD1E\"]", result_type::success, 0 ); // ...although both inputs are invalid in unicode. verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\xC3\x84\"]", result_type::success, 0 ); // German a-umlaut verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\xF4\x8F\xBF\xBF\"]", result_type::success, 0 ); // largest allowed codepoint U+10FFFF verify_rule< GRAMMAR >( __LINE__, __FILE__, "[\"\U0010FFFF\"]", result_type::success, 0 ); // largest allowed codepoint U+10FFFF TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " [", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " ]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[ ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "] ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " [ ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( " ] ", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\a\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\c\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\d\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\e\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\v\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\'\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\b\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\f\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\n\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\r\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\t\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\\\\\\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\\u12\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\xFF\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\xF4\x90\x80\x80\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( memory_input( "[\"\xF7\xBF\xBF\xBF\"]", "" ) ) ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( file_input( "src/test/pegtl/data/pass1.json" ) ) ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( file_input( "src/test/pegtl/data/pass2.json" ) ) ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( file_input( "src/test/pegtl/data/pass3.json" ) ) ); TAO_PEGTL_TEST_ASSERT( parse< GRAMMAR >( file_input( "src/test/pegtl/data/blns.json" ) ) ); // TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail1.json" ) )); // disabled as it is valid now TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail2.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail3.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail4.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail5.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail6.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail7.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail8.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail9.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail10.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail11.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail12.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail13.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail14.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail15.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail16.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail17.json" ) ) ); // TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail18.json" ) )); // disabled as deep nesting is allowed TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail19.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail20.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail21.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail22.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail23.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail24.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail25.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail26.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail27.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail28.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail29.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail30.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail31.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail32.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail33.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail34.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail35.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail36.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail37.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail38.json" ) ) ); TAO_PEGTL_TEST_ASSERT( !parse< GRAMMAR >( file_input( "src/test/pegtl/data/fail39.json" ) ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_parse_tree.cpp000066400000000000000000000132241426407250600226650ustar00rootroot00000000000000// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct C : one< 'c' > {}; struct D : sor< seq< A, B >, seq< A, C > > {}; struct E : star< A, B > {}; struct F : seq< E > {}; #if defined( __cpp_exceptions ) struct D2 : sor< try_catch< if_must< A, B > >, seq< A, C > > {}; #else struct D2 : D {}; #endif // clang-format on template< typename Rule > using selector = parse_tree::selector< Rule, parse_tree::store_content::on< A, B >, parse_tree::remove_content::on< C >, parse_tree::fold_one::on< D > >; template< typename Rule > using selector2 = parse_tree::selector< Rule, parse_tree::store_content::on< A >, parse_tree::discard_empty::on< B >, parse_tree::discard_empty::on< F >, parse_tree::fold_one::on< E > >; void unit_test() { { memory_input in( "ac", "input" ); const auto r = parse_tree::parse< D, selector >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 1 ); const auto& d = r->children.front(); TAO_PEGTL_TEST_ASSERT( !d->is_root() ); TAO_PEGTL_TEST_ASSERT( d->is_type< D >() ); TAO_PEGTL_TEST_ASSERT( !d->has_content() ); TAO_PEGTL_TEST_ASSERT( d->children.size() == 2 ); TAO_PEGTL_TEST_ASSERT( d->children.front()->is_type< A >() ); TAO_PEGTL_TEST_ASSERT( d->children.back()->is_type< C >() ); memory_input in2( "x", "input" ); const auto r2 = parse_tree::parse< D, selector >( in2 ); TAO_PEGTL_TEST_ASSERT( !r2 ); } { memory_input in( "aba", "input" ); const auto r = parse_tree::parse< E, selector >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 2 ); TAO_PEGTL_TEST_ASSERT( r->children.front()->is_type< A >() ); TAO_PEGTL_TEST_ASSERT( r->children.back()->is_type< B >() ); } { memory_input in( "ab", "input" ); const auto r = parse_tree::parse< E, selector2 >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 1 ); TAO_PEGTL_TEST_ASSERT( r->children.front()->is_type< A >() ); } { memory_input in( "aba", "input" ); const auto r = parse_tree::parse< F, selector2 >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 1 ); const auto& f = r->children.front(); TAO_PEGTL_TEST_ASSERT( !f->is_root() ); TAO_PEGTL_TEST_ASSERT( f->is_type< F >() ); TAO_PEGTL_TEST_ASSERT( !f->has_content() ); TAO_PEGTL_TEST_ASSERT( f->children.size() == 1 ); const auto& a = f->children.front(); TAO_PEGTL_TEST_ASSERT( !a->is_root() ); TAO_PEGTL_TEST_ASSERT( a->is_type< A >() ); TAO_PEGTL_TEST_ASSERT( a->has_content() ); TAO_PEGTL_TEST_ASSERT( a->children.empty() ); } { memory_input in( "ac", "input" ); const auto r = parse_tree::parse< D2, selector >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 2 ); TAO_PEGTL_TEST_ASSERT( r->children.front()->is_type< A >() ); TAO_PEGTL_TEST_ASSERT( r->children.back()->is_type< C >() ); } { memory_input in( "ac", "input" ); const auto r = parse_tree::parse< D2 >( in ); TAO_PEGTL_TEST_ASSERT( r ); TAO_PEGTL_TEST_ASSERT( r->is_root() ); TAO_PEGTL_TEST_ASSERT( !r->has_content() ); TAO_PEGTL_TEST_ASSERT( r->children.size() == 1 ); const auto& d2 = r->children.front(); TAO_PEGTL_TEST_ASSERT( !d2->is_root() ); TAO_PEGTL_TEST_ASSERT( d2->is_type< D2 >() ); TAO_PEGTL_TEST_ASSERT( d2->has_content() ); TAO_PEGTL_TEST_ASSERT( d2->begin().byte == 0 ); TAO_PEGTL_TEST_ASSERT( d2->end().byte == 2 ); TAO_PEGTL_TEST_ASSERT( d2->string() == "ac" ); const auto& internal = d2->children.front(); TAO_PEGTL_TEST_ASSERT( !internal->is_root() ); TAO_PEGTL_TEST_ASSERT( internal->is_type< seq< A, C > >() ); TAO_PEGTL_TEST_ASSERT( internal->has_content() ); TAO_PEGTL_TEST_ASSERT( internal->begin().byte == 0 ); TAO_PEGTL_TEST_ASSERT( internal->end().byte == 2 ); TAO_PEGTL_TEST_ASSERT( internal->string_view() == "ac" ); TAO_PEGTL_TEST_ASSERT( internal->children.size() == 2 ); TAO_PEGTL_TEST_ASSERT( internal->children.front()->is_type< A >() ); TAO_PEGTL_TEST_ASSERT( internal->children.back()->is_type< C >() ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_parse_tree_to_dot.cpp000066400000000000000000000020271426407250600242340ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include #include namespace TAO_PEGTL_NAMESPACE { // clang-format off struct A : one< 'a' > {}; struct B : one< 'b' > {}; struct C : one< 'c' > {}; #if defined( __cpp_exceptions ) struct S : if_must< one< '[' >, until< one< ']' > > > {}; #else struct S : seq< one< '[' >, until< one< ']' > > > {}; #endif struct D : sor< seq< A, B >, seq< A, C, S > > {}; // clang-format on template< typename Rule > struct selector : parse_tree::selector< Rule, parse_tree::store_content::on< A, B, C, D, S > > {}; void unit_test() { memory_input in( "ac[\"\\\x01\x7f\b\n\r\f\t\a\v]", "input" ); const auto root = parse_tree::parse< D, selector >( in ); parse_tree::print_dot( std::cout, *root ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_partial_trace.cpp000066400000000000000000000015051426407250600233450ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { // clang-format off struct inner : seq< one< 'a' >, sor< one< 'b' >, one< 'c' >, inner > > {}; struct outer : seq< one< 'x' >, inner, one< 'y' > > {}; // how to run a tracer on a *part* of the grammar: template< typename > struct partial_action {}; template<> struct partial_action< inner > : trace_standard {}; // clang-format on void unit_test() { memory_input in( "xaacy", "trace test please ignore" ); const auto result = parse< outer, partial_action >( in ); TAO_PEGTL_TEST_ASSERT( result ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_predicates.cpp000066400000000000000000000120261426407250600226560ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< predicates_or< one< ' ' > > >( __LINE__, __FILE__, true, false ); verify_analyze< predicates_or< one< ' ' >, range< 'a', 'z' > > >( __LINE__, __FILE__, true, false ); verify_rule< predicates_or< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); for( char i = 1; i < 'a'; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } for( char i = 'b'; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } verify_rule< predicates_or< one< 'a', 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< predicates_or< one< 'a', 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 0 ); for( char i = 1; i < 'a'; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a', 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } for( char i = 'c'; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a', 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } verify_rule< predicates_or< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< predicates_or< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 0 ); for( char i = 1; i < 'a'; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } for( char i = 'c'; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } verify_rule< predicates_or< range< 'a', 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< predicates_or< range< 'a', 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 0 ); for( char i = 1; i < 'a'; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< range< 'a', 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } for( char i = 'c'; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< range< 'a', 'b' > > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } using rule_t = predicates_or< one< 'f' >, range< 'b', 'd' >, range< 'm', 'n' >, one< 'x', 'y' > >; verify_rule< rule_t >( __LINE__, __FILE__, "b", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "c", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "d", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "m", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "n", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "x", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "y", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "f", result_type::success, 0 ); verify_rule< rule_t >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "e", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "g", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "l", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "w", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "z", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "k", result_type::local_failure, 1 ); verify_rule< rule_t >( __LINE__, __FILE__, "r", result_type::local_failure, 1 ); using pred_t = predicates_or< one< 'a' >, predicates_or< one< 'b' > > >; verify_rule< predicates_or< pred_t > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< predicates_or< pred_t > >( __LINE__, __FILE__, "b", result_type::success, 0 ); for( char i = 1; i < 'a'; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< pred_t > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } for( char i = 'c'; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< predicates_or< pred_t > >( __LINE__, __FILE__, std::string( t ), result_type::local_failure, 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_print.cpp000066400000000000000000000012121426407250600216620ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { using grammar = seq< alpha, digit >; void unit_test() { // Just enough to see that it compiles and nothing explodes; // the output format probabaly changes between compilers and // versions making a proper test difficult. print_names< grammar >( std::cout ); print_debug< grammar >( std::cout ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_raw_string.cpp000066400000000000000000000137031426407250600227150ustar00rootroot00000000000000// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include namespace TAO_PEGTL_NAMESPACE { std::string content; using rstring = raw_string< '[', '=', ']' >; using qstring = raw_string< '[', '=', ']', alpha, digit >; template< typename Rule > struct raction {}; template<> struct raction< rstring::content > { template< typename ActionInput, typename... States > static void apply( const ActionInput& in, const States&... /*unused*/ ) { content.assign( in.begin(), in.end() ); } }; template< typename Rule > struct qaction {}; template<> struct qaction< qstring::content > { template< typename ActionInput, typename... States > static void apply( const ActionInput& in, const States&... /*unused*/ ) { content.assign( in.begin(), in.end() ); } }; struct rgrammar : seq< rstring, eof > {}; struct qgrammar : seq< qstring, eof > {}; template< typename Rule, template< typename > class Action, unsigned M, unsigned N > void verify_data( const std::size_t line, const char* file, const char ( &m )[ M ], const char ( &n )[ N ] ) { content.clear(); memory_input in( m, m + M - 1, file, 0, line, 1 ); const auto r = parse< Rule, Action >( in ); if( ( !r ) || ( content != std::string_view( n, N - 1 ) ) ) { TAO_PEGTL_TEST_FAILED( "input data [ '" << m << "' ] expected success with [ '" << n << "' ] but got [ '" << content << "' ] result [ " << r << " ]" ); // LCOV_EXCL_LINE } content.clear(); memory_input< tracking_mode::lazy > in2( m, m + M - 1, file, 0, line, 1 ); const auto r2 = parse< Rule, Action >( in2 ); if( ( !r2 ) || ( content != std::string_view( n, N - 1 ) ) ) { TAO_PEGTL_TEST_FAILED( "input data [ '" << m << "' ] with tracking_mode::lazy expected success with [ '" << n << "' ] but got [ '" << content << "' ] result [ " << r2 << " ]" ); // LCOV_EXCL_LINE } } template< typename Rule > void verify_fail( const std::size_t line, const char* file, const std::string& s ) { memory_input in( s, "expect exception" ); if( parse< Rule >( in ) ) { TAO_PEGTL_TEST_FAILED( "expected exception" ); // LCOV_EXCL_LINE } } void unit_test() { verify_analyze< rstring >( __LINE__, __FILE__, true, false ); verify_analyze< qstring >( __LINE__, __FILE__, true, false ); verify_analyze< raw_string< 'a', 'b', 'c', star< star< any > > > >( __LINE__, __FILE__, true, true ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[[]]", "" ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[[foo]]", "foo" ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[===[foo]===]", "foo" ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[===[\nfoo]===]", "foo" ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[===[\r\nfoo]===]", "foo" ); verify_data< rgrammar, raction >( __LINE__, __FILE__, "[===[\0\0\0]===]", "\0\0\0" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[[]]", "" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[[a1]]", "a1" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[===[a1]===]", "a1" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[===[\na1]===]", "a1" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[===[\r\na1]===]", "a1" ); verify_data< qgrammar, qaction >( __LINE__, __FILE__, "[===[a0a1a2a3]===]", "a0a1a2a3" ); verify_fail< rgrammar >( __LINE__, __FILE__, "" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[=" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[=[" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[=[]=" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[=[]]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[[]] " ); verify_fail< rgrammar >( __LINE__, __FILE__, " [[]]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[=[]-]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[-[]=]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[-[]-]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[===[]====]" ); verify_fail< rgrammar >( __LINE__, __FILE__, "[====[]===]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[]=" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[]]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[[]] " ); verify_fail< qgrammar >( __LINE__, __FILE__, " [[]]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[]-]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[-[]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[-[]-]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[===[]====]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[====[]===]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[-]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[1]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[a]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[a+]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[aa]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[11]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[a1a]=]" ); verify_fail< qgrammar >( __LINE__, __FILE__, "[=[a1aa]=]" ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_remove_first_state.cpp000066400000000000000000000043761426407250600244500ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< one< 'F' > > { static void apply0( unsigned& u ) noexcept { u |= 1; } }; template<> struct test_action< eof > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, unsigned& u ) noexcept { u |= 2; } }; template< typename Rule > struct control_impl : normal< Rule > { template< typename ParseInput > static void start( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 64; } template< typename ParseInput > static void success( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 32; } template< typename ParseInput > static void failure( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 16; } #if defined( __cpp_exceptions ) template< typename ParseInput > [[noreturn]] static void raise( ParseInput& in, unsigned& u ) { u |= 4; throw parse_error( "raise", in ); } template< typename ParseInput > static void unwind( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 8; } #endif }; template< typename Rule > struct test_control : remove_first_state< control_impl< Rule > > {}; #if defined( __cpp_exceptions ) struct test_rule : seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof > {}; #else struct test_rule : seq< sor< one< 'a' >, one< 'F' > >, eof > {}; #endif void unit_test() { unsigned u = 0; const std::string d = "F"; memory_input in( d, __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< test_rule, test_action, test_control >( in, d, u ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_ASSERT( u == 127 ); #else TAO_PEGTL_TEST_ASSERT( u == 115 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_remove_last_states.cpp000066400000000000000000000044041426407250600244370ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< one< 'F' > > { static void apply0( unsigned& u ) noexcept { u |= 1; } }; template<> struct test_action< eof > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, unsigned& u ) noexcept { u |= 2; } }; template< typename Rule > struct control_impl : normal< Rule > { template< typename ParseInput > static void start( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 64; } template< typename ParseInput > static void success( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 32; } template< typename ParseInput > static void failure( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 16; } #if defined( __cpp_exceptions ) template< typename ParseInput > [[noreturn]] static void raise( ParseInput& in, unsigned& u ) { u |= 4; throw parse_error( "raise", in ); } template< typename ParseInput > static void unwind( ParseInput& /*unused*/, unsigned& u ) noexcept { u |= 8; } #endif }; template< typename Rule > struct test_control : remove_last_states< control_impl< Rule >, 2 > {}; #if defined( __cpp_exceptions ) struct test_rule : seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof > {}; #else struct test_rule : seq< sor< one< 'a' >, one< 'F' > >, eof > {}; #endif void unit_test() { unsigned u = 0; const std::string d = "F"; memory_input in( d, __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< test_rule, test_action, test_control >( in, u, d, d ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_ASSERT( u == 127 ); #else TAO_PEGTL_TEST_ASSERT( u == 115 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_rep_one_min_max.cpp000066400000000000000000000037701426407250600237000ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_one_min_max< 0, 1, '+' > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_one_min_max< 1, 1, '+' > >( __LINE__, __FILE__, true, false ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, ".", result_type::local_failure, 1 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "..", result_type::local_failure, 2 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "....", result_type::local_failure, 4 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "...", result_type::success, 0 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "... ", result_type::success, 1 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "...+", result_type::success, 1 ); verify_rule< rep_one_min_max< 3, 3, '.' > >( __LINE__, __FILE__, "...a", result_type::success, 1 ); verify_rule< rep_one_min_max< 0, 2, '+' > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_one_min_max< 0, 2, '+' > >( __LINE__, __FILE__, "-", result_type::success, 1 ); verify_rule< rep_one_min_max< 0, 2, '+' > >( __LINE__, __FILE__, "+-", result_type::success, 1 ); verify_rule< rep_one_min_max< 0, 2, '+' > >( __LINE__, __FILE__, "++-", result_type::success, 1 ); verify_rule< rep_one_min_max< 0, 2, '+' > >( __LINE__, __FILE__, "+++", result_type::local_failure, 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_rep_string.cpp000066400000000000000000000052761426407250600227200ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_string< 0 > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_string< 1 > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_string< 0, 'a' > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_string< 0, 'a', 'b' > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_string< 1, 'a' > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_string< 3, 'a' > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_string< 4, 'a', 'b' > >( __LINE__, __FILE__, true, false ); verify_rule< rep_string< 0 > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_string< 1 > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_string< 0, 'a' > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_string< 0 > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_string< 1 > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_string< 0, 'a' > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_string< 1, 'a', 'b' > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep_string< 1, 'a', 'b' > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep_string< 1, 'a', 'b' > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< rep_string< 1, 'a', 'b' > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "aabb", result_type::local_failure, 4 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "abaa", result_type::local_failure, 4 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< rep_string< 2, 'a', 'b' > >( __LINE__, __FILE__, "ababab", result_type::success, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_separated_seq.cpp000066400000000000000000000013211426407250600233470ustar00rootroot00000000000000// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include // clang-format off struct A {}; struct B {}; struct C {}; struct D {}; struct S {}; // clang-format on using namespace TAO_PEGTL_NAMESPACE; static_assert( std::is_base_of_v< internal::seq<>, separated_seq< S > > ); static_assert( std::is_base_of_v< internal::seq< A >, separated_seq< S, A > > ); static_assert( std::is_base_of_v< internal::seq< A, S, B >, separated_seq< S, A, B > > ); static_assert( std::is_base_of_v< internal::seq< A, S, B, S, C, S, D >, separated_seq< S, A, B, C, D > > ); int main() {} tao-pegtl-3.2.7/src/test/pegtl/contrib_state_control.cpp000066400000000000000000000205121426407250600234120ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include #include #include #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { struct test_entry { std::string_view rule; std::string_view func; std::size_t b; }; 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 ); } template< bool E > struct test_state { std::vector< test_entry > trace; template< typename Rule > static constexpr bool enable = E; template< typename Rule, typename Input, typename... States > void start( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "start", ++b } ); } template< typename Rule, typename Input, typename... States > void success( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "success", ++b } ); } template< typename Rule, typename Input, typename... States > void failure( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "failure", ++b } ); } template< typename Rule, typename Input, typename... States > void raise( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "raise", ++b } ); } template< typename Rule, typename Input, typename... States > void unwind( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "unwind", ++b } ); } template< typename Rule, typename Input, typename... States > void apply( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "apply", ++b } ); } template< typename Rule, typename Input, typename... States > void apply0( const Input& /*unused*/, const int a, std::size_t& b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); trace.push_back( { demangle< Rule >(), "apply0", ++b } ); } }; struct test_grammar : must< sor< one< 'a' >, try_catch< seq< one< 'b' >, must< one< 'c' > > > >, two< 'b' > >, eof > {}; template< typename Rule > struct test_action : nothing< Rule > {}; bool test_action_one = false; template<> struct test_action< one< 'b' > > { static void apply0( const int a, const std::size_t b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); if( test_action_one ) { TAO_PEGTL_TEST_ASSERT( b == 0 ); test_action_one = false; } else { TAO_PEGTL_TEST_ASSERT( b == 9 ); test_action_one = true; } } }; bool test_action_two = false; template<> struct test_action< two< 'b' > > { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, const int a, const std::size_t b ) { TAO_PEGTL_TEST_ASSERT( a == -1 ); if( test_action_two ) { TAO_PEGTL_TEST_ASSERT( b == 0 ); test_action_two = false; } else { TAO_PEGTL_TEST_ASSERT( b == 19 ); test_action_two = true; } } }; void unit_test() { { test_state< true > st; memory_input in( "bb", __FUNCTION__ ); std::size_t b = 0; const bool result = parse< test_grammar, test_action, state_control< normal >::type >( in, -1, b, st ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( test_action_one ); TAO_PEGTL_TEST_ASSERT( test_action_two ); 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_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< 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< 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 } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'b' > >(), "success", ++b } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< must< one< 'c' > > >(), "start", ++b } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'c' > >(), "start", ++b } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< one< 'c' > >(), "failure", ++b } ); 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< 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< 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 } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< internal::must< eof > >(), "success", ++b } ); TAO_PEGTL_TEST_ASSERT( st.trace[ i++ ] == test_entry{ demangle< test_grammar >(), "success", ++b } ); TAO_PEGTL_TEST_ASSERT( i == st.trace.size() ); TAO_PEGTL_TEST_ASSERT( b == st.trace.size() ); } { test_state< false > st; memory_input in( "bb", __FUNCTION__ ); std::size_t b = 0; const bool result = parse< test_grammar, test_action, state_control< normal >::type >( in, -1, b, st ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( !test_action_one ); TAO_PEGTL_TEST_ASSERT( !test_action_two ); TAO_PEGTL_TEST_ASSERT( st.trace.empty() ); TAO_PEGTL_TEST_ASSERT( b == 0 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/contrib_to_string.cpp000066400000000000000000000025301426407250600225420ustar00rootroot00000000000000// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include #include namespace TAO_PEGTL_NAMESPACE { void unit_test() { TAO_PEGTL_TEST_ASSERT( to_string< string<> >().empty() ); TAO_PEGTL_TEST_ASSERT( ( to_string< string< 'a', 'b', 'c' > >() == "abc" ) ); TAO_PEGTL_TEST_ASSERT( to_string< istring<> >().empty() ); TAO_PEGTL_TEST_ASSERT( ( to_string< istring< 'a', 'b', 'c' > >() == "abc" ) ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_STRING( "" ) >().empty() ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_STRING( "abc" ) >() == "abc" ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_STRING( "AbC" ) >() == "AbC" ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_STRING( "abc" ) >() != "AbC" ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_ISTRING( "abc" ) >() == "abc" ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_ISTRING( "AbC" ) >() == "AbC" ); TAO_PEGTL_TEST_ASSERT( to_string< TAO_PEGTL_ISTRING( "abc" ) >() != "AbC" ); // to_string does *not* care about the outer class template TAO_PEGTL_TEST_ASSERT( ( to_string< one< 'a', 'b', 'c' > >() == "abc" ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_trace1.cpp000066400000000000000000000015711426407250600217150ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { #if defined( __cpp_exceptions ) using grammar = seq< sor< try_catch< must< one< 'a' > > >, one< 'F' > >, eof >; #else using grammar = seq< sor< one< 'a' >, one< 'F' > >, eof >; #endif void unit_test() { const std::string data = "F"; memory_input in( data, __FILE__ ); // Just enough to see that it compiles and nothing explodes; // the output format probabaly changes between compilers and // versions making a proper test difficult. standard_trace< grammar >( in ); in.restart(); complete_trace< grammar >( in ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_trace2.cpp000066400000000000000000000050201426407250600217070ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { using GRAMMAR1 = sor< failure, one< 'a' > >; 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' > > > >; #endif template< typename Rule > struct trace_action {}; unsigned a0 = 0; unsigned a = 0; template<> struct trace_action< one< 'a' > > { template< typename... Ts > static void apply0( Ts&&... /*unused*/ ) { ++a0; } }; template<> struct trace_action< GRAMMAR1 > { template< typename... Ts > static void apply( Ts&&... /*unused*/ ) { ++a; } }; void unit_test() { { memory_input in( "ab", "trace test please ignore" ); const auto result = standard_trace< GRAMMAR1 >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( a0 == 0 ); TAO_PEGTL_TEST_ASSERT( a == 0 ); } { memory_input in( "ab", "trace test please ignore" ); const auto result = standard_trace< GRAMMAR1, trace_action >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( a0 == 1 ); TAO_PEGTL_TEST_ASSERT( a == 1 ); } { memory_input in( "a\r\n\t\0b", 6, "trace test please ignore" ); const auto result = standard_trace< GRAMMAR2 >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( a0 == 1 ); TAO_PEGTL_TEST_ASSERT( a == 1 ); } { memory_input in( "a\r\n\t\0b", 6, "trace test please ignore" ); const auto result = standard_trace< GRAMMAR2, trace_action >( in ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( a0 == 2 ); TAO_PEGTL_TEST_ASSERT( a == 1 ); } { memory_input in( "c", "trace test please ignore" ); const auto result = standard_trace< GRAMMAR3 >( in ); TAO_PEGTL_TEST_ASSERT( !result ); } #if defined( __cpp_exceptions ) { memory_input in( "c", "trace test please ignore" ); const auto result = standard_trace< GRAMMAR4 >( in ); TAO_PEGTL_TEST_ASSERT( !result ); } #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_unescape.cpp000066400000000000000000000134071426407250600223420ustar00rootroot00000000000000// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include namespace TAO_PEGTL_NAMESPACE { // clang-format off struct escaped_c : one< '"', '\\', 't' > {}; struct escaped_u : seq< one< 'u' >, rep< 4, xdigit > > {}; struct escaped_U : seq< one< 'U' >, rep< 8, xdigit > > {}; struct escaped_j : list< seq< one< 'j' >, rep< 4, xdigit > >, one< '\\' > > {}; struct escaped_x : seq< one< 'x' >, rep< 2, xdigit > > {}; struct escaped : sor< escaped_c, escaped_u, escaped_U, escaped_j, escaped_x > {}; struct character : if_then_else< one< '\\' >, escaped, utf8::any > {}; struct unstring : until< eof, character > {}; template< typename Rule > struct unaction {}; template<> struct unaction< escaped_c > : unescape::unescape_c< escaped_c, '"', '\\', '\t' > {}; template<> struct unaction< escaped_u > : unescape::unescape_u {}; template<> struct unaction< escaped_U > : unescape::unescape_u {}; template<> struct unaction< escaped_j > : unescape::unescape_j {}; template<> struct unaction< escaped_x > : unescape::unescape_x {}; template<> struct unaction< utf8::any > : unescape::append_all {}; // clang-format on template< unsigned M, unsigned N > bool verify_data( const char ( &m )[ M ], const char ( &n )[ N ] ) { std::string s; memory_input in( m, M - 1, __FUNCTION__ ); if( !parse< unstring, unaction >( in, s ) ) { return false; // LCOV_EXCL_LINE } return s == std::string( n, N - 1 ); } bool verify_fail( const std::string& m ) { std::string s; memory_input in( m, __FUNCTION__ ); #if defined( __cpp_exceptions ) try { return !parse< unstring, unaction >( in, s ); } catch( const parse_error& ) { } return true; #else return !parse< unstring, unaction >( in, s ); #endif } void unit_test() { TAO_PEGTL_TEST_ASSERT( verify_data( "\\t", "\t" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\\\", "\\" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "abc", "abc" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\\"foo\\\"", "\"foo\"" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\x20", " " ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\x30", "0" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\x2000", " 00" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\u0020", " " ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\u0020\\u0020", " " ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\u00e4", "\xc3\xa4" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\u00E4", "\xC3\xA4" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\u20ac", "\xe2\x82\xac" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\ud800" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\ud800X" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\ud800\\u0020" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\ud800\\udc00" ) ); // unescape_u does not support surrogate pairs. TAO_PEGTL_TEST_ASSERT( verify_fail( "\\udc00\\ud800" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\j0020", " " ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\j0020\\j0020", " " ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\j20ac", "\xe2\x82\xac" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\jd800\\jdc00", "\xf0\x90\x80\x80" ) ); // unescape_j does support proper surrogate pairs. TAO_PEGTL_TEST_ASSERT( verify_fail( "\\jd800" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\jd800X" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\jd800\\j0020" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\jdc00\\jd800" ) ); TAO_PEGTL_TEST_ASSERT( verify_data( "\\j0000\\u0000\x00", "\x00\x00\x00" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\\\\\" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\x" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\xx" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\xa" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\x1" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\x1h" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\x" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\xx" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\xa" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\x1" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "a\\x1h" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\a" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\_" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\z" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\1" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\a00" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\_1111" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\z22222222" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\13333333333333333" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\u" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\uu" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\uuuu" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\u123" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\u999" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\u444h" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\j" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\ju" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\juuu" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\j123" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\j999" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\j444h" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\U00110000" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\U80000000" ) ); TAO_PEGTL_TEST_ASSERT( verify_fail( "\\Uffffffff" ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" tao-pegtl-3.2.7/src/test/pegtl/contrib_uri.cpp000066400000000000000000000056261426407250600213420ustar00rootroot00000000000000// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" #include namespace TAO_PEGTL_NAMESPACE { using GRAMMAR = must< uri::URI, eof >; void unit_test() { verify_analyze< GRAMMAR >( __LINE__, __FILE__, true, false ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "http://de.wikipedia.org/wiki/Uniform_Resource_Identifier", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ftp://ftp.is.co.za/rfc/rfc1808.txt", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///C:/Users/Benutzer/Desktop/Uniform%20Resource%20Identifier.html", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///etc/fstab", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "geo:48.33,14.122;u=22.5", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ldap://[2001:db8::7]/c=GB?objectClass?one", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "gopher://gopher.floodgap.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "mailto:John.Doe@example.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "sip:911@pbx.mycompany.com", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "news:comp.infosystems.www.servers.unix", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "data:text/plain;charset=iso-8859-7,%be%fa%be", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "tel:+1-816-555-1212", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "telnet://192.0.2.16:80/", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "git://github.com/rails/rails.git", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "crid://broadcaster.com/movies/BestActionMovieEver", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "http://nobody:password@example.org:8080/cgi-bin/script.php?action=submit&pageid=86392001#section_2", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "quake://480fps.com:26000/", result_type::success ); verify_rule< GRAMMAR >( __LINE__, __FILE__, "ftp://300.300.300.300/foo", result_type::success ); // 300.300.300.300 is a valid hostname! TAO_PEGTL_TEST_THROWS( parse< GRAMMAR >( memory_input( "", "" ) ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/control_unwind.cpp000066400000000000000000000025101426407250600220540ustar00rootroot00000000000000// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct r : seq< alpha, digit > {}; template< typename R > struct a : nothing< R > {}; template< typename R > struct c : normal< R > {}; unsigned flags = 0; template<> struct a< alpha > { static void apply0() { flags |= 1; } }; template<> struct a< digit > { static void apply0() { throw 42; } }; template<> struct c< r > : normal< r > { template< typename Input > static void unwind( const Input& /*unused*/ ) { flags |= 2; } }; void unit_test() { memory_input in( "a1", __FUNCTION__ ); try { parse< r, a, c >( in ); TAO_PEGTL_TEST_UNREACHABLE; // LCOV_EXCL_LINE } catch( const int& e ) { TAO_PEGTL_TEST_ASSERT( e == 42 ); } TAO_PEGTL_TEST_ASSERT( flags == 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif tao-pegtl-3.2.7/src/test/pegtl/data/000077500000000000000000000000001426407250600172175ustar00rootroot00000000000000tao-pegtl-3.2.7/src/test/pegtl/data/README.txt000066400000000000000000000031101426407250600207100ustar00rootroot00000000000000pass1 thru pass3 fail1 thru fail33 ================= http://json.org/JSON_checker If the JSON grammar and the PEGTL are working correctly, they must accept all of the `pass*.json` files and reject all of the `fail*.json` files. Two of the failure tests (#1 and #18) are disabled since they are no longer applicable to newer JSON standards. fail34 thru fail39 ================== Additional tests added by the PEGTL authors. blns ==== The Big List of Naughty Strings https://github.com/minimaxir/big-list-of-naughty-strings The MIT License (MIT) Copyright (c) 2015 Max Woolf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tao-pegtl-3.2.7/src/test/pegtl/data/blns.json000066400000000000000000000616261426407250600210630ustar00rootroot00000000000000[ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "TRUE", "FALSE", "None", "hasOwnProperty", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "INF", "1#INF", "-1#IND", "1#QNAN", "1#SNAN", "1#IND", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000 000,00", "1'000'000,00", "01000", "08", "09", "2.2250738585072011e-308", ",./;'[]\\-=", "<>?:\"{}|_+", "!@#$%^&*()`~", "Ω≈ç√∫˜µ≤≥÷", "åß∂ƒ©˙∆˚¬…æ", "œ∑´®†¥¨ˆøπ“‘", "¡™£¢∞§¶•ªº–≠", "¸˛Ç◊ı˜Â¯˘¿", "ÅÍÎÏ˝ÓÔÒÚÆ☃", "Œ„´‰ˇÁ¨ˆØ∏”’", "`⁄€‹›fifl‡°·‚—±", "⅛⅜⅝⅞", "ЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя", "٠١٢٣٤٥٦٧٨٩", "⁰⁴⁵", "₀₁₂", "⁰⁴⁵₀₁₂", "ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็", "'", "\"", "''", "\"\"", "'\"'", "\"''''\"'\"", "\"'\"'\"''''\"", "", "", "", "", "田中さんにあげて下さい", "パーティーへ行かないか", "和製漢語", "部落格", "사회과학원 어학연구소", "찦차를 타고 온 펲시맨과 쑛다리 똠방각하", "社會科學院語學研究所", "울란바토르", "𠜎𠜱𠝹𠱓𠱸𠲖𠳏", "ヽ༼ຈل͜ຈ༽ノ ヽ༼ຈل͜ຈ༽ノ ", "(。◕ ∀ ◕。)", "`ィ(´∀`∩", "__ロ(,_,*)", "・( ̄∀ ̄)・:*:", "゚・✿ヾ╲(。◕‿◕。)╱✿・゚", ",。・:*:・゜’( ☻ ω ☻ )。・:*:・゜’", "(╯°□°)╯︵ ┻━┻) ", "(ノಥ益ಥ)ノ ┻━┻", "┬─┬ノ( º _ ºノ)", "( ͡° ͜ʖ ͡°)", "😍", "👩🏽", "👾 🙇 💁 🙅 🙆 🙋 🙎 🙍 ", "🐵 🙈 🙉 🙊", "❤️ 💔 💌 💕 💞 💓 💗 💖 💘 💝 💟 💜 💛 💚 💙", "✋🏿 💪🏿 👐🏿 🙌🏿 👏🏿 🙏🏿", "🚾 🆒 🆓 🆕 🆖 🆗 🆙 🏧", "0️⃣ 1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟", "🇺🇸🇷🇺🇸 🇦🇫🇦🇲🇸 ", "🇺🇸🇷🇺🇸🇦🇫🇦🇲", "🇺🇸🇷🇺🇸🇦", "123", "١٢٣", "ثم نفس سقطت وبالتحديد،, جزيرتي باستخدام أن دنو. إذ هنا؟ الستار وتنصيب كان. أهّل ايطاليا، بريطانيا-فرنسا قد أخذ. سليمان، إتفاقية بين ما, يذكر الحدود أي بعد, معاملة بولندا، الإطلاق عل إيو.", "בְּרֵאשִׁית, בָּרָא אֱלֹהִים, אֵת הַשָּׁמַיִם, וְאֵת הָאָרֶץ", "הָיְתָהtestالصفحات التّحول", "﷽", "ﷺ", "مُنَاقَشَةُ سُبُلِ اِسْتِخْدَامِ اللُّغَةِ فِي النُّظُمِ الْقَائِمَةِ وَفِيم يَخُصَّ التَّطْبِيقَاتُ الْحاسُوبِيَّةُ، ", "​", " ", "᠎", " ", "", "␣", "␢", "␡", "‪‪test‪", "‫test‫", "
test
", "test⁠test‫", "⁦test⁧", "Ṱ̺̺̕o͞ ̷i̲̬͇̪͙n̝̗͕v̟̜̘̦͟o̶̙̰̠kè͚̮̺̪̹̱̤ ̖t̝͕̳̣̻̪͞h̼͓̲̦̳̘̲e͇̣̰̦̬͎ ̢̼̻̱̘h͚͎͙̜̣̲ͅi̦̲̣̰̤v̻͍e̺̭̳̪̰-m̢iͅn̖̺̞̲̯̰d̵̼̟͙̩̼̘̳ ̞̥̱̳̭r̛̗̘e͙p͠r̼̞̻̭̗e̺̠̣͟s̘͇̳͍̝͉e͉̥̯̞̲͚̬͜ǹ̬͎͎̟̖͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ͏͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣", "̡͓̞ͅI̗̘̦͝n͇͇͙v̮̫ok̲̫̙͈i̖͙̭̹̠̞n̡̻̮̣̺g̲͈͙̭͙̬͎ ̰t͔̦h̞̲e̢̤ ͍̬̲͖f̴̘͕̣è͖ẹ̥̩l͖͔͚i͓͚̦͠n͖͍̗͓̳̮g͍ ̨o͚̪͡f̘̣̬ ̖̘͖̟͙̮c҉͔̫͖͓͇͖ͅh̵̤̣͚͔á̗̼͕ͅo̼̣̥s̱͈̺̖̦̻͢.̛̖̞̠̫̰", "̗̺͖̹̯͓Ṯ̤͍̥͇͈h̲́e͏͓̼̗̙̼̣͔ ͇̜̱̠͓͍ͅN͕͠e̗̱z̘̝̜̺͙p̤̺̹͍̯͚e̠̻̠͜r̨̤͍̺̖͔̖̖d̠̟̭̬̝͟i̦͖̩͓͔̤a̠̗̬͉̙n͚͜ ̻̞̰͚ͅh̵͉i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "", "<script>alert('123');</script>", "", " ", "\">", "'>", ">", "", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "ript>alert(123)ript>", "-->", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><\\x3Cscript>javascript:alert(1) ", "'`\"><\\x00script>javascript:alert(1)", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "XXX", "javascript:alert(1)\"` `>", "", "", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<u oncopy=alert()> Copy me</u>", "<i onwheel=alert(1)> Scroll over me </i>", "<plaintext>", "http://a/%%30%30", "</textarea><script>alert(123)</script>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", " ", "%", "_", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "{0}", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "+++ATH0", "<<< %s(un='%s') = %u", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "DCC SEND STARTKEYLOGGER 0 0 0", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "Dick Van Dyke", "basement", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] ����������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail1.json������������������������������������������������������0000664�0000000�0000000�00000000074�14264072506�0021107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"A JSON payload should be an object or array, not a string."��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail10.json�����������������������������������������������������0000664�0000000�0000000�00000000072�14264072506�0021165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Extra value after close": true} "misplaced quoted value"����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail11.json�����������������������������������������������������0000664�0000000�0000000�00000000035�14264072506�0021165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Illegal expression": 1 + 2}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail12.json�����������������������������������������������������0000664�0000000�0000000�00000000037�14264072506�0021170�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Illegal invocation": alert()}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail13.json�����������������������������������������������������0000664�0000000�0000000�00000000053�14264072506�0021167�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Numbers cannot have leading zeroes": 013}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail14.json�����������������������������������������������������0000664�0000000�0000000�00000000037�14264072506�0021172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Numbers cannot be hex": 0x14}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail15.json�����������������������������������������������������0000664�0000000�0000000�00000000042�14264072506�0021167�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Illegal backslash escape: \x15"]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail16.json�����������������������������������������������������0000664�0000000�0000000�00000000010�14264072506�0021163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[\naked]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail17.json�����������������������������������������������������0000664�0000000�0000000�00000000042�14264072506�0021171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Illegal backslash escape: \017"]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail18.json�����������������������������������������������������0000664�0000000�0000000�00000000062�14264072506�0021174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail19.json�����������������������������������������������������0000664�0000000�0000000�00000000026�14264072506�0021175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Missing colon" null}����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail2.json������������������������������������������������������0000664�0000000�0000000�00000000021�14264072506�0021100�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Unclosed array"���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail20.json�����������������������������������������������������0000664�0000000�0000000�00000000027�14264072506�0021166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Double colon":: null}���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail21.json�����������������������������������������������������0000664�0000000�0000000�00000000040�14264072506�0021162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Comma instead of colon", null}������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail22.json�����������������������������������������������������0000664�0000000�0000000�00000000041�14264072506�0021164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Colon instead of comma": false]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail23.json�����������������������������������������������������0000664�0000000�0000000�00000000024�14264072506�0021166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Bad value", truth]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail24.json�����������������������������������������������������0000664�0000000�0000000�00000000020�14264072506�0021163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������['single quote']����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail25.json�����������������������������������������������������0000664�0000000�0000000�00000000035�14264072506�0021172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[" tab character in string "]���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail26.json�����������������������������������������������������0000664�0000000�0000000�00000000046�14264072506�0021175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["tab\ character\ in\ string\ "]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail27.json�����������������������������������������������������0000664�0000000�0000000�00000000016�14264072506�0021173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["line break"]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail28.json�����������������������������������������������������0000664�0000000�0000000�00000000017�14264072506�0021175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["line\ break"]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail29.json�����������������������������������������������������0000664�0000000�0000000�00000000004�14264072506�0021172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[0e]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail3.json������������������������������������������������������0000664�0000000�0000000�00000000045�14264072506�0021107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{unquoted_key: "keys must be quoted"}�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail30.json�����������������������������������������������������0000664�0000000�0000000�00000000005�14264072506�0021163�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[0e+]���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail31.json�����������������������������������������������������0000664�0000000�0000000�00000000007�14264072506�0021166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[0e+-1]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail32.json�����������������������������������������������������0000664�0000000�0000000�00000000050�14264072506�0021165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Comma instead if closing brace": true,����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail33.json�����������������������������������������������������0000664�0000000�0000000�00000000014�14264072506�0021166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["mismatch"}��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail34.json�����������������������������������������������������0000664�0000000�0000000�00000000002�14264072506�0021164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������00������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail35.json�����������������������������������������������������0000664�0000000�0000000�00000000024�14264072506�0021171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["bracket mismatch"}������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail36.json�����������������������������������������������������0000664�0000000�0000000�00000000026�14264072506�0021174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"bracket":"mismatch"]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail37.json�����������������������������������������������������0000664�0000000�0000000�00000000000�14264072506�0021165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail38.json�����������������������������������������������������0000664�0000000�0000000�00000000001�14264072506�0021167�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail39.json�����������������������������������������������������0000664�0000000�0000000�00000000032�14264072506�0021174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"invalid utf-8 sequence "������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail4.json������������������������������������������������������0000664�0000000�0000000�00000000020�14264072506�0021101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["extra comma",]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail5.json������������������������������������������������������0000664�0000000�0000000�00000000030�14264072506�0021103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["double extra comma",,]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail6.json������������������������������������������������������0000664�0000000�0000000�00000000032�14264072506�0021106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[ , "<-- missing value"]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail7.json������������������������������������������������������0000664�0000000�0000000�00000000032�14264072506�0021107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Comma after the close"],������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail8.json������������������������������������������������������0000664�0000000�0000000�00000000020�14264072506�0021105�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������["Extra close"]]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/fail9.json������������������������������������������������������0000664�0000000�0000000�00000000026�14264072506�0021114�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"Extra comma": true,}����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/pass1.json������������������������������������������������������0000664�0000000�0000000�00000002641�14264072506�0021144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[ "JSON Test Pattern pass1", {"object with 1 member":["array with 1 element"]}, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.543210, "e": 0.123456789e-12, "E": 1.234567890E+34, "": 23456789012E66, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & \/", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "0123456789": "digit", "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?", "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", "true": true, "false": false, "null": null, "array":[ ], "object":{ }, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* <!-- --", "# -- --> */": " ", " s p a c e d " :[1,2 , 3 , 4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \u0022 %22 0x22 034 "", "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "A key can be any string" }, 0.5 ,98.6 , 99.44 , 1066, 1e1, 0.1e1, 1e-1, 1e00,2e+00,2e-00 ,"rosebud"]�����������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/pass2.json������������������������������������������������������0000664�0000000�0000000�00000000064�14264072506�0021142�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data/pass3.json������������������������������������������������������0000664�0000000�0000000�00000000224�14264072506�0021141�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/data_cstring.cpp�����������������������������������������������������0000664�0000000�0000000�00000001750�14264072506�0021457�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include <tao/pegtl/internal/cstring_reader.hpp> namespace TAO_PEGTL_NAMESPACE { template< typename Rule, template< typename... > class Action = nothing, template< typename... > class Control = normal > bool parse_cstring( const char* string, const char* source, const std::size_t maximum ) { buffer_input< internal::cstring_reader > in( source, maximum, string ); return parse< Rule, Action, Control >( in ); } struct test_grammar : seq< string< 'a', 'b', 'c', 'd', 'e', 'f' >, not_at< any >, eof > {}; void unit_test() { TAO_PEGTL_TEST_ASSERT( parse_cstring< test_grammar >( "abcdef", "test data", 10 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< test_grammar >( "abcdef\0g", "test data", 10 ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������tao-pegtl-3.2.7/src/test/pegtl/demangle.cpp���������������������������������������������������������0000664�0000000�0000000�00000002310�14264072506�0020562�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include <tao/pegtl/demangle.hpp> namespace TAO_PEGTL_NAMESPACE { template< typename T > void test( const std::string& s ) { TAO_PEGTL_TEST_ASSERT( demangle< T >() == s ); } void unit_test() { #if !defined( __clang__ ) && defined( __GNUC__ ) && ( __GNUC__ == 9 ) && ( __GNUC_MINOR__ <= 2 ) // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91155 test< int >( "i" ); test< double >( "d" ); test< seq< bytes< 42 >, eof > >( "N3tao5pegtl3seqIJNS0_5bytesILj42EEENS0_3eofEEEE" ); #elif defined( _MSC_VER ) && !defined( __clang__ ) test< int >( "int" ); test< double >( "double" ); // in the Microsoft world, class and struct are not the same! test< seq< bytes< 42 >, eof > >( "struct tao::pegtl::seq<struct tao::pegtl::bytes<42>,struct tao::pegtl::eof>" ); #else test< int >( "int" ); test< double >( "double" ); test< seq< bytes< 42 >, eof > >( "tao::pegtl::seq<tao::pegtl::bytes<42>, tao::pegtl::eof>" ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/discard_input.cpp����������������������������������������������������0000664�0000000�0000000�00000005654�14264072506�0021654�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <string> #include "test.hpp" #include <tao/pegtl/internal/cstring_reader.hpp> namespace TAO_PEGTL_NAMESPACE { template< typename Rule, template< typename... > class Action > bool parse_cstring( const char* string, const char* source, const std::size_t maximum ) { buffer_input< internal::cstring_reader, eol::lf_crlf, const char*, 1 > in( source, maximum, string ); return parse< Rule, Action >( in ); } // clang-format off struct n : one< 'n' > {}; struct a : one< 'a' > {}; struct f : one< 'f' > {}; struct s : one< 's' > {}; template< typename Rule > struct my_action {}; template<> struct my_action< a > : discard_input {}; template<> struct my_action< f > : discard_input_on_failure {}; template<> struct my_action< s > : discard_input_on_success {}; // clang-format on void unit_test() { #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< rep< 4, sor< n, n > >, my_action >( "nnnn", TAO_TEST_LINE, 2 ) ); #endif TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< a, n > >, my_action >( "nnnn", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< f, n > >, my_action >( "nnnn", TAO_TEST_LINE, 2 ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< rep< 4, sor< s, n > >, my_action >( "nnnn", TAO_TEST_LINE, 2 ) ); #endif TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< n, a > >, my_action >( "aaaa", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< a, a > >, my_action >( "aaaa", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< f, a > >, my_action >( "aaaa", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< s, a > >, my_action >( "aaaa", TAO_TEST_LINE, 2 ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< rep< 4, sor< n, f > >, my_action >( "ffff", TAO_TEST_LINE, 2 ) ); #endif TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< a, f > >, my_action >( "ffff", TAO_TEST_LINE, 2 ) ); #if defined( __cpp_exceptions ) TAO_PEGTL_TEST_THROWS( parse_cstring< rep< 4, sor< f, f > >, my_action >( "ffff", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_THROWS( parse_cstring< rep< 4, sor< s, f > >, my_action >( "ffff", TAO_TEST_LINE, 2 ) ); #endif TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< n, s > >, my_action >( "ssss", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< a, s > >, my_action >( "ssss", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< f, s > >, my_action >( "ssss", TAO_TEST_LINE, 2 ) ); TAO_PEGTL_TEST_ASSERT( parse_cstring< rep< 4, sor< s, s > >, my_action >( "ssss", TAO_TEST_LINE, 2 ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/enable_control.cpp���������������������������������������������������0000664�0000000�0000000�00000003113�14264072506�0021776�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <tao/pegtl.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct r : seq< internal::seq< any > > {}; static_assert( !internal::enable_control< internal::seq< any > > ); static_assert( internal::enable_control< seq< any > > ); static_assert( !internal::enable_control< internal::seq< internal::seq< any > > > ); static_assert( internal::enable_control< seq< internal::seq< any > > > ); static_assert( internal::enable_control< r > ); static_assert( !normal< internal::seq< any > >::enable ); static_assert( normal< seq< any > >::enable ); static_assert( !normal< internal::seq< internal::seq< any > > >::enable ); static_assert( normal< seq< internal::seq< any > > >::enable ); static_assert( normal< r >::enable ); template< typename R > struct a : nothing< R > {}; unsigned flags = 0; template<> struct a< r > { static void apply0() { flags |= 0x01; } }; template<> struct a< any > { static void apply0() { flags |= 0x02; } }; template<> struct a< internal::seq< any > > { static void apply0() { flags |= 0x10; } }; void unit_test() { memory_input in( "a", __FUNCTION__ ); const bool b = parse< r, a >( in ); TAO_PEGTL_TEST_ASSERT( b ); TAO_PEGTL_TEST_ASSERT( flags == 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/error_message.cpp����������������������������������������������������0000664�0000000�0000000�00000002421�14264072506�0021646�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" namespace test1 { using namespace TAO_PEGTL_NAMESPACE; // clang-format off struct a : one< 'a' > {}; struct b : one< 'b' > {}; struct grammar : sor< a, b > {}; template< typename > inline constexpr const char* error_message = nullptr; template<> inline constexpr auto error_message< test1::b > = "test123"; // clang-format on struct error { template< typename Rule > static constexpr auto message = error_message< Rule >; }; template< typename Rule > using control = must_if< error >::control< Rule >; } // namespace test1 namespace TAO_PEGTL_NAMESPACE { void unit_test() { try { parse< test1::grammar, nothing, test1::control >( memory_input( "c", __FUNCTION__ ) ); TAO_PEGTL_TEST_UNREACHABLE; // LCOV_EXCL_LINE } catch( const parse_error& e ) { TAO_PEGTL_TEST_ASSERT( e.message() == "test123" ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_cstream.cpp�����������������������������������������������������0000664�0000000�0000000�00000001606�14264072506�0021452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <clocale> #include <cstdio> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct file_content : seq< TAO_PEGTL_STRING( "dummy content" ), eol, discard > {}; struct file_grammar : seq< rep_min_max< 11, 11, file_content >, eof > {}; void unit_test() { const char* const filename = "src/test/pegtl/file_data.txt"; #if defined( _MSC_VER ) std::FILE* stream; ::fopen_s( &stream, filename, "rb" ); #else std::FILE* stream = std::fopen( filename, "rb" ); #endif TAO_PEGTL_TEST_ASSERT( stream != nullptr ); TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( cstream_input( stream, 16, filename ) ) ); std::fclose( stream ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_data.txt��������������������������������������������������������0000664�0000000�0000000�00000000232�14264072506�0020754�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_file.cpp��������������������������������������������������������0000664�0000000�0000000�00000000526�14264072506�0020733�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_file.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_file< file_input<> >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_istream.cpp�����������������������������������������������������0000664�0000000�0000000�00000002320�14264072506�0021452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <cerrno> #include <fstream> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct file_content : seq< TAO_PEGTL_STRING( "dummy content" ), eol, discard > {}; struct file_grammar : seq< rep_min_max< 11, 11, file_content >, eof > {}; void unit_test() { #if defined( __cpp_exceptions ) { const char* filename = "src/test/pegtl/no_such_file.txt"; try { std::ifstream stream( filename ); parse< file_grammar >( istream_input( stream, 16, filename ) ); TAO_PEGTL_TEST_UNREACHABLE; // LCOV_EXCL_LINE } catch( const std::system_error& e ) { TAO_PEGTL_TEST_ASSERT( e.code().category() == std::system_category() ); TAO_PEGTL_TEST_ASSERT( e.code().value() == ENOENT ); } } #endif const char* filename = "src/test/pegtl/file_data.txt"; std::ifstream stream( filename ); TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( istream_input( stream, 16, filename ) ) ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_mmap.cpp��������������������������������������������������������0000664�0000000�0000000�00000001063�14264072506�0020743�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ // this include gives us _POSIX_MAPPED_FILES to test and mmap_input<> if it is set #include <tao/pegtl/file_input.hpp> #if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 ) #include "test.hpp" #include "verify_file.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_file< mmap_input<> >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #else int main() { return 0; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_read.cpp��������������������������������������������������������0000664�0000000�0000000�00000001245�14264072506�0020726�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_file.hpp" namespace TAO_PEGTL_NAMESPACE { template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf > struct open_input : public read_input< P, Eol > { explicit open_input( const internal::filesystem::path& path ) : read_input< P, Eol >( internal::file_open( path ), path ) {} }; void unit_test() { verify_file< read_input<> >(); verify_file< open_input<> >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/file_äöü𝄞_data.txt���������������������������������������������0000664�0000000�0000000�00000000232�14264072506�0024531�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content dummy content ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/icu_general.cpp������������������������������������������������������0000664�0000000�0000000�00000001246�14264072506�0021272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" //#include <tao/pegtl/contrib/icu/utf8.hpp> namespace TAO_PEGTL_NAMESPACE { void unit_test() { // verify_analyze< utf8::icu::alphabetic >( __LINE__, __FILE__, true, false ); // verify_rule< utf8::icu::alphabetic >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); // verify_rule< utf8::icu::alphabetic >( __LINE__, __FILE__, "a", result_type::success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/internal_endian.cpp��������������������������������������������������0000664�0000000�0000000�00000015456�14264072506�0022157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <tao/pegtl/contrib/internal/endian.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int8_t( 0x7a ) ) == std::int8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint8_t( 0x7a ) ) == std::uint8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int8_t( 0x7a ) ) == std::int8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint8_t( 0x7a ) ) == std::uint8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int8_t( 0x7a ) ) == std::int8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint8_t( 0x7a ) ) == std::uint8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int8_t( 0x7a ) ) == std::int8_t( 0x7a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint8_t( 0x7a ) ) == std::uint8_t( 0x7a ) ); if constexpr( internal::endian::native == internal::endian::big ) { TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x675544332b1f397a ) ); } else if constexpr( internal::endian::native == internal::endian::little ) { TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x7a39 ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int16_t( 0x7a39 ) ) == std::int16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint16_t( 0x7a39 ) ) == std::uint16_t( 0x397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x7a391f2b ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int32_t( 0x7a391f2b ) ) == std::int32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint32_t( 0x7a391f2b ) ) == std::uint32_t( 0x2b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_le( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::h_to_be( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::le_to_h( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x7a391f2b33445567 ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::int64_t( 0x7a391f2b33445567 ) ) == std::int64_t( 0x675544332b1f397a ) ); TAO_PEGTL_TEST_ASSERT( internal::be_to_h( std::uint64_t( 0x7a391f2b33445567 ) ) == std::uint64_t( 0x675544332b1f397a ) ); } else { TAO_PEGTL_TEST_UNREACHABLE; // LCOV_EXCL_LINE } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/internal_file_mapper.cpp���������������������������������������������0000664�0000000�0000000�00000003015�14264072506�0023170�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) || !defined( _POSIX_MAPPED_FILES ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include <tao/pegtl/file_input.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { try { internal::file_mapper dummy( "include" ); // LCOV_EXCL_START std::cerr << "pegtl: unit test failed for [ internal::file_mapper ]" << std::endl; ++failed; // LCOV_EXCL_STOP } catch( const internal::filesystem::filesystem_error& ) { } // LCOV_EXCL_START catch( ... ) { std::cerr << "pegtl: unit test failed for [ internal::file_mapper ] with unexpected exception" << std::endl; ++failed; } // LCOV_EXCL_STOP const std::string s = "dummy content\n"; const std::string dummy_content = s + s + s + s + s + s + s + s + s + s + s; internal::file_mapper mapper( "src/test/pegtl/file_data.txt" ); TAO_PEGTL_TEST_ASSERT( !mapper.empty() ); TAO_PEGTL_TEST_ASSERT( mapper.size() == 154 ); TAO_PEGTL_TEST_ASSERT( std::string_view( mapper.data(), mapper.size() ) == dummy_content ); TAO_PEGTL_TEST_ASSERT( std::string_view( mapper.begin(), mapper.end() - mapper.begin() ) == dummy_content ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/internal_file_opener.cpp���������������������������������������������0000664�0000000�0000000�00000001635�14264072506�0023202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) || !defined( _POSIX_MAPPED_FILES ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include <tao/pegtl/file_input.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { const internal::file_opener fo( "Makefile" ); ::close( fo.m_fd ); // Provoke exception, nobody would normally do this. try { (void)fo.size(); // expected to throw // LCOV_EXCL_START std::cerr << "pegtl: unit test failed for [ internal::file_opener ] " << std::endl; ++failed; // LCOV_EXCL_STOP } catch( const std::exception& ) { } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ���������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/limit_bytes.cpp������������������������������������������������������0000664�0000000�0000000�00000002306�14264072506�0021337�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <tao/pegtl/contrib/limit_bytes.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct test_rule : star< alpha > {}; struct test_grammar : seq< test_rule, eof > {}; template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< test_rule > : limit_bytes< 5 > {}; void unit_test() { memory_input<> i1( "aaa", __FUNCTION__ ); const auto r1 = pegtl::parse< test_grammar >( i1 ); TAO_PEGTL_TEST_ASSERT( r1 ); memory_input<> i2( "aaaaaaaaaaa", __FUNCTION__ ); const auto r2 = pegtl::parse< test_grammar >( i2 ); TAO_PEGTL_TEST_ASSERT( r2 ); memory_input<> i3( "aaa", __FUNCTION__ ); const auto r3 = pegtl::parse< test_grammar, test_action >( i3 ); TAO_PEGTL_TEST_ASSERT( r3 ); #if defined( __cpp_exceptions ) memory_input<> i4( "aaaaaaaaaaa", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( pegtl::parse< test_grammar, test_action >( i4 ) ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/limit_depth.cpp������������������������������������������������������0000664�0000000�0000000�00000002353�14264072506�0021317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2021-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <tao/pegtl/contrib/limit_depth.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { struct test_recursive : seq< alpha, opt< test_recursive > > {}; struct test_grammar : seq< test_recursive, eof > {}; template< typename Rule > struct test_action : nothing< Rule > {}; template<> struct test_action< test_recursive > : limit_depth< 5 > {}; void unit_test() { memory_input<> i1( "aaa", __FUNCTION__ ); const auto r1 = pegtl::parse< test_grammar >( i1 ); TAO_PEGTL_TEST_ASSERT( r1 ); memory_input<> i2( "aaaaaaaaaaa", __FUNCTION__ ); const auto r2 = pegtl::parse< test_grammar >( i2 ); TAO_PEGTL_TEST_ASSERT( r2 ); memory_input<> i3( "aaa", __FUNCTION__ ); const auto r3 = pegtl::parse< test_grammar, test_action >( i3 ); TAO_PEGTL_TEST_ASSERT( r3 ); #if defined( __cpp_exceptions ) memory_input<> i4( "aaaaaaaaaaa", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( pegtl::parse< test_grammar, test_action >( i4 ) ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/main.hpp�������������������������������������������������������������0000664�0000000�0000000�00000001141�14264072506�0017740�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_MAIN_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_MAIN_HPP #include <cstdlib> #include <iostream> int main( int /*unused*/, char** argv ) { TAO_PEGTL_NAMESPACE::unit_test(); if( TAO_PEGTL_NAMESPACE::failed != 0 ) { std::cerr << "pegtl: unit test " << argv[ 0 ] << " failed " << TAO_PEGTL_NAMESPACE::failed << std::endl; // LCOV_EXCL_LINE } return ( TAO_PEGTL_NAMESPACE::failed == 0 ) ? EXIT_SUCCESS : EXIT_FAILURE; } #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/parse_error.cpp������������������������������������������������������0000664�0000000�0000000�00000003612�14264072506�0021337�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" namespace TAO_PEGTL_NAMESPACE { template< tracking_mode M > void unit_test() { const std::string rulename{ demangle< digit >() }; memory_input< M > in( "foo\nbar bla blubb\nbaz", "test_source" ); try { parse< seq< identifier, eol, identifier, one< ' ' >, must< digit > > >( in ); } catch( const parse_error& e ) { TAO_PEGTL_TEST_ASSERT( e.what() == "test_source:2:5: parse error matching " + rulename ); TAO_PEGTL_TEST_ASSERT( e.message() == "parse error matching " + rulename ); TAO_PEGTL_TEST_ASSERT( e.positions().size() == 1 ); const auto& p = e.positions().front(); TAO_PEGTL_TEST_ASSERT( p.byte == 8 ); TAO_PEGTL_TEST_ASSERT( p.line == 2 ); TAO_PEGTL_TEST_ASSERT( p.column == 5 ); TAO_PEGTL_TEST_ASSERT( p.source == "test_source" ); TAO_PEGTL_TEST_ASSERT( in.line_at( p ) == "bar bla blubb" ); position p2 = p; 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 } void unit_test() { unit_test< tracking_mode::eager >(); unit_test< tracking_mode::lazy >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ����������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/pegtl_string_t.cpp���������������������������������������������������0000664�0000000�0000000�00000003566�14264072506�0022050�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <type_traits> #include <tao/pegtl.hpp> #include <tao/pegtl/contrib/alphabet.hpp> namespace test { // We only need to test that this compiles... struct foo : TAO_PEGTL_STRING( "foo" ) {}; struct foobar : TAO_PEGTL_NAMESPACE::sor< TAO_PEGTL_STRING( "foo" ), TAO_PEGTL_STRING( "bar" ) > {}; static_assert( std::is_same_v< TAO_PEGTL_STRING( "Hello" ), TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o' > > ); static_assert( !std::is_same_v< TAO_PEGTL_ISTRING( "Hello" ), TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o' > > ); static_assert( std::is_same_v< TAO_PEGTL_ISTRING( "Hello" ), TAO_PEGTL_NAMESPACE::istring< 'H', 'e', 'l', 'l', 'o' > > ); static_assert( std::is_same_v< TAO_PEGTL_KEYWORD( "private" ), TAO_PEGTL_NAMESPACE::keyword< 'p', 'r', 'i', 'v', 'a', 't', 'e' > > ); // Strings may even contain embedded nulls static_assert( std::is_same_v< TAO_PEGTL_STRING( "Hello, w\0rld!" ), TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 0, 'r', 'l', 'd', '!' > > ); // The strings currently have a maximum length of 512 characters. using namespace TAO_PEGTL_NAMESPACE::alphabet; static_assert( std::is_same_v< TAO_PEGTL_STRING( "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" ), TAO_PEGTL_NAMESPACE::string< a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z > > ); } // namespace test int main() { return 0; } ������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/position.cpp���������������������������������������������������������0000664�0000000�0000000�00000016477�14264072506�0020675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include <tao/pegtl/internal/cstring_reader.hpp> namespace TAO_PEGTL_NAMESPACE { struct buffer_input_t : buffer_input< internal::cstring_reader > { buffer_input_t( const std::string& in_string, const std::string& in_source ) : buffer_input< internal::cstring_reader >( in_source, 42, in_string.c_str() ) {} }; template< typename Rule, typename ParseInput = memory_input<> > void test_matches_lf() { static const std::string s1 = "\n"; ParseInput i1( s1, __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< Rule >( i1 ) ); TAO_PEGTL_TEST_ASSERT( i1.line() == 2 ); TAO_PEGTL_TEST_ASSERT( i1.column() == 1 ); } template< typename Rule, typename ParseInput = memory_input<> > void test_matches_other( const std::string& s2 ) { TAO_PEGTL_TEST_ASSERT( s2.size() == 1 ); ParseInput i2( s2, __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< Rule >( i2 ) ); TAO_PEGTL_TEST_ASSERT( i2.line() == 1 ); TAO_PEGTL_TEST_ASSERT( i2.column() == 2 ); } template< typename Rule, typename ParseInput = memory_input<> > void test_mismatch( const std::string& s3 ) { TAO_PEGTL_TEST_ASSERT( s3.size() == 1 ); ParseInput i3( s3, __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( !parse< Rule >( i3 ) ); TAO_PEGTL_TEST_ASSERT( i3.line() == 1 ); TAO_PEGTL_TEST_ASSERT( i3.column() == 1 ); } struct outer_grammar : must< two< 'a' >, two< 'b' >, two< 'c' >, eof > {}; struct inner_grammar : must< one< 'd' >, two< 'e' >, eof > {}; template< typename Rule > struct outer_action {}; template<> struct outer_action< two< 'b' > > { template< typename ActionInput > static void apply( const ActionInput& oi, const bool mode ) { const auto p = oi.position(); TAO_PEGTL_TEST_ASSERT( p.source == "outer" ); TAO_PEGTL_TEST_ASSERT( p.byte == 2 ); TAO_PEGTL_TEST_ASSERT( p.line == 1 ); TAO_PEGTL_TEST_ASSERT( p.column == 3 ); memory_input in( "dFF", "inner" ); if( mode ) { parse_nested< inner_grammar >( oi, in ); } else { parse_nested< inner_grammar >( oi.position(), in ); } } }; void test_nested_asserts( const parse_error& e ) { 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 ); } template< typename ParseInput = memory_input<> > void test_nested() { try { memory_input oi( "aabbcc", "outer" ); parse< outer_grammar, outer_action >( oi, true ); } catch( const parse_error& e ) { test_nested_asserts( e ); } try { memory_input oi( "aabbcc", "outer" ); parse< outer_grammar, outer_action >( oi, false ); } catch( const parse_error& e ) { test_nested_asserts( e ); } } void test_iterator() { const std::string s = "source"; const internal::iterator i( nullptr, 1, 2, 3 ); const position p( i, s ); TAO_PEGTL_TEST_ASSERT( p.byte == 1 ); TAO_PEGTL_TEST_ASSERT( p.line == 2 ); TAO_PEGTL_TEST_ASSERT( p.column == 3 ); TAO_PEGTL_TEST_ASSERT( p.source == s ); const position q( 1, 2, 3, s ); TAO_PEGTL_TEST_ASSERT( q.byte == 1 ); TAO_PEGTL_TEST_ASSERT( q.line == 2 ); TAO_PEGTL_TEST_ASSERT( q.column == 3 ); TAO_PEGTL_TEST_ASSERT( q.source == s ); } void unit_test() { test_matches_lf< any >(); test_matches_lf< any, buffer_input_t >(); test_matches_other< any >( " " ); test_matches_other< any, buffer_input_t >( " " ); test_matches_lf< one< '\n' > >(); test_matches_lf< one< '\n' >, buffer_input_t >(); test_mismatch< one< '\n' > >( " " ); test_mismatch< one< '\n' >, buffer_input_t >( " " ); test_matches_lf< one< ' ', '\n' > >(); test_matches_lf< one< ' ', '\n' >, buffer_input_t >(); test_matches_other< one< ' ', '\n' > >( " " ); test_matches_other< one< ' ', '\n' >, buffer_input_t >( " " ); test_matches_lf< one< ' ', '\n', 'b' > >(); test_matches_lf< one< ' ', '\n', 'b' >, buffer_input_t >(); test_matches_other< one< ' ', '\n', 'b' > >( " " ); test_matches_other< one< ' ', '\n', 'b' >, buffer_input_t >( " " ); test_matches_lf< string< '\n' > >(); test_matches_lf< string< '\n' >, buffer_input_t >(); test_mismatch< string< '\n' > >( " " ); test_mismatch< string< '\n' >, buffer_input_t >( " " ); test_matches_other< string< ' ' > >( " " ); test_matches_other< string< ' ' >, buffer_input_t >( " " ); test_mismatch< string< ' ' > >( "\n" ); test_mismatch< string< ' ' >, buffer_input_t >( "\n" ); test_matches_lf< range< 8, 33 > >(); test_matches_lf< range< 8, 33 >, buffer_input_t >(); test_matches_other< range< 8, 33 > >( " " ); test_matches_other< range< 8, 33 >, buffer_input_t >( " " ); test_mismatch< range< 11, 30 > >( "\n" ); test_mismatch< range< 11, 30 >, buffer_input_t >( "\n" ); test_mismatch< range< 11, 30 > >( " " ); test_mismatch< range< 11, 30 >, buffer_input_t >( " " ); test_matches_lf< not_range< 20, 30 > >(); test_matches_lf< not_range< 20, 30 >, buffer_input_t >(); test_matches_other< not_range< 20, 30 > >( " " ); test_matches_other< not_range< 20, 30 >, buffer_input_t >( " " ); test_mismatch< not_range< 5, 35 > >( "\n" ); test_mismatch< not_range< 5, 35 >, buffer_input_t >( "\n" ); test_mismatch< not_range< 5, 35 > >( " " ); test_mismatch< not_range< 5, 35 >, buffer_input_t >( " " ); test_matches_lf< ranges< 'a', 'z', 8, 33, 'A', 'Z' > >(); test_matches_lf< ranges< 'a', 'z', 8, 33, 'A', 'Z' >, buffer_input_t >(); test_matches_other< ranges< 'a', 'z', 8, 33, 'A', 'Z' > >( "N" ); test_mismatch< ranges< 'a', 'z', 8, 33, 'A', 'Z' > >( "9" ); test_mismatch< ranges< 'a', 'z', 8, 33, 'A', 'Z' >, buffer_input_t >( "9" ); test_matches_lf< ranges< 'a', 'z', 'A', 'Z', '\n' > >(); test_matches_lf< ranges< 'a', 'z', 'A', 'Z', '\n' >, buffer_input_t >(); test_matches_other< ranges< 'a', 'z', 'A', 'Z', '\n' > >( "P" ); test_matches_other< ranges< 'a', 'z', 'A', 'Z', '\n' >, buffer_input_t >( "P" ); test_mismatch< ranges< 'a', 'z', 'A', 'Z', '\n' > >( "8" ); test_mismatch< ranges< 'a', 'z', 'A', 'Z', '\n' >, buffer_input_t >( "8" ); test_nested<>(); test_nested< buffer_input_t >(); test_iterator(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/restart_input.cpp����������������������������������������������������0000664�0000000�0000000�00000002106�14264072506�0021714�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { using grammar = seq< string< 'a', 'b', 'c' >, eof >; void test_lazy() { const std::string data = "abc"; memory_input< tracking_mode::lazy, eol::lf_crlf, std::string > in( data, __FUNCTION__ ); bool success = parse< grammar >( in ); TAO_PEGTL_TEST_ASSERT( success ); in.restart(); success = parse< grammar >( in ); TAO_PEGTL_TEST_ASSERT( success ); } void test_eager() { const std::string data = "abc"; memory_input< tracking_mode::eager, eol::lf_crlf, std::string > in( std::string_view( data ), __FUNCTION__ ); bool success = parse< grammar >( in ); TAO_PEGTL_TEST_ASSERT( success ); in.restart(); success = parse< grammar >( in ); TAO_PEGTL_TEST_ASSERT( success ); } void unit_test() { test_lazy(); test_eager(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/result_type.hpp������������������������������������������������������0000664�0000000�0000000�00000001553�14264072506�0021402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_RESULT_TYPE_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_RESULT_TYPE_HPP #include <ostream> #include <tao/pegtl/config.hpp> namespace TAO_PEGTL_NAMESPACE { enum class result_type : int { success = 1, local_failure = 0, global_failure = -1 }; inline std::ostream& operator<<( std::ostream& o, const result_type t ) { switch( t ) { case result_type::success: return o << "success"; case result_type::local_failure: return o << "local_failure"; case result_type::global_failure: return o << "global_failure"; } return o << static_cast< int >( t ); } } // namespace TAO_PEGTL_NAMESPACE #endif �����������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_action.cpp������������������������������������������������������0000664�0000000�0000000�00000001354�14264072506�0021321�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... Rules > using test_action_rule = action< nothing, Rules... >; void unit_test() { verify_meta< action< nothing >, internal::success >(); verify_meta< action< nothing, eof >, internal::action< nothing, eof >, eof >(); verify_meta< action< nothing, eof, any >, internal::action< nothing, internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_seqs< test_action_rule >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_apply.cpp�������������������������������������������������������0000664�0000000�0000000�00000005577�14264072506�0021204�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { namespace test1 { struct action_a { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, int& r, int& s ) { TAO_PEGTL_TEST_ASSERT( !r ); TAO_PEGTL_TEST_ASSERT( !s ); r += 1; } }; struct action_b { template< typename ActionInput > static bool apply( const ActionInput& /*unused*/, int& r, int& s ) { TAO_PEGTL_TEST_ASSERT( !s ); TAO_PEGTL_TEST_ASSERT( r == 1 ); s += 2; return true; } }; struct action2_a { template< typename ActionInput > static void apply( const ActionInput& /*unused*/, bool& state_b ) { TAO_PEGTL_TEST_ASSERT( !state_b ); } }; struct action2_b { template< typename ActionInput > static bool apply( const ActionInput& /*unused*/, bool& state_b ) { TAO_PEGTL_TEST_ASSERT( !state_b ); state_b = true; return false; } }; struct action2_c { // LCOV_EXCL_START template< typename ActionInput > static void apply( const ActionInput& /*unused*/, bool& /*unused*/ ) { TAO_PEGTL_TEST_ASSERT( false ); } // LCOV_EXCL_STOP }; } // namespace test1 void unit_test() { int state_r = 0; int state_s = 0; TAO_PEGTL_TEST_ASSERT( parse< apply< test1::action_a, test1::action_b > >( memory_input( "", __FUNCTION__ ), state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( state_r == 1 ); TAO_PEGTL_TEST_ASSERT( state_s == 2 ); TAO_PEGTL_TEST_ASSERT( parse< disable< apply< test1::action_a, test1::action_b > > >( memory_input( "", __FUNCTION__ ), state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( state_r == 1 ); TAO_PEGTL_TEST_ASSERT( state_s == 2 ); bool state_b = false; TAO_PEGTL_TEST_ASSERT( !parse< apply< test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input( "", __FUNCTION__ ), state_b ) ); TAO_PEGTL_TEST_ASSERT( state_b ); verify_meta< apply< test1::action_a, test1::action_b >, internal::apply< test1::action_a, test1::action_b > >(); verify_analyze< apply<> >( __LINE__, __FILE__, false, false ); verify_rule< apply<> >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< apply<> >( __LINE__, __FILE__, std::string( t ), result_type::success, 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_apply0.cpp������������������������������������������������������0000664�0000000�0000000�00000005036�14264072506�0021252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { namespace test1 { struct action_a { static void apply0( int& r, int& s ) { TAO_PEGTL_TEST_ASSERT( !r ); TAO_PEGTL_TEST_ASSERT( !s ); r += 1; } }; struct action_b { static bool apply0( int& r, int& s ) { TAO_PEGTL_TEST_ASSERT( !s ); TAO_PEGTL_TEST_ASSERT( r == 1 ); s += 2; return true; } }; struct action2_a { static void apply0( bool& state_b ) { TAO_PEGTL_TEST_ASSERT( !state_b ); } }; struct action2_b { static bool apply0( bool& state_b ) { TAO_PEGTL_TEST_ASSERT( !state_b ); state_b = true; return false; } }; struct action2_c { // LCOV_EXCL_START static void apply0( bool& /*unused*/ ) { TAO_PEGTL_TEST_ASSERT( false ); } // LCOV_EXCL_STOP }; } // namespace test1 void unit_test() { int state_r = 0; int state_s = 0; TAO_PEGTL_TEST_ASSERT( parse< apply0< test1::action_a, test1::action_b > >( memory_input( "", __FUNCTION__ ), state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( state_r == 1 ); TAO_PEGTL_TEST_ASSERT( state_s == 2 ); TAO_PEGTL_TEST_ASSERT( parse< disable< apply< test1::action_a, test1::action_b > > >( memory_input( "", __FUNCTION__ ), state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( state_r == 1 ); TAO_PEGTL_TEST_ASSERT( state_s == 2 ); bool state_b = false; TAO_PEGTL_TEST_ASSERT( !parse< apply0< test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input( "", __FUNCTION__ ), state_b ) ); TAO_PEGTL_TEST_ASSERT( state_b ); verify_meta< apply0< test1::action_a, test1::action_b >, internal::apply0< test1::action_a, test1::action_b > >(); verify_analyze< apply0<> >( __LINE__, __FILE__, false, false ); verify_rule< apply0<> >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< apply0<> >( __LINE__, __FILE__, std::string( t ), result_type::success, 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_at.cpp����������������������������������������������������������0000664�0000000�0000000�00000003751�14264072506�0020453�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { int at_counter = 0; template< typename Rule > struct at_action {}; template<> struct at_action< any > { static void apply0() { ++at_counter; } }; void unit_test() { TAO_PEGTL_TEST_ASSERT( at_counter == 0 ); verify_meta< at<>, internal::success >(); verify_meta< at< eof >, internal::at< eof >, eof >(); verify_meta< at< eof, any >, internal::at< internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_analyze< at< eof > >( __LINE__, __FILE__, false, false ); verify_analyze< at< any > >( __LINE__, __FILE__, false, false ); verify_rule< at< eof > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< at< eof > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< at< any > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< at< any > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< at< any > >( __LINE__, __FILE__, "aa", result_type::success, 2 ); verify_rule< at< any > >( __LINE__, __FILE__, "aaaa", result_type::success, 4 ); #if defined( __cpp_exceptions ) verify_rule< must< at< alpha > > >( __LINE__, __FILE__, "1", result_type::global_failure, 1 ); verify_rule< must< at< alpha, alpha > > >( __LINE__, __FILE__, "a1a", result_type::global_failure, 3 ); #endif { memory_input in( "f", 1, __FILE__ ); parse< any, at_action >( in ); TAO_PEGTL_TEST_ASSERT( at_counter == 1 ); } { memory_input in( "f", 1, __FILE__ ); parse< at< any >, at_action >( in ); TAO_PEGTL_TEST_ASSERT( at_counter == 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������tao-pegtl-3.2.7/src/test/pegtl/rule_bof.cpp���������������������������������������������������������0000664�0000000�0000000�00000002255�14264072506�0020613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< bof, internal::bof >(); verify_analyze< bof >( __LINE__, __FILE__, false, false ); verify_rule< bof >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { const char s[] = { i, 0 }; verify_rule< bof >( __LINE__, __FILE__, s, result_type::success, 1 ); } verify_rule< seq< alpha, bof > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< seq< alpha, bof > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_rule< seq< alpha, bof, alpha > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_rule< seq< alpha, eol, bof > >( __LINE__, __FILE__, "a\n", result_type::local_failure, 2 ); verify_rule< seq< alpha, eol, bof > >( __LINE__, __FILE__, "a\nb", result_type::local_failure, 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_bol.cpp���������������������������������������������������������0000664�0000000�0000000�00000002112�14264072506�0020611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< bol, internal::bol >(); verify_analyze< bol >( __LINE__, __FILE__, false, false ); verify_only< bol >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { const char s[] = { i, 0 }; verify_only< bol >( __LINE__, __FILE__, s, result_type::success, 1 ); } verify_only< seq< alpha, bol > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_only< seq< alpha, bol > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_only< seq< alpha, bol, alpha > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_only< seq< alpha, eol, bol, alpha, eof > >( __LINE__, __FILE__, "a\nb", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_bytes.cpp�������������������������������������������������������0000664�0000000�0000000�00000003176�14264072506�0021176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< bytes< 0 >, internal::success >(); verify_meta< bytes< 1 >, internal::bytes< 1 > >(); verify_meta< bytes< 42 >, internal::bytes< 42 > >(); verify_analyze< bytes< 0 > >( __LINE__, __FILE__, false, false ); verify_rule< bytes< 0 > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< bytes< 0 > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_analyze< bytes< 1 > >( __LINE__, __FILE__, true, false ); for( char c = 0; c < 127; ++c ) { verify_char< bytes< 1 > >( __LINE__, __FILE__, c, result_type::success ); } verify_rule< bytes< 1 > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< bytes< 1 > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_analyze< bytes< 2 > >( __LINE__, __FILE__, true, false ); verify_analyze< bytes< 42 > >( __LINE__, __FILE__, true, false ); verify_rule< bytes< 3 > >( __LINE__, __FILE__, "abcd", result_type::success, 1 ); verify_rule< bytes< 4 > >( __LINE__, __FILE__, "abcd", result_type::success, 0 ); verify_rule< bytes< 5 > >( __LINE__, __FILE__, "abcd", result_type::local_failure, 4 ); verify_rule< bytes< 4 > >( __LINE__, __FILE__, "abcdefghij", result_type::success, 6 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_control.cpp�����������������������������������������������������0000664�0000000�0000000�00000001356�14264072506�0021526�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... Rules > using test_control_rule = control< normal, Rules... >; void unit_test() { verify_meta< control< normal >, internal::success >(); verify_meta< control< normal, eof >, internal::control< normal, eof >, eof >(); verify_meta< control< normal, eof, any >, internal::control< normal, internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_seqs< test_control_rule >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_disable.cpp�����������������������������������������������������0000664�0000000�0000000�00000001140�14264072506�0021440�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< disable<>, internal::success >(); verify_meta< disable< eof >, internal::disable< eof >, eof >(); verify_meta< disable< eof, any >, internal::disable< internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_seqs< disable >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_discard.cpp�����������������������������������������������������0000664�0000000�0000000�00000001311�14264072506�0021446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< discard, internal::discard >(); verify_analyze< discard >( __LINE__, __FILE__, false, false ); verify_rule< discard >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< discard >( __LINE__, __FILE__, std::string( t ), result_type::success, 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_enable.cpp������������������������������������������������������0000664�0000000�0000000�00000001132�14264072506�0021264�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< enable<>, internal::success >(); verify_meta< enable< eof >, internal::enable< eof >, eof >(); verify_meta< enable< eof, any >, internal::enable< internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_seqs< enable >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_eof.cpp���������������������������������������������������������0000664�0000000�0000000�00000001407�14264072506�0020614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< eof, internal::eof >(); verify_analyze< eof >( __LINE__, __FILE__, false, false ); verify_rule< eof >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { verify_char< eof >( __LINE__, __FILE__, i, result_type::local_failure ); } verify_rule< eof >( __LINE__, __FILE__, "abcdefghijklmn", result_type::local_failure, 14 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_failure.cpp�����������������������������������������������������0000664�0000000�0000000�00000001411�14264072506�0021465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< failure, internal::failure >(); verify_analyze< failure >( __LINE__, __FILE__, true, false ); // "Success implies consumption" is true because "success" never happens. verify_rule< failure >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); for( char i = 1; i < 127; ++i ) { verify_char< failure >( __LINE__, __FILE__, i, result_type::local_failure ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_if_apply.cpp����������������������������������������������������0000664�0000000�0000000�00000007465�14264072506�0021660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { namespace test1 { struct action_a { template< typename ActionInput > static void apply( const ActionInput& in, std::string& r, std::string& s ) { TAO_PEGTL_TEST_ASSERT( r.empty() ); TAO_PEGTL_TEST_ASSERT( s.empty() ); r += in.string(); } }; struct action_b { template< typename ActionInput > static void apply( const ActionInput& in, std::string& r, std::string& s ) { TAO_PEGTL_TEST_ASSERT( s.empty() ); s += in.string(); s += "*"; s += r; } }; struct action2_a { template< typename ActionInput > static void apply( const ActionInput& in, bool& state_b ) { TAO_PEGTL_TEST_ASSERT( in.string_view() == "foo" ); TAO_PEGTL_TEST_ASSERT( !state_b ); } }; struct action2_b { template< typename ActionInput > static bool apply( const ActionInput& in, bool& state_b ) { TAO_PEGTL_TEST_ASSERT( in.string_view() == "foo" ); TAO_PEGTL_TEST_ASSERT( !state_b ); state_b = true; return false; } }; struct action2_c { // LCOV_EXCL_START template< typename ActionInput > static void apply( const ActionInput& /*unused*/, bool& /*unused*/ ) { TAO_PEGTL_TEST_ASSERT( false ); } // LCOV_EXCL_STOP }; template< typename Rule > struct action {}; int flag = 0; template<> struct action< one< '-' > > { static void apply0( std::string& /*unused*/, std::string& /*unused*/ ) { ++flag; } }; } // namespace test1 template< typename... Rules > using if_apply_seq = if_apply< seq< Rules... > >; template< typename... Rules > using if_apply_disable = if_apply< disable< Rules... > >; void unit_test() { std::string state_r; std::string state_s; TAO_PEGTL_TEST_ASSERT( test1::flag == 0 ); memory_input in1( "-", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< if_apply< one< '-' >, test1::action_a, test1::action_b >, test1::action >( in1, state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( test1::flag == 1 ); TAO_PEGTL_TEST_ASSERT( state_r == "-" ); TAO_PEGTL_TEST_ASSERT( state_s == "-*-" ); memory_input in2( "-", __FUNCTION__ ); TAO_PEGTL_TEST_ASSERT( parse< disable< if_apply< one< '-' >, test1::action_a, test1::action_b > >, test1::action >( in2, state_r, state_s ) ); TAO_PEGTL_TEST_ASSERT( test1::flag == 1 ); TAO_PEGTL_TEST_ASSERT( state_r == "-" ); TAO_PEGTL_TEST_ASSERT( state_s == "-*-" ); { bool state_b = false; TAO_PEGTL_TEST_ASSERT( !parse< if_apply< plus< alpha >, test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input( "foo bar", __FUNCTION__ ), state_b ) ); TAO_PEGTL_TEST_ASSERT( state_b ); } { bool state_b = false; TAO_PEGTL_TEST_ASSERT( !parse< if_apply< plus< alpha >, test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input( "", __FUNCTION__ ), state_b ) ); TAO_PEGTL_TEST_ASSERT( !state_b ); } verify_meta< if_apply< any >, internal::if_apply< any >, any >(); verify_meta< if_apply< any, test1::action_a >, internal::if_apply< any, test1::action_a >, any >(); verify_seqs< if_apply_seq >(); verify_seqs< if_apply_disable >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_if_must.cpp�����������������������������������������������������0000664�0000000�0000000�00000007365�14264072506�0021522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< if_must< any >, internal::if_must< false, any >, any, internal::must<> >(); verify_meta< if_must< any, eof >, internal::if_must< false, any, eof >, any, internal::must< eof > >(); verify_meta< if_must< any, eof, one< 0 > >, internal::if_must< false, any, eof, one< 0 > >, any, internal::must< eof, one< 0 > > >(); verify_analyze< if_must< any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< if_must< eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< if_must< opt< any >, any > >( __LINE__, __FILE__, true, false ); verify_analyze< if_must< any, opt< any > > >( __LINE__, __FILE__, true, false ); verify_analyze< if_must< any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< if_must< opt< any >, opt< any > > >( __LINE__, __FILE__, false, false ); verify_analyze< if_must< eof, eof > >( __LINE__, __FILE__, false, false ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::global_failure, 0 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ba", result_type::local_failure, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ac", result_type::global_failure, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "acb", result_type::global_failure, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bc", result_type::local_failure, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "a", result_type::global_failure, 1 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ab", result_type::global_failure, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ac", result_type::global_failure, 2 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abb", result_type::global_failure, 3 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "acc", result_type::global_failure, 3 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "acb", result_type::global_failure, 3 ); verify_rule< if_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abc", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_if_must_else.cpp������������������������������������������������0000664�0000000�0000000�00000001023�14264072506�0022513�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_ifmt.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_ifmt< if_must_else >( result_type::global_failure ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_if_then_else.cpp������������������������������������������������0000664�0000000�0000000�00000000727�14264072506�0022473�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_ifmt.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< if_then_else< digit, alpha, print >, internal::if_then_else< digit, alpha, print >, digit, alpha, print >(); verify_ifmt< if_then_else >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_list.cpp��������������������������������������������������������0000664�0000000�0000000�00000010171�14264072506�0021014�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< list< eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list< any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< list< any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list< eof, eof, any > >( __LINE__, __FILE__, false, true ); verify_analyze< list< eof, any, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list< eof, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list< any, eof, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list< any, eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list< any, any, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list< any, any, any > >( __LINE__, __FILE__, true, false ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",a", result_type::local_failure, 2 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,", result_type::success, 1 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,b", result_type::success, 2 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,b", result_type::success, 2 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,,", result_type::success, 2 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ,a", result_type::success, 3 ); verify_rule< list< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a, a", result_type::success, 3 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ,a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a", result_type::success, 0 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a,", result_type::success, 1 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a ,", result_type::success, 2 ); verify_rule< list< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a , a ", result_type::local_failure, 7 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_list_must.cpp���������������������������������������������������0000664�0000000�0000000�00000010422�14264072506�0022063�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< list_must< eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_must< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list_must< any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< list_must< any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list_must< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_must< eof, eof, any > >( __LINE__, __FILE__, false, true ); verify_analyze< list_must< eof, any, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_must< eof, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list_must< any, eof, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list_must< any, eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list_must< any, any, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list_must< any, any, any > >( __LINE__, __FILE__, true, false ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",a", result_type::local_failure, 2 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,", result_type::global_failure, 2 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,b", result_type::global_failure, 3 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ,a", result_type::success, 3 ); verify_rule< list_must< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a, a", result_type::global_failure, 0 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ,a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a", result_type::success, 0 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a,", result_type::global_failure, 5 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a ,", result_type::global_failure, 6 ); verify_rule< list_must< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a , a ", result_type::local_failure, 7 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_list_tail.cpp���������������������������������������������������0000664�0000000�0000000�00000010467�14264072506�0022035�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< list_tail< eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_tail< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list_tail< any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< list_tail< any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list_tail< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_tail< eof, eof, any > >( __LINE__, __FILE__, false, true ); verify_analyze< list_tail< eof, any, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< list_tail< eof, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< list_tail< any, eof, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list_tail< any, eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< list_tail< any, any, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< list_tail< any, any, any > >( __LINE__, __FILE__, true, false ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, ",a", result_type::local_failure, 2 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,b", result_type::success, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,b", result_type::success, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a,a,a,,", result_type::success, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a ,a", result_type::success, 3 ); verify_rule< list_tail< one< 'a' >, one< ',' > > >( __LINE__, __FILE__, "a, a", result_type::success, 2 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, ",", result_type::local_failure, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ", result_type::success, 1 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a ,a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a,", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, "a, a ,", result_type::success, 0 ); verify_rule< list_tail< one< 'a' >, one< ',' >, blank > >( __LINE__, __FILE__, " a , a ", result_type::local_failure, 7 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_minus.cpp�������������������������������������������������������0000664�0000000�0000000�00000007034�14264072506�0021200�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2016-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< minus< alpha, digit > >( __LINE__, __FILE__, true, false ); verify_analyze< minus< opt< alpha >, digit > >( __LINE__, __FILE__, false, false ); verify_rule< minus< alnum, digit > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< minus< alnum, digit > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< minus< alnum, digit > >( __LINE__, __FILE__, "1", result_type::local_failure, 1 ); verify_rule< minus< alnum, digit > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< minus< alnum, digit > >( __LINE__, __FILE__, "a%", result_type::success, 1 ); #if defined( __cpp_exceptions ) verify_rule< must< minus< alnum, digit > > >( __LINE__, __FILE__, "%", result_type::global_failure, 1 ); verify_rule< must< minus< alnum, digit > > >( __LINE__, __FILE__, "1", result_type::global_failure, 0 ); #endif verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "1", result_type::local_failure, 1 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "a%", result_type::success, 1 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "a1", result_type::success, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "1a", result_type::success, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "11", result_type::success, 0 ); verify_rule< minus< plus< alnum >, digit > >( __LINE__, __FILE__, "%%", result_type::local_failure, 2 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1", result_type::local_failure, 1 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a%", result_type::success, 1 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aaa%", result_type::success, 1 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "111", result_type::local_failure, 3 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "111%", result_type::local_failure, 4 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a1a", result_type::success, 0 ); verify_rule< minus< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1a1", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_must.cpp��������������������������������������������������������0000664�0000000�0000000�00000001446�14264072506�0021036�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< must<>, internal::success >(); verify_meta< must< alpha >, internal::must< alpha >, alpha >(); verify_meta< must< alpha, digit >, internal::seq< internal::must< alpha >, internal::must< digit > >, internal::must< alpha >, internal::must< digit > >(); verify_seqs< must >( result_type::global_failure ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_not_at.cpp������������������������������������������������������0000664�0000000�0000000�00000004340�14264072506�0021326�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { int at_counter = 0; template< typename Rule > struct at_action {}; template<> struct at_action< alpha > { static void apply0() { ++at_counter; } }; void unit_test() { TAO_PEGTL_TEST_ASSERT( at_counter == 0 ); verify_meta< not_at<>, internal::failure >(); verify_meta< not_at< eof >, internal::not_at< eof >, eof >(); verify_meta< not_at< eof, any >, internal::not_at< internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_analyze< not_at< eof > >( __LINE__, __FILE__, false, false ); verify_analyze< not_at< any > >( __LINE__, __FILE__, false, false ); verify_rule< not_at< eof > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< not_at< eof > >( __LINE__, __FILE__, " ", result_type::success, 1 ); verify_rule< not_at< any > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< not_at< any > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< not_at< any > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< not_at< any > >( __LINE__, __FILE__, "aaaa", result_type::local_failure, 4 ); #if defined( __cpp_exceptions ) verify_rule< must< not_at< alpha > > >( __LINE__, __FILE__, "a", result_type::global_failure, 1 ); verify_rule< must< not_at< alpha, alpha > > >( __LINE__, __FILE__, "aa1", result_type::global_failure, 3 ); #endif { memory_input in( "a", 1, __FILE__ ); parse< alpha, at_action >( in ); TAO_PEGTL_TEST_ASSERT( at_counter == 1 ); } { memory_input in( "1", 1, __FILE__ ); parse< not_at< alpha >, at_action >( in ); TAO_PEGTL_TEST_ASSERT( at_counter == 1 ); } { memory_input in( "a", 1, __FILE__ ); parse< not_at< alpha >, at_action >( in ); TAO_PEGTL_TEST_ASSERT( at_counter == 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_opt.cpp���������������������������������������������������������0000664�0000000�0000000�00000007011�14264072506�0020642�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct my_action {}; template<> struct my_action< eof > { static void apply0( bool& b ) { b = true; } }; void unit_test() { verify_meta< opt<>, internal::success >(); verify_meta< opt< eof >, internal::opt< eof >, eof >(); verify_meta< opt< eof, any >, internal::opt< internal::seq< eof, any > >, internal::seq< eof, any > >(); verify_analyze< opt< any > >( __LINE__, __FILE__, false, false ); verify_analyze< opt< eof > >( __LINE__, __FILE__, false, false ); verify_rule< opt< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< opt< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< opt< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< opt< one< 'a' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< opt< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); verify_rule< opt< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "cb", result_type::success, 2 ); #if defined( __cpp_exceptions ) verify_rule< must< opt< one< 'a' > > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< must< opt< one< 'a' > > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< must< opt< one< 'a' > > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< must< opt< one< 'a' > > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< must< opt< one< 'a' > > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); verify_rule< must< opt< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "cb", result_type::success, 2 ); #endif bool success = false; TAO_PEGTL_TEST_ASSERT( parse< opt< eof >, my_action >( memory_input( "", __FUNCTION__ ), success ) ); TAO_PEGTL_TEST_ASSERT( success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_opt_must.cpp����������������������������������������������������0000664�0000000�0000000�00000006616�14264072506�0021724�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< opt_must< any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< opt< any >, any > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< any, opt< any > > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< opt< any >, opt< any > > >( __LINE__, __FILE__, false, false ); verify_analyze< opt_must< eof, eof > >( __LINE__, __FILE__, false, false ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::global_failure, 0 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ac", result_type::global_failure, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "acb", result_type::global_failure, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "", result_type::success ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bc", result_type::success, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "a", result_type::global_failure, 1 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ab", result_type::global_failure, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ac", result_type::global_failure, 2 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abb", result_type::global_failure, 3 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "acc", result_type::global_failure, 3 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "acb", result_type::global_failure, 3 ); verify_rule< opt_must< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abc", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif ������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_pad.cpp���������������������������������������������������������0000664�0000000�0000000�00000006477�14264072506�0020623�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< pad< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< pad< eof, eof, any > >( __LINE__, __FILE__, false, true ); verify_analyze< pad< eof, any, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< pad< eof, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< pad< any, eof, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< pad< any, eof, any > >( __LINE__, __FILE__, true, true ); verify_analyze< pad< any, any, eof > >( __LINE__, __FILE__, true, true ); verify_analyze< pad< any, any, any > >( __LINE__, __FILE__, true, false ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " ", result_type::local_failure, 1 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " ", result_type::local_failure, 2 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "ba", result_type::local_failure, 2 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, "a a", result_type::success, 1 ); verify_rule< pad< one< 'a' >, space > >( __LINE__, __FILE__, " a a ", result_type::success, 2 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "1a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "123a", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "123a ", result_type::success, 0 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, " a", result_type::local_failure, 2 ); verify_rule< pad< one< 'a' >, digit, blank > >( __LINE__, __FILE__, "a1", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_pad_opt.cpp�����������������������������������������������������0000664�0000000�0000000�00000004433�14264072506�0021473�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< pad_opt< eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< pad_opt< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< pad_opt< any, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< pad_opt< any, any > >( __LINE__, __FILE__, false, false ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " a", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " a", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " b", result_type::success, 1 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "a ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " a ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " a ", result_type::success, 0 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, "a a", result_type::success, 1 ); verify_rule< pad_opt< one< 'a' >, space > >( __LINE__, __FILE__, " a a ", result_type::success, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_plus.cpp��������������������������������������������������������0000664�0000000�0000000�00000005540�14264072506�0021030�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< plus< alpha >, internal::plus< alpha >, alpha >(); verify_meta< plus< alpha, digit >, internal::plus< internal::seq< alpha, digit > >, internal::seq< alpha, digit > >(); verify_analyze< plus< eof > >( __LINE__, __FILE__, false, true ); verify_analyze< plus< any > >( __LINE__, __FILE__, true, false ); verify_analyze< plus< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< plus< any, eof, any > >( __LINE__, __FILE__, true, false ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "aab", result_type::success, 1 ); verify_rule< plus< one< 'a' > > >( __LINE__, __FILE__, "aaab", result_type::success, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ac", result_type::local_failure, 2 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abc", result_type::success, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 ); verify_rule< plus< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababb", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_raise.cpp�������������������������������������������������������0000664�0000000�0000000�00000002174�14264072506�0021150�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #if defined( _MSC_VER ) #pragma warning( push ) #pragma warning( disable : 4702 ) #endif namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< raise< int >, internal::raise< int > >(); verify_meta< raise< any >, internal::raise< any > >(); verify_analyze< raise< int > >( __LINE__, __FILE__, true, false ); verify_analyze< raise< any > >( __LINE__, __FILE__, true, false ); memory_input in( "foo", __FUNCTION__ ); TAO_PEGTL_TEST_THROWS( parse< raise< int > >( in ) ); TAO_PEGTL_TEST_ASSERT( in.size( 4 ) == 3 ); TAO_PEGTL_TEST_THROWS( parse< raise< any > >( in ) ); TAO_PEGTL_TEST_ASSERT( in.size( 4 ) == 3 ); } } // namespace TAO_PEGTL_NAMESPACE #if defined( _MSC_VER ) #pragma warning( pop ) #endif #include "main.hpp" #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rematch.cpp�����������������������������������������������������0000664�0000000�0000000�00000021715�14264072506�0021472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2019-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "c", result_type::success ); verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "a", result_type::local_failure ); verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "b", result_type::local_failure ); verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "cc", result_type::success, 1 ); verify_rule< rematch< one< 'c' > > >( __LINE__, __FILE__, "bc", result_type::local_failure ); verify_analyze< rematch< alpha, digit > >( __LINE__, __FILE__, true, false ); verify_analyze< rematch< opt< alpha >, digit > >( __LINE__, __FILE__, false, false ); verify_analyze< rematch< alnum, opt< alpha > > >( __LINE__, __FILE__, true, false ); { struct foo : rematch< foo, alnum > {}; verify_analyze< foo >( __LINE__, __FILE__, false, true ); } { struct foo : rematch< alnum, foo > {}; verify_analyze< foo >( __LINE__, __FILE__, true, true ); } { struct foo : rematch< alnum, alpha, foo > {}; verify_analyze< foo >( __LINE__, __FILE__, true, true ); } verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "1", result_type::success, 0 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "1%", result_type::success, 1 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "a%", result_type::local_failure, 2 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "12", result_type::success, 1 ); verify_rule< rematch< alnum, digit > >( __LINE__, __FILE__, "1c", result_type::success, 1 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "1", result_type::success, 0 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "1%", result_type::success, 1 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "a%", result_type::local_failure, 2 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "12", result_type::success, 1 ); verify_rule< rematch< alnum, digit, success > >( __LINE__, __FILE__, "1c", result_type::success, 1 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "1", result_type::success, 0 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "1%", result_type::success, 1 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "a%", result_type::local_failure, 2 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "12", result_type::success, 1 ); verify_rule< rematch< alnum, success, digit > >( __LINE__, __FILE__, "1c", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1", result_type::success ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a", result_type::local_failure ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "%", result_type::local_failure ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a%", result_type::local_failure ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "12", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "1c", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "a1", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, digit > >( __LINE__, __FILE__, "%%", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "%", result_type::local_failure, 1 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a%", result_type::local_failure ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "12", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1c", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a1", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "%%", result_type::local_failure, 2 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aaa", result_type::local_failure, 3 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "aaa%", result_type::local_failure, 4 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "111", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "111%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "a1a", result_type::local_failure, 3 ); verify_rule< rematch< plus< alnum >, plus< digit > > >( __LINE__, __FILE__, "1a1", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo5", result_type::local_failure, 4 ); verify_rule< rematch< plus< alnum >, success, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, success, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, success, seq< string< 'f', 'o', 'o' >, eof > > >( __LINE__, __FILE__, "foo5", result_type::local_failure, 4 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, success > >( __LINE__, __FILE__, "foo", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, success > >( __LINE__, __FILE__, "foo%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, success > >( __LINE__, __FILE__, "foo5", result_type::local_failure, 4 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, string< 'f', 'o', 'o' > > >( __LINE__, __FILE__, "foo", result_type::success, 0 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, string< 'f', 'o', 'o' > > >( __LINE__, __FILE__, "foo%", result_type::success, 1 ); verify_rule< rematch< plus< alnum >, seq< string< 'f', 'o', 'o' >, eof >, string< 'f', 'o', 'o' > > >( __LINE__, __FILE__, "foo5", result_type::local_failure, 4 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rep.cpp���������������������������������������������������������0000664�0000000�0000000�00000013155�14264072506�0020634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep< 0, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 0, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 1, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 1, any > >( __LINE__, __FILE__, true, false ); verify_analyze< rep< 7, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 9, any > >( __LINE__, __FILE__, true, false ); verify_analyze< rep< 0, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 0, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 0, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 0, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 1, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep< 1, any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< rep< 1, any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< rep< 1, eof, any > >( __LINE__, __FILE__, true, false ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 1 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "aaab", result_type::success, 1 ); verify_rule< rep< 3, one< 'a' > > >( __LINE__, __FILE__, "baaab", result_type::local_failure, 5 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::local_failure, 3 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaa", result_type::success, 1 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaa", result_type::success, 2 ); verify_rule< rep< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaaa", result_type::success, 3 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::local_failure, 2 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::local_failure, 3 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 ); verify_rule< rep< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababab", result_type::success, 2 ); #if defined( __cpp_exceptions ) verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::global_failure, 0 ); verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::global_failure, 1 ); verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::global_failure, 0 ); verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "aba", result_type::global_failure, 1 ); verify_rule< must< rep< 2, one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); 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 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rep_max.cpp�����������������������������������������������������0000664�0000000�0000000�00000007516�14264072506�0021505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_max< 1, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_max< 2, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_max< 1, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_max< 2, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_max< 1, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_max< 2, any, any > >( __LINE__, __FILE__, false, false ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::success, 2 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "bbb", result_type::success, 3 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::local_failure, 4 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "aaab", result_type::success, 1 ); verify_rule< rep_max< 3, one< 'a' > > >( __LINE__, __FILE__, "baaab", result_type::success, 5 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aa", result_type::success, 2 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aab", result_type::success, 3 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababb", result_type::success, 1 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababa", result_type::success, 1 ); verify_rule< rep_max< 2, one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababab", result_type::local_failure, 6 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 1 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaa", result_type::success, 1 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaa", result_type::local_failure, 6 ); verify_rule< rep_max< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaaa", result_type::local_failure, 7 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rep_min.cpp�����������������������������������������������������0000664�0000000�0000000�00000004572�14264072506�0021502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_min< 0, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< rep_min< 1, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< rep_min< 0, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min< 1, any > >( __LINE__, __FILE__, true, false ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "aaab", result_type::success, 1 ); verify_rule< rep_min< 3, one< 'a' > > >( __LINE__, __FILE__, "baaab", result_type::local_failure, 5 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aa", result_type::local_failure, 2 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::local_failure, 3 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaa", result_type::success, 1 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaa", result_type::success, 0 ); verify_rule< rep_min< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaaa", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rep_min_max.cpp�������������������������������������������������0000664�0000000�0000000�00000006466�14264072506�0022353�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_min_max< 0, 1, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 0, 2, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 1, 2, any > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_min_max< 0, 1, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 0, 2, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 1, 2, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 0, 1, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 0, 2, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 1, 2, eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< rep_min_max< 0, 1, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 0, 2, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_min_max< 1, 2, eof, eof > >( __LINE__, __FILE__, false, false ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "aaaaa", result_type::local_failure, 5 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "bbb", result_type::local_failure, 3 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "bbbb", result_type::local_failure, 4 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "bbbbb", result_type::local_failure, 5 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::local_failure, 2 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "baa", result_type::local_failure, 3 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "baaa", result_type::local_failure, 4 ); verify_rule< rep_min_max< 2, 4, one< 'a' > > >( __LINE__, __FILE__, "baaaa", result_type::local_failure, 5 ); #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 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_rep_opt.cpp�����������������������������������������������������0000664�0000000�0000000�00000005222�14264072506�0021512�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< rep_opt< 1, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 6, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 1, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 6, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 1, any, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 1, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 1, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< rep_opt< 1, eof, eof > >( __LINE__, __FILE__, false, false ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::success, 2 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "bbb", result_type::success, 3 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 1 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "aaab", result_type::success, 1 ); verify_rule< rep_opt< 3, one< 'a' > > >( __LINE__, __FILE__, "baaab", result_type::success, 5 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 1 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaa", result_type::success, 0 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaa", result_type::success, 1 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaa", result_type::success, 2 ); verify_rule< rep_opt< 2, two< 'a' > > >( __LINE__, __FILE__, "aaaaaaa", result_type::success, 3 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_require.cpp�����������������������������������������������������0000664�0000000�0000000�00000004332�14264072506�0021517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2017-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< require< 0 >, internal::success >(); verify_meta< require< 1 >, internal::require< 1 > >(); verify_analyze< require< 0 > >( __LINE__, __FILE__, false, false ); verify_analyze< require< 1 > >( __LINE__, __FILE__, false, false ); verify_analyze< require< 9 > >( __LINE__, __FILE__, false, false ); verify_rule< require< 0 > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< require< 0 > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< require< 0 > >( __LINE__, __FILE__, " ", result_type::success, 2 ); verify_rule< require< 1 > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< require< 1 > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< require< 1 > >( __LINE__, __FILE__, " ", result_type::success, 2 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "1", result_type::local_failure, 1 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "12", result_type::local_failure, 2 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "123", result_type::local_failure, 3 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "1234", result_type::local_failure, 4 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "12345", result_type::local_failure, 5 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "123456", result_type::local_failure, 6 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "1234567", result_type::local_failure, 7 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "12345678", result_type::local_failure, 8 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "123456789", result_type::success, 9 ); verify_rule< require< 9 > >( __LINE__, __FILE__, "123456789123456789", result_type::success, 18 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_seq.cpp���������������������������������������������������������0000664�0000000�0000000�00000001070�14264072506�0020627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< seq<>, internal::success >(); verify_meta< seq< alpha >, internal::seq< alpha >, alpha >(); verify_meta< seq< alpha, digit >, internal::seq< alpha, digit >, alpha, digit >(); verify_seqs< seq >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_sor.cpp���������������������������������������������������������0000664�0000000�0000000�00000005765�14264072506�0020661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< sor<>, internal::failure >(); verify_meta< sor< alpha >, internal::sor< alpha >, alpha >(); verify_meta< sor< alpha, digit >, internal::sor< alpha, digit >, alpha, digit >(); verify_analyze< sor< eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< any > >( __LINE__, __FILE__, true, false ); verify_analyze< sor< any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< sor< any, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< any, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< any, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< any, any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< sor< eof, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< eof, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< eof, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< sor< eof, any, any > >( __LINE__, __FILE__, false, false ); verify_rule< sor<> >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< sor<> >( __LINE__, __FILE__, "a", result_type::local_failure, 1 ); verify_rule< sor< one< 'a' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< sor< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< sor< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 0 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "c", result_type::local_failure, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ba", result_type::success, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bb", result_type::success, 1 ); verify_rule< sor< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "cb", result_type::local_failure, 2 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������tao-pegtl-3.2.7/src/test/pegtl/rule_star.cpp��������������������������������������������������������0000664�0000000�0000000�00000004322�14264072506�0021013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< star< alpha >, internal::star< alpha >, alpha >(); verify_meta< star< alpha, digit >, internal::star< internal::seq< alpha, digit > >, internal::seq< alpha, digit > >(); verify_analyze< star< eof > >( __LINE__, __FILE__, false, true ); verify_analyze< star< any > >( __LINE__, __FILE__, false, false ); verify_analyze< star< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< star< any, eof, any > >( __LINE__, __FILE__, false, false ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< star< one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababc", result_type::success, 1 ); verify_rule< star< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababab", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_star_must.cpp���������������������������������������������������0000664�0000000�0000000�00000004425�14264072506�0022067�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_analyze< star_must< eof > >( __LINE__, __FILE__, false, true ); verify_analyze< star_must< any > >( __LINE__, __FILE__, false, false ); verify_analyze< star_must< eof, eof, eof > >( __LINE__, __FILE__, false, true ); verify_analyze< star_must< any, eof, any > >( __LINE__, __FILE__, false, false ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "aaa", result_type::success, 0 ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); verify_rule< star_must< one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::global_failure, 1 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::global_failure, 3 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 0 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababc", result_type::success, 1 ); verify_rule< star_must< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ababab", result_type::success, 0 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_state.cpp�������������������������������������������������������0000664�0000000�0000000�00000002045�14264072506�0021162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { struct test_state_state { template< typename ParseInput > explicit test_state_state( const ParseInput& /*unused*/ ) {} template< typename ParseInput > void success( const ParseInput& /*unused*/ ) const {} }; template< typename... Rules > using test_state_rule = state< test_state_state, Rules... >; void unit_test() { verify_meta< state< test_state_state >, internal::success >(); verify_meta< state< test_state_state, any >, internal::state< test_state_state, any >, any >(); verify_meta< state< test_state_state, alpha, digit >, internal::state< test_state_state, internal::seq< alpha, digit > >, internal::seq< alpha, digit > >(); verify_seqs< test_state_rule >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_success.cpp�����������������������������������������������������0000664�0000000�0000000�00000001311�14264072506�0021505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_meta< success, internal::success >(); verify_analyze< success >( __LINE__, __FILE__, false, false ); verify_rule< success >( __LINE__, __FILE__, "", result_type::success, 0 ); for( char i = 1; i < 127; ++i ) { char t[] = { i, 0 }; verify_rule< success >( __LINE__, __FILE__, std::string( t ), result_type::success, 1 ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_try_catch.cpp���������������������������������������������������0000664�0000000�0000000�00000001177�14264072506�0022027�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #if !defined( __cpp_exceptions ) #include <iostream> int main() { std::cout << "Exception support disabled, skipping test..." << std::endl; } #else #include "test.hpp" #include "verify_seqs.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename... Rules > using test_try_catch_rule = try_catch< must< Rules... > >; void unit_test() { verify_seqs< try_catch >(); verify_seqs< test_try_catch_rule >(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/rule_until.cpp�������������������������������������������������������0000664�0000000�0000000�00000016660�14264072506�0021205�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { struct my_rule { template< apply_mode A, rewind_mode M, template< typename... > class Action, template< typename... > class Control, typename ParseInput, typename... States > static bool match( ParseInput& /*unused*/, bool& v, States... /*unused*/ ) { return v; } }; template< typename Rule > struct my_action {}; template<> struct my_action< eof > { static void apply0( bool& v ) { v = true; } }; void unit_test() { verify_analyze< until< eof > >( __LINE__, __FILE__, false, false ); verify_analyze< until< any > >( __LINE__, __FILE__, true, false ); verify_analyze< until< eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< until< any, any > >( __LINE__, __FILE__, true, false ); verify_rule< until< eof > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< until< any > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 0 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "bba", result_type::success, 0 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbba", result_type::success, 0 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "bab", result_type::success, 1 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "bbab", result_type::success, 1 ); verify_rule< until< one< 'a' > > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbbab", result_type::success, 1 ); #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 ); #endif verify_rule< until< eof, any > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< until< any, any > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "ba", result_type::success, 0 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "bba", result_type::success, 0 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbba", result_type::success, 0 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "bab", result_type::success, 1 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "bbab", result_type::success, 1 ); verify_rule< until< one< 'a' >, any > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbbab", result_type::success, 1 ); verify_rule< until< eof, one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< until< eof, one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< until< eof, one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 0 ); verify_rule< until< eof, one< 'a' > > >( __LINE__, __FILE__, "aaaaab", result_type::local_failure, 6 ); verify_rule< until< eof, one< 'a' > > >( __LINE__, __FILE__, "baaaaa", result_type::local_failure, 6 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::local_failure, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bb", result_type::local_failure, 2 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ba", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bba", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bbbbbbbbbbbbbba", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "baa", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bbaa", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbaa", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bab", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bbab", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bbbbbbbbbbbbbbab", result_type::success, 1 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bca", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bcbca", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bcbcbcbcbca", result_type::success, 0 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "babca", result_type::local_failure, 5 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bcbcb", result_type::local_failure, 5 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "cbcbc", result_type::local_failure, 5 ); verify_rule< until< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "bcbcbc", result_type::local_failure, 6 ); #if defined( __cpp_exceptions ) 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 ); #endif bool success = false; const bool result = parse< until< my_rule, eof >, my_action >( memory_input<>( "", __FUNCTION__ ), success ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/test.hpp�������������������������������������������������������������0000664�0000000�0000000�00000006551�14264072506�0020005�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_TEST_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_TEST_HPP #include <cstddef> #include <exception> #include <iostream> #include <tao/pegtl.hpp> namespace TAO_PEGTL_NAMESPACE { std::size_t failed = 0; } // namespace TAO_PEGTL_NAMESPACE #define TAO_TEST_STRINGIZE_INTERNAL( ... ) #__VA_ARGS__ #define TAO_TEST_STRINGIZE( ... ) TAO_TEST_STRINGIZE_INTERNAL( __VA_ARGS__ ) #define TAO_TEST_LINE TAO_TEST_STRINGIZE( __LINE__ ) #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; \ } while( false ) #define TAO_PEGTL_TEST_ASSERT( ... ) \ do { \ if( !( __VA_ARGS__ ) ) { \ std::cerr << "pegtl: unit test assert [ " \ << ( #__VA_ARGS__ ) \ << " ] failed in line [ " \ << __LINE__ \ << " ] file [ " \ << __FILE__ << " ]" \ << std::endl; \ ++TAO_PEGTL_NAMESPACE::failed; \ } \ } while( false ) #define TAO_PEGTL_TEST_THROWS( ... ) \ do { \ try { \ __VA_ARGS__; \ std::cerr << "pegtl: unit test [ " \ << ( #__VA_ARGS__ ) \ << " ] did not throw in line [ " \ << __LINE__ \ << " ] file [ " \ << __FILE__ << " ]" \ << std::endl; \ ++TAO_PEGTL_NAMESPACE::failed; \ } \ catch( ... ) { \ } \ } while( false ) #define TAO_PEGTL_TEST_UNREACHABLE \ do { \ std::cerr << "Code should be unreachable in " << __FUNCTION__ << " (" << __FILE__ << ':' << __LINE__ << ')' << std::endl; \ std::terminate(); \ } while( false ) #endif �������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/test_empty.cpp�������������������������������������������������������0000664�0000000�0000000�00000000422�14264072506�0021205�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() {} } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/test_result.cpp������������������������������������������������������0000664�0000000�0000000�00000001640�14264072506�0021370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <sstream> #include "test.hpp" #include "result_type.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { { std::ostringstream oss; oss << result_type::success; TAO_PEGTL_TEST_ASSERT( oss.str() == "success" ); } { std::ostringstream oss; oss << result_type::local_failure; TAO_PEGTL_TEST_ASSERT( oss.str() == "local_failure" ); } { std::ostringstream oss; oss << result_type::global_failure; TAO_PEGTL_TEST_ASSERT( oss.str() == "global_failure" ); } { std::ostringstream oss; oss << result_type( 1764 ); TAO_PEGTL_TEST_ASSERT( oss.str() == "1764" ); } } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/test_setup.cpp�������������������������������������������������������0000664�0000000�0000000�00000002473�14264072506�0021217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <iostream> #include <utility> int main() { #ifdef __GNUC__ std::cout << "__GNUC__: " << __GNUC__ << std::endl; std::cout << "__GNUC_MINOR__: " << __GNUC_MINOR__ << std::endl; std::cout << "__GNUC_PATCHLEVEL__: " << __GNUC_PATCHLEVEL__ << std::endl; #endif #ifdef __GLIBCPP__ std::cout << "__GLIBCPP__: " << __GLIBCPP__ << std::endl; #endif #ifdef __GLIBCXX__ std::cout << "__GLIBCXX__: " << __GLIBCXX__ << std::endl; #endif #ifdef __clang__ std::cout << "__clang__: " << __clang__ << std::endl; std::cout << "__clang_major__: " << __clang_major__ << std::endl; std::cout << "__clang_minor__: " << __clang_minor__ << std::endl; std::cout << "__clang_patchlevel__: " << __clang_patchlevel__ << std::endl; std::cout << "__clang_version__: " << __clang_version__ << std::endl; #endif #ifdef __apple_build_version__ std::cout << "__apple_build_version__: " << __apple_build_version__ << std::endl; #endif #ifdef _LIBCPP_VERSION std::cout << "_LIBCPP_VERSION: " << _LIBCPP_VERSION << std::endl; #endif #ifdef _MSC_VER std::cout << "_MSC_VER: " << _MSC_VER << std::endl; std::cout << "_MSC_FULL_VER: " << _MSC_FULL_VER << std::endl; #endif return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/uint16_general.cpp���������������������������������������������������0000664�0000000�0000000�00000035060�14264072506�0021641�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/uint16.hpp> namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< uint16_be::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x01\x02", result_type::success ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x71\x72", result_type::success ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x01\x02", result_type::success ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x71\x72", result_type::success ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x01\x02\x03", result_type::success, 1 ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::success, 1 ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x01\x02\x03", result_type::success, 1 ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::success, 1 ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x01\x02\x03\x55", result_type::success, 2 ); verify_rule< uint16_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::success, 2 ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x01\x02\x03\x55", result_type::success, 2 ); verify_rule< uint16_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::success, 2 ); verify_rule< uint16_be::mask_not_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint16_be::mask_not_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::local_failure ); verify_rule< uint16_be::mask_not_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::success ); verify_rule< uint16_le::mask_not_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::success ); verify_rule< uint16_le::mask_not_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::local_failure ); verify_rule< uint16_be::mask_not_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\xf3\x11", result_type::success ); verify_rule< uint16_be::mask_not_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\xf1\x11", result_type::local_failure ); verify_rule< uint16_le::mask_not_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\xf3", result_type::success ); verify_rule< uint16_le::mask_not_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\xf1", result_type::local_failure ); verify_rule< uint16_be::mask_not_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::local_failure ); verify_rule< uint16_be::mask_not_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::success ); verify_rule< uint16_le::mask_not_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::success ); verify_rule< uint16_le::mask_not_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::local_failure ); verify_rule< uint16_be::mask_not_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x52\x77", result_type::local_failure ); verify_rule< uint16_be::mask_not_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x56\x77", result_type::success ); verify_rule< uint16_le::mask_not_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x52", result_type::local_failure ); verify_rule< uint16_le::mask_not_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x56", result_type::success ); verify_rule< uint16_be::mask_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::success ); verify_rule< uint16_be::mask_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::local_failure ); verify_rule< uint16_le::mask_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::local_failure ); verify_rule< uint16_le::mask_one< 0xffff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::success ); verify_rule< uint16_be::mask_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\xf3\x11", result_type::local_failure ); verify_rule< uint16_be::mask_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\xf1\x11", result_type::success ); verify_rule< uint16_le::mask_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\xf3", result_type::local_failure ); verify_rule< uint16_le::mask_one< 0x0fff, 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\xf1", result_type::success ); verify_rule< uint16_be::mask_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::success ); verify_rule< uint16_be::mask_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::local_failure ); verify_rule< uint16_le::mask_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::local_failure ); verify_rule< uint16_le::mask_range< 0xffff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::success ); verify_rule< uint16_be::mask_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x52\x77", result_type::success ); verify_rule< uint16_be::mask_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x56\x77", result_type::local_failure ); verify_rule< uint16_le::mask_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x52", result_type::success ); verify_rule< uint16_le::mask_range< 0x0fff, 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x56", result_type::local_failure ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x01\x23", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x02\x34", result_type::local_failure ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x03\x45", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x67\x89", result_type::local_failure ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x23\x01", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x34\x02", result_type::local_failure ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x45\x03", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x89\x67", result_type::local_failure ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x01\x23", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x02\x34", result_type::local_failure ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x03\x45", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x67\x89", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x23\x01", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x34\x02", result_type::local_failure ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x45\x03", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x89\x67", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xff0f, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x02\x50", result_type::success ); verify_rule< uint16_be::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x02\x50", result_type::local_failure ); verify_rule< uint16_le::mask_ranges< 0xff0f, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x50\x02", result_type::success ); verify_rule< uint16_le::mask_ranges< 0xffff, 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x50\x02", result_type::local_failure ); verify_rule< uint16_be::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint16_be::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x01\x67\x45", result_type::local_failure ); verify_rule< uint16_le::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::local_failure ); verify_rule< uint16_le::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x01\x67\x45", result_type::success ); verify_rule< uint16_be::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x81\x23\x45\x67", result_type::local_failure ); verify_rule< uint16_be::mask_string< 0x4fff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x81\x23\x45\x67", result_type::success ); verify_rule< uint16_le::mask_string< 0xffff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x81\x67\x45", result_type::local_failure ); verify_rule< uint16_le::mask_string< 0x4fff, 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x81\x67\x45", result_type::success ); verify_rule< uint16_be::not_one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::local_failure ); verify_rule< uint16_be::not_one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::success ); verify_rule< uint16_le::not_one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::success ); verify_rule< uint16_le::not_one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::local_failure ); verify_rule< uint16_be::not_range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::local_failure ); verify_rule< uint16_be::not_range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::success ); verify_rule< uint16_le::not_range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::success ); verify_rule< uint16_le::not_range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::local_failure ); verify_rule< uint16_be::one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::success ); verify_rule< uint16_be::one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::local_failure ); verify_rule< uint16_le::one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x01\x11", result_type::local_failure ); verify_rule< uint16_le::one< 0x0111, 0x0222 > >( __LINE__, __FILE__, "\x11\x01", result_type::success ); verify_rule< uint16_be::range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::success ); verify_rule< uint16_be::range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::local_failure ); verify_rule< uint16_le::range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x02\x77", result_type::local_failure ); verify_rule< uint16_le::range< 0x0100, 0x0400 > >( __LINE__, __FILE__, "\x77\x02", result_type::success ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x01\x23", result_type::success ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x02\x34", result_type::local_failure ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x03\x45", result_type::success ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x67\x89", result_type::local_failure ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x23\x01", result_type::success ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x34\x02", result_type::local_failure ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x45\x03", result_type::success ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444 > >( __LINE__, __FILE__, "\x89\x67", result_type::local_failure ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x01\x23", result_type::success ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x02\x34", result_type::local_failure ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x03\x45", result_type::success ); verify_rule< uint16_be::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x67\x89", result_type::success ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x23\x01", result_type::success ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x34\x02", result_type::local_failure ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x45\x03", result_type::success ); verify_rule< uint16_le::ranges< 0x0111, 0x0222, 0x0333, 0x0444, 0x6789 > >( __LINE__, __FILE__, "\x89\x67", result_type::success ); verify_rule< uint16_be::string< 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint16_be::string< 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x01\x67\x45", result_type::local_failure ); verify_rule< uint16_le::string< 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::local_failure ); verify_rule< uint16_le::string< 0x0123, 0x4567 > >( __LINE__, __FILE__, "\x23\x01\x67\x45", result_type::success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/uint32_general.cpp���������������������������������������������������0000664�0000000�0000000�00000042275�14264072506�0021645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/uint32.hpp> namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< uint32_be::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x01\x02", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x71\x72", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x01\x02", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x71\x72", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x01\x02\x03", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x01\x02\x03", result_type::local_failure ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::local_failure ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x01\x02\x03\x55", result_type::success ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::success ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x01\x02\x03\x55", result_type::success ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::success ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x01\x02\x03\x55\x44", result_type::success, 1 ); verify_rule< uint32_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44", result_type::success, 1 ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x01\x02\x03\x55\x44", result_type::success, 1 ); verify_rule< uint32_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44", result_type::success, 1 ); verify_rule< uint32_be::mask_not_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11", result_type::local_failure ); verify_rule< uint32_be::mask_not_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_be::mask_not_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::success ); verify_rule< uint32_le::mask_not_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::success ); verify_rule< uint32_le::mask_not_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint32_be::mask_not_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\xf3\x11\x11\x11", result_type::success ); verify_rule< uint32_be::mask_not_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\xf1\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_le::mask_not_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\xf3", result_type::success ); verify_rule< uint32_le::mask_not_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\xf1", result_type::local_failure ); verify_rule< uint32_be::mask_not_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_be::mask_not_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::success ); verify_rule< uint32_le::mask_not_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::success ); verify_rule< uint32_le::mask_not_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint32_be::mask_not_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x52\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_be::mask_not_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x56\x77\x77\x77", result_type::success ); verify_rule< uint32_le::mask_not_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x52", result_type::local_failure ); verify_rule< uint32_le::mask_not_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x56", result_type::success ); verify_rule< uint32_be::mask_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::success ); verify_rule< uint32_be::mask_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint32_le::mask_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_le::mask_one< 0xffffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::success ); verify_rule< uint32_be::mask_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\xf3\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_be::mask_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\xf1\x11\x11\x11", result_type::success ); verify_rule< uint32_le::mask_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\xf3", result_type::local_failure ); verify_rule< uint32_le::mask_one< 0x0fffffff, 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\xf1", result_type::success ); verify_rule< uint32_be::mask_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::success ); verify_rule< uint32_be::mask_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint32_le::mask_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_le::mask_range< 0xffffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::success ); verify_rule< uint32_be::mask_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x52\x77\x77\x77", result_type::success ); verify_rule< uint32_be::mask_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x56\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_le::mask_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x52", result_type::success ); verify_rule< uint32_le::mask_range< 0x0fffffff, 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x56", result_type::local_failure ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x34\x56\x78", result_type::local_failure ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x03\x45\x67\x89", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x67\x89\x12\x34", result_type::local_failure ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x67\x45\x23\x01", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x89\x67\x45\x03", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x34\x12\x89\x67", result_type::local_failure ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x02\x34\x56\x78", result_type::local_failure ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x03\x45\x67\x89", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x67\x89\x01\x02", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x67\x45\x23\x01", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x89\x67\x45\x03", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x02\x01\x89\x67", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xff0fffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x50\x02\x02", result_type::success ); verify_rule< uint32_be::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x50\x02\x02", result_type::local_failure ); verify_rule< uint32_le::mask_ranges< 0xff0fffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x02\x50\x02", result_type::success ); verify_rule< uint32_le::mask_ranges< 0xffffffff, 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x02\x50\x02", result_type::local_failure ); verify_rule< uint32_be::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x01\x23\x32\x10\x45\x67\x76\x54", result_type::success ); verify_rule< uint32_be::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x01\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint32_le::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x01\x23\x32\x10\x45\x67\x76\x54", result_type::local_failure ); verify_rule< uint32_le::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x01\x54\x76\x67\x45", result_type::success ); verify_rule< uint32_be::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x81\x23\x32\x10\x45\x67\x76\x54", result_type::local_failure ); verify_rule< uint32_be::mask_string< 0x4fffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x81\x23\x32\x10\x45\x67\x76\x54", result_type::success ); verify_rule< uint32_le::mask_string< 0xffffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x81\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint32_le::mask_string< 0x4fffffff, 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x81\x54\x76\x67\x45", result_type::success ); verify_rule< uint32_be::not_one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_be::not_one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::success ); verify_rule< uint32_le::not_one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::success ); verify_rule< uint32_le::not_one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint32_be::not_range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_be::not_range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::success ); verify_rule< uint32_le::not_range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::success ); verify_rule< uint32_le::not_range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint32_be::one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::success ); verify_rule< uint32_be::one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint32_le::one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11", result_type::local_failure ); verify_rule< uint32_le::one< 0x01111111, 0x02222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x01", result_type::success ); verify_rule< uint32_be::range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::success ); verify_rule< uint32_be::range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint32_le::range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77", result_type::local_failure ); verify_rule< uint32_le::range< 0x01000000, 0x04000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x02", result_type::success ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x02\x34\x56\x78", result_type::local_failure ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x03\x45\x67\x89", result_type::success ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x67\x89\x12\x34", result_type::local_failure ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x67\x45\x23\x01", result_type::success ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x89\x67\x45\x03", result_type::success ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444 > >( __LINE__, __FILE__, "\x34\x12\x89\x67", result_type::local_failure ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x01\x23\x45\x67", result_type::success ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x02\x34\x56\x78", result_type::local_failure ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x03\x45\x67\x89", result_type::success ); verify_rule< uint32_be::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x67\x89\x01\x02", result_type::success ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x67\x45\x23\x01", result_type::success ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x89\x67\x45\x03", result_type::success ); verify_rule< uint32_le::ranges< 0x01111111, 0x02222222, 0x03333333, 0x04444444, 0x67890102 > >( __LINE__, __FILE__, "\x02\x01\x89\x67", result_type::success ); verify_rule< uint32_be::string< 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x01\x23\x32\x10\x45\x67\x76\x54", result_type::success ); verify_rule< uint32_be::string< 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x01\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint32_le::string< 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x01\x23\x32\x10\x45\x67\x76\x54", result_type::local_failure ); verify_rule< uint32_le::string< 0x01233210, 0x45677654 > >( __LINE__, __FILE__, "\x10\x32\x23\x01\x54\x76\x67\x45", result_type::success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/uint64_general.cpp���������������������������������������������������0000664�0000000�0000000�00000053333�14264072506�0021647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/uint64.hpp> namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< uint64_be::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22", result_type::local_failure ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22", result_type::local_failure ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22\x11", result_type::success ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22\x11", result_type::success ); verify_rule< uint64_be::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22\x11\x99", result_type::success, 1 ); verify_rule< uint64_le::any >( __LINE__, __FILE__, "\x71\x72\x03\x55\x44\x33\x22\x11\x99", result_type::success, 1 ); verify_rule< uint64_be::mask_not_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_be::mask_not_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_be::mask_not_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::success ); verify_rule< uint64_le::mask_not_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_le::mask_not_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint64_be::mask_not_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\xf3\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_be::mask_not_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\xf1\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_le::mask_not_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\xf3", result_type::success ); verify_rule< uint64_le::mask_not_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\xf1", result_type::local_failure ); verify_rule< uint64_be::mask_not_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_be::mask_not_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::success ); verify_rule< uint64_le::mask_not_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_le::mask_not_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint64_be::mask_not_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x52\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_be::mask_not_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x56\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_le::mask_not_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x52", result_type::local_failure ); verify_rule< uint64_le::mask_not_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x56", result_type::success ); verify_rule< uint64_be::mask_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_be::mask_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint64_le::mask_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_le::mask_one< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::success ); verify_rule< uint64_be::mask_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\xf3\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_be::mask_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\xf1\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_le::mask_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\xf3", result_type::local_failure ); verify_rule< uint64_le::mask_one< 0x0fffffffffffffff, 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\xf1", result_type::success ); verify_rule< uint64_be::mask_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_be::mask_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint64_le::mask_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_le::mask_range< 0xffffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::success ); verify_rule< uint64_be::mask_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x52\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_be::mask_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x56\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_le::mask_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x52", result_type::success ); verify_rule< uint64_le::mask_range< 0x0fffffffffffffff, 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x56", result_type::local_failure ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x01\x23\x45\x67\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x02\x34\x56\x78\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x03\x45\x67\x89\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x67\x89\x12\x34\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x67\x45\x23\x01", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x89\x67\x45\x03", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x34\x12\x89\x67", result_type::local_failure ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x01\x23\x45\x67\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x02\x34\x56\x78\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x03\x45\x67\x89\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x67\x89\x01\x02\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x67\x45\x23\x01", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x89\x67\x45\x03", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x02\x01\x89\x67", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xff0fffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x02\x50\x02\x02\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x02\x50\x02\x02\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_le::mask_ranges< 0xff0fffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x02\x02\x50\x02", result_type::success ); verify_rule< uint64_le::mask_ranges< 0xffffffffffffffff, 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x02\x02\x50\x02", result_type::local_failure ); verify_rule< uint64_be::mask_string< 0xffffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x01\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::success ); verify_rule< uint64_be::mask_string< 0xffffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x01\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint64_le::mask_string< 0xffffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x01\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::local_failure ); verify_rule< uint64_le::mask_string< 0xffffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x01\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::success ); verify_rule< uint64_be::mask_string< 0x4fffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x81\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::success ); verify_rule< uint64_be::mask_string< 0x8fffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x81\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::local_failure ); verify_rule< uint64_le::mask_string< 0x4fffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x81\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::success ); verify_rule< uint64_le::mask_string< 0x8fffffffffffffff, 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x81\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint64_be::not_one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_be::not_one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::success ); verify_rule< uint64_le::not_one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_le::not_one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint64_be::not_range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_be::not_range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::success ); verify_rule< uint64_le::not_range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_le::not_range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint64_be::one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::success ); verify_rule< uint64_be::one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::local_failure ); verify_rule< uint64_le::one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x01\x11\x11\x11\x11\x11\x11\x11", result_type::local_failure ); verify_rule< uint64_le::one< 0x0111111111111111, 0x0222222222222222 > >( __LINE__, __FILE__, "\x11\x11\x11\x11\x11\x11\x11\x01", result_type::success ); verify_rule< uint64_be::range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::success ); verify_rule< uint64_be::range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::local_failure ); verify_rule< uint64_le::range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x02\x77\x77\x77\x77\x77\x77\x77", result_type::local_failure ); verify_rule< uint64_le::range< 0x0100000000000000, 0x0400000000000000 > >( __LINE__, __FILE__, "\x77\x77\x77\x77\x77\x77\x77\x02", result_type::success ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x01\x23\x45\x67\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x02\x34\x56\x78\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x03\x45\x67\x89\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x67\x89\x12\x34\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x67\x45\x23\x01", result_type::success ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x89\x67\x45\x03", result_type::success ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x34\x12\x89\x67", result_type::local_failure ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x01\x23\x45\x67\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x02\x34\x56\x78\x99\x99\x99\x99", result_type::local_failure ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x03\x45\x67\x89\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_be::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x67\x89\x01\x02\x99\x99\x99\x99", result_type::success ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x67\x45\x23\x01", result_type::success ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x78\x56\x34\x02", result_type::local_failure ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x89\x67\x45\x03", result_type::success ); verify_rule< uint64_le::ranges< 0x0111111111111111, 0x0222222222222222, 0x0333333333333333, 0x0444444444444444, 0x6789010299999999 > >( __LINE__, __FILE__, "\x99\x99\x99\x99\x02\x01\x89\x67", result_type::success ); verify_rule< uint64_be::string< 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x01\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::success ); verify_rule< uint64_be::string< 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x01\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::local_failure ); verify_rule< uint64_le::string< 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\x01\x23\x32\x10\xde\xad\xca\xfe\x45\x67\x76\x54\xba\xff\xb1\xff", result_type::local_failure ); verify_rule< uint64_le::string< 0x01233210deadcafe, 0x45677654baffb1ff > >( __LINE__, __FILE__, "\xfe\xca\xad\xde\x10\x32\x23\x01\xff\xb1\xff\xba\x54\x76\x67\x45", result_type::success ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/uint8_general.cpp����������������������������������������������������0000664�0000000�0000000�00000061524�14264072506�0021566�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2018-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/uint8.hpp> namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< uint8::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); for( int i = -100; i < 200; ++i ) { verify_char< uint8::any >( __LINE__, __FILE__, char( i ), true ); } verify_rule< uint8::mask_not_one< 0xff, 0x01, 0x02 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_not_one< 0xff, 0x01, 0x02 > >( __LINE__, __FILE__, "\x03", result_type::success ); verify_rule< uint8::mask_not_one< 0xff, 0x01, 0x02 > >( __LINE__, __FILE__, "\x03\x01", result_type::success, 1 ); verify_rule< uint8::mask_not_one< 0xff, 0x01, 0x10 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_not_one< 0xff, 0x01, 0x10 > >( __LINE__, __FILE__, "\x01\x01", result_type::local_failure ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x02 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x02 > >( __LINE__, __FILE__, "\x03", result_type::success ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x02 > >( __LINE__, __FILE__, "\x03\x01", result_type::success, 1 ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x01", result_type::success ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x01\x01", result_type::success, 1 ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x31", result_type::success ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x31\x01", result_type::success, 1 ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x11", result_type::local_failure ); verify_rule< uint8::mask_not_one< 0xf0, 0x01, 0x10 > >( __LINE__, __FILE__, "\x11\x01", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x0f", result_type::success ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x0f\x0f", result_type::success, 1 ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x30", result_type::success ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x30\x30", result_type::success, 1 ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x10", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x10\x10", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x2f", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xff, 0x10, 0x2f > >( __LINE__, __FILE__, "\x2f\x2f", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x0f", result_type::success ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x0f\x0f", result_type::success, 1 ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x40\x40", result_type::success, 1 ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x30", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x30\x30", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x31", result_type::local_failure ); verify_rule< uint8::mask_not_range< 0xf0, 0x10, 0x30 > >( __LINE__, __FILE__, "\x31\x31", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x10\x10", result_type::success, 1 ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x40\x40", result_type::success, 1 ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x20", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x20\x20", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x11", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x11\x10", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_one< 0xff, 0x10, 0x40 > >( __LINE__, __FILE__, "\x3f\x10", result_type::local_failure ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\x10\x10", result_type::success, 1 ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\xf0", result_type::success ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\xf0\x10", result_type::success, 1 ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\x54", result_type::success ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x14 > >( __LINE__, __FILE__, "\x54\x54", result_type::success, 1 ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x40 > >( __LINE__, __FILE__, "\x11", result_type::local_failure ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x40 > >( __LINE__, __FILE__, "\x11\x10", result_type::local_failure ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x40 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_one< 0x1f, 0x10, 0x40 > >( __LINE__, __FILE__, "\x3f\x10", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x16", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x16\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x17", result_type::success ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x17\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x27", result_type::success ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x27\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x28", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x28\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\x7f", result_type::local_failure ); verify_rule< uint8::mask_range< 0xff, 0x17, 0x27 > >( __LINE__, __FILE__, "\xff", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x91", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x16", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x16\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x96", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x96\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x17", result_type::success ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x17\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x57", result_type::success ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x57\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x27", result_type::success ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x27\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x67", result_type::success ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x67\x17", result_type::success, 1 ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x28", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x28\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x68", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x68\x17", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\x7f", result_type::local_failure ); verify_rule< uint8::mask_range< 0xbf, 0x17, 0x27 > >( __LINE__, __FILE__, "\xff", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x18", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x48", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x94", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x17", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\x47", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\xf0", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47 > >( __LINE__, __FILE__, "\xf1", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x18", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x48", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x94", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x17", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\x47", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\xf0", result_type::success ); verify_rule< uint8::mask_ranges< 0xff, 0x10, 0x17, 0x40, 0x47, 0xf0 > >( __LINE__, __FILE__, "\xf1", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x18", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x48", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x94", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x11", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41 > >( __LINE__, __FILE__, "\x47", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x18", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x3f", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x48", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x94", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x11", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x47", result_type::local_failure ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x73", result_type::success ); verify_rule< uint8::mask_ranges< 0x73, 0x10, 0x11, 0x40, 0x41, 0x73 > >( __LINE__, __FILE__, "\x72", result_type::local_failure ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10", result_type::local_failure ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20", result_type::local_failure ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20\x30", result_type::success ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20\x30\x10", result_type::success, 1 ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x11\x22\x33", result_type::success ); verify_rule< uint8::mask_string< 0xf0, 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x1f\x2f\x3f", result_type::success ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x10", result_type::local_failure ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x20", result_type::local_failure ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x20\x02", result_type::local_failure ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x02", result_type::success ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x02\x20", result_type::success, 1 ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x11", result_type::success ); verify_rule< uint8::not_one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x1f", result_type::success ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x0f", result_type::success ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x21", result_type::success ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x10", result_type::local_failure ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x17", result_type::local_failure ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x20", result_type::local_failure ); verify_rule< uint8::not_range< 0x10, 0x20 > >( __LINE__, __FILE__, "\xab", result_type::success ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x21", result_type::local_failure ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x17", result_type::local_failure ); verify_rule< uint8::one< 0x10, 0x20 > >( __LINE__, __FILE__, "\x20", result_type::success ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x21", result_type::local_failure ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x17", result_type::success ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\x20", result_type::success ); verify_rule< uint8::range< 0x10, 0x20 > >( __LINE__, __FILE__, "\xab", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x21", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x2f", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x41", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x8f", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x16", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x1f", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x20", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x30", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x36", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x3f", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40 > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x0f", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x21", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x2f", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x41", result_type::local_failure ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x8f", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x10", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x16", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x1f", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x20", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x30", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x36", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x3f", result_type::success ); verify_rule< uint8::ranges< 0x10, 0x20, 0x30, 0x40, 0x8f > >( __LINE__, __FILE__, "\x40", result_type::success ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10", result_type::local_failure ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20", result_type::local_failure ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20\x30", result_type::success ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x10\x20\x30\x10", result_type::success, 1 ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x11\x22\x33", result_type::local_failure ); verify_rule< uint8::string< 0x10, 0x20, 0x30 > >( __LINE__, __FILE__, "\x1f\x21\x31", result_type::local_failure ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/utf16_general.cpp����������������������������������������������������0000664�0000000�0000000�00000024511�14264072506�0021457�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2015-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/utf16.hpp> namespace TAO_PEGTL_NAMESPACE { namespace { std::string u16s( const char16_t u ) { return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } std::string u16s_be( const char16_t v ) { const std::uint16_t u = internal::h_to_be( std::uint16_t( v ) ); return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } std::string u16s_le( const char16_t v ) { const std::uint16_t u = internal::h_to_le( std::uint16_t( v ) ); return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } } // namespace void test_utf16() { verify_rule< utf16::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, "\xff", result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 1 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, " ", result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x00ff ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0100 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0fff ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x1000 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd900 ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xde00 ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xfffe ) + " ", result_type::success, 1 ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xffff ) + " ", result_type::success, 2 ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd7ff ) + u16s( 0xdfff ), result_type::success, 2 ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdc00 ) + u16s( 0xdfff ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0x0020 ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xff20 ), result_type::local_failure ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdf00 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdfff ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdc00 ), result_type::success ); verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdfff ), result_type::success ); verify_rule< utf16::one< 0x20 > >( __LINE__, __FILE__, u16s( 0x20 ), result_type::success ); verify_rule< utf16::one< 0x20ac > >( __LINE__, __FILE__, u16s( 0x20ac ), result_type::success ); verify_rule< utf16::one< 0x10437 > >( __LINE__, __FILE__, u16s( 0xd801 ) + u16s( 0xdc37 ), result_type::success ); verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfeff ), result_type::success ); verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfffe ), result_type::local_failure ); verify_rule< utf16::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s( 0x20 ) + u16s( 0x20ac ) + u16s( 0xd801 ) + u16s( 0xdc37 ) + u16s( 0x20 ), result_type::success, 2 ); } void test_utf16_be() { verify_rule< utf16_be::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, "\xff", result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 1 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, " ", result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x00ff ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0100 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0fff ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x1000 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd900 ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xde00 ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xfffe ) + " ", result_type::success, 1 ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xffff ) + " ", result_type::success, 2 ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd7ff ) + u16s_be( 0xdfff ), result_type::success, 2 ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdc00 ) + u16s_be( 0xdfff ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0x0020 ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xff20 ), result_type::local_failure ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdf00 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdfff ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdc00 ), result_type::success ); verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdfff ), result_type::success ); verify_rule< utf16_be::one< 0x20 > >( __LINE__, __FILE__, u16s_be( 0x20 ), result_type::success ); verify_rule< utf16_be::one< 0x20ac > >( __LINE__, __FILE__, u16s_be( 0x20ac ), result_type::success ); verify_rule< utf16_be::one< 0x10437 > >( __LINE__, __FILE__, u16s_be( 0xd801 ) + u16s_be( 0xdc37 ), result_type::success ); verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfeff ), result_type::success ); verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfffe ), result_type::local_failure ); verify_rule< utf16_be::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s_be( 0x20 ) + u16s_be( 0x20ac ) + u16s_be( 0xd801 ) + u16s_be( 0xdc37 ) + u16s_be( 0x20 ), result_type::success, 2 ); } void test_utf16_le() { verify_rule< utf16_le::any >( __LINE__, __FILE__, "", result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, "\x01", result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, "\xff", result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 1 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, " ", result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x00ff ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0100 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0fff ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x1000 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd900 ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xde00 ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xfffe ) + " ", result_type::success, 1 ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xffff ) + " ", result_type::success, 2 ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd7ff ) + u16s_le( 0xdfff ), result_type::success, 2 ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdc00 ) + u16s_le( 0xdfff ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0x0020 ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xff20 ), result_type::local_failure ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdf00 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdfff ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdc00 ), result_type::success ); verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdfff ), result_type::success ); verify_rule< utf16_le::one< 0x20 > >( __LINE__, __FILE__, u16s_le( 0x20 ), result_type::success ); verify_rule< utf16_le::one< 0x20ac > >( __LINE__, __FILE__, u16s_le( 0x20ac ), result_type::success ); verify_rule< utf16_le::one< 0x10437 > >( __LINE__, __FILE__, u16s_le( 0xd801 ) + u16s_le( 0xdc37 ), result_type::success ); verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfeff ), result_type::success ); verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfffe ), result_type::local_failure ); verify_rule< utf16_le::string< 0x20, 0x20ac, 0x10437 > >( __LINE__, __FILE__, u16s_le( 0x20 ) + u16s_le( 0x20ac ) + u16s_le( 0xd801 ) + u16s_le( 0xdc37 ) + u16s_le( 0x20 ), result_type::success, 2 ); } void unit_test() { test_utf16(); test_utf16_be(); test_utf16_le(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/utf32_general.cpp����������������������������������������������������0000664�0000000�0000000�00000020524�14264072506�0021455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_rule.hpp" #include <tao/pegtl/contrib/utf32.hpp> namespace TAO_PEGTL_NAMESPACE { namespace { std::string u32s( const char32_t u ) { return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } std::string u32s_be( const char32_t v ) { const std::uint32_t u = internal::h_to_be( std::uint32_t( v ) ); return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } std::string u32s_le( const char32_t v ) { const std::uint32_t u = internal::h_to_le( std::uint32_t( v ) ); return std::string( reinterpret_cast< const char* >( &u ), sizeof( u ) ); } } // namespace void test_utf32() { verify_rule< utf32::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 ); verify_rule< utf32::any >( __LINE__, __FILE__, "\xff\xff", result_type::local_failure, 2 ); verify_rule< utf32::any >( __LINE__, __FILE__, "\xff\xff\xff", result_type::local_failure, 3 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0 ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 1 ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x00ff ) + " ", result_type::success, 1 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x0100 ) + " ", result_type::success, 2 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x0fff ) + " ", result_type::success, 3 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x1000 ) + " ", result_type::success, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xd7ff ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xe000 ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xfffe ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xffff ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x100000 ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x10fffe ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x10ffff ), result_type::success, 0 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xd800 ), result_type::local_failure, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xd900 ), result_type::local_failure, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xdc00 ), result_type::local_failure, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0xdfff ), result_type::local_failure, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x110000 ), result_type::local_failure, 4 ); verify_rule< utf32::any >( __LINE__, __FILE__, u32s( 0x110000 ) + u32s( 0 ), result_type::local_failure, 8 ); verify_rule< utf32::one< 0x20 > >( __LINE__, __FILE__, u32s( 0x20 ), result_type::success, 0 ); verify_rule< utf32::one< 0x20ac > >( __LINE__, __FILE__, u32s( 0x20ac ), result_type::success, 0 ); verify_rule< utf32::one< 0x10fedc > >( __LINE__, __FILE__, u32s( 0x10fedc ), result_type::success, 0 ); verify_rule< utf32::string< 0x20, 0x20ac, 0x10fedc > >( __LINE__, __FILE__, u32s( 0x20 ) + u32s( 0x20ac ) + u32s( 0x10fedc ) + u32s( 0x20 ), result_type::success, 4 ); } void test_utf32_be() { verify_rule< utf32_be::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, "\xff\xff", result_type::local_failure, 2 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, "\xff\xff\xff", result_type::local_failure, 3 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0 ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 1 ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x00ff ) + " ", result_type::success, 1 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x0100 ) + " ", result_type::success, 2 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x0fff ) + " ", result_type::success, 3 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x1000 ) + " ", result_type::success, 4 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0xfffe ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0xffff ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x100000 ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x10fffe ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x10ffff ), result_type::success, 0 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x110000 ), result_type::local_failure, 4 ); verify_rule< utf32_be::any >( __LINE__, __FILE__, u32s_be( 0x110000 ) + u32s_be( 0 ), result_type::local_failure, 8 ); verify_rule< utf32_be::one< 0x20 > >( __LINE__, __FILE__, u32s_be( 0x20 ), result_type::success, 0 ); verify_rule< utf32_be::one< 0x20ac > >( __LINE__, __FILE__, u32s_be( 0x20ac ), result_type::success, 0 ); verify_rule< utf32_be::one< 0x10fedc > >( __LINE__, __FILE__, u32s_be( 0x10fedc ), result_type::success, 0 ); verify_rule< utf32_be::string< 0x20, 0x20ac, 0x10fedc > >( __LINE__, __FILE__, u32s_be( 0x20 ) + u32s_be( 0x20ac ) + u32s_be( 0x10fedc ) + u32s_be( 0x20 ), result_type::success, 4 ); } void test_utf32_le() { verify_rule< utf32_le::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, "\xff\xff", result_type::local_failure, 2 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, "\xff\xff\xff", result_type::local_failure, 3 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0 ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 1 ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x00ff ) + " ", result_type::success, 1 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x0100 ) + " ", result_type::success, 2 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x0fff ) + " ", result_type::success, 3 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x1000 ) + " ", result_type::success, 4 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0xfffe ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0xffff ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x100000 ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x10fffe ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x10ffff ), result_type::success, 0 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x110000 ), result_type::local_failure, 4 ); verify_rule< utf32_le::any >( __LINE__, __FILE__, u32s_le( 0x110000 ) + u32s_le( 0 ), result_type::local_failure, 8 ); verify_rule< utf32_le::one< 0x20 > >( __LINE__, __FILE__, u32s_le( 0x20 ), result_type::success, 0 ); verify_rule< utf32_le::one< 0x20ac > >( __LINE__, __FILE__, u32s_le( 0x20ac ), result_type::success, 0 ); verify_rule< utf32_le::one< 0x10fedc > >( __LINE__, __FILE__, u32s_le( 0x10fedc ), result_type::success, 0 ); verify_rule< utf32_le::string< 0x20, 0x20ac, 0x10fedc > >( __LINE__, __FILE__, u32s_le( 0x20 ) + u32s_le( 0x20ac ) + u32s_le( 0x10fedc ) + u32s_le( 0x20 ), result_type::success, 4 ); } void unit_test() { test_utf32(); test_utf32_be(); test_utf32_le(); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/utf8_general.cpp�����������������������������������������������������0000664�0000000�0000000�00000052531�14264072506�0021403�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include "test.hpp" #include "verify_char.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { void unit_test() { verify_rule< utf8::any >( __LINE__, __FILE__, "", result_type::local_failure, 0 ); for( int i = -100; i < 200; ++i ) { verify_char< utf8::any >( __LINE__, __FILE__, char( i ), ( i & 0x80 ) == 0 ); } verify_rule< utf8::any >( __LINE__, __FILE__, "\x30", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc2\xa2", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe2\x82\xac", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x90\x8d\x88", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x30\x20", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc2\xa2\x20", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe2\x82\xac\x20", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x90\x8d\x88\x20", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x01", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x3c", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x7f", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x01", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x3c", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x7f", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x01\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x3c\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc0\x7f\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x01\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x3c\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x7f\x81", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc3\x81", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc3\x81\x81", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc3\x81\x81\x81", result_type::success, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xc3\x81\x81\x81\x81", result_type::success, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x80\x80\x80", result_type::success, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\x80\x80\x80\x80", result_type::success, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xbf", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xbf\xbf", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xbf\xbf\xbf", result_type::success, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xbf\xbf\xbf\xbf", result_type::success, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xff", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xff\xff", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xff\xff\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xcf\xff\xff\xff\xff", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\x0f", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\x0f", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\x0f", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\xff", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\xff", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe0\xff\xff", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xe7\x80\x80\x80\x80", result_type::success, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xbf\xbf", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xbf\xbf\xbf", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xbf\xbf\xbf\xbf", result_type::success, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\x80\xff", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\x80\xff\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\x80\xff\xff\xff", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xef\xff\xff\xff\xff", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x80\x80\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\x80\x80\xff", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\xc0\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\xc0\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x80\xf0\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\x80\xf0\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf5\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf6\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf7\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf4\x9f\xbf\xbf", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf1\x80\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf2\x80\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf3\x80\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf4\x80\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\xa0\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x90\x80\x80", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf4\x8f\xbf\xbf", result_type::success, 0 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf1\x80\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf2\x80\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf3\x80\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf4\x80\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\xa0\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf0\x90\x80\x80\x80", result_type::success, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xff\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfe\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xfc\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8 ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\xf8\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80 ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x80\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81 ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x81\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f", result_type::local_failure, 1 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f ", result_type::local_failure, 8 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80", result_type::local_failure, 2 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80", result_type::local_failure, 3 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80\x80", result_type::local_failure, 4 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80\x80\x80", result_type::local_failure, 5 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80\x80\x80\x80", result_type::local_failure, 6 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80\x80\x80\x80\x80", result_type::local_failure, 7 ); verify_rule< utf8::any >( __LINE__, __FILE__, "\x8f\x80\x80\x80\x80\x80\x80\x80", result_type::local_failure, 8 ); verify_rule< utf8::one< 0x20 > >( __LINE__, __FILE__, "\x20", result_type::success, 0 ); verify_rule< utf8::one< 0xa2 > >( __LINE__, __FILE__, "\xc2\xa2", result_type::success, 0 ); verify_rule< utf8::one< 0x20ac > >( __LINE__, __FILE__, "\xe2\x82\xac", result_type::success, 0 ); verify_rule< utf8::one< 0x10348 > >( __LINE__, __FILE__, "\xf0\x90\x8d\x88", result_type::success, 0 ); verify_rule< utf8::bom >( __LINE__, __FILE__, "\xef\xbb\xbf", result_type::success, 0 ); verify_rule< utf8::bom >( __LINE__, __FILE__, "\xef\xbb\xbf ", result_type::success, 1 ); verify_rule< utf8::string< 0x20, 0xa2, 0x20ac, 0x10348 > >( __LINE__, __FILE__, "\x20\xc2\xa2\xe2\x82\xac\xf0\x90\x8d\x88\x20", result_type::success, 1 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_char.hpp������������������������������������������������������0000664�0000000�0000000�00000001643�14264072506�0021324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_CHAR_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_CHAR_HPP #include <cstdlib> #include <string> #include "result_type.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Rule > void verify_char( const std::size_t line, const char* file, const char data, const result_type result ) { verify_rule< Rule >( line, file, std::string( std::size_t( 1 ), data ), result, ( result == result_type::success ) ? 0 : 1 ); } template< typename Rule > void verify_char( const std::size_t line, const char* file, const char data, const bool result ) { verify_char< Rule >( line, file, data, result ? result_type::success : result_type::local_failure ); } } // namespace TAO_PEGTL_NAMESPACE #endif ���������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_file.hpp������������������������������������������������������0000664�0000000�0000000�00000007550�14264072506�0021331�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_FILE_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_FILE_HPP #include <tao/pegtl.hpp> #include "test.hpp" #if defined( _MSC_VER ) #define TAO_PEGTL_TEST_FILENAME u"src/test/pegtl/file_äöü𝄞_data.txt" #else #define TAO_PEGTL_TEST_FILENAME "src/test/pegtl/file_äöü𝄞_data.txt" #endif namespace TAO_PEGTL_NAMESPACE { struct file_content : seq< TAO_PEGTL_STRING( "dummy content" ), eol, discard > {}; struct file_grammar : seq< rep_min_max< 11, 11, file_content >, eof > {}; template< typename Rule > struct file_action {}; template<> struct file_action< eof > { static void apply0( bool& flag ) { flag = true; } }; template< typename Rule > struct file_control : normal< Rule > {}; template<> struct file_control< eof > : normal< eof > { template< typename ParseInput > static void success( const ParseInput& /*unused*/, bool& flag ) { flag = true; } }; template< typename T > void verify_file() { #if defined( __cpp_exceptions ) { try { T in( "src/test/pegtl/no_such_file.txt" ); TAO_PEGTL_TEST_UNREACHABLE; // LCOV_EXCL_LINE } catch( const internal::filesystem::filesystem_error& ) { } } #endif { T in( "src/test/pegtl/file_data.txt" ); TAO_PEGTL_TEST_ASSERT( in.source() == "src/test/pegtl/file_data.txt" ); TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in ) ); TAO_PEGTL_TEST_ASSERT( in.source() == "src/test/pegtl/file_data.txt" ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = true; TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in, flag ) ); TAO_PEGTL_TEST_ASSERT( flag == true ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in, flag ) ); TAO_PEGTL_TEST_ASSERT( flag == false ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; const bool result = parse< file_grammar, file_action >( in, flag ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( flag == true ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; const bool result = parse< file_grammar, nothing, file_control >( in, flag ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( flag == true ); } const char* foo = "foo"; const memory_input m( foo, foo + 3, foo ); { T in( TAO_PEGTL_TEST_FILENAME ); TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in ) ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = true; TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in, flag ) ); TAO_PEGTL_TEST_ASSERT( flag == true ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in, flag ) ); TAO_PEGTL_TEST_ASSERT( flag == false ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; const bool result = parse_nested< file_grammar, file_action >( m, in, flag ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( flag == true ); } { T in( TAO_PEGTL_TEST_FILENAME ); bool flag = false; const bool result = parse_nested< file_grammar, nothing, file_control >( m, in, flag ); TAO_PEGTL_TEST_ASSERT( result ); TAO_PEGTL_TEST_ASSERT( flag == true ); } } } // namespace TAO_PEGTL_NAMESPACE #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_ifmt.hpp������������������������������������������������������0000664�0000000�0000000�00000005012�14264072506�0021340�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_IFMT_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_IFMT_HPP #include <tao/pegtl.hpp> #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename, typename, typename > class S > void verify_ifmt( const result_type failure = result_type::local_failure ) { verify_analyze< S< eof, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< S< eof, eof, any > >( __LINE__, __FILE__, false, false ); verify_analyze< S< eof, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< S< eof, any, any > >( __LINE__, __FILE__, true, false ); verify_analyze< S< any, eof, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< S< any, eof, any > >( __LINE__, __FILE__, true, false ); verify_analyze< S< any, any, eof > >( __LINE__, __FILE__, false, false ); verify_analyze< S< any, any, any > >( __LINE__, __FILE__, true, false ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "", failure, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "b", failure, 1 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "c", result_type::success, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ac", failure, 2 ); #if defined( __cpp_exceptions ) verify_rule< must< S< one< 'a' >, one< 'b' >, one< 'c' > > > >( __LINE__, __FILE__, "", result_type::global_failure, 0 ); verify_rule< must< S< one< 'a' >, one< 'b' >, one< 'c' > > > >( __LINE__, __FILE__, "a", result_type::global_failure, 0 ); verify_rule< must< S< one< 'a' >, one< 'b' >, one< 'c' > > > >( __LINE__, __FILE__, "ac", result_type::global_failure, 1 ); verify_rule< must< S< one< 'a' >, one< 'b' >, one< 'c' > > > >( __LINE__, __FILE__, "b", result_type::global_failure, 1 ); verify_rule< must< S< one< 'a' >, one< 'b' >, seq< one< 'c' >, one< 'd' > > > > >( __LINE__, __FILE__, "c", result_type::global_failure, 0 ); verify_rule< must< S< one< 'a' >, one< 'b' >, seq< one< 'c' >, one< 'd' > > > > >( __LINE__, __FILE__, "cc", result_type::global_failure, 1 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_impl.hpp������������������������������������������������������0000664�0000000�0000000�00000004064�14264072506�0021350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_IMPL_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_IMPL_HPP #include <cstddef> #include <cstdlib> #include <iostream> #include <string> #include <tao/pegtl/apply_mode.hpp> #include <tao/pegtl/normal.hpp> #include <tao/pegtl/rewind_mode.hpp> #include "result_type.hpp" #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Rule, template< typename... > class Action, typename ParseInput > result_type verify_impl_two( ParseInput& in ) { #if defined( __cpp_exceptions ) try { if( normal< Rule >::template match< apply_mode::action, rewind_mode::required, Action, normal >( in ) ) { return result_type::success; } return result_type::local_failure; } catch( const std::exception& ) { return result_type::global_failure; } // LCOV_EXCL_START catch( ... ) { TAO_PEGTL_TEST_UNREACHABLE; } // LCOV_EXCL_STOP #else if( normal< Rule >::template match< apply_mode::action, rewind_mode::required, Action, normal >( in ) ) { return result_type::success; } return result_type::local_failure; #endif } template< typename Rule, template< typename... > class Action, typename ParseInput > void verify_impl_one( const std::size_t line, const char* file, const std::string& data, ParseInput& in, const result_type expected, const std::size_t remain ) { const result_type received = verify_impl_two< Rule, Action >( in ); if( ( received == expected ) && ( ( received == result_type::global_failure ) || ( in.size( 999999999 ) == remain ) ) ) { return; } TAO_PEGTL_TEST_FAILED( "input data [ '" << data << "' ] result received/expected [ " << received << " / " << expected << " ] remain received/expected [ " << in.size( 999999999 ) << " / " << remain << " ]" ); // LCOV_EXCL_LINE } } // namespace TAO_PEGTL_NAMESPACE #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_meta.hpp������������������������������������������������������0000664�0000000�0000000�00000002765�14264072506�0021343�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_META_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_META_HPP #include <type_traits> #include <tao/pegtl/type_list.hpp> #include <tao/pegtl/contrib/analyze.hpp> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Name, typename Rule, typename... Rules > void verify_meta() { static_assert( std::is_same_v< typename Name::rule_t, Rule > ); static_assert( std::is_same_v< typename Name::subs_t, type_list< Rules... > > ); } template< typename Rule > void verify_analyze( const unsigned line, const char* file, const bool expect_consume, const bool expect_problems ) { internal::analyze_cycles< Rule > a( -1 ); const auto problems = a.problems(); TAO_PEGTL_TEST_ASSERT( problems == analyze< Rule >( -1 ) ); const bool has_problems = ( problems != 0 ); const bool does_consume = a.template consumes< Rule >(); if( has_problems != expect_problems ) { TAO_PEGTL_TEST_FAILED( "analyze -- problems received/expected [ " << has_problems << " / " << expect_problems << " ]" ); // LCOV_EXCL_LINE } if( does_consume != expect_consume ) { TAO_PEGTL_TEST_FAILED( "analyze -- consumes received/expected [ " << does_consume << " / " << expect_consume << " ]" ); // LCOV_EXCL_LINE } } } // namespace TAO_PEGTL_NAMESPACE #endif �����������tao-pegtl-3.2.7/src/test/pegtl/verify_rule.hpp������������������������������������������������������0000664�0000000�0000000�00000006475�14264072506�0021366�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_RULE_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_RULE_HPP #include <cstdlib> #include <string> #include <tao/pegtl/eol.hpp> #include <tao/pegtl/memory_input.hpp> #include <tao/pegtl/tracking_mode.hpp> #include <tao/pegtl/type_list.hpp> #include "result_type.hpp" #include "verify_impl.hpp" namespace TAO_PEGTL_NAMESPACE { template< typename Rule > struct verify_action_impl { template< typename ActionInput, typename... States > static void apply( const ActionInput& /*unused*/, States&&... /*unused*/ ) {} }; template< typename Rule > struct verify_action_impl0 { template< typename... States > static void apply0( States&&... /*unused*/ ) {} }; template< typename Rule, typename Eol = eol::lf_crlf > void verify_rule( const std::size_t line, const char* file, const std::string& data, const result_type expected, int remain = -1 ) { if( remain < 0 ) { remain = ( expected == result_type::success ) ? 0 : int( data.size() ); } { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, nothing >( line, file, data, in, expected, remain ); memory_input< tracking_mode::lazy, Eol > i2( data.data(), data.data() + data.size(), file ); verify_impl_one< Rule, nothing >( line, file, data, i2, expected, remain ); } { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, verify_action_impl >( line, file, data, in, expected, remain ); memory_input< tracking_mode::lazy, Eol > i2( data.data(), data.data() + data.size(), file ); verify_impl_one< Rule, verify_action_impl >( line, file, data, i2, expected, remain ); } { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, verify_action_impl0 >( line, file, data, in, expected, remain ); memory_input< tracking_mode::lazy, Eol > i2( data.data(), data.data() + data.size(), file ); verify_impl_one< Rule, verify_action_impl0 >( line, file, data, i2, expected, remain ); } } template< typename Rule, typename Eol = eol::lf_crlf > void verify_only( const std::size_t line, const char* file, const std::string& data, const result_type expected, const std::size_t remain ) { { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, nothing >( line, file, data, in, expected, remain ); } { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, verify_action_impl >( line, file, data, in, expected, remain ); } { memory_input< tracking_mode::eager, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 1 ); verify_impl_one< Rule, verify_action_impl0 >( line, file, data, in, expected, remain ); } } } // namespace TAO_PEGTL_NAMESPACE #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/verify_seqs.hpp������������������������������������������������������0000664�0000000�0000000�00000011172�14264072506�0021360�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2014-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #ifndef TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_SEQS_HPP #define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_SEQS_HPP #include <tao/pegtl.hpp> #include "verify_meta.hpp" #include "verify_rule.hpp" namespace TAO_PEGTL_NAMESPACE { template< template< typename... > class S > void verify_seqs( const result_type failure = result_type::local_failure ) { verify_analyze< S< any > >( __LINE__, __FILE__, true, false ); verify_analyze< S< eof > >( __LINE__, __FILE__, false, false ); verify_analyze< S< any, eof > >( __LINE__, __FILE__, true, false ); verify_analyze< S< opt< any >, eof > >( __LINE__, __FILE__, false, false ); verify_rule< S<> >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< S<> >( __LINE__, __FILE__, "a", result_type::success, 1 ); verify_rule< S< eof > >( __LINE__, __FILE__, "", result_type::success, 0 ); verify_rule< S< eof > >( __LINE__, __FILE__, "a", failure, 1 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "", failure, 0 ); verify_rule< S< one< 'c' >, eof > >( __LINE__, __FILE__, "", failure, 0 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "c", result_type::success, 0 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "a", failure, 1 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "b", failure, 1 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "cc", result_type::success, 1 ); verify_rule< S< one< 'c' > > >( __LINE__, __FILE__, "bc", failure, 2 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", failure, 0 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", failure, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", failure, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "c", failure, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abb", result_type::success, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abc", result_type::success, 1 ); verify_rule< S< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "", failure, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "a", failure, 1 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "ab", failure, 2 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abc", result_type::success, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' >, eof > >( __LINE__, __FILE__, "abc", result_type::success, 0 ); verify_rule< S< one< 'a' >, one< 'b' >, one< 'c' > > >( __LINE__, __FILE__, "abcd", result_type::success, 1 ); #if defined( __cpp_exceptions ) verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::global_failure, 0 ); verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::global_failure, 0 ); verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "b", result_type::global_failure, 1 ); verify_rule< must< S< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "c", result_type::global_failure, 1 ); 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 ); #endif } } // namespace TAO_PEGTL_NAMESPACE #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tao-pegtl-3.2.7/src/test/pegtl/visit.cpp������������������������������������������������������������0000664�0000000�0000000�00000001301�14264072506�0020143�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (c) 2020-2022 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ #include <string> #include <vector> #include "test.hpp" namespace TAO_PEGTL_NAMESPACE { using grammar = seq< plus< alpha >, star< sor< space, digit > > >; template< typename Name > struct visitor { static void visit( std::vector< std::string >& names ) { names.emplace_back( demangle< Name >() ); } }; void unit_test() { std::vector< std::string > names; visit< grammar, visitor >( names ); TAO_PEGTL_TEST_ASSERT( names.size() == 7 ); } } // namespace TAO_PEGTL_NAMESPACE #include "main.hpp" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������