diff --git a/CMakeLists.txt b/CMakeLists.txt index 53ae505bca6492f407a895ef267322bf738454cf..9a397a2753ce5021034007d171cf3d41c74db138 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,15 +176,19 @@ include_directories(${PASTIS_SOURCE_DIR}/packages/rang/include) # CLI11 include_directories(${PASTIS_SOURCE_DIR}/packages/CLI11/include) +# PGETL +include_directories(${PASTIS_SOURCE_DIR}/packages/PEGTL/include/tao) + # Pastis src add_subdirectory(src) include_directories(src) include_directories(src/algebra) +include_directories(src/language) include_directories(src/mesh) include_directories(src/output) -include_directories(src/utils) include_directories(src/scheme) +include_directories(src/utils) # Pastis generated sources include_directories(${PASTIS_BINARY_DIR}/src/utils) @@ -273,6 +277,7 @@ target_link_libraries( pastis PastisMesh PastisUtils + PastisLanguage kokkos ${PARMETIS_LIBRARIES} ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES} diff --git a/packages/PEGTL/.appveyor.yml b/packages/PEGTL/.appveyor.yml new file mode 100644 index 0000000000000000000000000000000000000000..db3d921f8ab9b7d44c989e54009b60cc46189e75 --- /dev/null +++ b/packages/PEGTL/.appveyor.yml @@ -0,0 +1,64 @@ +version: '{branch}-{build}' + +os: +- Visual Studio 2015 + +configuration: +- Release +- Debug + +environment: + matrix: + - GENERATOR: Visual Studio 14 2015 + + - GENERATOR: Visual Studio 14 2015 Win64 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + GENERATOR: Visual Studio 15 2017 + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + GENERATOR: Visual Studio 15 2017 Win64 + + - GENERATOR: MinGW Makefiles + BINDIR: C:\MinGW\bin + + - GENERATOR: MinGW Makefiles + COMPILER: MinGW 5 + BINDIR: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin + + - GENERATOR: MinGW Makefiles + COMPILER: MinGW 6 + BINDIR: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin + + - GENERATOR: MinGW Makefiles + COMPILER: MinGW 6 + BINDIR: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + GENERATOR: Visual Studio 15 2017 + CONAN_VISUAL_VERSIONS: 15 + PYTHON: "C:\\Python27" + PYTHON_VERSION: "2.7.8" + PYTHON_ARCH: "32" + CONAN: TRUE + +init: [] + +install: +- if defined CONAN (pip.exe install -U conan conan-package-tools) +- if defined CONAN (conan profile new default --detect) + +before_build: +- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" (del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets") +- if defined BINDIR (set "PATH=%BINDIR%;%PATH:C:\Program Files\Git\usr\bin;=%") +- md build +- cd build +- cmake -Wno-dev --config "%CONFIGURATION%" -G "%GENERATOR%" .. + +build_script: +- cmake --build . --config "%CONFIGURATION%" + +test_script: +- ctest -C "%CONFIGURATION%" --output-on-failure +- if defined CONAN (cd ..) +- if defined CONAN (python .conan/build.py) diff --git a/packages/PEGTL/.clang-format b/packages/PEGTL/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..f72eb4c2543b33a54eef70788962c11bfd5047b2 --- /dev/null +++ b/packages/PEGTL/.clang-format @@ -0,0 +1,71 @@ +# the official .clang-format style for https://github.com/taocpp +# +# clang-format-5.0 -i -style=file $(find . -name '[^.]*.[hc]pp') + +Language: Cpp +Standard: Cpp11 + +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: true +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum : true + AfterFunction : true + AfterNamespace : true + AfterStruct : true + AfterUnion : true + BeforeCatch : true + BeforeElse : true + IndentBraces : false +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: false +BreakStringLiterals: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 3 +ContinuationIndentWidth: 3 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: true +IndentWidth: 3 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +PointerAlignment: Left +ReflowComments: false +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Never +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: true +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: true +SpacesInSquareBrackets: true +TabWidth: 8 +UseTab: Never diff --git a/packages/PEGTL/.conan/build.py b/packages/PEGTL/.conan/build.py new file mode 100644 index 0000000000000000000000000000000000000000..4c23b8385aadbfd0b0d2186ca561d618fb85ace7 --- /dev/null +++ b/packages/PEGTL/.conan/build.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import re +from cpt.packager import ConanMultiPackager +from cpt.ci_manager import CIManager +from cpt.printer import Printer + + +class BuilderSettings(object): + @property + def username(self): + """ Set taocpp as package's owner + """ + return os.getenv("CONAN_USERNAME", "taocpp") + + @property + def upload(self): + """ Set taocpp repository to be used on upload. + The upload server address could be customized by env var + CONAN_UPLOAD. If not defined, the method will check the branch name. + Only master or CONAN_STABLE_BRANCH_PATTERN will be accepted. + The master branch will be pushed to testing channel, because it does + not match the stable pattern. Otherwise it will upload to stable + channel. + """ + if os.getenv("CONAN_UPLOAD", None) is not None: + return os.getenv("CONAN_UPLOAD") + + printer = Printer(None) + ci_manager = CIManager(printer) + branch = ci_manager.get_branch() + + patterns = [r"v?\d+\.\d+\.\d+-.*", self.stable_branch_pattern] + for pattern in patterns: + prog = re.compile(pattern) + if branch and prog.match(branch): + return "https://api.bintray.com/conan/taocpp/public-conan" + + @property + def upload_only_when_stable(self): + """ Force to upload when running over tag branch + """ + return os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True) + + @property + def stable_branch_pattern(self): + """ Only upload the package the branch name is like a tag + """ + return os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"\d+\.\d+\.\d+") + + @property + def reference(self): + """ Read project version from CMake file to create Conan referece + """ + pattern = re.compile(r"project \(pegtl VERSION (\d+\.\d+\.\d+) LANGUAGES CXX\)") + version = None + with open('CMakeLists.txt') as file: + for line in file: + result = pattern.match(line) + if result: + version = result.group(1) + if not version: + raise Exception("Could not find version in CMakeLists.txt") + return os.getenv("CONAN_REFERENCE", "pegtl/{}@taocpp/stable".format(version)) + +if __name__ == "__main__": + settings = BuilderSettings() + builder = ConanMultiPackager( + reference=settings.reference, + username=settings.username, + upload=settings.upload, + upload_only_when_stable=settings.upload_only_when_stable, + stable_branch_pattern=settings.stable_branch_pattern, + test_folder=os.path.join(".conan", "test_package")) + builder.add() + builder.run() diff --git a/packages/PEGTL/.conan/test_package/CMakeLists.txt b/packages/PEGTL/.conan/test_package/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..33bc5e0f830aeb3734ed72fb5193122762bdcd1b --- /dev/null +++ b/packages/PEGTL/.conan/test_package/CMakeLists.txt @@ -0,0 +1,12 @@ +project(test_package CXX) +cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) + +set(CMAKE_VERBOSE_MAKEFILE TRUE) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +find_package(PEGTL REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} taocpp::pegtl) diff --git a/packages/PEGTL/.conan/test_package/conanfile.py b/packages/PEGTL/.conan/test_package/conanfile.py new file mode 100644 index 0000000000000000000000000000000000000000..fc54c64a69fc0741aaf61ad6c3c62e08ffdbaf4c --- /dev/null +++ b/packages/PEGTL/.conan/test_package/conanfile.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from conans import ConanFile, CMake, tools, RunEnvironment +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + with tools.environment_append(RunEnvironment(self).vars): + bin_path = os.path.join("bin", "test_package") + self.run('{} "2 + 3 * -7" "(2 + 3) * 7"'.format(bin_path)) diff --git a/packages/PEGTL/.conan/test_package/test_package.cpp b/packages/PEGTL/.conan/test_package/test_package.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5404848ed21370871602f85175f08f4e91468fac --- /dev/null +++ b/packages/PEGTL/.conan/test_package/test_package.cpp @@ -0,0 +1,366 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <functional> +#include <iostream> +#include <map> +#include <sstream> +#include <vector> + +#include <tao/pegtl.hpp> + +// Include the analyze function that checks +// a grammar for possible infinite cycles. + +#include <tao/pegtl/analyze.hpp> + +namespace pegtl = tao::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.insert( { name, { p, f } } ); + } + + const std::map< std::string, op >& ops() const + { + return m_ops; + } + + private: + std::map< std::string, op > m_ops; + }; + + // Here the actual grammar starts. + + using namespace tao::pegtl; // NOLINT + + // Comments are introduced by a '#' and proceed to the end-of-line/file. + + struct comment + : if_must< 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 analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& in, const operators& b, stacks& s ) + { + // 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 Input > + static bool match( Input& 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 preceeded 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 + : if_must< 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 singlar expression). + + struct expression + : list< atomic, infix, ignored > + { + }; + + // The top-level grammar allows one expression and then expects eof. + + struct grammar + : must< 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 must derive from + // pegtl::nothing (or, alternatively, define an action that does something + // sensible for all rules for which no specialisation exists). + + template< typename Rule > + struct action + : pegtl::nothing< Rule > + { + }; + + // 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 Input > + static void apply( const Input& in, const operators& /*unused*/, stacks& s ) + { + std::stringstream ss; + ss.str( 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 ) +{ + // Check the grammar for some possible issues. + + pegtl::analyze< calculator::grammar >(); + + // 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 ); + pegtl::parse< calculator::grammar, calculator::action >( in, b, s ); + + // ...and print the respective results to std::cout. + + std::cout << s.finish() << std::endl; + } + return 0; +} diff --git a/packages/PEGTL/.doozer.json b/packages/PEGTL/.doozer.json new file mode 100644 index 0000000000000000000000000000000000000000..9f877bda3fcaced4aa5444ea441d4e4af99220bc --- /dev/null +++ b/packages/PEGTL/.doozer.json @@ -0,0 +1,74 @@ +{ + "targets": { + "jessie-i386": { + "buildenv": "jessie-i386", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "trusty-i386": { + "buildenv": "trusty-i386", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "trusty-amd64": { + "buildenv": "trusty-amd64", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "xenial-i386": { + "buildenv": "xenial-i386", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "xenial-amd64": { + "buildenv": "xenial-amd64", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "xenial-armhf": { + "buildenv": "xenial-armhf", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "xenial-arm64": { + "buildenv": "xenial-arm64", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + }, + "fedora24-x86_64-g++": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=g++ cmake ..", "make -j", "ctest --output-on-failure"] + }, + "fedora24-x86_64-clang": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=clang++ cmake ..", "make -j", "ctest --output-on-failure"] + }, + "fedora24-x86_64-g++-debug": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=g++ cmake -DCMAKE_BUILD_TYPE=Debug ..", "make -j", "ctest --output-on-failure"] + }, + "fedora24-x86_64-clang-debug": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Debug ..", "make -j", "ctest --output-on-failure"] + }, + "fedora24-x86_64-g++-release": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=g++ cmake -DCMAKE_BUILD_TYPE=Release ..", "make -j", "ctest --output-on-failure"] + }, + "fedora24-x86_64-clang-release": { + "buildenv": "fedora24-x86_64", + "builddeps": ["cmake", "make", "clang"], + "buildcmd": ["mkdir build", "cd build", "CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release ..", "make -j", "ctest --output-on-failure"] + }, + "osx": { + "buildenv": "osx", + "builddeps": ["build-essential"], + "buildcmd": "make -j" + } + } +} diff --git a/packages/PEGTL/.gitignore b/packages/PEGTL/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..454bccb45403f97193099b1a478996608a632508 --- /dev/null +++ b/packages/PEGTL/.gitignore @@ -0,0 +1,3 @@ +*~ +build +private diff --git a/packages/PEGTL/.gitrepo b/packages/PEGTL/.gitrepo new file mode 100644 index 0000000000000000000000000000000000000000..13c3bc8b31205195acd81b7e81e3089b28b88ba3 --- /dev/null +++ b/packages/PEGTL/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = git@github.com:taocpp/PEGTL.git + branch = master + commit = 0a5ab8c8efb421f00d9b0e3f593c971991888a97 + parent = 8a3664d89a9a662c3dfdd402d573b3618ebbdbbf + cmdver = 0.3.1 diff --git a/packages/PEGTL/.travis.yml b/packages/PEGTL/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..f4e899c9cb167fb3f2d99c1beba0e02b47d50356 --- /dev/null +++ b/packages/PEGTL/.travis.yml @@ -0,0 +1,453 @@ +language: generic +os: linux +dist: trusty + +matrix: + include: + - compiler: gcc + env: + - CXX=g++-4.8 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.9'] + env: + - CXX=g++-4.9 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-5'] + env: + - CXX=g++-5 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-5'] + env: + - CXX=g++-5 + - CXXSTD=-std=c++14 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-6'] + env: + - CXX=g++-6 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-7'] + env: + - CXX=g++-7 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-7'] + env: + - CXX=g++-7 + - CXXSTD=-std=c++17 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8'] + env: + - CXX=g++-8 + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8'] + env: + - CXX=g++-8 + - CXXSTD=-std=c++17 + + - dist: precise + compiler: clang + env: + - CXX=clang++ + + - compiler: clang + addons: + apt: + packages: ['clang-3.5'] + env: + - CXX=clang++-3.5 + + - compiler: clang + addons: + apt: + packages: ['clang-3.6'] + env: + - CXX=clang++-3.6 + + - dist: precise + compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7'] + packages: ['clang-3.7'] + env: + - CXX=clang++-3.7 + + - compiler: clang + addons: + apt: + packages: ['clang-3.8'] + env: + - CXX=clang++-3.8 + + - compiler: clang + addons: + apt: + packages: ['clang-3.9'] + env: + - CXX=clang++-3.9 + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-4.0'] + packages: ['clang-4.0'] + env: + - CXX=clang++-4.0 + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-4.0'] + packages: ['clang-4.0'] + env: + - CXX=clang++-4.0 + - CXXSTD=-std=c++14 + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0'] + packages: ['clang-5.0'] + env: + - CXX=clang++-5.0 + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0'] + env: + - CXX=clang++-6.0 + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0'] + env: + - CXX=clang++-6.0 + - CPPFLAGS=-fms-extensions + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0'] + env: + - CXX=clang++-6.0 + - CXXSTD=-std=c++17 + + - os: osx + osx_image: xcode6.4 + compiler: clang + env: + - CXX=clang++ + + - os: osx + osx_image: xcode7.3 + compiler: clang + env: + - CXX=clang++ + + - os: osx + osx_image: xcode8.3 + compiler: clang + env: + - CXX=clang++ + + - os: osx + osx_image: xcode9.4 + compiler: clang + env: + - CXX=clang++ + + - language: android + jdk: openjdk8 + android: + components: + - tools + - platform-tools + - build-tools-23.0.3 + - extra-android-support + - extra-android-m2repository + - android-19 + - sys-img-armeabi-v7a-android-19 + # Unfortunately travis uses the old android sdk tool instead of the new sdkmanager. + # In this deprecated android sdk tool there is no ndk-bundle or cmake package! + licenses: + - '.+' + before_install: + # Install NDK and cmake via android sdkmanager. Unfortunately to acknowledge the licenses + # takes a while. Looks like the "echo y" solution is not working. Needs improvement! + - export TERM=dumb + - touch ~/.android/repositories.cfg + - mkdir -p /usr/local/android-sdk/licenses + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > /usr/local/android-sdk/licenses/android-sdk-license + - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> /usr/local/android-sdk/licenses/android-sdk-license + # Install NDK and cmake via android sdkmanager. + - /usr/local/android-sdk/tools/bin/sdkmanager --update > /dev/null + - echo "y" | /usr/local/android-sdk/tools/bin/sdkmanager "emulator" "ndk-bundle" "cmake;3.6.4111459" > /dev/null + before_script: + - export TERM=dumb + - export _NO_CHECK_SIGNATURE=true + - echo no | /usr/local/android-sdk/tools/bin/avdmanager create avd -n test -k "system-images;android-19;default;armeabi-v7a" + - /usr/local/android-sdk/emulator/emulator -avd test -no-audio -no-window -dns-server 8.8.8.8 & + - android-wait-for-emulator || android-wait-for-emulator + - /usr/local/android-sdk/platform-tools/adb shell input keyevent 82 & + script: + # Using the ninja build command. Is much faster then make build command. + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake -G'Android Gradle - Ninja' -DANDROID_ABI=armeabi-v7a -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/usr/local/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-19 -DCMAKE_MAKE_PROGRAM=/usr/local/android-sdk/cmake/3.6.4111459/bin/ninja -DPEGTL_BUILD_EXAMPLES=OFF + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake --build . --target all + - /usr/local/android-sdk/cmake/3.6.4111459/bin/ctest --output-on-failure + + + - language: android + jdk: openjdk8 + android: + components: + - tools + - platform-tools + - build-tools-23.0.3 + - extra-android-support + - extra-android-m2repository + - android-22 + - sys-img-armeabi-v7a-android-22 + # Unfortunately travis uses the old android sdk tool instead of the new sdkmanager. + # In this deprecated android sdk tool there is no ndk-bundle or cmake package! + licenses: + - '.+' + before_install: + # Install NDK and cmake via android sdkmanager. Unfortunately to acknowledge the licenses + # takes a while. Looks like the "echo y" solution is not working. Needs improvement! + - export TERM=dumb + - touch ~/.android/repositories.cfg + - mkdir -p /usr/local/android-sdk/licenses + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > /usr/local/android-sdk/licenses/android-sdk-license + - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> /usr/local/android-sdk/licenses/android-sdk-license + # Install NDK and cmake via android sdkmanager. + - /usr/local/android-sdk/tools/bin/sdkmanager --update > /dev/null + - echo "y" | /usr/local/android-sdk/tools/bin/sdkmanager "emulator" "ndk-bundle" "cmake;3.6.4111459" > /dev/null + before_script: + - export TERM=dumb + - export _NO_CHECK_SIGNATURE=true + - echo no | /usr/local/android-sdk/tools/bin/avdmanager create avd -n test -k "system-images;android-22;default;armeabi-v7a" + - /usr/local/android-sdk/emulator/emulator -avd test -no-audio -no-window -dns-server 8.8.8.8 & + - android-wait-for-emulator || android-wait-for-emulator + - /usr/local/android-sdk/platform-tools/adb shell input keyevent 82 & + script: + # Using the ninja build command. Is much faster then make build command. + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake -G'Android Gradle - Ninja' -DANDROID_ABI=armeabi-v7a -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/usr/local/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-22 -DCMAKE_MAKE_PROGRAM=/usr/local/android-sdk/cmake/3.6.4111459/bin/ninja -DPEGTL_BUILD_EXAMPLES=OFF + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake --build . --target all + - /usr/local/android-sdk/cmake/3.6.4111459/bin/ctest --output-on-failure + + - language: android + jdk: openjdk8 + android: + components: + - tools + - platform-tools + - build-tools-23.0.3 + - extra-android-support + - extra-android-m2repository + - android-23 + # Unfortunately travis uses the old android sdk tool instead of the new sdkmanager. + # In this deprecated android sdk tool there is no ndk-bundle or cmake package! + licenses: + - '.+' + before_install: + # Install NDK and cmake via android sdkmanager. Unfortunately to acknowledge the licenses + # takes a while. Looks like the "echo y" solution is not working. Needs improvement! + - export TERM=dumb + - touch ~/.android/repositories.cfg + - mkdir -p /usr/local/android-sdk/licenses + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > /usr/local/android-sdk/licenses/android-sdk-license + - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> /usr/local/android-sdk/licenses/android-sdk-license + # Install NDK and cmake via android sdkmanager. + - /usr/local/android-sdk/tools/bin/sdkmanager --update > /dev/null + - echo "y" | /usr/local/android-sdk/tools/bin/sdkmanager "emulator" "ndk-bundle" "cmake;3.6.4111459" "system-images;android-23;google_apis;armeabi-v7a" > /dev/null + before_script: + - export TERM=dumb + - export _NO_CHECK_SIGNATURE=true + - echo no | /usr/local/android-sdk/tools/bin/avdmanager create avd -n test -k "system-images;android-23;google_apis;armeabi-v7a" + - /usr/local/android-sdk/emulator/emulator -avd test -no-audio -no-window -dns-server 8.8.8.8 & + - android-wait-for-emulator || android-wait-for-emulator + - /usr/local/android-sdk/platform-tools/adb shell input keyevent 82 & + script: + # Using the ninja build command. Is much faster then make build command. + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake -G'Android Gradle - Ninja' -DANDROID_ABI=armeabi-v7a -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/usr/local/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-23 -DCMAKE_MAKE_PROGRAM=/usr/local/android-sdk/cmake/3.6.4111459/bin/ninja -DPEGTL_BUILD_EXAMPLES=OFF + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake --build . --target all + - /usr/local/android-sdk/cmake/3.6.4111459/bin/ctest --output-on-failure + + - language: android + jdk: openjdk8 + android: + components: + - tools + - platform-tools + - build-tools-23.0.3 + - extra-android-support + - extra-android-m2repository + - android-24 + - sys-img-armeabi-v7a-android-24 + # Unfortunately travis uses the old android sdk tool instead of the new sdkmanager. + # In this deprecated android sdk tool there is no ndk-bundle or cmake package! + licenses: + - '.+' + before_install: + # Install NDK and cmake via android sdkmanager. Unfortunately to acknowledge the licenses + # takes a while. Looks like the "echo y" solution is not working. Needs improvement! + - export TERM=dumb + - touch ~/.android/repositories.cfg + - mkdir -p /usr/local/android-sdk/licenses + - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > /usr/local/android-sdk/licenses/android-sdk-license + - echo -e "\nd56f5187479451eabf01fb78af6dfcb131a6481e" >> /usr/local/android-sdk/licenses/android-sdk-license + # Install NDK and cmake via android sdkmanager. + - /usr/local/android-sdk/tools/bin/sdkmanager --update > /dev/null + - echo "y" | /usr/local/android-sdk/tools/bin/sdkmanager "emulator" "ndk-bundle" "cmake;3.6.4111459" > /dev/null + before_script: + - export TERM=dumb + - export _NO_CHECK_SIGNATURE=true + - echo no | /usr/local/android-sdk/tools/bin/avdmanager create avd -n test -k "system-images;android-24;default;armeabi-v7a" + - /usr/local/android-sdk/emulator/emulator -avd test -no-audio -no-window -dns-server 8.8.8.8 & + - android-wait-for-emulator || android-wait-for-emulator + - /usr/local/android-sdk/platform-tools/adb shell input keyevent 82 & + script: + # Using the ninja build command. Is much faster then make build command. + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake -G'Android Gradle - Ninja' -DANDROID_ABI=armeabi-v7a -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/usr/local/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-24 -DCMAKE_MAKE_PROGRAM=/usr/local/android-sdk/cmake/3.6.4111459/bin/ninja -DPEGTL_BUILD_EXAMPLES=OFF + - /usr/local/android-sdk/cmake/3.6.4111459/bin/cmake --build . --target all + - /usr/local/android-sdk/cmake/3.6.4111459/bin/ctest --output-on-failure + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-7'] + env: + - CXX=g++-7 + - CXXFLAGS="-O0 --coverage" + before_script: + - pip install --user cpp-coveralls + script: + - make -kj3 check + - coveralls --gcov gcov-7 --gcov-options '\-lp' --exclude src + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8'] + env: + - CXX=g++-8 + - CPPFLAGS="-fsanitize=undefined -fuse-ld=gold" + + - compiler: gcc + sudo: true + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8'] + env: + - CXX=g++-8 + - CPPFLAGS="-fsanitize=address -fuse-ld=gold" + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0'] + env: + - CXX=clang++-6.0 + - CPPFLAGS=-fsanitize=undefined + + - compiler: clang + sudo: true + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0'] + env: + - CXX=clang++-6.0 + - CPPFLAGS=-fsanitize=address + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8', 'valgrind'] + env: + - CXX=g++-8 + - SPECIAL=valgrind + script: + - make -kj3 valgrind + + - compiler: gcc + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-8', 'cppcheck'] + env: + - CXX=g++-8 + - SPECIAL=cppcheck + script: + - make -kj3 cppcheck + + - compiler: clang + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0', 'clang-tidy-6.0'] + env: + - CXX=clang++-6.0 + - CLANG_TIDY=clang-tidy-6.0 + script: + - "sed -i 's#TAO_PEGTL_NAMESPACE#pegtl#g' $(find . -name '*.[hc]pp')" + - make -kj3 clang-tidy + + - language: python + python: + - "3.6" + sudo: required + install: + - pip install conan conan-package-tools + env: + - CONAN_GCC_VERSIONS=7 + - CONAN_DOCKER_IMAGE=lasote/conangcc7 + script: + - python .conan/build.py + +script: + - $CXX --version + - make -j3 build/src/test/pegtl/tester + - build/src/test/pegtl/tester + - make -kj3 diff --git a/packages/PEGTL/CMakeLists.txt b/packages/PEGTL/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c355e7cfb804aa7da64055d1b24ebde39d40c781 --- /dev/null +++ b/packages/PEGTL/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required (VERSION 3.3.0 FATAL_ERROR) + +project (pegtl VERSION 2.7.1 LANGUAGES CXX) + +# 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 + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${PEGTL_INSTALL_INCLUDE_DIR}> +) + +# features required by the PEGTL +target_compile_features (pegtl INTERFACE + cxx_alias_templates + cxx_auto_type + cxx_constexpr + cxx_decltype + cxx_default_function_template_args + cxx_defaulted_functions + cxx_delegating_constructors + cxx_deleted_functions + cxx_explicit_conversions + cxx_generalized_initializers + cxx_inheriting_constructors + cxx_inline_namespaces + cxx_noexcept + cxx_nonstatic_member_init + cxx_nullptr + cxx_range_for + cxx_rvalue_references + cxx_static_assert + cxx_strong_enums + cxx_template_template_parameters + cxx_trailing_return_types + cxx_uniform_initialization + cxx_variadic_macros + cxx_variadic_templates +) + +# testing +enable_testing () +option (PEGTL_BUILD_TESTS "Build test programs" ON) +if (PEGTL_BUILD_TESTS) + add_subdirectory (src/test/pegtl) +endif () + +# examples +option (PEGTL_BUILD_EXAMPLES "Build example programs" ON) +if (PEGTL_BUILD_EXAMPLES) + add_subdirectory (src/example/pegtl) +endif () + +# 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 (DIRECTORY include/ DESTINATION ${PEGTL_INSTALL_INCLUDE_DIR}) +install (FILES LICENSE DESTINATION ${PEGTL_INSTALL_DOC_DIR}) diff --git a/packages/PEGTL/LICENSE b/packages/PEGTL/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..84bd84ac18dd866adf34571907f10682b4318a62 --- /dev/null +++ b/packages/PEGTL/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2007-2018 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. diff --git a/packages/PEGTL/Makefile b/packages/PEGTL/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..edf34b2f06fd9594a3ba757beefea4c6d54b88d5 --- /dev/null +++ b/packages/PEGTL/Makefile @@ -0,0 +1,94 @@ +# The Art of C++ +# Copyright (c) 2014-2018 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++11 (or newer) so +# that -stdlib=libc++ is not automatically added. + +ifeq ($(CXXSTD),) +CXXSTD := -std=c++11 +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) + +CLANG_TIDY ?= clang-tidy + +HEADERS := $(filter-out include/tao/pegtl/internal/endian_win.hpp include/tao/pegtl/internal/file_mapper_win32.hpp,$(shell find include -name '*.hpp')) $(filter-out src/test/pegtl/main.hpp,$(shell find src -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 + +build/%.valgrind: build/% + valgrind --error-exitcode=1 --leak-check=full $< + @touch $@ + +.PHONY: valgrind +valgrind: $(UNIT_TESTS:%=%.valgrind) + @echo "All $(words $(UNIT_TESTS)) valgrind tests passed." + +build/%.cppcheck: %.hpp + cppcheck --error-exitcode=1 --inconclusive --force --std=c++11 $< + @mkdir -p $(@D) + @touch $@ + +.PHONY: cppcheck +cppcheck: $(HEADERS:%.hpp=build/%.cppcheck) + @echo "All $(words $(HEADERS)) cppcheck tests passed." + +build/%.clang-tidy: % + $(CLANG_TIDY) -extra-arg "-Iinclude" -extra-arg "-std=c++11" -checks=*,-fuchsia-*,-google-runtime-references,-google-runtime-int,-google-readability-todo,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-hicpp-signed-bitwise,-modernize-raw-string-literal,-misc-sizeof-expression -warnings-as-errors=* $< 2>/dev/null + @mkdir -p $(@D) + @touch $@ + +.PHONY: clang-tidy +clang-tidy: $(HEADERS:%=build/%.clang-tidy) $(SOURCES:%=build/%.clang-tidy) + @echo "All $(words $(HEADERS) $(SOURCES)) clang-tidy tests passed." + +.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) $< -o $@ + +ifeq ($(findstring $(MAKECMDGOALS),clean),) +-include $(DEPENDS) +endif diff --git a/packages/PEGTL/README.md b/packages/PEGTL/README.md new file mode 100644 index 0000000000000000000000000000000000000000..150ea9e90b6c979b532c6413a37a875063c9c254 --- /dev/null +++ b/packages/PEGTL/README.md @@ -0,0 +1,133 @@ +# Welcome to the PEGTL + +[](https://github.com/taocpp/PEGTL/releases/latest) +[](https://bintray.com/taocpp/public-conan/pegtl%3Ataocpp/_latestVersion) +[](https://travis-ci.org/taocpp/PEGTL) +[](https://ci.appveyor.com/project/taocpp/PEGTL) +[](https://doozer.io/user/taocpp/PEGTL) +[](https://coveralls.io/github/taocpp/PEGTL) + +The Parsing Expression Grammar Template Library (PEGTL) is a zero-dependency C++11 header-only parser combinator library for creating parsers according to a [Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar) (PEG). + +## Documentation + +* [Version 2.x Documentation](doc/README.md) +* [Version 1.3 Documentation](https://github.com/taocpp/PEGTL/blob/1.3.x/doc/README.md) + +## 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: + +// integer ::= ( '+' / '-' )? digit+ + +// The same parsing rule implemented with the PEGTL: + +using namespace tao::pegtl; + +struct integer : seq< opt< one< '+', '-' > >, 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. + +* Windows + + * Visual Studio 2015 (x86, x64) + * Visual Studio 2017 (x86, x64) + * MinGW (i686), GCC 5.x + * MinGW-w64 (i686), GCC 5.x, 6.x + * MinGW-w64 (x86_64), GCC 6.x + +* Mac OS X / macOS (using libc++) + + * Mac OS X 10.10, Xcode 6.4 + * Mac OS X 10.11, Xcode 7.3 + * macOS 10.12, Xcode 8.3 + * macOS 10.13, Xcode 9.4 + +* Linux (using libstdc++) + + * Debian 8 (i386), GCC 4.9 + * Ubuntu 12.04 LTS (amd64), Clang 3.4, 3.7 + * Ubuntu 14.04 LTS (amd64), GCC 4.8, 4.9, 5.x, 6.x, 7.x, 8.x + * Ubuntu 14.04 LTS (amd64), Clang 3.5, 3.6, 3.8, 3.9, 4.x, 5.x, 6.x + * Ubuntu 14.04 LTS (i386, amd64), GCC 4.8 + * Ubuntu 16.04 LTS (i386, amd64, armhf, arm64), GCC 5.x + * Fedora 24 (x86_64), GCC 6.x + * Fedora 24 (x86_64), Clang 3.8 + +* Android + + * Android 4.4 "KitKat" (API level 19) + * Android 5.1 "Lollipop" (API level 22) + * Android 6.0 "Marshmellow" (API level 23) + * Android 7.0 "Nougat" (API level 24) + +Additionally, each commit is checked with GCC's and Clang's sanitizers, as well as [`valgrind`](http://valgrind.org/) +and [`clang-tidy`](http://clang.llvm.org/extra/clang-tidy/). 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. +For details see the [changelog](doc/Changelog.md). + +## Thank You + +* Christopher Diggins and the YARD parser for the general idea. +* George Makrydakis for the [inspiration](https://github.com/irrequietus/typestring) to `TAO_PEGTL_STRING`. +* Johannes Overmann for his invaluable [`streplace`](https://code.google.com/p/streplace/) command-line tool. +* Jörg-Christian Böhme for improving the Android CI build. +* Kai Wolf for help with CMake. +* Kenneth Geisshirt for Android compatibility and Android CI. +* Kuzma Shapran for EOL testing and fixes. +* Michael Becker for help with CMake. +* Paul Le Roux for CMake improvements and Conan support. +* Paulo Custodio for Windows-related fixes. +* Sam Hocevar for contributing Visual Studio 2015 compatibility. +* Stephan Beal for the bug reports, suggestions and discussions. +* Stuart Dootson for `mmap_input<>` support on Windows. +* Sven Johannsen for help with CMake. +* Zhihao Yuan for fixing several warnings when compiling with Visual Studio 2015. + +## Contact + +The PEGTL is part of [The Art of C++](https://taocpp.github.io/). + +For questions and suggestions regarding the PEGTL, success or failure stories, and any other kind of feedback, please feel free to contact the authors at `taocpp(at)icemx.net`. + +## License + +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-2018 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. diff --git a/packages/PEGTL/conanfile.py b/packages/PEGTL/conanfile.py new file mode 100644 index 0000000000000000000000000000000000000000..78036adcadb53acf82b3225121d3f9572481f68d --- /dev/null +++ b/packages/PEGTL/conanfile.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from conans import ConanFile, CMake + +class PEGTLConan(ConanFile): + name = "pegtl" + description = "C++11 header-only parser combinator library for creating PEG parsers" + homepage = "https://github.com/taocpp/PEGTL" + url = homepage + license = "MIT" + author = "taocpp@icemx.net" + exports = "LICENSE" + exports_sources = "include/*", "CMakeLists.txt" + generators = "cmake" + no_copy_source = True + + def build(self): + pass + + def package(self): + cmake = CMake(self) + cmake.definitions["PEGTL_BUILD_TESTS"] = "OFF" + cmake.definitions["PEGTL_BUILD_EXAMPLES"] = "OFF" + cmake.definitions["PEGTL_INSTALL_DOC_DIR"] = "licenses" + cmake.configure() + cmake.install() + + def package_id(self): + self.info.header_only() diff --git a/packages/PEGTL/doc/Actions-and-States.md b/packages/PEGTL/doc/Actions-and-States.md new file mode 100644 index 0000000000000000000000000000000000000000..0b114929781f4e136209fdf9f2c27b7108bf6e31 --- /dev/null +++ b/packages/PEGTL/doc/Actions-and-States.md @@ -0,0 +1,291 @@ +# Actions and States + +Parsing, i.e. matching an input with a grammar rule, by itself only indicates whether (a portion of) the input is valid according to the grammar. +In order to do something useful with the input, it is usually necessary to attach user-defined *actions* to one or more rules. +An action is *applied* whenever the rule to which it is attached succeeds. +Applying an action means that its static `apply()` or `apply0()`-method is called. +The first argument to an `apply()` method is always an object that represents the portion of the input consumed by the successful match of the rule. +An action's `apply()` or `apply0()`-method can either return `void`, or a `bool`. + +## Contents + +* [Actions](#actions) + * [Apply0](#apply0) + * [Apply](#apply) +* [States](#states) +* [Action Specialisation](#action-specialisation) +* [Changing Actions](#changing-actions) +* [Changing States](#changing-states) + * [No Switching](#no-switching) + * [Intrusive Switching](#intrusive-switching) + * [External Switching](#external-switching) +* [Legacy Actions](#legacy-actions) + +## Actions + +Actions are implemented as static `apply()` or `apply0()`-method of specialisations of custom class templates (which is not quite as difficult as it sounds). +First the default- or base-case of the action class template has to be defined: + +```c++ +template< typename Rule > +struct my_actions + : tao::pegtl::nothing< Rule > {}; +``` + +Inheriting from `tao::pegtl::nothing< Rule >` indicates to the PEGTL that no action is attached to `Rule`, i.e. that no `apply()` or `apply0()`-method should be called for successful matches of `Rule`. + +To attach an action to `Rule`, this class template has to be specialised for `Rule` with two important properties. + +1. The specialisation *must not* inherit from `tao::pegtl::nothing< Rule >`. + +2. An *appropriate* static `apply()` or `apply0()`-method has to be implemented. + +The PEGTL will auto-detect whether an action, i.e. a specialisation of an action class template, contains an appropriate `apply()` or `apply0()` function, and whether it returns `void` or `bool`. +It will fail to compile when both `apply()` and `apply0()` are found. + +### Apply0 + +In cases where the matched part of the input is not required, an action method named `apply0()` is implemented. +This allows for some optimisations compared to the `apply()` method which receives the matched input as first argument. + +```c++ +template<> +struct my_actions< tao::pegtl::plus< tao::pegtl::alpha > > +{ + static void apply0( /* all the states */ ) + { + // Called whenever a call to tao::pegtl::plus< tao::pegtl::alpha > + // in the grammar succeeds. + } + + // OR ALTERNATIVELY + + static bool apply0( /* all the states */ ) + { + // Called whenever a call to tao::pegtl::plus< tao::pegtl::alpha > + // in the grammar succeeds. + return // see below + } +} +``` + +When the return type is `bool`, the action can determine whether matching the rule to which it was attached, and which already returned with success, should be retro-actively considered a (local) failure. +For the overall parsing run, there is no difference between a rule or an attached action returning `false` (but of course the action is not called when the rule already returned `false`). +When an action returns `false`, the PEGTL takes care of rewinding the input to where it was when the rule to which the action was attached started its (successful) match (which is unlike rules' `match()` methods that have to take care of rewinding themselves). + +Note that 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` (remembering that actions are disabled within an `at<>` combinator). + +### Apply + +When the action method is called `apply()`, it receives a const-reference to an instance of an input class as first argument. + +```c++ +template<> +struct my_actions< tao::pegtl::plus< tao::pegtl::digit > > +{ + template< typename Input > + static void apply( const Input& in, /* all the states */ ) + { + // Called whenever a call to tao::pegtl::plus< tao::pegtl::digit > + // in the grammar succeeds. The argument named 'in' represents the + // matched part of the input. + } + + // OR ALTERNATIVELY + + template< typename Input > + static bool apply( const Input& in, /* all the states */ ) + { + // Called whenever a call to tao::pegtl::plus< tao::pegtl::digit > + // in the grammar succeeds. The argument named 'in' represents the + // matched part of the input. + return // see description for apply0() above + } +} +``` + +The exact type of the input class passed to an action's `apply()`-method is not specified. +It is currently 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 members. +The `Input` template parameter is set to the class of the input used at the point in the parsing run 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. + +```c++ +template< typename Input > +class action_input +{ +public: + using input_t = Input; + using iterator_t = typename Input::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; // { return std::string( begin(), end() ); } + + char peek_char( const std::size_t offset = 0 ) const noexcept; // { return begin()[ offset ]; } + unsigned char peek_byte( const std::size_t offset = 0 ) const noexcept; // As above with cast. + + pegtl::position position() const noexcept; // Not efficient with LAZY inputs. + + const Input& input() const noexcept; // The input from the parsing run. + + const iterator_t& iterator() const noexcept; +}; +``` + +Note that 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 the `apply()`-method**! + +When the original input has tracking mode `IMMEDIATE`, the `iterator_t` returned by `action_input::iterator()` will contain the `byte`, `line` and `byte_in_line` 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()` method, in the data structures built while parsing. + +## States + +In most applications, the actions also need some kind of data or user-defined (parser/action) *state* to operate on. +Since the `apply()` and `apply0()`-methods are `static`, they do not have an instance of the class of which they are a member function available for this purpose. +Therefore the *state(s)* are an arbitrary collection of objects that are + +* passed by the user as additional arguments to the [`parse()`-function](Inputs-and-Parsing.md#parse-function) that starts a parsing run, and then + +* passed by the PEGTL as additional arguments to all actions' `apply()` or `apply0()`-method. + +In other words, the additional arguments to the `apply()` and `apply0()`-method can be chosen freely, however **all** actions **must** accept the same argument list since they are **all** called with the same arguments. + +For example, in a practical grammar the example from above might use a second argument to store the parsed sequence of digits somewhere. + +```c++ +template<> struct my_actions< tao::pegtl::plus< tao::pegtl::digit > > +{ + template< typename Input > + static void apply( const Input& in, + std::vector< std::string >& digit_strings ) + { + digit_strings.push_back( in.string() ); + } +} +``` + +If we then assume that our grammar `my_grammar` contains the rule `tao::pegtl::plus< tao::pegtl::digit >` somewhere, we can use + +```c++ +const std::string parsed_data = ...; +std::vector< std::string > digit_strings; + +tao::pegtl::memory_input<> in( parsed_data, "data-source-name" ); +tao::pegtl::parse< my_grammar, my_actions >( in, digit_strings ); +``` + +to collect all `digit_strings` that were detected by the grammar, i.e. the vector will contain one string for every time that the `tao::pegtl::plus< tao::pegtl::digit >` rule was matched against the input. + +Since the `parse()`-functions are variadic function templates, an arbitrary sequence of state arguments can be used. + +## Action Specialisation + +The rule class for which the action class template is specialised *must* exactly match how the rule is defined and referenced in the grammar. +For example given the rule + +```c++ +struct foo : tao::pegtl::plus< tao::pegtl::one< '*' > > {}; +``` + +an action class template can be specialised for `foo` or for `tao::pegtl::one< '*' >`, but *not* for `tao::pegtl::plus< tao::pegtl::one< '*' > >` because that is not the rule class name whose `match()`-method is called. + +(The method is called on class `foo`, which happens to inherit `match()` from `tao::pegtl::plus< tao::pegtl::one< '*' > >`, however base classes are not taken into consideration by the C++ language when choosing a specialisation.) + +While it is possible to specialize for `tao::pegtl::one< '*' >` in the above rule, any such specialization would also match any other occurrence in the grammar. It is therefore best practice to *always* specialize for explicitly named top-level rules. + +To then use these actions in a parsing run, simply pass them as additional template parameter to one of the parser functions defined in `<tao/pegtl/parse.hpp>`. + +```c++ +tao::pegtl::parse< my_grammar, my_actions >( ... ); +``` + +## Changing Actions + +Within a grammar, the action class template can be changed, enabled or disabled using the `action<>`, `enable<>` and `disable<>` 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 within the grammar). + +```c++ +tao::pegtl::parse< my_grammar >( ... ); +tao::pegtl::parse< tao::pegtl::disable< my_grammar >, my_actions >( ... ); +``` + +Similarly the following two lines both start parsing `my_grammar` with `my_actions` (again with the caveat that something might change somewhere in the grammar). + +```c++ +tao::pegtl::parse< my_grammar, my_actions >( ... ); +tao::pegtl::parse< tao::pegtl::action< my_actions, my_grammar > >( ... ); +``` + +In other words, `enable<>` and `disable<>` behave just like `seq<>` but enable or disable the calling of actions. `action<>` changes the active action class template, which must be supplied as first template parameter to `action<>`. + +Note that `action<>` does *not* implicitly enable actions when they were previously explicitly disabled. + +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: + +```c++ +struct comment + : tao::pegtl::seq< tao::pegtl::one< '#' >, tao::pegtl::disable< cons_list > > {}; +``` + +This also allows using the same rules multiple times with different actions within the grammar. + +## Changing States + +Implementing a parser with the PEGTL consists of two main parts. + +1. The actual grammar that drives the parser. +2. The states and actions that "do something". + +For the second part, there are three distinct styles of how to manage the states and actions in non-trivial parsers. + +The **main issue** addressed by the switching styles is the **growing complexity** encountered when a single state argument to a parsing run must perform multiple different tasks, including the management of nested data structures. + +The way that this issue is addressed is by providing another tool for performing divide-and-conquer: A large state class with multiple tasks can be divided into + +- multiple smaller state classes that each take care of a single issue, +- one or more [control classes](Control-and-Debug.md) that switch between the states, +- using the C++ stack for nested structures (rather than manually managing a stack). + +The different styles can also be freely mixed within the same parser. + +### No Switching + +The "no switching style" consists of having one (or more) state-arguments that are passed to a parsing run and that are the arguments to all action's `apply0()`- and `apply()`-methods. + +For an example of how to build a generic JSON data structure with the "no switching style" see `src/example/pegtl/json_build_two.cpp`. + +### Intrusive Switching + +The `state<>` and `action<>` [meta combinators](Rule-Reference.md#meta-rules) can be used to hard-code state and actions switches in the grammar. + +In some cases a state object is required for the grammar itself, and in these cases embedding the state-switch into the grammar is recommended. + +### External Switching + +"External switching" is when the states and/or actions are switched from outside of the grammar by providing a specialised control class. + +For an example of how to build a generic JSON data structure with the "external switching style" see `src/example/pegtl/json_build_one.cpp`. + +The actual switching control classes are defined in `<tao/pegtl/contrib/changes.hpp>` and can be used as template for custom switching. + +## Legacy Actions + +See the [section on legacy-style action rules](Rule-Reference.md#action-rules). + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Changelog.md b/packages/PEGTL/doc/Changelog.md new file mode 100644 index 0000000000000000000000000000000000000000..06b7ff0fd4ed30b01bb38acfeb3ebd1d82a8fad5 --- /dev/null +++ b/packages/PEGTL/doc/Changelog.md @@ -0,0 +1,503 @@ +# Changelog + +## 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 function to `memory_input<>` to obtain the line around a position. +* Added function 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 + +* 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. +* 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()`-methods returning boolean values. +* Simplified implementation of [`raw_string`](Contrib-and-Examples.md#taopegtlcontribraw_stringhpp), the optional `Contents...` rules' `apply()`/`apply0()`-methods are now called with the original states. +* Fixed the tracer to work with `apply()`/`apply0()`-methods returning boolean values. (Thanks Joel Frederico) +* 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()`-method when a rule with an `apply()`-method 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 actions' `apply()`- or `apply0()`-methods to return a `bool` which is then used to determine overall success or failure of the rule to which such an action was attached. +* Added [`<tao/pegtl/contrib/parse_tree.hpp>`](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). + * A [**migration guide**](Migration-Guide.md#from-1y-to-2z) for porting applications from 1.y to 2.z is available. + * 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()` methods to [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()`-method 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<raw_string<...>::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` methods 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 method 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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Contrib-and-Examples.md b/packages/PEGTL/doc/Contrib-and-Examples.md new file mode 100644 index 0000000000000000000000000000000000000000..fc311f854efe6a17a3951e8dae68c54a39d5a14e --- /dev/null +++ b/packages/PEGTL/doc/Contrib-and-Examples.md @@ -0,0 +1,233 @@ +# 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 + +###### `<tao/pegtl/contrib/abnf.hpp>` + +* Core ABNF rules according to [RFC 5234, Appendix B](https://tools.ietf.org/html/rfc5234). +* Ready for production use. + +###### `<tao/pegtl/contrib/alphabet.hpp>` + +* Constants for ASCII letters. +* Shortens `string<'f','o','o'>` to `string<f,o,o>`. +* Ready for production use. + +###### `<tao/pegtl/contrib/changes.hpp>` + +* Control class components for [external switching style](Actions-and-States.md#external-switching). +* Ready for production use but might be changed in the future. + +###### `<tao/pegtl/contrib/counter.hpp>` + +* Control class for obtaining basic statistics from a parsing run, namely how often each rule + 1. was attempted to match, + 2. succeeded to match, + 3. failed to match. + +###### `<tao/pegtl/contrib/http.hpp>` + +* HTTP 1.1 grammar according to [RFC 7230](https://tools.ietf.org/html/rfc7230). +* Has been used successfully but is still considered experimental. + +###### `<tao/pegtl/contrib/integer.hpp>` + +* Grammars and actions for PEGTL-input-to-integer conversions. + +###### `<tao/pegtl/contrib/json.hpp>` + +* JSON grammar according to [RFC 7159](https://tools.ietf.org/html/rfc7159) (for UTF-8 encoded JSON only). +* Ready for production use. + +###### `<tao/pegtl/contrib/parse_tree.hpp>` + +* See [Parse Tree](Parse-Tree.md). + +###### `<tao/pegtl/contrib/raw_string.hpp>` + +* Grammar rules to parse Lua-style long (or raw) string literals. +* Ready for production use. + +###### `<tao/pegtl/contrib/rep_one_min_max.hpp>` + +* Contains optimised version of `rep_min_max< Min, Max, ascii::one< C > >`: +* Rule `ascii::rep_one_min_max< Min, Max, C >`. +* Rule `ascii::ellipsis` as shortcut for `ascii::rep_one_min_max< 3, 3, '.' >`. + +###### `<tao/pegtl/contrib/to_string.hpp>` + +Utility function `to_string<>()` that converts template classes with arbitrary sequences of characters as template arguments into a `std::string` that contains these characters. + +###### `<tao/pegtl/contrib/tracer.hpp>` + +* Control class that prints a line of information to `std::cerr` + 1. when and where a rule is attempted to match, + 2. when and where a rule succeeded to match, + 3. when and where a rule failed to match. + +###### `<tao/pegtl/contrib/unescape.hpp>` + +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. + +###### `<tao/pegtl/contrib/uri.hpp>` + +* 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 `<tao/pegtl/contrib/json.hpp>` grammar to parse command line arguments as JSON data. + +###### `src/example/pegtl/json_build_one.cpp` + +Extends on `json_parse.cpp` by parsing JSON files into generic JSON data structures using the "[switching style](Actions-and-States.md#changing-state)" of managing actions and states. + +###### `src/example/pegtl/json_build_two.cpp` + +Extends on `json_parse.cpp` by parsing JSON files into generic JSON data structures using a more monolithic approach to managing the states and actions. + +###### `src/example/pegtl/json_count.cpp` + +Shows how to use the included [counter control](#taopegtlcontribcounterhpp), here together with the JSON grammar from `<tao/pegtl/contrib/json.hpp>`. +Invoked with one or more JSON files as argument, will attempt to parse the files and print the statistics counters to `std::cout`. + +###### `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 [`<tao/pegtl/contrib/parse_tree.hpp>`](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. + +Running the example with a slightly longer expression: + +```sh +$ build/src/example/pegtl/parse_tree "2 + a*b*4 - x / ( 2 - b + c - d )" +ROOT + example::minus at :1:9(9) + example::plus at :1:1(1) + example::integer "2" at :1:0(0) to :1:1(1) + example::multiply at :1:7(7) + example::multiply at :1:5(5) + example::variable "a" at :1:4(4) to :1:5(5) + example::variable "b" at :1:6(6) to :1:7(7) + example::integer "4" at :1:8(8) to :1:9(9) + example::divide at :1:13(13) + example::variable "x" at :1:12(12) to :1:13(13) + example::minus at :1:27(27) + example::plus at :1:23(23) + example::minus at :1:19(19) + example::integer "2" at :1:18(18) to :1:19(19) + example::variable "b" at :1:22(22) to :1:23(23) + example::variable "c" at :1:26(26) to :1:27(27) + example::variable "d" at :1:30(30) to :1:31(31) +``` + +###### `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 `<tao/pegtl/contrib/unescape.hpp>` 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 `<tao/pegtl/contrib/uri.hpp>`. +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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Control-and-Debug.md b/packages/PEGTL/doc/Control-and-Debug.md new file mode 100644 index 0000000000000000000000000000000000000000..ef851de2f66b225a9b0d6d54c5bebe6550f92592 --- /dev/null +++ b/packages/PEGTL/doc/Control-and-Debug.md @@ -0,0 +1,158 @@ +# 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 functions to + +1. trace which rules are attempted to match where, and whether they succeed or fail, +1. customise which exceptions are thrown in case of errors, +3. customise how actions' `apply()` and `apply0()` methods are called, +4. customise how rules' `match()` methods are 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 +{ + template< typename Input, + typename... States > + static void start( const Input&, States&&... ) + { + } + + template< typename Input, + typename... States > + static void success( const Input&, States&&... ) + { + } + + template< typename Input, + typename... States > + static void failure( const Input&, States&&... ) + { + } + + template< typename Input, + typename... States > + static void raise( const Input& in, States&&... ) + { + throw parse_error( "parse error matching " + + internal::demangle< Rule >(), in ); + } + + template< template< typename... > class Action, + typename Input, + typename... States > + static void apply0( const Input&, States&&... st ) + { + Action< Rule >::apply0( st... ); + } + + template< template< typename... > class Action, + typename Iterator, + typename Input, + typename... States > + static void apply( const Iterator& begin, const Input& in, States&&... st ) + { + using action_t = typename Input::action_t; + const action_t action_input( begin, in ); + Action< Rule >::apply( action_input, st... ); + } + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + constexpr bool use_control = !internal::skip_control< Rule >::value; + constexpr bool use_action = use_control && ( A == apply_mode::ACTION ) && ( !is_nothing< Action, Rule >::value ); + constexpr bool use_apply0 = use_action && internal::has_apply0< Action< Rule >, internal::type_list< States... > >::value; + constexpr dusel_mode mode = static_cast< dusel_mode >( static_cast< char >( use_control ) + static_cast< char >( use_action ) + static_cast< char >( use_apply0 ) ); + return internal::duseltronik< Rule, A, M, Action, Control, mode >::match( in, st... ); + } +}; +``` + +The `start()`, `success()` and `failure()`-functions can be used to debug a grammar by using them to provide insight into what exactly is going on during a parsing run. + +The `raise()`-function is used to create a global error, and any replacement should again throw an exception, or abort the application. + +The `apply()` and `apply0()`-functions can customise how actions with, and without, receiving the matched input are called, respectively. + +The `match`-function wraps the actual matching duseltronik and chooses the correct one based on whether control is enabled for `Rule`, and whether the current action is enabled and has an `apply()` or `apply0()`-function. + +## Control Functions + +For debugging a grammar and tracing exactly what happens during a parsing run, the control class methods `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 failure, i.e. a return value of `false` from its `match()`-function, then `C< R >::failure()` is called; a failed match is not allowed to consume input. + +- 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. + +- If a sub-rule of `R` finishes with a global failure, and the exception is not caught by a `try_catch` or similar combinator, then no other function of `C< R >` is called after `C< R >::start()`. + +Additionally, if matching `R` was successful, actions are enabled, and `A< R >` is not derived from `tao::pegtl::nothing`, where `A` is the current action class template: + +- If `A< R >::apply0()` exists, then `C< R >::apply0()` is called with the current state arguments. + +- If `A< R >::apply()` exists, then `C< R >::apply()` is called with the matched input and the current state arguments. + +It is an error when both `A< R >::apply0()` and `A< R >::apply()` exist. + +In case of actions that return `bool`, i.e. actions whose `apply0()` or `apply()` function returns `bool`, the `C< R >::success()` function 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 class `tao::pegtl::tracer` in `<tao/pegtl/contrib/tracer.hpp>` gives a pratical example that can be used as control class to debug grammars. +When an instance of class `tao::pegtl::trace_state` is used as single state in a parsing run with the tracer-control then the debug output contains a line number and rule number as additional information. + +## Exception Throwing + +The `raise()`-control-hook-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 template's `match()`-function is the first, or outside-most, function that is called in the flow that eventually leads to calling a rule's `match()`-function. + +For advanced use cases it is possible to create a custom control class with a custom `match()`-function that can change "everything" before calling the actual rule's `match()`-function. + +Similarly the control's `apply()` and `apply0()`-functions can customise action invocation; in particular `apply()` can change how the matched portion of the input is presented to the action. + +## Changing Control + +Just like the action class template, a custom control class template can be used by either + +1. supplying it as explicit template argument to the `parse()`-functions, or +2. setting it for a portion of the grammar with the `tao::pegtl::control` combinator. + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Errors-and-Exceptions.md b/packages/PEGTL/doc/Errors-and-Exceptions.md new file mode 100644 index 0000000000000000000000000000000000000000..bfa14bd4a58e9cfc92e58c13583379837a5f70be --- /dev/null +++ b/packages/PEGTL/doc/Errors-and-Exceptions.md @@ -0,0 +1,162 @@ +# 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 the `match()`-method 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 exceptions of type `tao::pegtl::input_error`. +Other exception classes can be used freely from actions and custom parsing rules. + +## Contents + +* [Local to Global Failure](#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) + +## 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()`-method. + +## 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 message for all `must<>` error points uses a custom control class whose `raise()`-method uses a static string as error message. + +```c++ +template< typename Rule > +struct my_control + : tao::pegtl::normal< Rule > +{ + static const std::string error_message; + + template< typename Input, typename... States > + static void raise( const Input& in, States&&... ) + { + throw tao::pegtl::parse_error( error_message, in ); + } +}; +``` + +Now only the `error_message` string needs to be specialised per error point as follows. + +```c++ +template<> const std::string my_control< MyRule >::error_message = "expected ..."; +``` + +Since the `raise()`-method 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 linker error for all rules for which the specialisation was forgotten although `raise()` could be called. +For an example of this method see `src/examples/pegtl/json_errors.hpp`, where all errors that might occur in the supplied JSON grammar are customised like this: + +```c++ +template<> const std::string errors< tao::pegtl::json::text >::error_message = "no valid JSON"; + +template<> const std::string errors< tao::pegtl::json::end_array >::error_message = "incomplete array, expected ']'"; +template<> const std::string errors< tao::pegtl::json::end_object >::error_message = "incomplete object, expected '}'"; +template<> const std::string errors< tao::pegtl::json::member >::error_message = "expected member"; +template<> const std::string errors< tao::pegtl::json::name_separator >::error_message = "expected ':'"; +template<> const std::string errors< tao::pegtl::json::array_element >::error_message = "expected value"; +template<> const std::string errors< tao::pegtl::json::value >::error_message = "expected value"; + +template<> const std::string errors< tao::pegtl::json::digits >::error_message = "expected at least one digit"; +template<> const std::string errors< tao::pegtl::json::xdigit >::error_message = "incomplete universal character name"; +template<> const std::string errors< tao::pegtl::json::escaped >::error_message = "unknown escape sequence"; +template<> const std::string errors< tao::pegtl::json::char_ >::error_message = "invalid character in string"; +template<> const std::string errors< tao::pegtl::json::string::content >::error_message = "unterminated string"; +template<> const std::string errors< tao::pegtl::json::key::content >::error_message = "unterminated key"; + +template<> const std::string errors< tao::pegtl::eof >::error_message = "unexpected character after JSON value"; +``` + +It is also possible to provide a default error message that will be chosen by the compiler in the absence of a specialised one as follows. + +```c++ +template< typename T > +const std::string my_control< T >::error_message = + "parse error matching " + tao::pegtl::internal::demangle< T >(); +``` + +This is similar to the default behaviour, but one will not get a linker error in case as error point is missed. + +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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Getting-Started.md b/packages/PEGTL/doc/Getting-Started.md new file mode 100644 index 0000000000000000000000000000000000000000..f294acd97f85a9e5a36ddea183485874d4a4e4cf --- /dev/null +++ b/packages/PEGTL/doc/Getting-Started.md @@ -0,0 +1,105 @@ +# 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++ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <string> +#include <iostream> + +#include <tao/pegtl.hpp> + +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 + : pegtl::nothing< Rule > + {}; + + // 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 Input > + static void apply( const Input& in, std::string& v ) + { + v = in.string(); + } + }; + +} // namespace hello + +int main( int argc, char* argv[] ) +{ + if( argc > 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; + } +} +``` + +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++11 -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) +``` + +Frequently an application will include a top-level `try-catch` block to handle +the exception. + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Grammar-Analysis.md b/packages/PEGTL/doc/Grammar-Analysis.md new file mode 100644 index 0000000000000000000000000000000000000000..43b1c49e75dde150e9f224c8cd7def462575c0ce --- /dev/null +++ b/packages/PEGTL/doc/Grammar-Analysis.md @@ -0,0 +1,78 @@ +# Grammar Analysis + +The PEGTL contains an `analyze()`-function that checks a grammar for rules that can go into an infinite loop without consuming input. + +Unfortunately, given the expressive power of PEGs and the possibility of arbitrary custom combinator rules, it is impossible to detect *all* kinds of infinite loops. + +It does however catch most cases of left-recursion that are typical for grammars converted from CFGs or other formalisms that gracefully handle left-recursion. + +## Rule Analysis + +In order to run an analysis on a grammar it is necessary to explicitly include `<tao/pegtl/analyze.hpp>`. +Then call `tao::pegtl::analyze()` with the top-level grammar rule as template argument. + +```c++ +#include <tao/pegtl/analyze.hpp> + +const std::size_t issues_found = tao::pegtl::analyze< my_grammar >(); +``` + +The `analyze()`-function returns the number of issues found and writes some information about them to `std::cout`. + +Analysing a grammar is usually only done while developing and debugging a grammar, or after changing it. + +Regarding the kinds of issues that are detected, consider the following example grammar 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. + +## Background + +In order to look for infinite loops in a grammar, the `analyze()`-function needs some information about all rules in the grammar. +This "information" consists of a classification of the rules according to the following enum, plus, for non-atomic rules, a list of the sub-rules. + +```c++ +// namespace tao::pegtl::analysis + +enum class rule_type : char +{ + ANY, + OPT, + SEQ, + SOR +}; +``` + +This enum value and rule list are provided to the `analyze()`-function via an `analyze_t` type member that all rules that are part of a grammar that is to be analysed with `analyze()` need to define. + +The names of the enum values correspond to one of the PEGTL rule classes that has this rule type, however some rule types are used by many different classes. + +* `ANY` is for rules where "success implies consumption" is true; assumes bounded repetition of conjunction of sub-rules. +* `OPT` is for rules where "success implies consumption" is false; assumes bounded repetition of conjunction of sub-rules. +* `SEQ` is for rules where consumption on success depends on non-zero bounded repetition of the conjunction of sub-rules. +* `SOR` is for rules where consumption on success depends on non-zero bounded repetition of the disjunction of sub-rules. + +At the beginning of an `analyze()`-run the function `R::analyze_t::insert()` is called for all rules `R` in the grammar in order to insert the information about the rule `R` into a data structure. + +## Custom Rules + +For custom rules it should usually be sufficient to follow the lead of the rules supplied with the PEGTL and define `analyze_t` to either `tao::pegtl::analysis::generic` or `tao::pegtl::analysis::counted`. +In both cases, the `rule_type` and the list of sub-rules must be supplied as template parameters. +Class `tao::pegtl::analysis::counted` additionally takes an integer argument `Count` with the assumption being that a count of zero indicates that everything the rule type is `OPT` while a non-zero count uses the rule type given as template parameter. + +When a custom rule goes beyond what can be currently expressed and all other questions, please contact the authors at **taocpp(at)icemx.net**. + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Inputs-and-Parsing.md b/packages/PEGTL/doc/Inputs-and-Parsing.md new file mode 100644 index 0000000000000000000000000000000000000000..16aa7e9c2bd7cd84758a56c9de84386fb8c07f3e --- /dev/null +++ b/packages/PEGTL/doc/Inputs-and-Parsing.md @@ -0,0 +1,436 @@ +# 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 : nothing< Rule > {}; + +// 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) + * [Grammars and Buffering](#grammars-and-buffering) + * [Custom Data Sources](#custom-data-sources) +* [Error Reporting](#error-reporting) +* [C++17 Deduction Guides](#c17-deduction-guides) + +## Tracking Mode + +Some input classes allow a choice of tracking mode, or whether the `byte`, `line` and `byte_in_line` counters are continuously updated during a parsing run with `tracking_mode::IMMEDIATE`, or only calculated on-demand in the `position()`-method 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`. + +Immediate 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 argument 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 contructors. + +Most file input classes take a single argument, the filename, which can be supplied as `std::string` or `const char*`. +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::IMMEDIATE, typename Eol = eol::lf_crlf > +struct read_input +{ + explicit read_input( const char* filename ); + explicit read_input( const std::string& filename ); + + read_input( FILE* file, const char* filename ); + read_input( FILE* file, const std::string& filename ); +}; + +template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > +struct mmap_input +{ + explicit mmap_input( const char* filename ); + explicit mmap_input( const std::string& filename ); +}; + +template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > +using file_input = mmap_input< P, Eol >; // Or read_input when no mmap_input available. +``` + +Note that the implementation of the constructors is different than shown. +They should be used "as if" this was the actual signature. + +## 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 `byte_in_line` arguments initialise the internal counters with the supplied values, rather than the defaults of `0`, `1` and `0`. + +```c++ +template< tracking_mode P = tracking_mode::IMMEDIATE, 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 byte_in_line ) 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::IMMEDIATE, 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 byte_in_line ) noexcept(...); +}; +``` + +### 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 prepare a grammar for incremental input support using the `discard`-rule. + +```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::IMMEDIATE, 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 method. + +```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 Input, + typename... States > +bool parse( Input& 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...". + +Calling `parse_nested()` requires one additional argument compared to `parse()`, the input from the outer parsing run as 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 Outer, + typename Input, + typename... States > +bool parse_nested( const Outer& oi, + Input& in, + States&&... st ); +``` + +## Incremental Input + +The PEGTL is designed and optimised for parsing single contiguous blocks of memory, e.g. the contents of a file made available via `mmap(2)`, or the contents of a `std::string`. + +In cases where the input does not fit into memory, or there are other reasons to not create a single memory block containing all input data, it is possible, with a little help from the grammar, to perform incremental parsing, where the data is incrementally made available, e.g. when reading from a stream. + +### Grammars and Buffering + +A buffer is used to keep a portion of the input data in a contiguous memory block. +The buffer is allocated at the begin of the parsing run with a user-supplied maximum size. + +The maximum buffer size usually depends on the grammar, the actions, and the input data. +It must be chosen large enough to keep the data required for (a) any backtracking, and (b) all action invocations. + +The buffer is automatically filled by the parsing rules that require input data, however **discarding data from the buffer is** (currently) **not automatic**: +The grammar has to call [`discard`](Rule-Reference.md#discard) in appropriate places to free the buffer again. + +More precisely, each rule that uses one of the following methods on the input will implicitly make a call to `tao::pegtl::buffer_input<>::require( amount )`. +(The `empty()`-method uses a hard-coded `amount` of 1.) + +```c++ +namespace tao +{ + namespace pegtl + { + template< class Reader, typename Eol = eol::lf_crlf > + class buffer_input + { + empty(); + size( const std::size_t amount ); + end( const std::size_t amount ); + ... + }; + } +} +``` + +This tells the input that a rule wants to inspect and/or consume a certain `amount` of input bytes, and it will attempt to fill the buffer accordingly. +The returned `size()`, and the distance from `begin()` to `end()`, can also be larger than the requested amount. + +For example, the rule `tao::pegtl::ascii::eol`, which (usually) checks for both `"\r\n"` and "`\n`", calls `size(2)` because it needs to inspect up to two bytes. +Depending on whether the result of `size(2)` is `0`, `1` or `2`, it will choose which of these two sequences it can attempt to match. +The number of actually consumed bytes can again be `0`, `1` or `2`, depending on whether they match a valid `eol`-sequence. + +To prevent the buffer from overflowing, the `discard()`-method of class `tao::pegtl::buffer_input` must be called, usually by using the `discard` parsing rule. +It discards all data in the buffer that precedes the current `begin()`-point, and any remaining data is moved to the beginning of the buffer. + +**A `discard` 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.** + +``` +Buffer Memory Layout + +B begin of buffer space +: +B + X begin of unconsumed buffered data as per begin() +: +B + X + size( 0 ) end of unconsumed buffered data as per end( 0 ) +: +B + maximum end of buffer space +``` + +A discard moves the data in the buffer such that `X` is zero, and updates `begin()` to point at the beginning of the buffer. + +### Custom Data Sources + +The PEGTL contains a set of stream parser input classes that take care of everything (except discarding data from the buffer, see above) for certain data sources. +In order to support other data sources, it is necessary to create a custom input class, usually by creating a suitable *reader* class that can be supplied as template argument to class `tao::pegtl::buffer_input<>`. + +The reader class can be anything that can be called like the following standard function 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: +Attempt to read up to `length` bytes into the memory pointed to by `buffer` and return the number of bytes actually read. +Reaching the end of the input should be the only reason for the reader to return zero. + +The steps required to use a custom reader for a parsing run are: + +1. Create a suitable reader class `Reader` (or function). +2. Create an instance of class `tao::pegtl::buffer_input< Reader >`, using the fact that the `buffer_input`'s constructor can pass arbitrary arguments to the embedded reader instance. +3. Call `tao::pegtl::parse()` (or `tao::pegtl::parse_nested()`) with the previously created `buffer_input` instance as first argument. + +The included examples for C- and C++-style streams can also be used as reference on how to create and use suitable readers, simply `grep(1)` for `cstream_reader` and `istream_reader` (and `cstring_reader`) in the PEGTL source code. + +## 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 methods `at( p )`, `begin_of_line( p )`, `end_of_line( p )` and `line_as_string( p )` which take a `tao::pegtl::position` as parameter. +The first three methods 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_as_string( p )` returns a `std::string` 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_as_string( p ) << std::endl + << std::string( p.byte_in_line, ' ' ) << '^' << 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 methods on `buffer_input<>`-based instances will lead to a compile error. + +## C++17 Deduction Guides + +All input classes support C++17's [deduction guides](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction) when compiling with C++17 or newer, e.g. instead of `file_input<> in( "filename.txt" )` one can use `file_input in( "filename.txt" )`. + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Installing-and-Using.md b/packages/PEGTL/doc/Installing-and-Using.md new file mode 100644 index 0000000000000000000000000000000000000000..7c3ab624bbaf76bdc3b220722b582eeda131ba20 --- /dev/null +++ b/packages/PEGTL/doc/Installing-and-Using.md @@ -0,0 +1,169 @@ +# Installing and Using + +## Contents + +* [Requirements](#requirements) +* [Installation Packages](#installation-packages) +* [CMake Installation](#cmake-installation) +* [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) + +## Requirements + +The PEGTL requires a C++11-capable compiler, e.g. one of + +* GCC 4.8 +* Clang 3.4 +* Visual Studio 2015 + +on either + +* Linux +* macOS +* Windows + +It requires C++11, e.g. using the `--std=c++11` compiler switch. +Using newer versions of the C++ standard is supported. + +It should also work with other C++11 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. + +## Installation Packages + +Installation packages are available from several package managers. Note that some of the listed packages are not updated regularly. + +[](https://repology.org/metapackage/pegtl) + +### Other + +* [Conan] +* [Spack] + +## 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. 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 `pegtl`, which leads to all symbols residing in namespace +`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 <tao/pegtl.hpp> +#include <tao/contrib/json.hpp> + +int main( int argc, char* argv[] ) +{ + if( argc > 1 ) { + tao::mylib_pegtl::argv_input<> in( argv, 1 ); + tao::mylib_pegtl::parse< tao::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 commands will achieve this: + +```sh +$ sed -i 's/TAO_PEGTL_/MYLIB_TAO_PEGTL_/g' $(find -name '[^.]*.[hc]pp') +$ sed -i 's/TAOCPP_PEGTL_/MYLIB_TAOCPP_PEGTL_/g' $(find -name '[^.]*.[hc]pp') +``` + +The above commands needs to run from the top-level directory of the embedded +PEGTL. Additionally, `MYLIB_TAO_PEGTL_NAMESPACE` needs to be set as explained +above; alternatively `include/tao/pegtl/config.hpp` can be directly modified. + +Note that the second command is only needed because the PEGTL contains +some compatibility macros for older versions that start with `TAOCPP_PEGTL_` +instead of `TAO_PEGTL_`. Those older compatibility macros will be removed +in version 3.0. Starting with version 2.4.0 you should only use macros +that start with `TAO_PEGTL_`. + +A practical example of how the result looks like can be found in our own +header-only [JSON library](https://github.com/taocpp/json/). + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey + +[CMake]: https://cmake.org/ +[CMake documentation]: https://cmake.org/documentation/ +[Conan]: https://bintray.com/taocpp/public-conan/pegtl%3Ataocpp +[Spack]: http://spack.readthedocs.io/en/latest/package_list.html#pegtl diff --git a/packages/PEGTL/doc/Migration-Guide.md b/packages/PEGTL/doc/Migration-Guide.md new file mode 100644 index 0000000000000000000000000000000000000000..6b8c95af968a8644cfab3ad24c409eb84a4b8165 --- /dev/null +++ b/packages/PEGTL/doc/Migration-Guide.md @@ -0,0 +1,39 @@ +# Migration Guide + +## Version 2.4.0 + +The common prefix for all macros was changed from `TAOCPP_PEGTL_` to `TAO_PEGTL_`. + +Compatibility macros can still be used, the library should be fully compatible when +used with older macros. Note, however, that the old macros will be removed in a +future version 3.0. Consider updating your macro prefixes now. + +## From 1.y to 2.z + +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.y. +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 `<tao/pegtl.hpp>`, all other include files are `<tao/pegtl/*.hpp>`. +* 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()` method of the input-classes is now called `current()`. +* The first argument to actions' `apply()`-methods 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. + +## From 0.x to 1.y or 2.z + +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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Parse-Tree.md b/packages/PEGTL/doc/Parse-Tree.md new file mode 100644 index 0000000000000000000000000000000000000000..961ecba1ecafe259b9eae0e41b762c5ad7135fba --- /dev/null +++ b/packages/PEGTL/doc/Parse-Tree.md @@ -0,0 +1,138 @@ +# Parse Tree + +The PEGTL provides facilities for building a [parse tree](https://en.wikipedia.org/wiki/Parse_tree) / [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) in the header + +```c++ +#include <tao/pegtl/contrib/parse_tree.hpp> +``` + +It provides the basic infrastructure to build a parse tree and: + +* Builds a full parse tree (one node for each matched rule) by default. +* Includes a default node class to hold parse tree information. +* Supports custom node classes to contain additional information. +* Supports a selector class template to choose which nodes to store in the parse tree. +* Supports a transform method in the selector specialization for custom modifications of the tree. + +> The parse tree / AST part of the PEGTL is currently in active development and serves as a prove-of-concept, expect changes at any time. Try it out, experiment with it, and most importantly let us know what you think of it. We need **your** feedback! + +## Full Parse Tree + +To obtain a full parse tree, call the `tao::pegtl::parse_tree::parse()`-method with a grammar and an input: + +```c++ +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. Intermediate nodes from rules which did not match will be removed automatically. + +## Partial Parse Tree + +When a full parse tree with nodes for all rules is too much it is possible to supply a second template parameter to the `parse_tree::parse()` function that controls which rules get a parse tree node. This second template parameter `S` is itself a class template. For each rule `Rule` that matched, a node is generated only when `S<Rule>::value` is `true`. It is then possible to select the rules that should generate nodes as follows: + +```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 ); +``` + +The above style is a white-list, where the default is `std::false_type` and you explicitly list those rules which will generate a node. Of course, you can also set the default to `std::true_type` and explicitly list the rules that are *not* to generate a node (black-list style). + +## 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()` method can be added to each specialization of the selector class template (that generates a node). This methods 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... + } +}; +``` + +You can transform `n` in almost any way you can imagine, the [`parse_tree.cpp`](https://github.com/taocpp/PEGTL/blob/master/src/example/pegtl/parse_tree.cpp)-example shows two techniques for marking nodes as "content-less", and for actual transformations of the parse tree into an AST. + +There is another option not shown in the example: You can call `n.reset()` before returning from `transform()`. This prevents the node from being added to its parent. It removes the node (as well as all of its children) from the generated parse tree. + +## `tao::pegtl::parse_tree::node` + +This is the default node class used by `tao::pegtl::parse_tree::parse` if no custom node class is specified. In that case, the root node, as well as all (nested) child nodes, provide the following interface: + +```c++ +struct node +{ + std::vector< std::unique_ptr< node > > children; + + bool is_root() const noexcept(); + + // precondition from here on: !is_root() + + std::string name() const; + + bool has_content() const noexcept(); + std::string content() const; // precondition: has_content() + + std::string source() const; + + // useful for transform: + void remove_content(); +}; +``` + +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. You only need to check `has_content()` if you previously used `remove_content()` in your transform methods, otherwise there will always be content (except for at the root). + +See the [`parse_tree.cpp`](https://github.com/taocpp/PEGTL/blob/master/src/example/pegtl/parse_tree.cpp)-example for more information how to output (or otherwise use) the nodes. + +## Custom Node Class + +If you need more control over how data is stored/handled in the nodes, you can provide your own node class. You can add it to the parse call as an additional template parameter after the rule: + +```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 type while `my_selector` is a class template. If you provide your own node class, it must provide the following interface: + +```c++ +struct my_node +{ + // it must be default constructible + my_node() = default; + + // no copy/move is necessary + // (nodes are always owned/handled by a std::unique_ptr) + my_node( const my_node& ) = delete; + my_node( my_node&& ) = delete; + + // it must be destructible + ~my_node() = default; + + // no assignment necessary + my_node& operator=( const my_node& ) = delete; + my_node& operator=( my_node&& ) = delete; + + // all non-root nodes are initialized by calling this method + template< typename Rule, typename Input > + void start( const Input& in ); + + // if parsing of the rule succeeded, this method is called + template< typename Rule, typename Input > + void success( const Input& in ); + + // 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. + void append( std::unique_ptr< my_node > child ); +}; +``` + +Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Performance-Notes.md b/packages/PEGTL/doc/Performance-Notes.md new file mode 100644 index 0000000000000000000000000000000000000000..699319d28cdabd518285eb159aec5c90a54465e2 --- /dev/null +++ b/packages/PEGTL/doc/Performance-Notes.md @@ -0,0 +1,45 @@ +# 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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/README.md b/packages/PEGTL/doc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4fc2c5e2d351f9598e0470b4288a7583972a7f28 --- /dev/null +++ b/packages/PEGTL/doc/README.md @@ -0,0 +1,258 @@ +# 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) + * [Installation Packages](Installing-and-Using.md#installation-packages) + * [CMake Installation](Installing-and-Using.md#cmake-installation) + * [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) + * [Limitations](Installing-and-Using.md#limitations) +* [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) + * [Actions](Actions-and-States.md#actions) + * [Apply0](Actions-and-States.md#apply0) + * [Apply](Actions-and-States.md#apply) + * [States](Actions-and-States.md#states) + * [Action Specialisation](Actions-and-States.md#action-specialisation) + * [Changing Actions](Actions-and-States.md#changing-actions) + * [Changing States](Actions-and-States.md#changing-states) + * [No Switching](Actions-and-States.md#no-switching) + * [Intrusive Switching](Actions-and-States.md#intrusive-switching) + * [External Switching](Actions-and-States.md#external-switching) +* [Errors and Exceptions](Errors-and-Exceptions.md) + * [Local to Global Failure](Errors-and-Exceptions.md#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) + * [Grammars and Buffering](Inputs-and-Parsing.md#grammars-and-buffering) + * [Custom Data Sources](Inputs-and-Parsing.md#custom-data-sources) + * [Error Reporting](Inputs-and-Parsing.md#error-reporting) + * [C++17 Deduction Guides](Inputs-and-Parsing.md#c17-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) +* [Contrib and Examples](Contrib-and-Examples.md) + * [Contrib](Contrib-and-Examples.md#contrib) + * [Examples](Contrib-and-Examples.md#examples) +* [Grammar Analysis](Grammar-Analysis.md) +* [Changelog](Changelog.md) +* [Migration Guide](Migration-Guide.md) + +# Rule Reference Index + +* [`action< A, R... >`](Rule-Reference.md#action-a-r-) <sup>[(meta rules)](Rule-Reference.md#meta-rules)</sup> +* [`alnum`](Rule-Reference.md#alnum) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`alpha`](Rule-Reference.md#alpha) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`alphabetic`](Rule-Reference.md#alphabetic) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`any`](Rule-Reference.md#any) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`any`](Rule-Reference.md#any-1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`any`](Rule-Reference.md#any-2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`apply< A... >`](Rule-Reference.md#apply-a-) <sup>[(action rules)](Rule-Reference.md#action-rules)</sup> +* [`apply0< A... >`](Rule-Reference.md#apply0-a-) <sup>[(action rules)](Rule-Reference.md#action-rules)</sup> +* [`ascii_hex_digit`](Rule-Reference.md#ascii_hex_digit) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`at< R... >`](Rule-Reference.md#at-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`bidi_class< V >`](Rule-Reference.md#bidi_class-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`bidi_control`](Rule-Reference.md#bidi_control) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`bidi_mirrored`](Rule-Reference.md#bidi_mirrored) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`binary_property< P >`](Rule-Reference.md#binary_property-p-) <sup>[(icu rules)](Rule-Reference.md#basic-icu-rules)</sup> +* [`binary_property< P, V >`](Rule-Reference.md#binary_property-p-v-) <sup>[(icu rules)](Rule-Reference.md#basic-icu-rules)</sup> +* [`blank`](Rule-Reference.md#blank) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`block< V >`](Rule-Reference.md#block-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`bof`](Rule-Reference.md#bof) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`bol`](Rule-Reference.md#bol) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`bom`](Rule-Reference.md#bom) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`bytes< Num >`](Rule-Reference.md#bytes-num-) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`canonical_combining_class< V >`](Rule-Reference.md#canonical_combining_class-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-value-properties)</sup> +* [`case_sensitive`](Rule-Reference.md#case_sensitive) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`control< C, R... >`](Rule-Reference.md#control-c-r-) <sup>[(meta rules)](Rule-Reference.md#meta-rules)</sup> +* [`dash`](Rule-Reference.md#dash) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`decomposition_type< V >`](Rule-Reference.md#decomposition_type-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`default_ignorable_code_point`](Rule-Reference.md#default_ignorable_code_point) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`deprecated`](Rule-Reference.md#deprecated) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`diacritic`](Rule-Reference.md#diacritic) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`digit`](Rule-Reference.md#digit) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`disable< R... >`](Rule-Reference.md#disable-r-) <sup>[(meta rules)](Rule-Reference.md#meta-rules)</sup> +* [`discard`](Rule-Reference.md#discard) <sup>[(meta rules)](Rule-Reference.md#meta-rules)</sup> +* [`east_asian_width< V >`](Rule-Reference.md#east_asian_width-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`enable< R... >`](Rule-Reference.md#enable-r-) <sup>[(meta-rules)](Rule-Reference.md#meta-rules)</sup> +* [`eof`](Rule-Reference.md#eof) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`eol`](Rule-Reference.md#eol) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`eolf`](Rule-Reference.md#eolf) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`extender`](Rule-Reference.md#extender) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`failure`](Rule-Reference.md#failure) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`forty_two< C... >`](Rule-Reference.md#forty_two-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`full_composition_exclusion`](Rule-Reference.md#full_composition_exclusion) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`general_category< V >`](Rule-Reference.md#general_category-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`grapheme_base`](Rule-Reference.md#grapheme_base) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`grapheme_cluster_break< V >`](Rule-Reference.md#grapheme_cluster_break-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`grapheme_extend`](Rule-Reference.md#grapheme_extend) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`grapheme_link`](Rule-Reference.md#grapheme_link) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`hangul_syllable_type< V >`](Rule-Reference.md#hangul_syllable_type-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`hex_digit`](Rule-Reference.md#hex_digit) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`hyphen`](Rule-Reference.md#hyphen) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`id_continue`](Rule-Reference.md#id_continue) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`id_start`](Rule-Reference.md#id_start) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`identifier_first`](Rule-Reference.md#identifier_first) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`identifier_other`](Rule-Reference.md#identifier_other) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`identifier`](Rule-Reference.md#identifier) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`ideographic`](Rule-Reference.md#ideographic) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`ids_binary_operator`](Rule-Reference.md#ids_binary_operator) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`ids_trinary_operator`](Rule-Reference.md#ids_trinary_operator) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`if_apply< R, A... >`](Rule-Reference.md#if_apply-r-a-) <sup>[(action rules)](Rule-Reference.md#action-rules)</sup> +* [`if_must< R, S... >`](Rule-Reference.md#if_must-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`if_must_else< R, S, T >`](Rule-Reference.md#if_must_else-r-s-t-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`if_then_else< R, S, T >`](Rule-Reference.md#if_then_else-r-s-t-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`istring< C... >`](Rule-Reference.md#istring-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`join_control`](Rule-Reference.md#join_control) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`joining_group< V >`](Rule-Reference.md#joining_group-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`joining_type< V >`](Rule-Reference.md#joining_type-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`keyword< C... >`](Rule-Reference.md#keyword-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`lead_canonical_combining_class< V >`](Rule-Reference.md#lead_canonical_combining_class-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-value-properties)</sup> +* [`line_break< V >`](Rule-Reference.md#line_break-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`list< R, S >`](Rule-Reference.md#list-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`list< R, S, P >`](Rule-Reference.md#list-r-s-p-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`list_must< R, S >`](Rule-Reference.md#list_must-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`list_must< R, S, P >`](Rule-Reference.md#list_must-r-s-p-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`list_tail< R, S >`](Rule-Reference.md#list_tail-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`list_tail< R, S, P >`](Rule-Reference.md#list_tail-r-s-p-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`logical_order_exception`](Rule-Reference.md#logical_order_exception) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`lower`](Rule-Reference.md#lower) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`lowercase`](Rule-Reference.md#lowercase) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`mask_not_one< M, C... >`](Rule-Reference.md#mask_not_one-m-c-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_not_range< M, C, D >`](Rule-Reference.md#mask_not_range-m-c-d-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_one< M, C... >`](Rule-Reference.md#mask_one-m-c-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_range< M, C, D >`](Rule-Reference.md#mask_range-m-c-d-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_ranges< M, C1, D1, C2, D2, ... >`](Rule-Reference.md#mask_ranges-m-c1-d1-c2-d2--) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_ranges< M, C1, D1, C2, D2, ..., E >`](Rule-Reference.md#mask_ranges-m-c1-d1-c2-d2--e-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`mask_string< M, C... >`](Rule-Reference.md#mask_string-m-c-) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`math`](Rule-Reference.md#math) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`minus< M, S >`](Rule-Reference.md#minus-m-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`must< R... >`](Rule-Reference.md#must-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`nfc_inert`](Rule-Reference.md#nfc_inert) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`nfd_inert`](Rule-Reference.md#nfd_inert) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`nfkc_inert`](Rule-Reference.md#nfkc_inert) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`nfkd_inert`](Rule-Reference.md#nfkd_inert) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`noncharacter_code_point`](Rule-Reference.md#noncharacter_code_point) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`not_at< R... >`](Rule-Reference.md#not_at-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`not_one< C... >`](Rule-Reference.md#not_one-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`not_one< C... >`](Rule-Reference.md#not_one-c--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`not_one< C... >`](Rule-Reference.md#not_one-c--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`not_range< C, D >`](Rule-Reference.md#not_range-c-d-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`not_range< C, D >`](Rule-Reference.md#not_range-c-d--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`not_range< C, D >`](Rule-Reference.md#not_range-c-d--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`nul`](Rule-Reference.md#nul) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`numeric_type< V >`](Rule-Reference.md#numeric_type-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`one< C... >`](Rule-Reference.md#one-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`one< C... >`](Rule-Reference.md#one-c--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`one< C... >`](Rule-Reference.md#one-c--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`opt< R... >`](Rule-Reference.md#opt-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`opt_must< R, S...>`](Rule-Reference.md#opt_must-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`pad< R, S, T = S >`](Rule-Reference.md#pad-r-s-t--s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`pad_opt< R, P >`](Rule-Reference.md#pad_opt-r-p-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`pattern_syntax`](Rule-Reference.md#pattern_syntax) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`pattern_white_space`](Rule-Reference.md#pattern_white_space) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`plus< R... >`](Rule-Reference.md#plus-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`posix_alnum`](Rule-Reference.md#posix_alnum) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`posix_blank`](Rule-Reference.md#posix_blank) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`posix_graph`](Rule-Reference.md#posix_graph) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`posix_print`](Rule-Reference.md#posix_print) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`posix_xdigit`](Rule-Reference.md#posix_xdigit) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`print`](Rule-Reference.md#print) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`property_value< P, V >`](Rule-Reference.md#property_value-p-v-) <sup>[(icu rules)](Rule-Reference.md#basic-icu-rules)</sup> +* [`quotation_mark`](Rule-Reference.md#quotation_mark) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`radical`](Rule-Reference.md#radical) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`raise< T >`](Rule-Reference.md#raise-t-) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`range< C, D >`](Rule-Reference.md#range-c-d-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`range< C, D >`](Rule-Reference.md#range-c-d--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`range< C, D >`](Rule-Reference.md#range-c-d--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2--) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2---1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](Rule-Reference.md#ranges-c1-d1-c2-d2---2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](Rule-Reference.md#ranges-c1-d1-c2-d2--e--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`rep< Num, R... >`](Rule-Reference.md#rep-num-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`rep_max< Max, R... >`](Rule-Reference.md#rep_max-max-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`rep_min< Min, R... >`](Rule-Reference.md#rep_min-min-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`rep_min_max< Min, Max, R... >`](Rule-Reference.md#rep_min_max-min-max-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`rep_opt< Num, R... >`](Rule-Reference.md#rep_opt-num-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`require< Num >`](Rule-Reference.md#require-num-) <sup>[(meta-rules)](Rule-Reference.md#meta-rules)</sup> +* [`s_term`](Rule-Reference.md#s_term) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`segment_starter`](Rule-Reference.md#segment_starter) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`sentence_break< V >`](Rule-Reference.md#sentence_break-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`seq< R... >`](Rule-Reference.md#seq-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`seven`](Rule-Reference.md#seven) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`shebang`](Rule-Reference.md#shebang) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`soft_dotted`](Rule-Reference.md#soft_dotted) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`sor< R... >`](Rule-Reference.md#sor-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`space`](Rule-Reference.md#space) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`star< R... >`](Rule-Reference.md#star-r-) <sup>[(combinators)](Rule-Reference.md#combinators)</sup> +* [`star_must< R, S... >`](Rule-Reference.md#star_must-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`state< S, R... >`](Rule-Reference.md#state-s-r-) <sup>[(meta rules)](Rule-Reference.md#meta-rules)</sup> +* [`string< C... >`](Rule-Reference.md#string-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`string< C... >`](Rule-Reference.md#string-c--1) <sup>[(unicode rules)](Rule-Reference.md#unicode-rules)</sup> +* [`string< C... >`](Rule-Reference.md#string-c--2) <sup>[(binary rules)](Rule-Reference.md#binary-rules)</sup> +* [`success`](Rule-Reference.md#success) <sup>[(atomic rules)](Rule-Reference.md#atomic-rules)</sup> +* [`TAO_PEGTL_ISTRING( "..." )`](Rule-Reference.md#tao_pegtl_istring--) <sup>[(ascii rules)](Rule-Reference.md#ascii_rules)</sup> +* [`TAO_PEGTL_KEYWORD( "..." )`](Rule-Reference.md#tao_pegtl_keyword--) <sup>[(ascii rules)](Rule-Reference.md#ascii_rules)</sup> +* [`TAO_PEGTL_STRING( "..." )`](Rule-Reference.md#tao_pegtl_string--) <sup>[(ascii rules)](Rule-Reference.md#ascii_rules)</sup> +* [`terminal_punctuation`](Rule-Reference.md#terminal_punctuation) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`three< C >`](Rule-Reference.md#three-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`trail_canonical_combining_class< V >`](Rule-Reference.md#trail_canonical_combining_class-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-value-properties)</sup> +* [`try_catch< R... >`](Rule-Reference.md#try_catch-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`try_catch_type< E, R... >`](Rule-Reference.md#try_catch_type-e-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`two< C >`](Rule-Reference.md#two-c-) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`unified_ideograph`](Rule-Reference.md#unified_ideograph) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`until< R >`](Rule-Reference.md#until-r-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`until< R, S... >`](Rule-Reference.md#until-r-s-) <sup>[(convenience)](Rule-Reference.md#convenience)</sup> +* [`upper`](Rule-Reference.md#upper) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`uppercase`](Rule-Reference.md#uppercase) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`variation_selector`](Rule-Reference.md#variation_selector) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`white_space`](Rule-Reference.md#white_space) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`word_break< V >`](Rule-Reference.md#word_break-v-) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-enumerated-properties)</sup> +* [`xdigit`](Rule-Reference.md#xdigit) <sup>[(ascii rules)](Rule-Reference.md#ascii-rules)</sup> +* [`xid_continue`](Rule-Reference.md#xid_continue) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> +* [`xid_start`](Rule-Reference.md#xid_start) <sup>[(icu rules)](Rule-Reference.md#icu-rules-for-binary-properties)</sup> + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Rule-Reference.md b/packages/PEGTL/doc/Rule-Reference.md new file mode 100644 index 0000000000000000000000000000000000000000..bb91804332e446e6150ca005520be874f8eae9fa --- /dev/null +++ b/packages/PEGTL/doc/Rule-Reference.md @@ -0,0 +1,1238 @@ +# 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()`-method. + +## Equivalence + +Some rule classes are said to be *equivalent* to a combination of other rules. +These rules are not completely equivalent to the shown definition because that +is not how they are implemented, therefore: + +- Rule equivalence is with regard to which inputs will match, but: +- *not* with regard to which actions will be invoked while matching. + +However, rule equivalence does show exactly where the `raise<>` rule is inserted +and therefore which rule will be used to call the control class' `raise()`-method. + +## 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). +* Actions can still be disabled explicitly (via `disable`) or implicitly (via `at` or `not_at`). + +###### `control< C, R... >` + +* Equivalent to `seq< R... >`, but: +* Uses the given class template `C` as [control class](Control-and-Debug.md). + +###### `disable< R... >` + +* Equivalent to `seq< R... >`, but: +* Disables all actions. + +###### `discard` + +* Equivalent to `success`, but: +* Calls the input's `discard()`-method. +* 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. + +###### `enable< R... >` + +* Equivalent to `seq< R... >`, but: +* Enables all actions (if any). + +###### `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. + +###### `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, and, if expected, with `A, M, Action, Control` as template parameters. + +## Combinators + +Combinators (or combinator rules) are rules that combine (other) rules into new ones. + +These are the classical PEG combinator rules 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. +* Allows local failure of `R...` even within `must<>` etc. + +###### `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. +* Allows local failure of `R...` even within `must<>` etc. + +###### `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 >`. +* Allows local failure of `R...` even within `must<>` etc. + +###### `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. + +###### `seq< R... >` + +* PEG **sequence** *e*<sub>1</sub> *e*<sub>2</sub> +* 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. + +###### `sor< R... >` + +* PEG **ordered choice** *e*<sub>1</sub> / *e*<sub>2</sub> +* 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. +* Allows local failure of `R...` even within `must<>` etc. +* Fails if `R` is an empty rule pack. + +###### `star< R... >` + +* PEG **zero-or-more** *e** +* Matches `seq< R... >` as often as possible and always succeeds. +* Allows local failure of `R...` even within `must<>` etc. +* `R` must be a non-empty rule pack. + +## 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 >`. + +###### `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 > >`. + +###### `if_then_else< R, S, T >` + +* Equivalent to `sor< seq< R, S >, seq< not_at< R >, T > >`. + +###### `list< R, S >` + +* Matches a non-empty list of `R` separated by `S`. +* Equivalent to `seq< R, 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 > >`. + +###### `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 > > >`. + +###### `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 > > >`. + +###### `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 > >`. + +###### `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 > >`. + +###### `minus< M, S >` + +* Succeeds if `M` matches, and then `S` does **not** match all of the input that `M` matched. +* Does not call actions for `S` (unless `S` contains `enable<>`). +* Ignores `S` for the [grammar analysis](Grammar-Analysis.md). + +###### `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 > >... >`. + +###### `opt_must< R, S... >` + +* Equivalent to `opt< if_must< R, S... > >`. + +###### `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 > >`. + +###### `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 > > >`. + +###### `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. + +###### `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... >`. + +###### `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. + +###### `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... > >`. + +###### `rep_opt< Num, R... >` + +* Matches `seq< R... >` for zero to `Num` times without check for further matches. +* Equivalent to `rep< Num, opt< R... > >`. + +###### `star_must< R, S... >` + +* Equivalent to `star< if_must< 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`. + +###### `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`. + +###### `until< R >` + +* Consumes all input until `R` matches. +* Equivalent to `until< R, any >`. + +###### `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 >, not_at< eof >, S... >, R >`. +* Does not apply if `S` is an empty rule pack, see the previous entry for the semantics of `until< R >`. + +## 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 the `parse()`-functions and `action<>`-rule). +These rules respect the current `apply_mode`, but don't 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. + +###### `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. + +###### `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. + +## 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()` method returns zero. +* Does not consume input. +* Does **not** work with inputs that don't have a `byte()` method. + +###### `bol` + +* Succeeds at "beginning-of-line", i.e. when the input's `byte_in_line()` method returns zero. +* Does not consume input. +* Does **not** work with inputs that don't have a `byte_in_line()` method. + +###### `bytes< Num >` + +* Succeeds when the input contains at least `Num` further bytes. +* Consumes these `Num` bytes from the input. + +###### `eof` + +* Succeeds at "end-of-file", i.e. when the input is empty or all input has been consumed. +* Does not consume input. + +###### `failure` + +* Dummy rule that never succeeds. +* Does not consume input. + +###### `raise< T >` + +* Generates a *global failure*. +* Calls the control-class' `Control< T >::raise()`-method. +* `T` *can* be a rule, but it does not have to be a rule. +* Does not consume input. + +###### `success` + +* Dummy rule that always succeeds. +* Does not consume input. + +## 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 >`.) + +###### `alnum` + +* Matches and consumes a single ASCII alphabetic or numeric character. +* Equivalent to `ranges< 'a', 'z', 'A', 'Z', '0', '9' >`. + +###### `alpha` + +* Matches and consumes a single ASCII alphabetic character. +* Equivalent to `ranges< 'a', 'z', 'A', 'Z' >`. + +###### `any` + +* Matches and consumes any single byte, including all ASCII characters. +* Equivalent to `bytes< 1 >`. + +###### `blank` + +* Matches and consumes a single ASCII horizontal space or horizontal tabulator character. +* Equivalent to `one< ' ', '\t' >`. + +###### `digit` + +* Matches and consumes a single ASCII decimal digit character. +* Equivalent to `range< '0', '9' >`. + +###### `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' > >`. + +###### `eolf` + +* Equivalent to `sor< eof, eol >`. + +###### `forty_two< C... >` + +* Equivalent to `rep< 42, one< 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', '_' >`. + +###### `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', '_' >`. + +###### `identifier` + +* Matches and consumes an ASCII identifier as defined for the C programming language. +* Equivalent to `seq< identifier_first, 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. + +###### `keyword< C... >` + +* Matches and consumes a non-empty string not followed by a subsequent identifier character. +* Equivalent to `seq< string< C... >, not_at< identifier_other > >`. + +###### `lower` + +* Matches and consumes a single ASCII lower-case alphabetic character. +* Equivalent to `range< '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. + +###### `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. + +###### `nul` + +* Matches and consumes an ASCII nul character. +* Equivalent to `one< 0 >`. + +###### `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. + +###### `print` + +* Matches and consumes any single ASCII character traditionally defined as printable. +* Equivalent to `range< 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. + +###### `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 > >`. + +###### `seven` + +* Matches and consumes any single true ASCII character that fits into 7 bits. +* Equivalent to `range< 0, 127 >`. + +###### `shebang` + +* Equivalent to `seq< string< '#', '!' >, until< 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 >... >`. + +###### `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. + +###### `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. + +###### `upper` + +* Matches and consumes a single ASCII upper-case alphabetic character. +* Equivalent to `range< 'A', 'Z' >`. + +###### `xdigit` + +* Matches and consumes a single ASCII hexadecimal digit character. +* Equivalent to `ranges< '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. + +Unaligned memory is no problem on x86 compatible processors; on some other architectures like ARM an unaligned access will 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). + +###### `any` + +* Succeeds when the input is not empty, and: +* The next N bytes encode of 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 the external dependency, the rules are in the contrib-section, and the required header files are not automatically included in `tao/pegtl.hpp`. + +The ICU-based rules are again available in multiple versions, + +* in namespace `tao::pegtl::icu::utf8` for UTF-8 encoded inputs, +* in namespace `tao::pegtl::icu::utf16_be` for big-endian UTF-16 encoded inputs, +* in namespace `tao::pegtl::icu::utf16_le` for little-endian UTF-16 encoded inputs, +* in namespace `tao::pegtl::icu::utf32_be` for big-endian UTF-32 encoded inputs, and +* in namespace `tao::pegtl::icu::utf32_le` for little-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. + +These rules read one or more bytes from the input to form (and match) an 8, 16, 32 or 64-bit value, respectively, and template parameters are given as matching `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. + +###### `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-) <sup>[(meta rules)](#meta-rules)</sup> +* [`alnum`](#alnum) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`alpha`](#alpha) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`alphabetic`](#alphabetic) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`any`](#any) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`any`](#any-1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`any`](#any-2) <sup>[(binary rules)](#binary-rules)</sup> +* [`apply< A... >`](#apply-a-) <sup>[(action rules)](#action-rules)</sup> +* [`apply0< A... >`](#apply0-a-) <sup>[(action rules)](#action-rules)</sup> +* [`ascii_hex_digit`](#ascii_hex_digit) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`at< R... >`](#at-r-) <sup>[(combinators)](#combinators)</sup> +* [`bidi_class< V >`](#bidi_class-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`bidi_control`](#bidi_control) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`bidi_mirrored`](#bidi_mirrored) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`binary_property< P >`](#binary_property-p-) <sup>[(icu rules)](#basic-icu-rules)</sup> +* [`binary_property< P, V >`](#binary_property-p-v-) <sup>[(icu rules)](#basic-icu-rules)</sup> +* [`blank`](#blank) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`block< V >`](#block-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`bof`](#bof) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`bol`](#bol) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`bom`](#bom) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`bytes< Num >`](#bytes-num-) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`canonical_combining_class< V >`](#canonical_combining_class-v-) <sup>[(icu rules)](#icu-rules-for-value-properties)</sup> +* [`case_sensitive`](#case_sensitive) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`control< C, R... >`](#control-c-r-) <sup>[(meta rules)](#meta-rules)</sup> +* [`dash`](#dash) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`decomposition_type< V >`](#decomposition_type-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`default_ignorable_code_point`](#default_ignorable_code_point) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`deprecated`](#deprecated) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`diacritic`](#diacritic) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`digit`](#digit) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`disable< R... >`](#disable-r-) <sup>[(meta rules)](#meta-rules)</sup> +* [`discard`](#discard) <sup>[(meta rules)](#meta-rules)</sup> +* [`east_asian_width< V >`](#east_asian_width-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`enable< R... >`](#enable-r-) <sup>[(meta-rules)](#meta-rules)</sup> +* [`eof`](#eof) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`eol`](#eol) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`eolf`](#eolf) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`extender`](#extender) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`failure`](#failure) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`forty_two< C... >`](#forty_two-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`full_composition_exclusion`](#full_composition_exclusion) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`general_category< V >`](#general_category-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`grapheme_base`](#grapheme_base) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`grapheme_cluster_break< V >`](#grapheme_cluster_break-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`grapheme_extend`](#grapheme_extend) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`grapheme_link`](#grapheme_link) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`hangul_syllable_type< V >`](#hangul_syllable_type-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`hex_digit`](#hex_digit) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`hyphen`](#hyphen) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`id_continue`](#id_continue) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`id_start`](#id_start) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`identifier_first`](#identifier_first) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`identifier_other`](#identifier_other) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`identifier`](#identifier) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`ideographic`](#ideographic) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`ids_binary_operator`](#ids_binary_operator) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`ids_trinary_operator`](#ids_trinary_operator) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`if_apply< R, A... >`](#if_apply-r-a-) <sup>[(action rules)](#action-rules)</sup> +* [`if_must< R, S... >`](#if_must-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`if_must_else< R, S, T >`](#if_must_else-r-s-t-) <sup>[(convenience)](#convenience)</sup> +* [`if_then_else< R, S, T >`](#if_then_else-r-s-t-) <sup>[(convenience)](#convenience)</sup> +* [`istring< C... >`](#istring-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`join_control`](#join_control) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`joining_group< V >`](#joining_group-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`joining_type< V >`](#joining_type-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`keyword< C... >`](#keyword-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`lead_canonical_combining_class< V >`](#lead_canonical_combining_class-v-) <sup>[(icu rules)](#icu-rules-for-value-properties)</sup> +* [`line_break< V >`](#line_break-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`list< R, S >`](#list-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`list< R, S, P >`](#list-r-s-p-) <sup>[(convenience)](#convenience)</sup> +* [`list_must< R, S >`](#list_must-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`list_must< R, S, P >`](#list_must-r-s-p-) <sup>[(convenience)](#convenience)</sup> +* [`list_tail< R, S >`](#list_tail-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`list_tail< R, S, P >`](#list_tail-r-s-p-) <sup>[(convenience)](#convenience)</sup> +* [`logical_order_exception`](#logical_order_exception) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`lower`](#lower) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`lowercase`](#lowercase) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`mask_not_one< M, C... >`](#mask_not_one-m-c-) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_not_range< M, C, D >`](#mask_not_range-m-c-d-) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_one< M, C... >`](#mask_one-m-c-) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_range< M, C, D >`](#mask_range-m-c-d-) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_ranges< M, C1, D1, C2, D2, ... >`](#mask_ranges-m-c1-d1-c2-d2--) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_ranges< M, C1, D1, C2, D2, ..., E >`](#mask_ranges-m-c1-d1-c2-d2--e-) <sup>[(binary rules)](#binary-rules)</sup> +* [`mask_string< M, C... >`](#mask_string-m-c-) <sup>[(binary rules)](#binary-rules)</sup> +* [`math`](#math) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`minus< M, S >`](#minus-m-s-) <sup>[(convenience)](#convenience)</sup> +* [`must< R... >`](#must-r-) <sup>[(convenience)](#convenience)</sup> +* [`nfc_inert`](#nfc_inert) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`nfd_inert`](#nfd_inert) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`nfkc_inert`](#nfkc_inert) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`nfkd_inert`](#nfkd_inert) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`noncharacter_code_point`](#noncharacter_code_point) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`not_at< R... >`](#not_at-r-) <sup>[(combinators)](#combinators)</sup> +* [`not_one< C... >`](#not_one-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`not_one< C... >`](#not_one-c--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`not_one< C... >`](#not_one-c--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`not_range< C, D >`](#not_range-c-d-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`not_range< C, D >`](#not_range-c-d--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`not_range< C, D >`](#not_range-c-d--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`nul`](#nul) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`numeric_type< V >`](#numeric_type-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`one< C... >`](#one-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`one< C... >`](#one-c--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`one< C... >`](#one-c--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`opt< R... >`](#opt-r-) <sup>[(combinators)](#combinators)</sup> +* [`opt_must< R, S...>`](#opt_must-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`pad< R, S, T = S >`](#pad-r-s-t--s-) <sup>[(convenience)](#convenience)</sup> +* [`pad_opt< R, P >`](#pad_opt-r-p-) <sup>[(convenience)](#convenience)</sup> +* [`pattern_syntax`](#pattern_syntax) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`pattern_white_space`](#pattern_white_space) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`plus< R... >`](#plus-r-) <sup>[(combinators)](#combinators)</sup> +* [`posix_alnum`](#posix_alnum) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`posix_blank`](#posix_blank) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`posix_graph`](#posix_graph) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`posix_print`](#posix_print) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`posix_xdigit`](#posix_xdigit) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`print`](#print) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`property_value< P, V >`](#property_value-p-v-) <sup>[(icu rules)](#basic-icu-rules)</sup> +* [`quotation_mark`](#quotation_mark) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`radical`](#radical) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`raise< T >`](#raise-t-) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`range< C, D >`](#range-c-d-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`range< C, D >`](#range-c-d--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`range< C, D >`](#range-c-d--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2--) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2---1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`ranges< C1, D1, C2, D2, ... >`](#ranges-c1-d1-c2-d2---2) <sup>[(binary rules)](#binary-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`ranges< C1, D1, C2, D2, ..., E >`](#ranges-c1-d1-c2-d2--e--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`rep< Num, R... >`](#rep-num-r-) <sup>[(convenience)](#convenience)</sup> +* [`rep_max< Max, R... >`](#rep_max-max-r-) <sup>[(convenience)](#convenience)</sup> +* [`rep_min< Min, R... >`](#rep_min-min-r-) <sup>[(convenience)](#convenience)</sup> +* [`rep_min_max< Min, Max, R... >`](#rep_min_max-min-max-r-) <sup>[(convenience)](#convenience)</sup> +* [`rep_opt< Num, R... >`](#rep_opt-num-r-) <sup>[(convenience)](#convenience)</sup> +* [`require< Num >`](#require-num-) <sup>[(meta-rules)](#meta-rules)</sup> +* [`s_term`](#s_term) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`segment_starter`](#segment_starter) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`sentence_break< V >`](#sentence_break-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`seq< R... >`](#seq-r-) <sup>[(combinators)](#combinators)</sup> +* [`seven`](#seven) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`shebang`](#shebang) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`soft_dotted`](#soft_dotted) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`sor< R... >`](#sor-r-) <sup>[(combinators)](#combinators)</sup> +* [`space`](#space) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`star< R... >`](#star-r-) <sup>[(combinators)](#combinators)</sup> +* [`star_must< R, S... >`](#star_must-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`state< S, R... >`](#state-s-r-) <sup>[(meta rules)](#meta-rules)</sup> +* [`string< C... >`](#string-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`string< C... >`](#string-c--1) <sup>[(unicode rules)](#unicode-rules)</sup> +* [`string< C... >`](#string-c--2) <sup>[(binary rules)](#binary-rules)</sup> +* [`success`](#success) <sup>[(atomic rules)](#atomic-rules)</sup> +* [`TAO_PEGTL_ISTRING( "..." )`](#tao_pegtl_istring--) <sup>[(ascii rules)](#ascii_rules)</sup> +* [`TAO_PEGTL_KEYWORD( "..." )`](#tao_pegtl_keyword--) <sup>[(ascii rules)](#ascii_rules)</sup> +* [`TAO_PEGTL_STRING( "..." )`](#tao_pegtl_string--) <sup>[(ascii rules)](#ascii_rules)</sup> +* [`terminal_punctuation`](#terminal_punctuation) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`three< C >`](#three-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`trail_canonical_combining_class< V >`](#trail_canonical_combining_class-v-) <sup>[(icu rules)](#icu-rules-for-value-properties)</sup> +* [`try_catch< R... >`](#try_catch-r-) <sup>[(convenience)](#convenience)</sup> +* [`try_catch_type< E, R... >`](#try_catch_type-e-r-) <sup>[(convenience)](#convenience)</sup> +* [`two< C >`](#two-c-) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`unified_ideograph`](#unified_ideograph) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`until< R >`](#until-r-) <sup>[(convenience)](#convenience)</sup> +* [`until< R, S... >`](#until-r-s-) <sup>[(convenience)](#convenience)</sup> +* [`upper`](#upper) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`uppercase`](#uppercase) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`variation_selector`](#variation_selector) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`white_space`](#white_space) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`word_break< V >`](#word_break-v-) <sup>[(icu rules)](#icu-rules-for-enumerated-properties)</sup> +* [`xdigit`](#xdigit) <sup>[(ascii rules)](#ascii-rules)</sup> +* [`xid_continue`](#xid_continue) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> +* [`xid_start`](#xid_start) <sup>[(icu rules)](#icu-rules-for-binary-properties)</sup> + +Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/doc/Rules-and-Grammars.md b/packages/PEGTL/doc/Rules-and-Grammars.md new file mode 100644 index 0000000000000000000000000000000000000000..78c548c2ddde11e33717a49628ad3b7879746c54 --- /dev/null +++ b/packages/PEGTL/doc/Rules-and-Grammars.md @@ -0,0 +1,398 @@ +# 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++ +using namespace tao::pegtl; + +struct line_comment + : until< eolf > {}; + +struct list; + +struct list_comment + : if_must< at< one< '(' >, disable< list > > > {}; + +struct comment + : if_must< one< '#' >, sor< list_comment, line_comment > > {}; + +struct nothing + : sor< space, comment > {}; + +struct number + : plus< digit > {}; + +struct symbol + : identifier {}; + +struct atom + : sor< number, symbol > {}; + +struct anything; + +struct list + : if_must< one< '(' >, until< one< ')' >, anything > > {}; + +struct something + : sor< atom, list > {}; + +struct anything + : sor< nothing, something > {}; + +struct file + : until< eof, 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 `match()`-method 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 a rules' `match()`-method 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()`-method returns, and decrements the size by the same amount. + +The PEGTL makes one **important** assumption about all parsing rules. +If a call to a `match()`-method 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, the `match()`-function is called with a single argument, the input. +All rules' `match()`-method return 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 Input > + static bool match( Input& 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` methods, + +1. first `size()` to check whether the input is not empty, + +2. then `begin()` 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++ +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 Input > + static bool match( Input& in ) + { + if( ! in.empty() ) { + if( ( ( *in.begin() ) % M ) == R ) { + in.bump( 1 ); + return true; + } + } + return false; + } + }; + + struct grammar + : tao::pegtl::until< tao::pegtl::eof, my_rule< 3 > > {}; + +} // namespace modulus + +int main( int argc, char* argv[] ) +{ + if( argc > 1 ) { + tao::pegtl::argv_input<> in( argv, 1 ); + tao::pegtl::parse< modulus::grammar >( in ); + } + return 0; +} +``` + +### Complex Rules + +The complex calling convention gives a rule's `match()`-method access to "everything", i.e. some modes, the action and control classes, and all state arguments. +All of these parameters are required for custom rules that need to themselves call other rules for matching. + +The `match()`-method in a complex rule takes the following form. + +```c++ +struct complex_rule +{ + // Optional; explained in the section on Grammar Analysis: + using analyze_t = ...; + + template< tao::pegtl::apply_mode A, + tao::pegtl::rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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 it (the `match()`-function) was first 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 the `match()`-function, to global failure, an exception) the `rewind_mode` is `DONTCARE`. + +The following implementation of the `seq`-rule's `match()`-method shows how to correctly handle the `rewind_mode`. +The input's `mark()`-method 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 the `match()`-method 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 Input, + typename... States > + static bool match( Input& 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 + : tao::pegtl::nothing< Rule > {}; + + template<> + struct action< long_literal_id > + { + template< typename Input > + static void apply( const Input& 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 Input > + static bool match( Input& 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 Input > + static void apply( const Input& 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-2018 Dr. Colin Hirsch and Daniel Frey diff --git a/packages/PEGTL/include/tao/pegtl.hpp b/packages/PEGTL/include/tao/pegtl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..993dfc193cc85f59dffa94a9ff96d2c9e65ada7b --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2014-2018 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/version.hpp" + +#include "pegtl/ascii.hpp" +#include "pegtl/parse.hpp" +#include "pegtl/rules.hpp" +#include "pegtl/uint16.hpp" +#include "pegtl/uint32.hpp" +#include "pegtl/uint64.hpp" +#include "pegtl/uint8.hpp" +#include "pegtl/utf16.hpp" +#include "pegtl/utf32.hpp" +#include "pegtl/utf8.hpp" + +#include "pegtl/argv_input.hpp" +#include "pegtl/buffer_input.hpp" +#include "pegtl/cstream_input.hpp" +#include "pegtl/file_input.hpp" +#include "pegtl/istream_input.hpp" +#include "pegtl/memory_input.hpp" +#include "pegtl/read_input.hpp" +#include "pegtl/string_input.hpp" + +// The following are not included by +// default because they include <iostream>. + +// #include "pegtl/analyze.hpp" + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/analyze_cycles.hpp b/packages/PEGTL/include/tao/pegtl/analysis/analyze_cycles.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e25f3bbf2bcf6df4963b213bd64c546f6af24410 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/analyze_cycles.hpp @@ -0,0 +1,135 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_ANALYZE_CYCLES_HPP +#define TAO_PEGTL_ANALYSIS_ANALYZE_CYCLES_HPP + +#include <cassert> + +#include <map> +#include <set> +#include <stdexcept> + +#include <iostream> +#include <utility> + +#include "../config.hpp" + +#include "grammar_info.hpp" +#include "insert_guard.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + class analyze_cycles_impl + { + protected: + explicit analyze_cycles_impl( const bool verbose ) noexcept + : m_verbose( verbose ), + m_problems( 0 ) + { + } + + const bool m_verbose; + unsigned m_problems; + grammar_info m_info; + std::set< std::string > m_stack; + std::map< std::string, bool > m_cache; + std::map< std::string, bool > m_results; + + const std::map< std::string, rule_info >::const_iterator find( const std::string& name ) const noexcept + { + const auto iter = m_info.map.find( name ); + assert( iter != m_info.map.end() ); + return iter; + } + + bool work( const std::map< std::string, rule_info >::const_iterator& start, const bool accum ) + { + const auto j = m_cache.find( start->first ); + + if( j != m_cache.end() ) { + return j->second; + } + if( const auto g = make_insert_guard( m_stack, start->first ) ) { + switch( start->second.type ) { + case rule_type::ANY: { + bool a = false; + for( const auto& r : start->second.rules ) { + a = a || work( find( r ), accum || a ); + } + return m_cache[ start->first ] = true; + } + case rule_type::OPT: { + bool a = false; + for( const auto& r : start->second.rules ) { + a = a || work( find( r ), accum || a ); + } + return m_cache[ start->first ] = false; + } + case rule_type::SEQ: { + bool a = false; + for( const auto& r : start->second.rules ) { + a = a || work( find( r ), accum || a ); + } + return m_cache[ start->first ] = a; + } + case rule_type::SOR: { + bool a = true; + for( const auto& r : start->second.rules ) { + a = a && work( find( r ), accum ); + } + return m_cache[ start->first ] = a; + } + } + throw std::logic_error( "code should be unreachable: invalid rule_type value" ); // NOLINT, LCOV_EXCL_LINE + } + if( !accum ) { + ++m_problems; + if( m_verbose ) { + std::cout << "problem: cycle without progress detected at rule class " << start->first << std::endl; // LCOV_EXCL_LINE + } + } + return m_cache[ start->first ] = accum; + } + }; + + template< typename Grammar > + class analyze_cycles + : private analyze_cycles_impl + { + public: + explicit analyze_cycles( const bool verbose ) + : analyze_cycles_impl( verbose ) + { + Grammar::analyze_t::template insert< Grammar >( m_info ); + } + + std::size_t problems() + { + for( auto i = m_info.map.begin(); i != m_info.map.end(); ++i ) { + m_results[ i->first ] = work( i, false ); + m_cache.clear(); + } + return m_problems; + } + + template< typename Rule > + bool consumes() const noexcept + { + const auto i = m_results.find( internal::demangle< Rule >() ); + assert( i != m_results.end() ); + return i->second; + } + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/counted.hpp b/packages/PEGTL/include/tao/pegtl/analysis/counted.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6dff5b9897866e2bc3253180814488830ab7bad7 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/counted.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_COUNTED_HPP +#define TAO_PEGTL_ANALYSIS_COUNTED_HPP + +#include "../config.hpp" + +#include "generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + template< rule_type Type, unsigned Count, typename... Rules > + struct counted + : generic< ( Count != 0 ) ? Type : rule_type::OPT, Rules... > + { + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/generic.hpp b/packages/PEGTL/include/tao/pegtl/analysis/generic.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9c0f4e6d653f74a7bb245a7c167d4886ca5ea540 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/generic.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_GENERIC_HPP +#define TAO_PEGTL_ANALYSIS_GENERIC_HPP + +#include "../config.hpp" + +#include "grammar_info.hpp" +#include "insert_rules.hpp" +#include "rule_type.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + template< rule_type Type, typename... Rules > + struct generic + { + template< typename Name > + static std::string insert( grammar_info& g ) + { + const auto r = g.insert< Name >( Type ); + if( r.second ) { + insert_rules< Rules... >::insert( g, r.first->second ); + } + return r.first->first; + } + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/grammar_info.hpp b/packages/PEGTL/include/tao/pegtl/analysis/grammar_info.hpp new file mode 100644 index 0000000000000000000000000000000000000000..06d73e844416ffc04bb3db88cddc1715477c4dc0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/grammar_info.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_GRAMMAR_INFO_HPP +#define TAO_PEGTL_ANALYSIS_GRAMMAR_INFO_HPP + +#include <map> +#include <string> +#include <utility> + +#include "../config.hpp" +#include "../internal/demangle.hpp" + +#include "rule_info.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + struct grammar_info + { + using map_t = std::map< std::string, rule_info >; + map_t map; + + template< typename Name > + std::pair< map_t::iterator, bool > insert( const rule_type type ) + { + return map.insert( map_t::value_type( internal::demangle< Name >(), rule_info( type ) ) ); + } + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/insert_guard.hpp b/packages/PEGTL/include/tao/pegtl/analysis/insert_guard.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6cd61c8062b46f6bbe4dcffd7fff3d5adfb14e8a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/insert_guard.hpp @@ -0,0 +1,68 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_INSERT_GUARD_HPP +#define TAO_PEGTL_ANALYSIS_INSERT_GUARD_HPP + +#include <utility> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + template< typename C > + class insert_guard + { + public: + insert_guard( C& container, const typename C::value_type& value ) + : m_i( container.insert( value ) ), + m_c( &container ) + { + } + + insert_guard( const insert_guard& ) = delete; + + insert_guard( insert_guard&& other ) noexcept + : m_i( other.m_i ), + m_c( other.m_c ) + { + other.m_c = nullptr; + } + + ~insert_guard() + { + if( m_c && m_i.second ) { + m_c->erase( m_i.first ); + } + } + + void operator=( const insert_guard& ) = delete; + void operator=( insert_guard&& ) = delete; + + explicit operator bool() const noexcept + { + return m_i.second; + } + + private: + const std::pair< typename C::iterator, bool > m_i; + C* m_c; + }; + + template< typename C > + insert_guard< C > make_insert_guard( C& container, const typename C::value_type& value ) + { + return insert_guard< C >( container, value ); + } + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/insert_rules.hpp b/packages/PEGTL/include/tao/pegtl/analysis/insert_rules.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6e172b3c7026edea59500fc02f1770c6ea0b4d1c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/insert_rules.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_INSERT_RULES_HPP +#define TAO_PEGTL_ANALYSIS_INSERT_RULES_HPP + +#include "../config.hpp" + +#include "grammar_info.hpp" +#include "rule_info.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + template< typename... > + struct insert_rules; + + template<> + struct insert_rules<> + { + static void insert( grammar_info& /*unused*/, rule_info& /*unused*/ ) + { + } + }; + + template< typename Rule, typename... Rules > + struct insert_rules< Rule, Rules... > + { + static void insert( grammar_info& g, rule_info& r ) + { + r.rules.push_back( Rule::analyze_t::template insert< Rule >( g ) ); + insert_rules< Rules... >::insert( g, r ); + } + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/rule_info.hpp b/packages/PEGTL/include/tao/pegtl/analysis/rule_info.hpp new file mode 100644 index 0000000000000000000000000000000000000000..30af0ed00adc2565c29bc7983a51a2614e89d233 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/rule_info.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_RULE_INFO_HPP +#define TAO_PEGTL_ANALYSIS_RULE_INFO_HPP + +#include <string> +#include <vector> + +#include "../config.hpp" + +#include "rule_type.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + struct rule_info + { + explicit rule_info( const rule_type in_type ) noexcept + : type( in_type ) + { + } + + rule_type type; + std::vector< std::string > rules; + }; + + } // namespace analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analysis/rule_type.hpp b/packages/PEGTL/include/tao/pegtl/analysis/rule_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ebd7f4e3ef7b31c74b4347bfa10179451683525f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analysis/rule_type.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYSIS_RULE_TYPE_HPP +#define TAO_PEGTL_ANALYSIS_RULE_TYPE_HPP + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace analysis + { + enum class rule_type : char + { + 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 analysis + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/analyze.hpp b/packages/PEGTL/include/tao/pegtl/analyze.hpp new file mode 100644 index 0000000000000000000000000000000000000000..08e0d7b406e6232f836dad2dcc3b9b808efc0b92 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/analyze.hpp @@ -0,0 +1,25 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_ANALYZE_HPP +#define TAO_PEGTL_ANALYZE_HPP + +#include "config.hpp" + +#include "analysis/analyze_cycles.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + std::size_t analyze( const bool verbose = true ) + { + return analysis::analyze_cycles< Rule >( verbose ).problems(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/apply_mode.hpp b/packages/PEGTL/include/tao/pegtl/apply_mode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c403c1b72e0c0cd01c615d3834d6c0fb93f48727 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/apply_mode.hpp @@ -0,0 +1,23 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + enum class apply_mode : bool + { + ACTION = true, + NOTHING = false + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/argv_input.hpp b/packages/PEGTL/include/tao/pegtl/argv_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..de2343c5bf3f67216685ca46aed757cfcb4c7334 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/argv_input.hpp @@ -0,0 +1,57 @@ +// Copyright (c) 2017-2018 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 <cstddef> +#include <sstream> +#include <string> +#include <utility> + +#include "config.hpp" +#include "eol.hpp" +#include "memory_input.hpp" +#include "tracking_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline std::string make_argv_source( const std::size_t argn ) + { + std::ostringstream os; + os << "argv[" << argn << ']'; + return os.str(); + } + + } // namespace internal + + template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > + struct argv_input + : public 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 ) ) + { + } + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + argv_input( Ts&&... )->argv_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/ascii.hpp b/packages/PEGTL/include/tao/pegtl/ascii.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b440b4d910253b33cacb11d1bf6fc22b1af15a38 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/ascii.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2014-2018 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 "eol.hpp" + +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + inline namespace ascii + { + // clang-format off + struct alnum : internal::alnum {}; + struct alpha : internal::alpha {}; + 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 eolf : internal::eolf {}; + 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 > > {}; + 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 ) > {}; + 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::if_must< false, 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::three< C > {}; + template< char C > struct two : internal::two< 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 + + template<> + struct keyword<> + { + template< typename Input > + static bool match( Input& /*unused*/ ) noexcept + { + static_assert( sizeof( Input ) == 0, "empty keywords not allowed" ); + return false; + } + }; + + } // namespace ascii + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "internal/pegtl_string.hpp" + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/buffer_input.hpp b/packages/PEGTL/include/tao/pegtl/buffer_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..143d94d3155f75df52d440e64210286e5ff879b0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/buffer_input.hpp @@ -0,0 +1,186 @@ +// Copyright (c) 2016-2018 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 <cstddef> +#include <cstdint> +#include <cstring> +#include <memory> +#include <string> + +#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_impl.hpp" +#include "internal/iterator.hpp" +#include "internal/marker.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Reader, typename Eol = eol::lf_crlf, typename Source = std::string > + class buffer_input + { + public: + static constexpr tracking_mode tracking_mode_v = tracking_mode::IMMEDIATE; + 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 >; + + 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 ), + m_buffer( new char[ maximum ] ), + m_current( m_buffer.get() ), + m_end( m_buffer.get() ), + m_source( std::forward< T >( in_source ) ) + { + } + + buffer_input( const buffer_input& ) = delete; + buffer_input( buffer_input&& ) = delete; + + ~buffer_input() = default; + + void operator=( const buffer_input& ) = delete; + void operator=( buffer_input&& ) = delete; + + bool empty() + { + require( 1 ); + return m_current.data == m_end; + } + + std::size_t size( const std::size_t amount ) + { + require( amount ); + return std::size_t( m_end - m_current.data ); + } + + const char* current() const noexcept + { + return m_current.data; + } + + const char* end( const std::size_t amount ) + { + require( amount ); + return m_end; + } + + std::size_t byte() const noexcept + { + return m_current.byte; + } + + std::size_t line() const noexcept + { + return m_current.line; + } + + std::size_t byte_in_line() const noexcept + { + return m_current.byte_in_line; + } + + const Source& source() const noexcept + { + return m_source; + } + + char peek_char( const std::size_t offset = 0 ) const noexcept + { + return m_current.data[ offset ]; + } + + std::uint8_t peek_byte( 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 + { + 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 ) { + if( m_current.data + amount <= m_buffer.get() + m_maximum ) { + if( const auto r = m_reader( m_end, amount - std::size_t( m_end - m_current.data ) ) ) { + m_end += r; + } + else { + m_maximum = 0; + } + } + } + } + + template< rewind_mode M > + internal::marker< iterator_t, M > mark() noexcept + { + return internal::marker< iterator_t, M >( m_current ); + } + + TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const + { + return TAO_PEGTL_NAMESPACE::position( it, m_source ); + } + + TAO_PEGTL_NAMESPACE::position position() const + { + return position( m_current ); + } + + const iterator_t& iterator() const noexcept + { + return m_current; + } + + 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; + void* internal_state = nullptr; + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/config.hpp b/packages/PEGTL/include/tao/pegtl/config.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ed8cbd1df6bb9c698e3587f59eea8f58526f02fc --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/config.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2017-2018 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 + +// Compatibility, remove with 3.0 +#ifdef TAOCPP_PEGTL_NAMESPACE +#define TAO_PEGTL_NAMESPACE TAOCPP_PEGTL_NAMESPACE +#endif + +#ifndef TAO_PEGTL_NAMESPACE +#define TAO_PEGTL_NAMESPACE pegtl +#endif + +// Enable some improvements to the readability of +// demangled type names under some circumstances. +// #define TAO_PEGTL_PRETTY_DEMANGLE + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/abnf.hpp b/packages/PEGTL/include/tao/pegtl/contrib/abnf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e006f0659b35019903113bdb31b84cc9e6314a46 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/abnf.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 abnf + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/alphabet.hpp b/packages/PEGTL/include/tao/pegtl/contrib/alphabet.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e0228b3282f90f93818105e0040d7bdb95f9ce0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/alphabet.hpp @@ -0,0 +1,75 @@ +// Copyright (c) 2015-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace alphabet + { + static const int a = 'a'; + static const int b = 'b'; + static const int c = 'c'; + static const int d = 'd'; + static const int e = 'e'; + static const int f = 'f'; + static const int g = 'g'; + static const int h = 'h'; + static const int i = 'i'; + static const int j = 'j'; + static const int k = 'k'; + static const int l = 'l'; + static const int m = 'm'; + static const int n = 'n'; + static const int o = 'o'; + static const int p = 'p'; + static const int q = 'q'; + static const int r = 'r'; + static const int s = 's'; + static const int t = 't'; + static const int u = 'u'; + static const int v = 'v'; + static const int w = 'w'; + static const int x = 'x'; + static const int y = 'y'; + static const int z = 'z'; + + static const int A = 'A'; + static const int B = 'B'; + static const int C = 'C'; + static const int D = 'D'; + static const int E = 'E'; + static const int F = 'F'; + static const int G = 'G'; + static const int H = 'H'; + static const int I = 'I'; + static const int J = 'J'; + static const int K = 'K'; + static const int L = 'L'; + static const int M = 'M'; + static const int N = 'N'; + static const int O = 'O'; + static const int P = 'P'; + static const int Q = 'Q'; + static const int R = 'R'; + static const int S = 'S'; + static const int T = 'T'; + static const int U = 'U'; + static const int V = 'V'; + static const int W = 'W'; + static const int X = 'X'; + static const int Y = 'Y'; + static const int Z = 'Z'; + + } // namespace alphabet + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/changes.hpp b/packages/PEGTL/include/tao/pegtl/contrib/changes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0aa8ab038dd195273b3f91edf690d32922405e88 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/changes.hpp @@ -0,0 +1,86 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_CONTRIB_CHANGES_HPP +#define TAO_PEGTL_CONTRIB_CHANGES_HPP + +#include "../config.hpp" +#include "../normal.hpp" + +#include "../internal/conditional.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct dummy_disabled_state + { + template< typename... Ts > + void success( Ts&&... /*unused*/ ) const noexcept + { + } + }; + + template< apply_mode A, typename State > + using state_disable_helper = typename conditional< A == apply_mode::ACTION >::template type< State, dummy_disabled_state >; + + } // namespace internal + + template< typename Rule, typename State, template< typename... > class Base = normal > + struct change_state + : public Base< Rule > + { + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + internal::state_disable_helper< A, State > s; + + if( Base< Rule >::template match< A, M, Action, Control >( in, s ) ) { + s.success( st... ); + return true; + } + return false; + } + }; + + template< typename Rule, template< typename... > class Action, template< typename... > class Base = normal > + struct change_action + : public Base< Rule > + { + template< apply_mode A, + rewind_mode M, + template< typename... > class, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return Base< Rule >::template match< A, M, Action, Control >( in, st... ); + } + }; + + template< template< typename... > class Action, template< typename... > class Base > + struct change_both_helper + { + template< typename T > + using change_action = change_action< T, Action, Base >; + }; + + template< typename Rule, typename State, template< typename... > class Action, template< typename... > class Base = normal > + struct change_state_and_action + : public change_state< Rule, State, change_both_helper< Action, Base >::template change_action > + { + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/counter.hpp b/packages/PEGTL/include/tao/pegtl/contrib/counter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..111fd38a8ebba58eaa73e5afddfaf13723961719 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/counter.hpp @@ -0,0 +1,58 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_CONTRIB_COUNTER_HPP +#define TAO_PEGTL_CONTRIB_COUNTER_HPP + +#include <map> +#include <string> + +#include "../config.hpp" +#include "../normal.hpp" + +#include "../internal/demangle.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct counter_data + { + unsigned start = 0; + unsigned success = 0; + unsigned failure = 0; + }; + + struct counter_state + { + std::map< std::string, counter_data > counts; + }; + + template< typename Rule > + struct counter + : normal< Rule > + { + template< typename Input > + static void start( const Input& /*unused*/, counter_state& ts ) + { + ++ts.counts[ internal::demangle< Rule >() ].start; + } + + template< typename Input > + static void success( const Input& /*unused*/, counter_state& ts ) + { + ++ts.counts[ internal::demangle< Rule >() ].success; + } + + template< typename Input > + static void failure( const Input& /*unused*/, counter_state& ts ) + { + ++ts.counts[ internal::demangle< Rule >() ].failure; + } + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/http.hpp b/packages/PEGTL/include/tao/pegtl/contrib/http.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c49cb6f681821a25ab090d70fdbb286077e61263 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/http.hpp @@ -0,0 +1,151 @@ +// Copyright (c) 2014-2018 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 + +#include "../ascii.hpp" +#include "../config.hpp" +#include "../rules.hpp" +#include "../utf8.hpp" + +#include "abnf.hpp" +#include "uri.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 + + // cppcheck-suppress constStatement + 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 > {}; + + struct chunk_size : plus< abnf::HEXDIG > {}; + + 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 > > {}; + + struct chunk_data : until< at< abnf::CRLF >, abnf::OCTET > {}; + + struct chunk : seq< chunk_size, opt< chunk_ext >, abnf::CRLF, chunk_data, abnf::CRLF > {}; + + struct last_chunk : seq< plus< one< '0' > >, opt< 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 http + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/icu/internal.hpp b/packages/PEGTL/include/tao/pegtl/contrib/icu/internal.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e1af0bba22525bff27052e13e0005b8492b4a294 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/icu/internal.hpp @@ -0,0 +1,76 @@ +// Copyright (c) 2018 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 <unicode/uchar.h> + +#include "../../config.hpp" + +#include "../../analysis/generic.hpp" +#include "../../internal/skip_control.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + namespace icu + { + template< typename Peek, UProperty P, bool V = true > + struct binary_property + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( Peek::peek( in ) ) ) + { + if( const auto r = Peek::peek( in ) ) { + if( u_hasBinaryProperty( r.data, P ) == V ) { + in.bump( r.size ); + return true; + } + } + return false; + } + }; + + template< typename Peek, UProperty P, int V > + struct property_value + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( Peek::peek( in ) ) ) + { + if( const auto r = Peek::peek( in ) ) { + if( u_getIntPropertyValue( r.data, P ) == V ) { + in.bump( r.size ); + return true; + } + } + return false; + } + }; + + } // namespace icu + + template< typename Peek, UProperty P, bool V > + struct skip_control< icu::binary_property< Peek, P, V > > : std::true_type + { + }; + + template< typename Peek, UProperty P, int V > + struct skip_control< icu::property_value< Peek, P, V > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/icu/utf16.hpp b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf16.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2412545d39d166ea2faf48b9ccf6e17bbd26caee --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf16.hpp @@ -0,0 +1,212 @@ +// Copyright (c) 2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace utf16_be + { + namespace 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 <unicode/unorm2.h>: + // 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 icu + + } // namespace utf16_be + + namespace utf16_le + { + namespace 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 <unicode/unorm2.h>: + // 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 icu + + } // namespace utf16_le + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/icu/utf32.hpp b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..95c1a34b82b80aa92f5888fe4caa606752666046 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf32.hpp @@ -0,0 +1,212 @@ +// Copyright (c) 2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace utf32_be + { + namespace 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 <unicode/unorm2.h>: + // 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 icu + + } // namespace utf32_be + + namespace utf32_le + { + namespace 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 <unicode/unorm2.h>: + // 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 icu + + } // namespace utf32_le + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/icu/utf8.hpp b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a2aba563f5d6200601a555a8b959911dc5d791f3 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/icu/utf8.hpp @@ -0,0 +1,117 @@ +// Copyright (c) 2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace utf8 + { + namespace 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 <unicode/unorm2.h>: + // 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 icu + + } // namespace utf8 + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/if_then.hpp b/packages/PEGTL/include/tao/pegtl/contrib/if_then.hpp new file mode 100644 index 0000000000000000000000000000000000000000..496ada60ec1565923b41130d2125be56a9303711 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/if_then.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2018 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 <type_traits> + +#include "../config.hpp" + +#include "../internal/if_then_else.hpp" +#include "../internal/seq.hpp" +#include "../internal/skip_control.hpp" +#include "../internal/trivial.hpp" + +namespace tao +{ + 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< trivial< true >, seq< Thens... > > > >; + }; + + template<> + struct if_then<> + : trivial< false > + { + }; + + template< typename... Pairs > + struct skip_control< if_then< Pairs... > > : std::true_type + { + }; + + } // namespace internal + + template< typename Cond, typename... Thens > + using if_then = internal::if_then< internal::if_pair< Cond, internal::seq< Thens... > > >; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp b/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d619afd31e28f6236e4c2c378305a683b3cdb25c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/integer.hpp @@ -0,0 +1,108 @@ +// Copyright (c) 2018 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 + +#include <limits> +#include <type_traits> + +#include "../ascii.hpp" +#include "../parse_error.hpp" +#include "../rules.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace integer + { + namespace internal + { + template< typename I, I Limit, typename Input > + I actual_convert( const Input& in, std::size_t index ) + { + static constexpr I cutoff = Limit / 10; + static constexpr I cutlim = Limit % 10; + + I out = in.peek_char( index ) - '0'; + while( ++index < in.size() ) { + const I c = in.peek_char( index ) - '0'; + if( ( out > cutoff ) || ( ( out == cutoff ) && ( c > cutlim ) ) ) { + throw parse_error( "integer out of range", in ); + } + out *= 10; + out += c; + } + return out; + } + + template< typename I, typename Input > + I convert_positive( const Input& in, std::size_t index ) + { + static constexpr I limit = std::numeric_limits< I >::max(); + return actual_convert< I, limit >( in, index ); + } + + template< typename I, typename Input > + I convert_negative( const Input& in, std::size_t index ) + { + using U = typename std::make_unsigned< I >::type; + static constexpr U limit = static_cast< U >( std::numeric_limits< I >::max() ) + 1; + return static_cast< I >( ~actual_convert< U, limit >( in, index ) ) + 1; + } + + } // namespace internal + + struct unsigned_rule + : plus< digit > + { + }; + + struct unsigned_action + { + // Assumes that 'in' contains a non-empty sequence of ASCII digits. + + template< typename Input, typename State > + static void apply( const Input& in, State& st ) + { + using T = typename std::decay< decltype( st.converted ) >::type; + static_assert( std::is_integral< T >::value, "need integral type" ); + static_assert( std::is_unsigned< T >::value, "need unsigned type" ); + st.converted = internal::convert_positive< T >( in, 0 ); + } + }; + + struct signed_rule + : seq< opt< one< '+', '-' > >, plus< digit > > + { + }; + + 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 Input, typename State > + static void apply( const Input& in, State& st ) + { + using T = typename std::decay< decltype( st.converted ) >::type; + static_assert( std::is_integral< T >::value, "need integral type" ); + static_assert( std::is_signed< T >::value, "need signed type" ); + const auto c = in.peek_char(); + if( c == '-' ) { + st.converted = internal::convert_negative< T >( in, 1 ); + } + else { + st.converted = internal::convert_positive< T >( in, std::size_t( c == '+' ) ); + } + } + }; + + } // namespace integer + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/json.hpp b/packages/PEGTL/include/tao/pegtl/contrib/json.hpp new file mode 100644 index 0000000000000000000000000000000000000000..576532c62ad3083704fbd67a316178f9fc6962a0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/json.hpp @@ -0,0 +1,98 @@ +// Copyright (c) 2014-2018 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" + +#include "abnf.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 : internal::seq< R, internal::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' > {}; + struct null : string< 'n', 'u', 'l', 'l' > {}; + struct true_ : string< 't', 'r', 'u', 'e' > {}; + + struct digits : plus< abnf::DIGIT > {}; + struct exp : seq< one< 'e', 'E' >, opt< one< '-', '+'> >, must< digits > > {}; + struct frac : if_must< one< '.' >, digits > {}; + struct int_ : sor< one< '0' >, digits > {}; + struct number : seq< opt< one< '-' > >, int_, opt< frac >, opt< exp > > {}; + + 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; + }; + + struct key_content : until< at< one< '"' > >, must< char_ > > {}; + struct key : seq< one< '"' >, must< key_content >, any > + { + using content = key_content; + }; + + struct value; + + struct array_element; + struct array_content : opt< list_must< array_element, value_separator > > {}; + struct array : seq< begin_array, array_content, must< end_array > > + { + using begin = begin_array; + using end = end_array; + using element = array_element; + using content = array_content; + }; + + struct member : if_must< key, name_separator, value > {}; + struct object_content : opt< list_must< member, value_separator > > {}; + struct object : seq< begin_object, object_content, must< end_object > > + { + using begin = begin_object; + using end = end_object; + using element = member; + using content = object_content; + }; + + struct value : padr< sor< string, number, object, array, false_, true_, null > > {}; + struct array_element : seq< value > {}; + + struct text : seq< star< ws >, value > {}; + // clang-format on + + } // namespace json + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp b/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp new file mode 100644 index 0000000000000000000000000000000000000000..66401e5eadd149fa96dd90fec341d92dcdb205d7 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/parse_tree.hpp @@ -0,0 +1,461 @@ +// Copyright (c) 2017-2018 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 <cassert> +#include <memory> +#include <type_traits> +#include <typeinfo> +#include <utility> +#include <vector> + +#include "../config.hpp" +#include "../normal.hpp" +#include "../nothing.hpp" +#include "../parse.hpp" + +#include "../analysis/counted.hpp" +#include "../analysis/generic.hpp" +#include "../internal/conditional.hpp" +#include "../internal/demangle.hpp" +#include "../internal/iterator.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace parse_tree + { + template< typename T > + struct basic_node + { + using node_t = T; + using children_t = std::vector< std::unique_ptr< node_t > >; + children_t children; + + const std::type_info* id = nullptr; + std::string 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; + + bool is_root() const noexcept + { + return id == nullptr; + } + + template< typename U > + bool is() const noexcept + { + return id == &typeid( U ); + } + + std::string name() const + { + assert( !is_root() ); + return TAO_PEGTL_NAMESPACE::internal::demangle( id->name() ); + } + + position begin() const + { + return position( m_begin, source ); + } + + position end() const + { + return position( m_end, source ); + } + + bool has_content() const noexcept + { + return m_end.data != nullptr; + } + + std::string content() const + { + assert( has_content() ); + return std::string( m_begin.data, m_end.data ); + } + + template< typename... States > + void remove_content( States&&... /*unused*/ ) noexcept + { + m_end.reset(); + } + + // all non-root nodes are initialized by calling this method + template< typename Rule, typename Input, typename... States > + void start( const Input& in, States&&... /*unused*/ ) + { + id = &typeid( Rule ); + source = in.source(); + m_begin = in.iterator(); + } + + // if parsing of the rule succeeded, this method is called + template< typename Rule, typename Input, typename... States > + void success( const Input& in, States&&... /*unused*/ ) noexcept + { + m_end = in.iterator(); + } + + // if parsing of the rule failed, this method is called + template< typename Rule, typename Input, typename... States > + void failure( const Input& /*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::unique_ptr< Node >( new Node ) ); // NOLINT: std::make_unique requires C++14 + } + + std::unique_ptr< Node >& back() noexcept + { + return stack.back(); + } + + void pop_back() noexcept + { + return stack.pop_back(); + } + }; + + template< typename Node, typename Selector, typename = void > + struct transform + { + template< typename... States > + static void call( std::unique_ptr< Node >& /*unused*/, States&&... /*unused*/ ) noexcept + { + } + }; + + template< typename Node, typename Selector > + struct transform< Node, Selector, decltype( Selector::transform( std::declval< std::unique_ptr< Node >& >() ), void() ) > + { + template< typename... States > + static void call( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( n, st... ) ) ) + { + Selector::transform( n, st... ); + } + }; + + template< unsigned Level, typename Analyse, template< typename... > class Selector > + struct is_leaf + : std::false_type + { + }; + + template< analysis::rule_type Type, template< typename... > class Selector > + struct is_leaf< 0, analysis::generic< Type >, Selector > + : std::true_type + { + }; + + template< analysis::rule_type Type, unsigned Count, template< typename... > class Selector > + struct is_leaf< 0, analysis::counted< Type, Count >, Selector > + : std::true_type + { + }; + + template< analysis::rule_type Type, typename... Rules, template< typename... > class Selector > + struct is_leaf< 0, analysis::generic< Type, Rules... >, Selector > + : std::false_type + { + }; + + template< analysis::rule_type Type, unsigned Count, typename... Rules, template< typename... > class Selector > + struct is_leaf< 0, analysis::counted< Type, Count, Rules... >, Selector > + : std::false_type + { + }; + + template< bool... > + struct bool_sequence; + + template< bool... Bs > + using is_all = std::is_same< bool_sequence< Bs..., true >, bool_sequence< true, Bs... > >; + + template< unsigned Level, typename Rule, template< typename... > class Selector > + using is_unselected_leaf = std::integral_constant< bool, !Selector< Rule >::value && is_leaf< Level, typename Rule::analyze_t, Selector >::value >; + + template< unsigned Level, analysis::rule_type Type, typename... Rules, template< typename... > class Selector > + struct is_leaf< Level, analysis::generic< Type, Rules... >, Selector > + : is_all< is_unselected_leaf< Level - 1, Rules, Selector >::value... > + { + }; + + template< unsigned Level, analysis::rule_type Type, unsigned Count, typename... Rules, template< typename... > class Selector > + struct is_leaf< Level, analysis::counted< Type, Count, Rules... >, Selector > + : is_all< is_unselected_leaf< Level - 1, Rules, Selector >::value... > + { + }; + + template< typename Node, template< typename... > class Selector, template< typename... > class Control > + struct make_control + { + template< typename Rule, bool, bool > + struct control; + + template< typename Rule > + using type = control< Rule, Selector< Rule >::value, is_leaf< 8, typename Rule::analyze_t, Selector >::value >; + }; + + template< typename Node, template< typename... > class Selector, template< typename... > class Control > + template< typename Rule > + struct make_control< Node, Selector, Control >::control< Rule, false, true > + : Control< Rule > + { + }; + + template< typename Node, template< typename... > class Selector, template< typename... > class Control > + template< typename Rule > + struct make_control< Node, Selector, Control >::control< Rule, false, false > + : Control< Rule > + { + template< typename Input, typename... States > + static void start( const Input& in, States&&... st ) + { + Control< Rule >::start( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + state.emplace_back(); + } + + template< typename Input, typename... States > + static void success( const Input& in, States&&... st ) + { + Control< Rule >::success( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + auto n = std::move( state.back() ); + state.pop_back(); + for( auto& c : n->children ) { + state.back()->children.emplace_back( std::move( c ) ); + } + } + + template< typename Input, typename... States > + static void failure( const Input& in, States&&... st ) noexcept( noexcept( Control< Rule >::failure( in, st... ) ) ) + { + Control< Rule >::failure( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + 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 >::control< Rule, true, B > + : Control< Rule > + { + template< typename Input, typename... States > + static void start( const Input& in, States&&... st ) + { + Control< Rule >::start( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + state.emplace_back(); + state.back()->template start< Rule >( in, st... ); + } + + template< typename Input, typename... States > + static void success( const Input& in, States&&... st ) + { + Control< Rule >::success( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + auto n = std::move( state.back() ); + state.pop_back(); + n->template success< Rule >( in, st... ); + transform< Node, Selector< Rule > >::call( n, st... ); + if( n ) { + state.back()->emplace_back( std::move( n ), st... ); + } + } + + template< typename Input, typename... States > + static void failure( const Input& in, States&&... st ) noexcept( noexcept( Control< Rule >::failure( in, st... ) ) && noexcept( std::declval< node& >().template failure< Rule >( in, st... ) ) ) + { + Control< Rule >::failure( in, st... ); + auto& state = *static_cast< internal::state< Node >* >( in.internal_state ); + state.back()->template failure< Rule >( in, st... ); + state.pop_back(); + } + }; + + template< typename > + struct element + { + }; + + template< typename > + struct store_all : std::true_type + { + }; + + } // namespace internal + + struct store_content : std::true_type + { + template< typename Node, typename... States > + static void transform( std::unique_ptr< Node >& /*unused*/, States&&... /*unused*/ ) noexcept + { + } + }; + + // some nodes don't need to store their content + struct remove_content : std::true_type + { + 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 apply B + template< typename Base > + struct fold_one_or : Base + { + template< typename Node, typename... States > + static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.size(), Base::transform( n, st... ) ) ) + { + if( n->children.size() == 1 ) { + n = std::move( n->children.front() ); + } + else { + Base::transform( n, st... ); + } + } + }; + + // if a node has no children, discard the node, otherwise apply B + template< typename Base > + struct discard_empty_or : Base + { + template< typename Node, typename... States > + static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.empty(), Base::transform( n, st... ) ) ) + { + if( n->children.empty() ) { + n.reset(); + } + else { + Base::transform( n, st... ); + } + } + }; + + using fold_one = fold_one_or< remove_content >; + using discard_empty = discard_empty_or< remove_content >; + + template< typename Rule, typename... Collections > + struct selector : std::false_type + { + }; + + // TODO: Implement in a non-recursive way + // TODO: Check for multiple matches (currently: first match wins) + template< typename Rule, typename Collection, typename... Collections > + struct selector< Rule, Collection, Collections... > + : TAO_PEGTL_NAMESPACE::internal::conditional< Collection::template contains< Rule >::value >::template type< typename Collection::type, selector< Rule, Collections... > > + { + }; + + template< typename Base > + struct apply + { + template< typename... Rules > + struct to + : internal::element< Rules >... + { + using type = Base; + + template< typename Rule > + using contains = std::is_base_of< internal::element< Rule >, to >; + }; + }; + + using apply_store_content = apply< store_content >; + using apply_remove_content = apply< remove_content >; + using apply_fold_one = apply< fold_one >; + using apply_discard_empty = apply< discard_empty >; + + template< typename Rule, + typename Node, + template< typename... > class Selector = internal::store_all, + template< typename... > class Action = nothing, + template< typename... > class Control = normal, + typename Input, + typename... States > + std::unique_ptr< Node > parse( Input&& in, States&&... st ) + { + internal::state< Node > state; + assert( in.internal_state == nullptr ); + in.internal_state = &state; + if( !TAO_PEGTL_NAMESPACE::parse< Rule, Action, internal::make_control< Node, Selector, Control >::template type >( in, st... ) ) { + 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 Input, + typename... States > + std::unique_ptr< node > parse( Input&& in, States&&... st ) + { + return parse< Rule, node, Selector, Action, Control >( in, st... ); + } + + } // namespace parse_tree + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/raw_string.hpp b/packages/PEGTL/include/tao/pegtl/contrib/raw_string.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9936b81178bcd25a48e0f201baee53211216709d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/raw_string.hpp @@ -0,0 +1,223 @@ +// Copyright (c) 2014-2018 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 <cstddef> +#include <type_traits> + +#include "../apply_mode.hpp" +#include "../config.hpp" +#include "../rewind_mode.hpp" + +#include "../internal/bytes.hpp" +#include "../internal/eof.hpp" +#include "../internal/eol.hpp" +#include "../internal/must.hpp" +#include "../internal/not_at.hpp" +#include "../internal/rule_conjunction.hpp" +#include "../internal/seq.hpp" +#include "../internal/skip_control.hpp" +#include "../internal/star.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< char Open, char Marker > + struct raw_string_open + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& 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 ); + eol::match( in ); + return true; + case Marker: + break; + default: + return false; + } + } + return false; + } + }; + + template< char Open, char Marker > + struct skip_control< raw_string_open< Open, Marker > > : std::true_type + { + }; + + template< char Marker, char Close > + struct at_raw_string_close + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& 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 > + struct skip_control< at_raw_string_close< Marker, Close > > : std::true_type + { + }; + + template< typename Cond, typename... Rules > + struct raw_string_until; + + template< typename Cond > + struct raw_string_until< Cond > + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, bytes< 1 > >, Cond >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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... Rules > + struct raw_string_until + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, Rules... >, Cond >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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( in.empty() || ( !rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) ) { + return false; + } + } + return m( true ); + } + }; + + template< typename Cond, typename... Rules > + struct skip_control< raw_string_until< Cond, Rules... > > : std::true_type + { + }; + + } // 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 immediately 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 analyze_t = typename internal::seq< internal::bytes< 1 >, content, internal::bytes< 1 > >::analyze_t; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + std::size_t marker_size; + if( internal::raw_string_open< Open, Marker >::template match< A, M, Action, Control >( in, marker_size ) ) { + internal::must< content >::template match< A, M, Action, Control >( in, marker_size, st... ); + in.bump_in_this_line( marker_size ); + return true; + } + return false; + } + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/rep_one_min_max.hpp b/packages/PEGTL/include/tao/pegtl/contrib/rep_one_min_max.hpp new file mode 100644 index 0000000000000000000000000000000000000000..99014d059287372b033630b179f6b2df0d5f9466 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/rep_one_min_max.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2017-2018 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 <algorithm> + +#include "../config.hpp" + +#include "../analysis/counted.hpp" + +#include "../internal/bump_help.hpp" +#include "../internal/skip_control.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Min, unsigned Max, char C > + struct rep_one_min_max + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, Min >; + + static_assert( Min <= Max, "invalid rep_one_min_max rule (maximum number of repetitions smaller than minimum)" ); + + template< typename Input > + static bool match( Input& 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< result_on_found::SUCCESS, Input, char, C >( in, i ); + return true; + } + return false; + } + }; + + template< unsigned Min, unsigned Max, char C > + struct skip_control< rep_one_min_max< Min, Max, C > > : std::true_type + { + }; + + } // 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 > + { + }; + + struct ellipsis : internal::rep_one_min_max< 3, 3, '.' > + { + }; + + } // namespace ascii + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/to_string.hpp b/packages/PEGTL/include/tao/pegtl/contrib/to_string.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ff60aa0aa56a8326b6a59f92d76abf4ab77c1fa1 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/to_string.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2017-2018 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 <string> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename > + struct to_string; + + template< template< char... > class X, char... Cs > + struct to_string< X< Cs... > > + { + static std::string get() + { + const char s[] = { Cs..., 0 }; + return std::string( s, sizeof...( Cs ) ); + } + }; + + } // namespace internal + + template< typename T > + std::string to_string() + { + return internal::to_string< T >::get(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/tracer.hpp b/packages/PEGTL/include/tao/pegtl/contrib/tracer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..05216f75b4a42cd7a6fb7638e77c5e513bcd2b38 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/tracer.hpp @@ -0,0 +1,115 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_CONTRIB_TRACER_HPP +#define TAO_PEGTL_CONTRIB_TRACER_HPP + +#include <cassert> +#include <iomanip> +#include <iostream> +#include <utility> +#include <vector> + +#include "../config.hpp" +#include "../normal.hpp" + +#include "../internal/demangle.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct trace_state + { + unsigned rule = 0; + unsigned line = 0; + std::vector< unsigned > stack; + }; + + template< typename Rule > + struct tracer + : normal< Rule > + { + template< typename Input, typename... States > + static void start( const Input& in, States&&... /*unused*/ ) + { + std::cerr << in.position() << " start " << internal::demangle< Rule >() << std::endl; + } + + template< typename Input > + static void start( const Input& in, trace_state& ts ) + { + std::cerr << std::setw( 6 ) << ++ts.line << " " << std::setw( 6 ) << ++ts.rule << " " << in.position() << " start " << internal::demangle< Rule >() << std::endl; + ts.stack.push_back( ts.rule ); + } + + template< typename Input, typename... States > + static void success( const Input& in, States&&... /*unused*/ ) + { + std::cerr << in.position() << " success " << internal::demangle< Rule >() << std::endl; + } + + template< typename Input > + static void success( const Input& in, trace_state& ts ) + { + assert( !ts.stack.empty() ); + std::cerr << std::setw( 6 ) << ++ts.line << " " << std::setw( 6 ) << ts.stack.back() << " " << in.position() << " success " << internal::demangle< Rule >() << std::endl; + ts.stack.pop_back(); + } + + template< typename Input, typename... States > + static void failure( const Input& in, States&&... /*unused*/ ) + { + std::cerr << in.position() << " failure " << internal::demangle< Rule >() << std::endl; + } + + template< typename Input > + static void failure( const Input& in, trace_state& ts ) + { + assert( !ts.stack.empty() ); + std::cerr << std::setw( 6 ) << ++ts.line << " " << std::setw( 6 ) << ts.stack.back() << " " << in.position() << " failure " << internal::demangle< Rule >() << std::endl; + ts.stack.pop_back(); + } + + template< template< typename... > class Action, typename Input, typename... States > + static auto apply0( const Input& /*unused*/, States&&... st ) + -> decltype( Action< Rule >::apply0( st... ) ) + { + std::cerr << "apply0 " << internal::demangle< Action< Rule > >() << std::endl; + return Action< Rule >::apply0( st... ); + } + + template< template< typename... > class Action, typename Input > + static auto apply0( const Input& /*unused*/, trace_state& ts ) + -> decltype( Action< Rule >::apply0( ts ) ) + { + std::cerr << std::setw( 6 ) << ++ts.line << " " << internal::demangle< Action< Rule > >() << "::apply0()" << std::endl; + return Action< Rule >::apply0( ts ); + } + + template< template< typename... > class Action, typename Iterator, typename Input, typename... States > + static auto apply( const Iterator& begin, const Input& in, States&&... st ) + -> decltype( Action< Rule >::apply( std::declval< typename Input::action_t >(), st... ) ) + { + std::cerr << "apply " << internal::demangle< Action< Rule > >() << std::endl; + using action_t = typename Input::action_t; + const action_t action_input( begin, in ); + return Action< Rule >::apply( action_input, st... ); + } + + template< template< typename... > class Action, typename Iterator, typename Input > + static auto apply( const Iterator& begin, const Input& in, trace_state& ts ) + -> decltype( Action< Rule >::apply( std::declval< typename Input::action_t >(), ts ) ) + { + std::cerr << std::setw( 6 ) << ++ts.line << " " << internal::demangle< Action< Rule > >() << "::apply()" << std::endl; + using action_t = typename Input::action_t; + const action_t action_input( begin, in ); + return Action< Rule >::apply( action_input, ts ); + } + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/unescape.hpp b/packages/PEGTL/include/tao/pegtl/contrib/unescape.hpp new file mode 100644 index 0000000000000000000000000000000000000000..704ede62ab8f7e7a9b4f368419b4dc1418418745 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/unescape.hpp @@ -0,0 +1,212 @@ +// Copyright (c) 2014-2018 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 <cassert> +#include <string> + +#include "../ascii.hpp" +#include "../config.hpp" +#include "../parse_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace unescape + { + struct state + { + std::string unescaped; + }; + + // Utility functions for the unescape actions. + + 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::TAO_PEGTL_NAMESPACE::ascii::xdigit! + template< typename I > + 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 ); + } + throw std::runtime_error( "invalid character in unhex" ); // NOLINT, LCOV_EXCL_LINE + } + + template< typename I > + 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 Input, typename State > + static void apply( const Input& in, State& st ) + { + st.unescaped.append( in.begin(), in.size() ); + } + }; + + // This action MUST be called for a character matching T which MUST be tao::TAO_PEGTL_NAMESPACE::one< ... >. + template< typename T, char... Rs > + struct unescape_c + { + template< typename Input, typename State > + static void apply( const Input& in, State& st ) + { + assert( in.size() == 1 ); + st.unescaped += apply_one( in, static_cast< const T* >( nullptr ) ); + } + + template< typename Input, char... Qs > + static char apply_one( const Input& 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 Input > + static char apply_two( const Input& 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 ); + } + } + throw parse_error( "invalid character in unescape", in ); // NOLINT, 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 + { + template< typename Input, typename State > + static void apply( const Input& in, State& st ) + { + assert( !in.empty() ); // First character MUST be present, usually 'u' or 'U'. + if( !utf8_append_utf32( st.unescaped, unhex_string< unsigned >( in.begin() + 1, in.end() ) ) ) { + throw parse_error( "invalid escaped unicode code point", in ); + } + } + }; + + struct unescape_x + { + template< typename Input, typename State > + static void apply( const Input& in, State& st ) + { + assert( !in.empty() ); // First character MUST be present, usually 'x'. + st.unescaped += 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 st.unescaped, as required for JSON by RFC 8259. + + struct unescape_j + { + template< typename Input, typename State > + static void apply( const Input& in, State& st ) + { + 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; + // note: no need to check the result code, as we are always >= 0x10000 and < 0x110000. + utf8_append_utf32( st.unescaped, ( ( ( c & 0x03ff ) << 10 ) | ( d & 0x03ff ) ) + 0x10000 ); + continue; + } + } + if( !utf8_append_utf32( st.unescaped, c ) ) { + throw parse_error( "invalid escaped unicode code point", in ); + } + } + } + }; + + } // namespace unescape + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp b/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7f51fad79cf22962c2570299157353e4b79ec2d3 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/contrib/uri.hpp @@ -0,0 +1,115 @@ +// Copyright (c) 2014-2018 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 + +#include "../ascii.hpp" +#include "../config.hpp" +#include "../rules.hpp" +#include "../utf8.hpp" + +#include "abnf.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 : sor< one< '0' >, + rep_min_max< 1, 2, abnf::DIGIT >, + seq< one< '1' >, abnf::DIGIT, abnf::DIGIT >, + seq< one< '2' >, range< '0', '4' >, abnf::DIGIT >, + seq< string< '2', '5' >, range< '0', '5' > > > {}; + + 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' >, 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 uri + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/cstream_input.hpp b/packages/PEGTL/include/tao/pegtl/cstream_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..88c1a8eadb5a0360a22259899f9d00d6e548f202 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/cstream_input.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2017-2018 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 <cstdio> + +#include "buffer_input.hpp" +#include "config.hpp" +#include "eol.hpp" + +#include "internal/cstream_reader.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Eol = eol::lf_crlf > + struct cstream_input + : buffer_input< internal::cstream_reader, Eol > + { + 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::forward< T >( in_source ), in_maximum, in_stream ) + { + } + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + cstream_input( Ts&&... )->cstream_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/eol.hpp b/packages/PEGTL/include/tao/pegtl/eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..29a8a8959e80ae2dafffa78c71a4e3600cf29e14 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/eol.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2016-2018 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 +{ + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/eol_pair.hpp b/packages/PEGTL/include/tao/pegtl/eol_pair.hpp new file mode 100644 index 0000000000000000000000000000000000000000..384bea1e5204b379d606dfa558a15c04e552a624 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/eol_pair.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2017-2018 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 <cstddef> +#include <utility> + +#include "config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + using eol_pair = std::pair< bool, std::size_t >; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/file_input.hpp b/packages/PEGTL/include/tao/pegtl/file_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1959a095a2462309216fe0c08c12d8842c1583dd --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/file_input.hpp @@ -0,0 +1,50 @@ +// Copyright (c) 2015-2018 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 <unistd.h> // 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 +{ + namespace TAO_PEGTL_NAMESPACE + { +#if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 ) + template< tracking_mode P = tracking_mode::IMMEDIATE, 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::IMMEDIATE, typename Eol = eol::lf_crlf > + struct file_input + : read_input< P, Eol > + { + using read_input< P, Eol >::read_input; + }; +#endif + +#ifdef __cpp_deduction_guides + template< typename... Ts > + explicit file_input( Ts&&... )->file_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/input_error.hpp b/packages/PEGTL/include/tao/pegtl/input_error.hpp new file mode 100644 index 0000000000000000000000000000000000000000..eb302c9f7967675a592b315fa6bc57666553a37a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/input_error.hpp @@ -0,0 +1,51 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INPUT_ERROR_HPP +#define TAO_PEGTL_INPUT_ERROR_HPP + +#include <cerrno> +#include <sstream> +#include <stdexcept> + +#include "config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct input_error + : std::runtime_error + { + input_error( const std::string& message, const int in_errorno ) + : std::runtime_error( message ), + errorno( in_errorno ) + { + } + + int errorno; + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#define TAO_PEGTL_INTERNAL_UNWRAP( ... ) __VA_ARGS__ + +#define TAO_PEGTL_THROW_INPUT_ERROR( MESSAGE ) \ + do { \ + const int errorno = errno; \ + std::ostringstream oss; \ + oss << "pegtl: " << TAO_PEGTL_INTERNAL_UNWRAP( MESSAGE ) << " errno " << errorno; \ + throw tao::TAO_PEGTL_NAMESPACE::input_error( oss.str(), errorno ); \ + } while( false ) + +#define TAO_PEGTL_THROW_INPUT_WIN32_ERROR( MESSAGE ) \ + do { \ + const int errorno = GetLastError(); \ + std::ostringstream oss; \ + oss << "pegtl: " << TAO_PEGTL_INTERNAL_UNWRAP( MESSAGE ) << " GetLastError() " << errorno; \ + throw tao::TAO_PEGTL_NAMESPACE::input_error( oss.str(), errorno ); \ + } while( false ) + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/action.hpp b/packages/PEGTL/include/tao/pegtl/internal/action.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b7a4f6ac111b4b068521bae679feed6e5544b47e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/action.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< template< typename... > class Action, typename... Rules > + struct action + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return duseltronik< seq< Rules... >, A, M, Action, Control >::match( in, st... ); + } + }; + + template< template< typename... > class Action, typename... Rules > + struct skip_control< action< Action, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp b/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ec15ea1096a4ab328edcf0d405b49a79154ab170 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/action_input.hpp @@ -0,0 +1,114 @@ +// Copyright (c) 2016-2018 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 <cstddef> +#include <cstdint> +#include <string> + +#include "iterator.hpp" + +#include "../config.hpp" +#include "../position.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline const char* begin_c_ptr( const char* p ) noexcept + { + return p; + } + + inline const char* begin_c_ptr( const iterator& it ) noexcept + { + return it.data; + } + + template< typename Input > + class action_input + { + public: + using input_t = Input; + using iterator_t = typename Input::iterator_t; + + action_input( const iterator_t& in_begin, const Input& 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; + + const iterator_t& iterator() const noexcept + { + return m_begin; + } + + const Input& input() const noexcept + { + return m_input; + } + + const char* begin() const noexcept + { + return begin_c_ptr( iterator() ); + } + + const char* end() const noexcept + { + return input().current(); + } + + bool empty() const noexcept + { + return begin() == end(); + } + + std::size_t size() const noexcept + { + return std::size_t( end() - begin() ); + } + + std::string string() const + { + return std::string( begin(), end() ); + } + + char peek_char( const std::size_t offset = 0 ) const noexcept + { + return begin()[ offset ]; + } + + std::uint8_t peek_byte( const std::size_t offset = 0 ) const noexcept + { + return static_cast< std::uint8_t >( peek_char( offset ) ); + } + + TAO_PEGTL_NAMESPACE::position position() const + { + return input().position( iterator() ); // NOTE: Not efficient with LAZY inputs. + } + + protected: + const iterator_t m_begin; + const Input& m_input; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/alnum.hpp b/packages/PEGTL/include/tao/pegtl/internal/alnum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f42fa1a2a145ed67235beb37625707ad8d5b23d3 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/alnum.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_ALNUM_HPP +#define TAO_PEGTL_INTERNAL_ALNUM_HPP + +#include "../config.hpp" + +#include "peek_char.hpp" +#include "ranges.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + using alnum = ranges< peek_char, 'a', 'z', 'A', 'Z', '0', '9' >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/alpha.hpp b/packages/PEGTL/include/tao/pegtl/internal/alpha.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b55d1ed633197aee479227938d786bfa2c6e7976 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/alpha.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_ALPHA_HPP +#define TAO_PEGTL_INTERNAL_ALPHA_HPP + +#include "../config.hpp" + +#include "peek_char.hpp" +#include "ranges.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + using alpha = ranges< peek_char, 'a', 'z', 'A', 'Z' >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/any.hpp b/packages/PEGTL/include/tao/pegtl/internal/any.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4c962d74708a610505b423b6bb7e0670c73398c0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/any.hpp @@ -0,0 +1,68 @@ +// Copyright (c) 2014-2018 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 "peek_char.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Peek > + struct any; + + template<> + struct any< peek_char > + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.empty() ) ) + { + if( !in.empty() ) { + in.bump(); + return true; + } + return false; + } + }; + + template< typename Peek > + struct any + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.empty() ) ) + { + if( !in.empty() ) { + if( const auto t = Peek::peek( in ) ) { + in.bump( t.size ); + return true; + } + } + return false; + } + }; + + template< typename Peek > + struct skip_control< any< Peek > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/apply.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7954f2fabdbf9d59ef8c712a58cf31e70060191f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/apply.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2017-2018 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 "skip_control.hpp" + +#include "../analysis/counted.hpp" +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< apply_mode A, typename... Actions > + struct apply_impl; + + template<> + struct apply_impl< apply_mode::ACTION > + { + template< typename Input, typename... States > + static bool match( Input& /*unused*/, States&&... /*unused*/ ) + { + return true; + } + }; + + template< typename... Actions > + struct apply_impl< apply_mode::ACTION, Actions... > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + using action_t = typename Input::action_t; + const action_t i2( in.iterator(), in ); // No data -- range is from begin to begin. +#ifdef __cpp_fold_expressions + return ( apply_single< Actions >::match( i2, st... ) && ... ); +#else + bool result = true; + using swallow = bool[]; + (void)swallow{ result = result && apply_single< Actions >::match( i2, st... )... }; + return result; +#endif + } + }; + + template< typename... Actions > + struct apply_impl< apply_mode::NOTHING, Actions... > + { + template< typename Input, typename... States > + static bool match( Input& /*unused*/, States&&... /*unused*/ ) + { + return true; + } + }; + + template< typename... Actions > + struct apply + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, 0 >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return apply_impl< A, Actions... >::match( in, st... ); + } + }; + + template< typename... Actions > + struct skip_control< apply< Actions... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/apply0.hpp b/packages/PEGTL/include/tao/pegtl/internal/apply0.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5a13f6d67553f235468f7b6404dbec3d98f74009 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/apply0.hpp @@ -0,0 +1,90 @@ +// Copyright (c) 2017-2018 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 "skip_control.hpp" + +#include "../analysis/counted.hpp" +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< apply_mode A, typename... Actions > + struct apply0_impl; + + template<> + struct apply0_impl< apply_mode::ACTION > + { + template< typename... States > + static bool match( States&&... /*unused*/ ) noexcept + { + return true; + } + }; + + template< typename... Actions > + struct apply0_impl< apply_mode::ACTION, Actions... > + { + template< typename... States > + static bool match( States&&... st ) + { +#ifdef __cpp_fold_expressions + return ( apply0_single< Actions >::match( st... ) && ... ); +#else + bool result = true; + using swallow = bool[]; + (void)swallow{ result = result && apply0_single< Actions >::match( st... )... }; + return result; +#endif + } + }; + + template< typename... Actions > + struct apply0_impl< apply_mode::NOTHING, Actions... > + { + template< typename... States > + static bool match( States&&... /*unused*/ ) noexcept + { + return true; + } + }; + + template< typename... Actions > + struct apply0 + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, 0 >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& /*unused*/, States&&... st ) + { + return apply0_impl< A, Actions... >::match( st... ); + } + }; + + template< typename... Actions > + struct skip_control< apply0< Actions... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/apply0_single.hpp b/packages/PEGTL/include/tao/pegtl/internal/apply0_single.hpp new file mode 100644 index 0000000000000000000000000000000000000000..06bae4f284b6613c96a2c7813953325690d82a55 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/apply0_single.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2017-2018 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 <type_traits> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Action > + struct apply0_single + { + template< typename... States > + static auto match( States&&... st ) + -> typename std::enable_if< std::is_same< decltype( Action::apply0( st... ) ), void >::value, bool >::type + { + Action::apply0( st... ); + return true; + } + + template< typename... States > + static auto match( States&&... st ) + -> typename std::enable_if< std::is_same< decltype( Action::apply0( st... ) ), bool >::value, bool >::type + { + return Action::apply0( st... ); + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/apply_single.hpp b/packages/PEGTL/include/tao/pegtl/internal/apply_single.hpp new file mode 100644 index 0000000000000000000000000000000000000000..99072343270f4301ccf4b87d30655bb42238312b --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/apply_single.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2017-2018 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 <type_traits> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Action > + struct apply_single + { + template< typename Input, typename... States > + static auto match( const Input& i2, States&&... st ) + -> typename std::enable_if< std::is_same< decltype( Action::apply( i2, st... ) ), void >::value, bool >::type + { + Action::apply( i2, st... ); + return true; + } + + template< typename Input, typename... States > + static auto match( const Input& i2, States&&... st ) + -> typename std::enable_if< std::is_same< decltype( Action::apply( i2, st... ) ), bool >::value, bool >::type + { + return Action::apply( i2, st... ); + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/at.hpp b/packages/PEGTL/include/tao/pegtl/internal/at.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b4997c9c7bd01b2ba641635dd60d16d95621c8b0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/at.hpp @@ -0,0 +1,62 @@ +// Copyright (c) 2014-2018 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 "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct at; + + template<> + struct at<> + : trivial< true > + { + }; + + template< typename... Rules > + struct at + { + using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules... >; + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + const auto m = in.template mark< rewind_mode::REQUIRED >(); + return rule_conjunction< Rules... >::template match< apply_mode::NOTHING, rewind_mode::ACTIVE, Action, Control >( in, st... ); + } + }; + + template< typename... Rules > + struct skip_control< at< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/bof.hpp b/packages/PEGTL/include/tao/pegtl/internal/bof.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b6c9c2177df9c748119c7f7d1ebd950b887ca27f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/bof.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct bof + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept + { + return in.byte() == 0; + } + }; + + template<> + struct skip_control< bof > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/bol.hpp b/packages/PEGTL/include/tao/pegtl/internal/bol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dda3179292de8d92f14b1d307458f920924f16bc --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/bol.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct bol + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept + { + return in.byte_in_line() == 0; + } + }; + + template<> + struct skip_control< bol > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/bump_help.hpp b/packages/PEGTL/include/tao/pegtl/internal/bump_help.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b09f2edac6c228494471692ead88657a06080a4d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/bump_help.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2015-2018 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 <cstddef> +#include <type_traits> + +#include "../config.hpp" + +#include "result_on_found.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< bool > + struct bump_impl; + + template<> + struct bump_impl< true > + { + template< typename Input > + static void bump( Input& in, const std::size_t count ) noexcept + { + in.bump( count ); + } + }; + + template<> + struct bump_impl< false > + { + template< typename Input > + static void bump( Input& in, const std::size_t count ) noexcept + { + in.bump_in_this_line( count ); + } + }; + + template< bool... > + struct bool_list + { + }; + + template< bool... Bs > + using bool_and = std::is_same< bool_list< Bs..., true >, bool_list< true, Bs... > >; + + template< result_on_found R, typename Input, typename Char, Char... Cs > + void bump_help( Input& in, const std::size_t count ) noexcept + { + bump_impl< bool_and< ( Cs != Input::eol_t::ch )... >::value != bool( R ) >::bump( in, count ); + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/bump_impl.hpp b/packages/PEGTL/include/tao/pegtl/internal/bump_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ffd904d46c385b9550634649fe92059fdf0867af --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/bump_impl.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_BUMP_IMPL_HPP +#define TAO_PEGTL_INTERNAL_BUMP_IMPL_HPP + +#include "../config.hpp" + +#include "iterator.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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.byte_in_line = 0; + } + else { + ++iter.byte_in_line; + } + } + 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.byte_in_line += count; + } + + inline void bump_to_next_line( iterator& iter, const std::size_t count ) noexcept + { + ++iter.line; + iter.byte += count; + iter.byte_in_line = 0; + iter.data += count; + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/bytes.hpp b/packages/PEGTL/include/tao/pegtl/internal/bytes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..789224c331838747bee398b5e2b4fb066cb17195 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/bytes.hpp @@ -0,0 +1,46 @@ +// Copyright (c) 2014-2018 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 "skip_control.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Num > + struct bytes + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, Num >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 0 ) ) ) + { + if( in.size( Num ) >= Num ) { + in.bump( Num ); + return true; + } + return false; + } + }; + + template< unsigned Num > + struct skip_control< bytes< Num > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/conditional.hpp b/packages/PEGTL/include/tao/pegtl/internal/conditional.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dbf356da1c061a057de4c8991d344ceb48d89f98 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/conditional.hpp @@ -0,0 +1,38 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_CONDITIONAL_HPP +#define TAO_PEGTL_INTERNAL_CONDITIONAL_HPP + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< bool > + struct conditional; + + template<> + struct conditional< true > + { + template< typename T, typename > + using type = T; + }; + + template<> + struct conditional< false > + { + template< typename, typename T > + using type = T; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/control.hpp b/packages/PEGTL/include/tao/pegtl/internal/control.hpp new file mode 100644 index 0000000000000000000000000000000000000000..88cc5a18a6799cad0eac46c1fc7245492f16599c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/control.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< template< typename... > class Control, typename... Rules > + struct control + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return duseltronik< seq< Rules... >, A, M, Action, Control >::match( in, st... ); + } + }; + + template< template< typename... > class Control, typename... Rules > + struct skip_control< control< Control, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/cr_crlf_eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/cr_crlf_eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8b83e24806ec975220927103e107c40dd84d8e92 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/cr_crlf_eol.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct cr_crlf_eol + { + static constexpr int ch = '\r'; + + template< typename Input > + static eol_pair match( Input& 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/cr_eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/cr_eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ad2bb5e718feb7ec42dd79af09ee2a9c12aa03f8 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/cr_eol.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct cr_eol + { + static constexpr int ch = '\r'; + + template< typename Input > + static eol_pair match( Input& 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/crlf_eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/crlf_eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..308eca99fee67d8212182511d8617f1f51bc0fa9 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/crlf_eol.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct crlf_eol + { + static constexpr int ch = '\n'; + + template< typename Input > + static eol_pair match( Input& 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/cstream_reader.hpp b/packages/PEGTL/include/tao/pegtl/internal/cstream_reader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..756bc546d3df1c66459b02777ded3eb8ca047f27 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/cstream_reader.hpp @@ -0,0 +1,50 @@ +// Copyright (c) 2016-2018 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 <cassert> +#include <cstddef> +#include <cstdio> + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct cstream_reader + { + explicit cstream_reader( std::FILE* s ) noexcept + : m_cstream( s ) + { + assert( m_cstream != nullptr ); + } + + std::size_t operator()( char* buffer, const std::size_t length ) + { + 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. + TAO_PEGTL_THROW_INPUT_ERROR( "error in fread() from cstream" ); // LCOV_EXCL_LINE + } + + std::FILE* m_cstream; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/cstring_reader.hpp b/packages/PEGTL/include/tao/pegtl/internal/cstring_reader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e745921346421c109726752d63b9c5875e97f0ad --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/cstring_reader.hpp @@ -0,0 +1,49 @@ +// Copyright (c) 2016-2018 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 <cassert> +#include <cstddef> + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct cstring_reader + { + explicit cstring_reader( const char* zero_terminated ) noexcept + : m_cstring( zero_terminated ) + { + assert( m_cstring != nullptr ); + } + + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/demangle.hpp b/packages/PEGTL/include/tao/pegtl/internal/demangle.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9795f71dc3539b066307e5b371ca1e71ceb12601 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/demangle.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DEMANGLE_HPP +#define TAO_PEGTL_INTERNAL_DEMANGLE_HPP + +#include <string> +#include <typeinfo> + +#include "../config.hpp" + +#if defined( __GLIBCXX__ ) +#include "demangle_cxxabi.hpp" +#elif defined( __has_include ) +#if __has_include( <cxxabi.h> ) +#include "demangle_cxxabi.hpp" +#else +#include "demangle_nop.hpp" +#endif +#else +#include "demangle_nop.hpp" +#endif + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename T > + std::string demangle() + { + return demangle( typeid( T ).name() ); + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/demangle_cxxabi.hpp b/packages/PEGTL/include/tao/pegtl/internal/demangle_cxxabi.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e5ecbf908b7ad59913657caccd0f848fa0231dea --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/demangle_cxxabi.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DEMANGLE_CXXABI_HPP +#define TAO_PEGTL_INTERNAL_DEMANGLE_CXXABI_HPP + +#include <cstdlib> +#include <cxxabi.h> +#include <memory> +#include <string> + +#include "../config.hpp" + +#include "demangle_sanitise.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline std::string demangle( const char* symbol ) + { + const std::unique_ptr< char, decltype( &std::free ) > demangled( abi::__cxa_demangle( symbol, nullptr, nullptr, nullptr ), &std::free ); + if( !demangled ) { + return symbol; + } + std::string result( demangled.get() ); +#ifdef TAO_PEGTL_PRETTY_DEMANGLE + demangle_sanitise_chars( result ); // LCOV_EXCL_LINE +#endif + return result; + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/demangle_nop.hpp b/packages/PEGTL/include/tao/pegtl/internal/demangle_nop.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fe72b88b3a807fec8026954056d7d9de4a11e44a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/demangle_nop.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DEMANGLE_NOP_HPP +#define TAO_PEGTL_INTERNAL_DEMANGLE_NOP_HPP + +#include <string> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline std::string demangle( const char* symbol ) + { + return symbol; + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/demangle_sanitise.hpp b/packages/PEGTL/include/tao/pegtl/internal/demangle_sanitise.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7dfb599561711696d9f853f073479b93a8b8b9fd --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/demangle_sanitise.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DEMANGLE_SANITISE_HPP +#define TAO_PEGTL_INTERNAL_DEMANGLE_SANITISE_HPP + +#include <string> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline void demangle_sanitise_chars( std::string& s ) + { + std::string::size_type p; + while( ( p = s.find( "(char)" ) ) != std::string::npos ) { + int c = 0; + std::string::size_type q; + for( q = p + 6; ( q < s.size() ) && ( s[ q ] >= '0' ) && ( s[ q ] <= '9' ); ++q ) { + c *= 10; + c += s[ q ] - '0'; + } + if( c == '\'' ) { + s.replace( p, q - p, "'\\''" ); + } + else if( c == '\\' ) { + s.replace( p, q - p, "'\\\\'" ); + } + else if( ( c < 32 ) || ( c > 126 ) ) { + s.replace( p, 6, std::string() ); + } + else { + s.replace( p, q - p, std::string( 1, '\'' ) + char( c ) + '\'' ); + } + } + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/disable.hpp b/packages/PEGTL/include/tao/pegtl/internal/disable.hpp new file mode 100644 index 0000000000000000000000000000000000000000..90ae99b31cc5a2909e1db13c7c14bfd458512e87 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/disable.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct disable + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return duseltronik< seq< Rules... >, apply_mode::NOTHING, M, Action, Control >::match( in, st... ); + } + }; + + template< typename... Rules > + struct skip_control< disable< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/discard.hpp b/packages/PEGTL/include/tao/pegtl/internal/discard.hpp new file mode 100644 index 0000000000000000000000000000000000000000..89cb2f16c1e95bfa7c1fb0e8e9f28ba577ae3cd0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/discard.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2016-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct discard + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept + { + static_assert( noexcept( in.discard() ), "an input's discard()-method must be noexcept" ); + in.discard(); + return true; + } + }; + + template<> + struct skip_control< discard > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/dusel_mode.hpp b/packages/PEGTL/include/tao/pegtl/internal/dusel_mode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9fc7a58d602b30241ccc0d9e89eeecaa3a95deb9 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/dusel_mode.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DUSEL_MODE_HPP +#define TAO_PEGTL_INTERNAL_DUSEL_MODE_HPP + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + enum class dusel_mode : char + { + NOTHING = 0, + CONTROL = 1, + CONTROL_AND_APPLY_VOID = 2, + CONTROL_AND_APPLY_BOOL = 3, + CONTROL_AND_APPLY0_VOID = 4, + CONTROL_AND_APPLY0_BOOL = 5 + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/duseltronik.hpp b/packages/PEGTL/include/tao/pegtl/internal/duseltronik.hpp new file mode 100644 index 0000000000000000000000000000000000000000..20099a477e760cb4144b205cc896d0d9bc908411 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/duseltronik.hpp @@ -0,0 +1,174 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_DUSELTRONIK_HPP +#define TAO_PEGTL_INTERNAL_DUSELTRONIK_HPP + +#include "../apply_mode.hpp" +#include "../config.hpp" +#include "../rewind_mode.hpp" + +#include "dusel_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + dusel_mode = dusel_mode::NOTHING > + struct duseltronik; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING > + { + template< typename Input, typename... States > + static auto match( Input& in, States&&... st ) + -> decltype( Rule::template match< A, M, Action, Control >( in, st... ), true ) + { + return Rule::template match< A, M, Action, Control >( in, st... ); + } + + // NOTE: The additional "int = 0" is a work-around for missing expression SFINAE in VS2015. + + template< typename Input, typename... States, int = 0 > + static auto match( Input& in, States&&... /*unused*/ ) + -> decltype( Rule::match( in ), true ) + { + return Rule::match( in ); + } + }; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + Control< Rule >::start( static_cast< const Input& >( in ), st... ); + + if( duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { + Control< Rule >::success( static_cast< const Input& >( in ), st... ); + return true; + } + Control< Rule >::failure( static_cast< const Input& >( in ), st... ); + return false; + } + }; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY_VOID > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< rewind_mode::REQUIRED >(); + + Control< Rule >::start( static_cast< const Input& >( in ), st... ); + + if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { + Control< Rule >::template apply< Action >( m.iterator(), static_cast< const Input& >( in ), st... ); + Control< Rule >::success( static_cast< const Input& >( in ), st... ); + return m( true ); + } + Control< Rule >::failure( static_cast< const Input& >( in ), st... ); + return false; + } + }; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY_BOOL > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< rewind_mode::REQUIRED >(); + + Control< Rule >::start( static_cast< const Input& >( in ), st... ); + + if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { + if( Control< Rule >::template apply< Action >( m.iterator(), static_cast< const Input& >( in ), st... ) ) { + Control< Rule >::success( static_cast< const Input& >( in ), st... ); + return m( true ); + } + } + Control< Rule >::failure( static_cast< const Input& >( in ), st... ); + return false; + } + }; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY0_VOID > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + Control< Rule >::start( static_cast< const Input& >( in ), st... ); + + if( duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { + Control< Rule >::template apply0< Action >( static_cast< const Input& >( in ), st... ); + Control< Rule >::success( static_cast< const Input& >( in ), st... ); + return true; + } + Control< Rule >::failure( static_cast< const Input& >( in ), st... ); + return false; + } + }; + + template< typename Rule, + apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control > + struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY0_BOOL > + { + template< typename Input, typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< rewind_mode::REQUIRED >(); + + Control< Rule >::start( static_cast< const Input& >( in ), st... ); + + if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { + if( Control< Rule >::template apply0< Action >( static_cast< const Input& >( in ), st... ) ) { + Control< Rule >::success( static_cast< const Input& >( in ), st... ); + return m( true ); + } + } + Control< Rule >::failure( static_cast< const Input& >( in ), st... ); + return false; + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/enable.hpp b/packages/PEGTL/include/tao/pegtl/internal/enable.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da490c6efad9948a4f4c5fcfcb052ee45122b1e7 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/enable.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct enable + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return duseltronik< seq< Rules... >, apply_mode::ACTION, M, Action, Control >::match( in, st... ); + } + }; + + template< typename... Rules > + struct skip_control< enable< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/endian.hpp b/packages/PEGTL/include/tao/pegtl/internal/endian.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b70775cc78ffc9c8023da9cc67fd2bcba19bcbee --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/endian.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_ENDIAN_HPP +#define TAO_PEGTL_INTERNAL_ENDIAN_HPP + +#include <cstdint> +#include <cstring> + +#include "../config.hpp" + +#if defined( _WIN32 ) && !defined( __MINGW32__ ) +#include "endian_win.hpp" +#else +#include "endian_gcc.hpp" +#endif + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename N > + N h_to_be( const N n ) noexcept + { + return N( to_and_from_be< sizeof( N ) >::convert( n ) ); + } + + template< typename N > + N be_to_h( const N n ) noexcept + { + return h_to_be( n ); + } + + template< typename N > + 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 > + N h_to_le( const N n ) noexcept + { + return N( to_and_from_le< sizeof( N ) >::convert( n ) ); + } + + template< typename N > + N le_to_h( const N n ) noexcept + { + return h_to_le( n ); + } + + template< typename N > + N le_to_h( const void* p ) noexcept + { + N n; + std::memcpy( &n, p, sizeof( n ) ); + return internal::le_to_h( n ); + } + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/endian_gcc.hpp b/packages/PEGTL/include/tao/pegtl/internal/endian_gcc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a8c514f8dd5d85b071b361ff7308bb64d97b3d50 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/endian_gcc.hpp @@ -0,0 +1,215 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_ENDIAN_GCC_HPP +#define TAO_PEGTL_INTERNAL_ENDIAN_GCC_HPP + +#include <cstdint> +#include <cstring> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + +#if not defined( __BYTE_ORDER__ ) +#error No byte order defined! +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + + template< unsigned S > + struct to_and_from_be + { + template< typename T > + static T convert( const T n ) noexcept + { + return n; + } + }; + + template< unsigned S > + struct to_and_from_le; + + template<> + struct to_and_from_le< 1 > + { + static std::uint8_t convert( const std::uint8_t n ) noexcept + { + return n; + } + + static std::int8_t convert( const std::int8_t n ) noexcept + { + return n; + } + }; + + template<> + struct to_and_from_le< 2 > + { + static std::int16_t convert( const std::int16_t n ) noexcept + { + return __builtin_bswap16( n ); + } + + static std::uint16_t convert( const std::uint16_t n ) noexcept + { + return __builtin_bswap16( n ); + } + }; + + template<> + struct to_and_from_le< 4 > + { + 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; + } + + static std::int32_t convert( const std::int32_t n ) noexcept + { + return __builtin_bswap32( n ); + } + + static std::uint32_t convert( const std::uint32_t n ) noexcept + { + return __builtin_bswap32( n ); + } + }; + + template<> + struct to_and_from_le< 8 > + { + 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; + } + + static std::int64_t convert( const std::int64_t n ) noexcept + { + return __builtin_bswap64( n ); + } + + static std::uint64_t convert( const std::uint64_t n ) noexcept + { + return __builtin_bswap64( n ); + } + }; + +#define TAO_PEGTL_NATIVE_ORDER be +#define TAO_PEGTL_NATIVE_UTF16 utf16_be +#define TAO_PEGTL_NATIVE_UTF32 utf32_be + +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + + template< unsigned S > + struct to_and_from_le + { + template< typename T > + static T convert( const T n ) noexcept + { + return n; + } + }; + + template< unsigned S > + struct to_and_from_be; + + template<> + struct to_and_from_be< 1 > + { + static std::int8_t convert( const std::int8_t n ) noexcept + { + return n; + } + + static std::uint8_t convert( const std::uint8_t n ) noexcept + { + return n; + } + }; + + template<> + struct to_and_from_be< 2 > + { + static std::int16_t convert( const std::int16_t n ) noexcept + { + return __builtin_bswap16( n ); + } + + static std::uint16_t convert( const std::uint16_t n ) noexcept + { + return __builtin_bswap16( n ); + } + }; + + template<> + struct to_and_from_be< 4 > + { + 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; + } + + static std::int32_t convert( const std::int32_t n ) noexcept + { + return __builtin_bswap32( n ); + } + + static std::uint32_t convert( const std::uint32_t n ) noexcept + { + return __builtin_bswap32( n ); + } + }; + + template<> + struct to_and_from_be< 8 > + { + 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; + } + + static std::uint64_t convert( const std::uint64_t n ) noexcept + { + return __builtin_bswap64( n ); + } + + static std::int64_t convert( const std::int64_t n ) noexcept + { + return __builtin_bswap64( n ); + } + }; + +#define TAO_PEGTL_NATIVE_ORDER le +#define TAO_PEGTL_NATIVE_UTF16 utf16_le +#define TAO_PEGTL_NATIVE_UTF32 utf32_le + +#else +#error Unknown host byte order! +#endif + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/endian_win.hpp b/packages/PEGTL/include/tao/pegtl/internal/endian_win.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6b89f5f9d9056a7af71bcf739a63f5e3bbba92a0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/endian_win.hpp @@ -0,0 +1,115 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_ENDIAN_WIN_HPP +#define TAO_PEGTL_INTERNAL_ENDIAN_WIN_HPP + +#include <cstdint> +#include <cstring> + +#include <stdlib.h> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned S > + struct to_and_from_le + { + template< typename T > + static T convert( const T t ) noexcept + { + return t; + } + }; + + template< unsigned S > + struct to_and_from_be; + + template<> + struct to_and_from_be< 1 > + { + static std::int8_t convert( const std::int8_t n ) noexcept + { + return n; + } + + static std::uint8_t convert( const std::uint8_t n ) noexcept + { + return n; + } + }; + + template<> + struct to_and_from_be< 2 > + { + static std::int16_t convert( const std::int16_t n ) noexcept + { + return std::int16_t( _byteswap_ushort( std::uint16_t( n ) ) ); + } + + static std::uint16_t convert( const std::uint16_t n ) noexcept + { + return _byteswap_ushort( n ); + } + }; + + template<> + struct to_and_from_be< 4 > + { + 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; + } + + static std::int32_t convert( const std::int32_t n ) noexcept + { + return std::int32_t( _byteswap_ulong( std::uint32_t( n ) ) ); + } + + static std::uint32_t convert( const std::uint32_t n ) noexcept + { + return _byteswap_ulong( n ); + } + }; + + template<> + struct to_and_from_be< 8 > + { + 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; + } + + static std::int64_t convert( const std::int64_t n ) noexcept + { + return std::int64_t( _byteswap_uint64( std::uint64_t( n ) ) ); + } + + static std::uint64_t convert( const std::uint64_t n ) noexcept + { + return _byteswap_uint64( n ); + } + }; + +#define TAO_PEGTL_NATIVE_ORDER le +#define TAO_PEGTL_NATIVE_UTF16 utf16_le +#define TAO_PEGTL_NATIVE_UTF32 utf32_le + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/eof.hpp b/packages/PEGTL/include/tao/pegtl/internal/eof.hpp new file mode 100644 index 0000000000000000000000000000000000000000..51ac283ca635d2b7befddecde742f3def6f8080c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/eof.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2014-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct eof + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.empty() ) ) + { + return in.empty(); + } + }; + + template<> + struct skip_control< eof > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9aae616a7cdef4895e157cee08727c8a525f015d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/eol.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2016-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct eol + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( Input::eol_t::match( in ) ) ) + { + return Input::eol_t::match( in ).first; + } + }; + + template<> + struct skip_control< eol > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/eolf.hpp b/packages/PEGTL/include/tao/pegtl/internal/eolf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..777b814b889fa8b529d881960c04daafa888888d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/eolf.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2014-2018 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 "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct eolf + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( Input::eol_t::match( in ) ) ) + { + const auto p = Input::eol_t::match( in ); + return p.first || ( !p.second ); + } + }; + + template<> + struct skip_control< eolf > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/file_mapper_posix.hpp b/packages/PEGTL/include/tao/pegtl/internal/file_mapper_posix.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ef7ad8ee06fe5fc42cd72fd60107dd5e11880269 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/file_mapper_posix.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2014-2018 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 <sys/mman.h> +#include <unistd.h> + +#include "../config.hpp" + +#include "file_opener.hpp" + +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + class file_mapper + { + public: + explicit file_mapper( const char* filename ) + : file_mapper( file_opener( filename ) ) + { + } + + 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 ) ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to mmap() file " << reader.m_source << " descriptor " << reader.m_fd ); + } + } + + file_mapper( const file_mapper& ) = delete; + file_mapper( file_mapper&& ) = delete; + + ~file_mapper() noexcept + { + // Legacy C interface requires pointer-to-mutable but does not write through the pointer. + ::munmap( const_cast< char* >( m_data ), m_size ); // NOLINT + } + + void operator=( const file_mapper& ) = delete; + void operator=( file_mapper&& ) = delete; + + bool empty() const noexcept + { + return m_size == 0; + } + + std::size_t size() const noexcept + { + return m_size; + } + + using iterator = const char*; + using const_iterator = const char*; + + iterator data() const noexcept + { + return m_data; + } + + iterator begin() const noexcept + { + return m_data; + } + + iterator end() const noexcept + { + return m_data + m_size; + } + + std::string string() const + { + return std::string( m_data, m_size ); + } + + private: + const std::size_t m_size; + const char* const m_data; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/file_mapper_win32.hpp b/packages/PEGTL/include/tao/pegtl/internal/file_mapper_win32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0f4d8f2b6c0586227da0aa95b39495bb0fd88074 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/file_mapper_win32.hpp @@ -0,0 +1,212 @@ +// Copyright (c) 2014-2018 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_MEAN_AND_LEAN +#define TAO_PEGTL_WIN32_MEAN_AND_LEAN_WAS_DEFINED +#endif + +#include <windows.h> + +#if defined( TAO_PEGTL_NOMINMAX_WAS_DEFINED ) +#undef NOMINMAX +#undef TAO_PEGTL_NOMINMAX_WAS_DEFINED +#endif + +#if defined( TAO_PEGTL_WIN32_MEAN_AND_LEAN_WAS_DEFINED ) +#undef WIN32_MEAN_AND_LEAN +#undef TAO_PEGTL_WIN32_MEAN_AND_LEAN_WAS_DEFINED +#endif + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct win32_file_opener + { + explicit win32_file_opener( const char* filename ) + : m_source( filename ), + m_handle( open() ) + { + } + + win32_file_opener( const win32_file_opener& ) = delete; + win32_file_opener( win32_file_opener&& ) = delete; + + ~win32_file_opener() noexcept + { + ::CloseHandle( m_handle ); + } + + void operator=( const win32_file_opener& ) = delete; + void operator=( win32_file_opener&& ) = delete; + + std::size_t size() const + { + LARGE_INTEGER size; + if( !::GetFileSizeEx( m_handle, &size ) ) { + TAO_PEGTL_THROW_INPUT_WIN32_ERROR( "unable to GetFileSizeEx() file " << m_source << " handle " << m_handle ); + } + return std::size_t( size.QuadPart ); + } + + const char* const m_source; + const HANDLE m_handle; + + private: + HANDLE open() const + { + SetLastError( 0 ); + const HANDLE handle = ::CreateFileA( m_source, + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + nullptr ); + if( handle != INVALID_HANDLE_VALUE ) { + return handle; + } + TAO_PEGTL_THROW_INPUT_WIN32_ERROR( "unable to CreateFileA() file " << m_source << " for reading" ); + } + }; + + struct win32_file_mapper + { + explicit win32_file_mapper( const char* filename ) + : win32_file_mapper( win32_file_opener( filename ) ) + { + } + + explicit win32_file_mapper( const win32_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() noexcept + { + ::CloseHandle( m_handle ); + } + + void operator=( const win32_file_mapper& ) = delete; + void operator=( win32_file_mapper&& ) = delete; + + const size_t m_size; + const HANDLE m_handle; + + private: + HANDLE open( const win32_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; + } + TAO_PEGTL_THROW_INPUT_WIN32_ERROR( "unable to CreateFileMappingW() file " << reader.m_source << " for reading" ); + } + }; + + class file_mapper + { + public: + explicit file_mapper( const char* filename ) + : file_mapper( win32_file_mapper( filename ) ) + { + } + + explicit file_mapper( const win32_file_mapper& mapper ) + : m_size( mapper.m_size ), + m_data( static_cast< const char* const >(::MapViewOfFile( mapper.m_handle, + FILE_MAP_READ, + 0, + 0, + 0 ) ) ) + { + if( ( m_size != 0 ) && ( intptr_t( m_data ) == 0 ) ) { + TAO_PEGTL_THROW_INPUT_WIN32_ERROR( "unable to MapViewOfFile() file mapping object with handle " << mapper.m_handle ); + } + } + + file_mapper( const file_mapper& ) = delete; + file_mapper( file_mapper&& ) = delete; + + ~file_mapper() noexcept + { + ::UnmapViewOfFile( LPCVOID( m_data ) ); + } + + void operator=( const file_mapper& ) = delete; + void operator=( file_mapper&& ) = delete; + + bool empty() const noexcept + { + return m_size == 0; + } + + std::size_t size() const noexcept + { + return m_size; + } + + using iterator = const char*; + using const_iterator = const char*; + + iterator data() const noexcept + { + return m_data; + } + + iterator begin() const noexcept + { + return m_data; + } + + iterator end() const noexcept + { + return m_data + m_size; + } + + std::string string() const + { + return std::string( m_data, m_size ); + } + + private: + const std::size_t m_size; + const char* const m_data; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/file_opener.hpp b/packages/PEGTL/include/tao/pegtl/internal/file_opener.hpp new file mode 100644 index 0000000000000000000000000000000000000000..478f5fcb9d4bc68d4d493a499be3645dad3aac45 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/file_opener.hpp @@ -0,0 +1,78 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_FILE_OPENER_HPP +#define TAO_PEGTL_INTERNAL_FILE_OPENER_HPP + +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <utility> + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct file_opener + { + explicit file_opener( const char* filename ) + : m_source( filename ), + m_fd( open() ) + { + } + + file_opener( const file_opener& ) = delete; + file_opener( file_opener&& ) = delete; + + ~file_opener() noexcept + { + ::close( m_fd ); + } + + void operator=( const file_opener& ) = delete; + void operator=( file_opener&& ) = delete; + + std::size_t size() const + { + struct stat st; // NOLINT + errno = 0; + if(::fstat( m_fd, &st ) < 0 ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to fstat() file " << m_source << " descriptor " << m_fd ); + } + return std::size_t( st.st_size ); + } + + const char* const m_source; + const int m_fd; + + private: + int open() const + { + errno = 0; + const int fd = ::open( m_source, // NOLINT + O_RDONLY +#ifdef O_CLOEXEC + | O_CLOEXEC +#endif + ); + if( fd >= 0 ) { + return fd; + } + TAO_PEGTL_THROW_INPUT_ERROR( "unable to open() file " << m_source << " for reading" ); + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/file_reader.hpp b/packages/PEGTL/include/tao/pegtl/internal/file_reader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6d95f8b1fca4c2877588cc8b9a96acd06a54884d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/file_reader.hpp @@ -0,0 +1,109 @@ +// Copyright (c) 2014-2018 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 <cstdio> +#include <memory> +#include <string> +#include <utility> + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline std::FILE* file_open( const char* filename ) + { + errno = 0; +#if defined( _MSC_VER ) + std::FILE* file; + if(::fopen_s( &file, filename, "rb" ) == 0 ) +#elif defined( __MINGW32__ ) + if( auto* file = std::fopen( filename, "rb" ) ) // NOLINT(cppcoreguidelines-owning-memory) +#else + if( auto* file = std::fopen( filename, "rbe" ) ) // NOLINT(cppcoreguidelines-owning-memory) +#endif + { + return file; + } + TAO_PEGTL_THROW_INPUT_ERROR( "unable to fopen() file " << filename << " for reading" ); + } + + struct file_close + { + void operator()( FILE* f ) const noexcept + { + std::fclose( f ); // NOLINT(cppcoreguidelines-owning-memory) + } + }; + + class file_reader + { + public: + explicit file_reader( const char* filename ) + : m_source( filename ), + m_file( file_open( m_source ) ) + { + } + + file_reader( FILE* file, const char* filename ) noexcept + : m_source( filename ), + m_file( file ) + { + } + + file_reader( const file_reader& ) = delete; + file_reader( file_reader&& ) = delete; + + ~file_reader() = default; + + void operator=( const file_reader& ) = delete; + void operator=( file_reader&& ) = delete; + + std::size_t size() const + { + errno = 0; + if( std::fseek( m_file.get(), 0, SEEK_END ) != 0 ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to end of file " << m_source ); // LCOV_EXCL_LINE + } + errno = 0; + const auto s = std::ftell( m_file.get() ); + if( s < 0 ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to ftell() file size of file " << m_source ); // LCOV_EXCL_LINE + } + errno = 0; + if( std::fseek( m_file.get(), 0, SEEK_SET ) != 0 ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to beginning of file " << m_source ); // LCOV_EXCL_LINE + } + return std::size_t( s ); + } + + 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 ) ) { + TAO_PEGTL_THROW_INPUT_ERROR( "unable to fread() file " << m_source << " size " << nrv.size() ); // LCOV_EXCL_LINE + } + return nrv; + } + + private: + const char* const m_source; + const std::unique_ptr< std::FILE, file_close > m_file; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/has_apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/has_apply.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4a4f8db280f4ae631980c955f8d076fdde9e2f18 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/has_apply.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2017-2018 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 <type_traits> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename, typename, typename... > + struct has_apply : std::false_type + { + }; + + template< typename A, typename... S > + struct has_apply< A, decltype( A::apply( std::declval< S >()... ) ), S... > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/has_apply0.hpp b/packages/PEGTL/include/tao/pegtl/internal/has_apply0.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6b1e486d9ba6b9ddc9da90cecc9abd66653f85fe --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/has_apply0.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2017-2018 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 <type_traits> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename, typename, typename... > + struct has_apply0 : std::false_type + { + }; + + template< typename A, typename... S > + struct has_apply0< A, decltype( A::apply0( std::declval< S >()... ) ), S... > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/identifier.hpp b/packages/PEGTL/include/tao/pegtl/internal/identifier.hpp new file mode 100644 index 0000000000000000000000000000000000000000..59f62188fcb005249e20ad2d8d69864bdc8227a7 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/identifier.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2017-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp b/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp new file mode 100644 index 0000000000000000000000000000000000000000..58d0e97ab2474db403e006621a90317397099e65 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/if_apply.hpp @@ -0,0 +1,110 @@ +// Copyright (c) 2017-2018 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 "skip_control.hpp" + +#include "../analysis/counted.hpp" +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< apply_mode A, typename Rule, typename... Actions > + struct if_apply_impl; + + template< typename Rule > + struct if_apply_impl< apply_mode::ACTION, Rule > + { + template< rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return Control< Rule >::template match< apply_mode::ACTION, M, Action, Control >( in, st... ); + } + }; + + template< typename Rule, typename... Actions > + struct if_apply_impl< apply_mode::ACTION, Rule, Actions... > + { + template< rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + using action_t = typename Input::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 ); +#ifdef __cpp_fold_expressions + return m( ( apply_single< Actions >::match( i2, st... ) && ... ) ); +#else + bool result = true; + using swallow = bool[]; + (void)swallow{ result = result && apply_single< Actions >::match( i2, st... )... }; + return m( result ); +#endif + } + return false; + } + }; + + template< typename Rule, typename... Actions > + struct if_apply_impl< apply_mode::NOTHING, Rule, Actions... > + { + template< rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return Control< Rule >::template match< apply_mode::NOTHING, M, Action, Control >( in, st... ); + } + }; + + template< typename Rule, typename... Actions > + struct if_apply + { + using analyze_t = typename Rule::analyze_t; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return if_apply_impl< A, Rule, Actions... >::template match< M, Action, Control >( in, st... ); + } + }; + + template< typename Rule, typename... Actions > + struct skip_control< if_apply< Rule, Actions... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/if_must.hpp b/packages/PEGTL/include/tao/pegtl/internal/if_must.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f81fee47b193267e0aa0d827e589f3dd74038f52 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/if_must.hpp @@ -0,0 +1,57 @@ +// Copyright (c) 2014-2018 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 + +#include "../config.hpp" + +#include "must.hpp" +#include "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< bool Default, typename Cond, typename... Rules > + struct if_must + { + using analyze_t = analysis::counted< analysis::rule_type::SEQ, Default ? 0 : 1, Cond, must< Rules... > >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + if( Control< Cond >::template match< A, M, Action, Control >( in, st... ) ) { + rule_conjunction< must< Rules >... >::template match< A, M, Action, Control >( in, st... ); + return true; + } + return Default; + } + }; + + template< bool Default, typename Cond, typename... Rules > + struct skip_control< if_must< Default, Cond, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/if_must_else.hpp b/packages/PEGTL/include/tao/pegtl/internal/if_must_else.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f049bcbfdbe095cb0fb70f0af0ce3586b6a627bd --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/if_must_else.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 + +#include "../config.hpp" + +#include "if_then_else.hpp" +#include "must.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Cond, typename Then, typename Else > + using if_must_else = if_then_else< Cond, must< Then >, must< Else > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/if_then_else.hpp b/packages/PEGTL/include/tao/pegtl/internal/if_then_else.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5e851d83925957d902aad5610698c7282c3d19dd --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/if_then_else.hpp @@ -0,0 +1,59 @@ +// Copyright (c) 2014-2018 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 "not_at.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "sor.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Cond, typename Then, typename Else > + struct if_then_else + { + using analyze_t = analysis::generic< analysis::rule_type::SOR, seq< Cond, Then >, seq< not_at< Cond >, Else > >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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 > + struct skip_control< if_then_else< Cond, Then, Else > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/input_pair.hpp b/packages/PEGTL/include/tao/pegtl/internal/input_pair.hpp new file mode 100644 index 0000000000000000000000000000000000000000..362b07c18d2edbea00fa664e79013d2db0940438 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/input_pair.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2014-2018 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 <cstdint> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/integer_sequence.hpp b/packages/PEGTL/include/tao/pegtl/internal/integer_sequence.hpp new file mode 100644 index 0000000000000000000000000000000000000000..29aeff69dfc65c2798bbb8460a229c62eee93941 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/integer_sequence.hpp @@ -0,0 +1,86 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_INTEGER_SEQUENCE_HPP +#define TAO_PEGTL_INTERNAL_INTEGER_SEQUENCE_HPP + +#include <cstddef> +#include <type_traits> +#include <utility> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename T, T... Ns > + struct integer_sequence + { + using value_type = T; + + static constexpr std::size_t size() noexcept + { + return sizeof...( Ns ); + } + }; + + template< std::size_t... Ns > + using index_sequence = integer_sequence< std::size_t, Ns... >; + + template< bool V, bool E > + struct generate_sequence; + + template<> + struct generate_sequence< false, true > + { + template< typename T, T M, T N, std::size_t S, T... Ns > + using f = integer_sequence< T, Ns... >; + }; + + template<> + struct generate_sequence< true, true > + { + template< typename T, T M, T N, std::size_t S, T... Ns > + using f = integer_sequence< T, Ns..., S >; + }; + + template<> + struct generate_sequence< false, false > + { + template< typename T, T M, T N, std::size_t S, T... Ns > + using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S, Ns..., ( Ns + S )... >; + }; + + template<> + struct generate_sequence< true, false > + { + template< typename T, T M, T N, std::size_t S, T... Ns > + using f = typename generate_sequence< ( N & ( M / 2 ) ) != 0, ( M / 2 ) == 0 >::template f< T, M / 2, N, 2 * S + 1, Ns..., ( Ns + S )..., 2 * S >; + }; + + template< typename T, T N > + struct memoize_sequence + { + static_assert( N < T( 1 << 20 ), "N too large" ); + using type = typename generate_sequence< false, false >::template f< T, ( N < T( 1 << 1 ) ) ? T( 1 << 1 ) : ( N < T( 1 << 2 ) ) ? T( 1 << 2 ) : ( N < T( 1 << 3 ) ) ? T( 1 << 3 ) : ( N < T( 1 << 4 ) ) ? T( 1 << 4 ) : ( N < T( 1 << 5 ) ) ? T( 1 << 5 ) : ( N < T( 1 << 6 ) ) ? T( 1 << 6 ) : ( N < T( 1 << 7 ) ) ? T( 1 << 7 ) : ( N < T( 1 << 8 ) ) ? T( 1 << 8 ) : ( N < T( 1 << 9 ) ) ? T( 1 << 9 ) : ( N < T( 1 << 10 ) ) ? T( 1 << 10 ) : ( N < T( 1 << 11 ) ) ? T( 1 << 11 ) : ( N < T( 1 << 12 ) ) ? T( 1 << 12 ) : ( N < T( 1 << 13 ) ) ? T( 1 << 13 ) : ( N < T( 1 << 14 ) ) ? T( 1 << 14 ) : ( N < T( 1 << 15 ) ) ? T( 1 << 15 ) : ( N < T( 1 << 16 ) ) ? T( 1 << 16 ) : ( N < T( 1 << 17 ) ) ? T( 1 << 17 ) : ( N < T( 1 << 18 ) ) ? T( 1 << 18 ) : ( N < T( 1 << 19 ) ) ? T( 1 << 19 ) : T( 1 << 20 ), N, 0 >; + }; + + template< typename T, T N > + using make_integer_sequence = typename memoize_sequence< T, N >::type; + + template< std::size_t N > + using make_index_sequence = make_integer_sequence< std::size_t, N >; + + template< typename... Ts > + using index_sequence_for = make_index_sequence< sizeof...( Ts ) >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/istream_reader.hpp b/packages/PEGTL/include/tao/pegtl/internal/istream_reader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..592c15e6ac64c6f009a68f5981ca542206591530 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/istream_reader.hpp @@ -0,0 +1,47 @@ +// Copyright (c) 2016-2018 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 <istream> + +#include "../config.hpp" +#include "../input_error.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct istream_reader + { + explicit istream_reader( std::istream& s ) noexcept + : m_istream( s ) + { + } + + 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; + } + TAO_PEGTL_THROW_INPUT_ERROR( "error in istream.read()" ); + } + + std::istream& m_istream; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/istring.hpp b/packages/PEGTL/include/tao/pegtl/internal/istring.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5c8c4ab3a1fae115c6be7a93a49df5c845a026a0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/istring.hpp @@ -0,0 +1,107 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "../config.hpp" + +#include "bump_help.hpp" +#include "result_on_found.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< char C > + using is_alpha = std::integral_constant< bool, ( ( 'a' <= C ) && ( C <= 'z' ) ) || ( ( 'A' <= C ) && ( C <= 'Z' ) ) >; + + template< char C, bool A = is_alpha< C >::value > + struct ichar_equal; + + template< char C > + struct ichar_equal< C, true > + { + static bool match( const char c ) noexcept + { + return ( C | 0x20 ) == ( c | 0x20 ); + } + }; + + template< char C > + struct ichar_equal< C, false > + { + static bool match( const char c ) noexcept + { + return c == C; + } + }; + + template< char... Cs > + struct istring_equal; + + template<> + struct istring_equal<> + { + static bool match( const char* /*unused*/ ) noexcept + { + return true; + } + }; + + template< char C, char... Cs > + struct istring_equal< C, Cs... > + { + static bool match( const char* r ) noexcept + { + return ichar_equal< C >::match( *r ) && istring_equal< Cs... >::match( r + 1 ); + } + }; + + template< char... Cs > + struct istring; + + template<> + struct istring<> + : trivial< true > + { + }; + + template< char... Cs > + struct istring + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, sizeof...( Cs ) >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 0 ) ) ) + { + if( in.size( sizeof...( Cs ) ) >= sizeof...( Cs ) ) { + if( istring_equal< Cs... >::match( in.current() ) ) { + bump_help< result_on_found::SUCCESS, Input, char, Cs... >( in, sizeof...( Cs ) ); + return true; + } + } + return false; + } + }; + + template< char... Cs > + struct skip_control< istring< Cs... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/iterator.hpp b/packages/PEGTL/include/tao/pegtl/internal/iterator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4bc46f398c89214ae94e5d3eda75141c9238138a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/iterator.hpp @@ -0,0 +1,60 @@ +// Copyright (c) 2017-2018 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 <cstdlib> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct iterator + { + iterator() noexcept = 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_byte_in_line ) noexcept + : data( in_data ), + byte( in_byte ), + line( in_line ), + byte_in_line( in_byte_in_line ) + { + } + + iterator( const iterator& ) = default; + iterator( iterator&& ) = default; + + ~iterator() = default; + + iterator& operator=( const iterator& ) = default; + iterator& operator=( iterator&& ) = default; + + void reset() noexcept + { + *this = iterator(); + } + + const char* data = nullptr; + + std::size_t byte = 0; + std::size_t line = 1; + std::size_t byte_in_line = 0; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/lf_crlf_eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/lf_crlf_eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..27a47c4caac7c85db5fdd02ca891db3788d8374b --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/lf_crlf_eol.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct lf_crlf_eol + { + static constexpr int ch = '\n'; + + template< typename Input > + static eol_pair match( Input& 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/lf_eol.hpp b/packages/PEGTL/include/tao/pegtl/internal/lf_eol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0104126d54747759e02877e5761f0eb3e6cbef97 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/lf_eol.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct lf_eol + { + static constexpr int ch = '\n'; + + template< typename Input > + static eol_pair match( Input& 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/list.hpp b/packages/PEGTL/include/tao/pegtl/internal/list.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7068d9cec6147a51475ca7df296c76faf3a892fe --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/list.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Sep > + using list = seq< Rule, star< Sep, Rule > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/list_must.hpp b/packages/PEGTL/include/tao/pegtl/internal/list_must.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c473f2daa5ada731ab94c2653d9b904f71a1a0c8 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/list_must.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 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 + +#include "../config.hpp" + +#include "must.hpp" +#include "seq.hpp" +#include "star.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Sep > + using list_must = seq< Rule, star< Sep, must< Rule > > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/list_tail.hpp b/packages/PEGTL/include/tao/pegtl/internal/list_tail.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e651df80b46f3302700d96c7adea387aa7fd6f06 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/list_tail.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 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 "list.hpp" +#include "opt.hpp" +#include "seq.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Sep > + using list_tail = seq< list< Rule, Sep >, opt< Sep > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/list_tail_pad.hpp b/packages/PEGTL/include/tao/pegtl/internal/list_tail_pad.hpp new file mode 100644 index 0000000000000000000000000000000000000000..291bcadefece0c238c041d2852455f0d9e2f24bb --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/list_tail_pad.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Sep, typename Pad > + using list_tail_pad = seq< list< Rule, pad< Sep, Pad > >, opt< star< Pad >, Sep > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/marker.hpp b/packages/PEGTL/include/tao/pegtl/internal/marker.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c11ad49be11c227d18a7f421faad4f87142838fc --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/marker.hpp @@ -0,0 +1,99 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Iterator, rewind_mode M > + class marker + { + public: + static constexpr rewind_mode next_rewind_mode = M; + + explicit marker( const Iterator& /*unused*/ ) noexcept + { + } + + marker( const marker& ) = delete; + + marker( marker&& /*unused*/ ) noexcept + { + } + + ~marker() = default; + + void operator=( const marker& ) = delete; + void operator=( marker&& ) = delete; + + bool operator()( const bool result ) const noexcept + { + return result; + } + }; + + template< typename Iterator > + class 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&& i ) noexcept + : m_saved( i.m_saved ), + m_input( i.m_input ) + { + i.m_input = nullptr; + } + + ~marker() noexcept + { + if( m_input != nullptr ) { + ( *m_input ) = m_saved; + } + } + + void operator=( const marker& ) = delete; + void operator=( marker&& ) = delete; + + bool operator()( const bool result ) noexcept + { + if( result ) { + m_input = nullptr; + return true; + } + return false; + } + + const Iterator& iterator() const noexcept + { + return m_saved; + } + + private: + const Iterator m_saved; + Iterator* m_input; + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/minus.hpp b/packages/PEGTL/include/tao/pegtl/internal/minus.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9481c827b2d41c2df10501df8ec4a67b49f0bda5 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/minus.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2016-2018 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 "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../memory_input.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + inline const char* source_pointer( const char* source ) noexcept + { + return source; + } + + inline const char* source_pointer( const std::string& source ) noexcept + { + return source.c_str(); + } + + template< typename R, typename S > + struct minus + { + using analyze_t = typename R::analyze_t; // NOTE: S is currently ignored for analyze(). + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< rewind_mode::REQUIRED >(); + + if( !Control< R >::template match< A, rewind_mode::ACTIVE, Action, Control >( in, st... ) ) { + return false; + } + memory_input< tracking_mode::LAZY, typename Input::eol_t, const char* > i2( m.iterator(), in.current(), source_pointer( in.source() ) ); + + if( !Control< S >::template match< apply_mode::NOTHING, rewind_mode::ACTIVE, Action, Control >( i2, st... ) ) { + return m( true ); + } + return m( !i2.empty() ); + } + }; + + template< typename R, typename S > + struct skip_control< minus< R, S > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/must.hpp b/packages/PEGTL/include/tao/pegtl/internal/must.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9f37243efd58be527c837246e51d70ebbedc024d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/must.hpp @@ -0,0 +1,79 @@ +// Copyright (c) 2014-2018 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 + +#include "../config.hpp" + +#include "raise.hpp" +#include "rule_conjunction.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + // The general case applies must<> to each of the + // rules in the 'Rules' parameter pack individually. + + template< typename... Rules > + struct must + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return rule_conjunction< must< Rules >... >::template match< A, M, Action, Control >( in, st... ); + } + }; + + // 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 analyze_t = typename Rule::analyze_t; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + if( !Control< Rule >::template match< A, rewind_mode::DONTCARE, Action, Control >( in, st... ) ) { + raise< Rule >::template match< A, rewind_mode::DONTCARE, Action, Control >( in, st... ); + } + return true; + } + }; + + template< typename... Rules > + struct skip_control< must< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp b/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d47932079738792507ec425400493aa67611007c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/not_at.hpp @@ -0,0 +1,62 @@ +// Copyright (c) 2014-2018 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 "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct not_at; + + template<> + struct not_at<> + : trivial< false > + { + }; + + template< typename... Rules > + struct not_at + { + using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules... >; + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + const auto m = in.template mark< rewind_mode::REQUIRED >(); + return !rule_conjunction< Rules... >::template match< apply_mode::NOTHING, rewind_mode::ACTIVE, Action, Control >( in, st... ); + } + }; + + template< typename... Rules > + struct skip_control< not_at< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/one.hpp b/packages/PEGTL/include/tao/pegtl/internal/one.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8d29d5118b15619df819feb9caee730f4b6f5793 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/one.hpp @@ -0,0 +1,81 @@ +// Copyright (c) 2014-2018 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 <algorithm> +#include <utility> + +#include "../config.hpp" + +#include "bump_help.hpp" +#include "result_on_found.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Char > + bool contains( const Char c, const std::initializer_list< Char >& l ) noexcept + { + return std::find( l.begin(), l.end(), c ) != l.end(); + } + + template< result_on_found R, typename Peek, typename Peek::data_t... Cs > + struct one + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.empty() ) ) + { + if( !in.empty() ) { + if( const auto t = Peek::peek( in ) ) { + if( contains( t.data, { Cs... } ) == bool( R ) ) { + bump_help< R, Input, typename Peek::data_t, Cs... >( in, t.size ); + return true; + } + } + } + return false; + } + }; + + template< result_on_found R, typename Peek, typename Peek::data_t C > + struct one< R, Peek, C > + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.empty() ) ) + { + if( !in.empty() ) { + if( const auto t = Peek::peek( in ) ) { + if( ( t.data == C ) == bool( R ) ) { + bump_help< R, Input, typename Peek::data_t, C >( in, t.size ); + return true; + } + } + } + return false; + } + }; + + template< result_on_found R, typename Peek, typename Peek::data_t... Cs > + struct skip_control< one< R, Peek, Cs... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/opt.hpp b/packages/PEGTL/include/tao/pegtl/internal/opt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f27046a47b03ae6f64ae5e7d2bc829b209bd7d81 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/opt.hpp @@ -0,0 +1,65 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "../config.hpp" + +#include "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct opt; + + template<> + struct opt<> + : trivial< true > + { + }; + + template< typename... Rules > + struct opt + { + using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules... >; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + duseltronik< seq< Rules... >, A, rewind_mode::REQUIRED, Action, Control >::match( in, st... ); + return true; + } + }; + + template< typename... Rules > + struct skip_control< opt< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/pad.hpp b/packages/PEGTL/include/tao/pegtl/internal/pad.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8aa586d54d4e6a079af53eedda01f6570368130d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/pad.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Pad1, typename Pad2 = Pad1 > + using pad = seq< star< Pad1 >, Rule, star< Pad2 > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/pad_opt.hpp b/packages/PEGTL/include/tao/pegtl/internal/pad_opt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bdd0f669300b5b430f0d45106727ea6a53f0e4f5 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/pad_opt.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename Pad > + using pad_opt = seq< star< Pad >, opt< Rule, star< Pad > > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_char.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_char.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f7eaf907ed4f3c3969fa8f2dec21cb27c0ef39a3 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_char.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2014-2018 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 <cstddef> + +#include "../config.hpp" + +#include "input_pair.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct peek_char + { + using data_t = char; + using pair_t = input_pair< char >; + + template< typename Input > + static pair_t peek( Input& in, const std::size_t o = 0 ) noexcept( noexcept( in.Input::peek_char( 0 ) ) ) + { + return { in.peek_char( o ), 1 }; + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b5709d6a71cfa72fcc63d02668bd780f4994b62c --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_MASK_UINT_HPP +#define TAO_PEGTL_INTERNAL_PEEK_MASK_UINT_HPP + +#include <cstddef> +#include <cstdint> + +#include "../config.hpp" + +#include "input_pair.hpp" +#include "read_uint.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 Input > + static pair_t peek( Input& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) ) + { + const std::size_t s = in.size( sizeof( data_t ) ); + if( s >= sizeof( data_t ) ) { + const data_t data = R::read( in.current() ) & M; + return { data, sizeof( data_t ) }; + } + return { 0, 0 }; + } + }; + + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint8.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8711918e7a3b95bc83e00206a1fcdc9ee5e0a56a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_mask_uint8.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_MASK_UINT8_HPP +#define TAO_PEGTL_INTERNAL_PEEK_MASK_UINT8_HPP + +#include <cstddef> +#include <cstdint> + +#include "../config.hpp" + +#include "input_pair.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 Input > + static pair_t peek( Input& in, const std::size_t o = 0 ) noexcept( noexcept( in.peek_byte( 0 ) ) ) + { + return { std::uint8_t( in.peek_byte( o ) & M ), 1 }; + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_uint.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_uint.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4a0fd8901615fadbc4b0c52e34eb1147c39d1652 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_uint.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_UINT_HPP +#define TAO_PEGTL_INTERNAL_PEEK_UINT_HPP + +#include <cstddef> +#include <cstdint> + +#include "../config.hpp" + +#include "input_pair.hpp" +#include "read_uint.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename R > + struct peek_uint_impl + { + using data_t = typename R::type; + using pair_t = input_pair< data_t >; + + template< typename Input > + static pair_t peek( Input& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) ) + { + const std::size_t s = in.size( sizeof( data_t ) ); + if( s >= sizeof( data_t ) ) { + const data_t data = R::read( in.current() ); + return { data, sizeof( data_t ) }; + } + return { 0, 0 }; + } + }; + + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_uint8.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_uint8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aebe1b22ecb2f39e66f9f6906724fa4f09b22187 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_uint8.hpp @@ -0,0 +1,38 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_UINT8_HPP +#define TAO_PEGTL_INTERNAL_PEEK_UINT8_HPP + +#include <cstddef> +#include <cstdint> + +#include "../config.hpp" + +#include "input_pair.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct peek_uint8 + { + using data_t = std::uint8_t; + using pair_t = input_pair< std::uint8_t >; + + template< typename Input > + static pair_t peek( Input& in, const std::size_t o = 0 ) noexcept( noexcept( in.peek_byte( 0 ) ) ) + { + return { in.peek_byte( o ), 1 }; + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_utf16.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_utf16.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8d88e42e04d63135236623e41af074b5f49075e6 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_utf16.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_UTF16_HPP +#define TAO_PEGTL_INTERNAL_PEEK_UTF16_HPP + +#include <type_traits> + +#include "../config.hpp" + +#include "input_pair.hpp" +#include "read_uint.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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, "expected size 2 for 16bit value" ); + static_assert( sizeof( char16_t ) == 2, "expected size 2 for 16bit value" ); + + template< typename Input > + static pair_t peek( Input& in ) noexcept( noexcept( in.size( 4 ) ) ) + { + const std::size_t s = in.size( 4 ); + if( s < 2 ) { + return { 0, 0 }; + } + const char32_t t = R::read( in.current() ); + if( ( t < 0xd800 ) || ( t > 0xdfff ) ) { + return { t, 2 }; + } + if( ( t >= 0xdc00 ) || ( s < 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_utf32.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_utf32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7d720b125e487a16ef621baf0674414ca95a37ab --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_utf32.hpp @@ -0,0 +1,51 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_PEEK_UTF32_HPP +#define TAO_PEGTL_INTERNAL_PEEK_UTF32_HPP + +#include <cstddef> + +#include "../config.hpp" + +#include "input_pair.hpp" +#include "read_uint.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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, "expected size 4 for 32bit value" ); + + template< typename Input > + static pair_t peek( Input& in ) noexcept( noexcept( in.size( 4 ) ) ) + { + const std::size_t s = in.size( 4 ); + if( s >= 4 ) { + const char32_t t = R::read( in.current() ); + if( ( 0 <= t ) && ( 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/peek_utf8.hpp b/packages/PEGTL/include/tao/pegtl/internal/peek_utf8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2b11f7533092b4876c9a2563f81b24ae71d54f4a --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/peek_utf8.hpp @@ -0,0 +1,88 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct peek_utf8 + { + using data_t = char32_t; + using pair_t = input_pair< char32_t >; + + template< typename Input > + static pair_t peek( Input& in ) noexcept( noexcept( in.size( 4 ) ) ) + { + char32_t c0 = in.peek_byte(); + + if( ( c0 & 0x80 ) == 0 ) { + return { c0, 1 }; + } + if( ( c0 & 0xE0 ) == 0xC0 ) { + if( in.size( 2 ) >= 2 ) { + const char32_t c1 = in.peek_byte( 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_byte( 1 ); + const char32_t c2 = in.peek_byte( 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_byte( 1 ); + const char32_t c2 = in.peek_byte( 2 ); + const char32_t c3 = in.peek_byte( 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp b/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5928d73307590b5eb9fb8b8dfeb511c65a862259 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/pegtl_string.hpp @@ -0,0 +1,103 @@ +// Copyright (c) 2015-2018 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 <cstddef> +#include <type_traits> + +#include "../ascii.hpp" +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + // Inspired by https://github.com/irrequietus/typestring + // Rewritten and reduced to what is needed for the PEGTL + // and to work with Visual Studio 2015. + + namespace internal + { + 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 internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#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::TAO_PEGTL_NAMESPACE::internal::string_at< S, ( 0##n < sizeof( x ) ) ? ( x )[ 0##n ] : 0, ( 0##n < sizeof( x ) - 1 ) >::type + +#define TAO_PEGTL_INTERNAL_JOIN_8( M, S, x, n ) \ + tao::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::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::TAO_PEGTL_NAMESPACE::ascii::string, x ) + +#define TAO_PEGTL_ISTRING( x ) \ + TAO_PEGTL_INTERNAL_STRING( tao::TAO_PEGTL_NAMESPACE::ascii::istring, x ) + +#define TAO_PEGTL_KEYWORD( x ) \ + TAO_PEGTL_INTERNAL_STRING( tao::TAO_PEGTL_NAMESPACE::ascii::keyword, x ) + +// Compatibility, remove with 3.0 +#define TAOCPP_PEGTL_STRING( x ) TAO_PEGTL_STRING( x ) +#define TAOCPP_PEGTL_ISTRING( x ) TAO_PEGTL_ISTRING( x ) +#define TAOCPP_PEGTL_KEYWORD( x ) TAO_PEGTL_KEYWORD( x ) + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/plus.hpp b/packages/PEGTL/include/tao/pegtl/internal/plus.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ebd23bf1ebf4a59a553b7829afb7390aee92970 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/plus.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "../config.hpp" + +#include "duseltronik.hpp" +#include "opt.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "star.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rule, Rules..., opt< plus > >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return seq< Rule, Rules... >::template match< A, M, Action, Control >( in, st... ) && star< Rule, Rules... >::template match< A, M, Action, Control >( in, st... ); + } + }; + + template< typename Rule, typename... Rules > + struct skip_control< plus< Rule, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/raise.hpp b/packages/PEGTL/include/tao/pegtl/internal/raise.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7a76dd2b80e08f7f0dd502b6feb22388b370cabd --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/raise.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2014-2018 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 + +#include <cstdlib> +#include <stdexcept> +#include <type_traits> + +#include "../config.hpp" + +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename T > + struct raise + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4702 ) +#endif + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + Control< T >::raise( static_cast< const Input& >( in ), st... ); + throw std::logic_error( "code should be unreachable: Control< T >::raise() did not throw an exception" ); // NOLINT, LCOV_EXCL_LINE +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + } + }; + + template< typename T > + struct skip_control< raise< T > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/range.hpp b/packages/PEGTL/include/tao/pegtl/internal/range.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3964463ecd7cf05a8498881d4514407eac27bf6d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/range.hpp @@ -0,0 +1,60 @@ +// Copyright (c) 2014-2018 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 "result_on_found.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > + struct range + { + static_assert( Lo <= Hi, "invalid range detected" ); + + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< int Eol > + struct can_match_eol + { + static constexpr bool value = ( ( ( Lo <= Eol ) && ( Eol <= Hi ) ) == bool( R ) ); + }; + + template< typename Input > + static bool match( Input& in ) + { + if( !in.empty() ) { + if( const auto t = Peek::peek( in ) ) { + if( ( ( Lo <= t.data ) && ( t.data <= Hi ) ) == bool( R ) ) { + bump_impl< can_match_eol< Input::eol_t::ch >::value >::bump( in, t.size ); + return true; + } + } + } + return false; + } + }; + + template< result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi > + struct skip_control< range< R, Peek, Lo, Hi > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/ranges.hpp b/packages/PEGTL/include/tao/pegtl/internal/ranges.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d91f433dd76ba2bf269238ffa957123d55fdc821 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/ranges.hpp @@ -0,0 +1,102 @@ +// Copyright (c) 2014-2018 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 "bump_help.hpp" +#include "range.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< int Eol, typename Char, Char... Cs > + struct ranges_impl; + + template< int Eol, typename Char > + struct ranges_impl< Eol, Char > + { + static constexpr bool can_match_eol = false; + + static bool match( const Char /*unused*/ ) noexcept + { + return false; + } + }; + + template< int Eol, typename Char, Char Eq > + struct ranges_impl< Eol, Char, Eq > + { + static constexpr bool can_match_eol = ( Eq == Eol ); + + static bool match( const Char c ) noexcept + { + return c == Eq; + } + }; + + template< int Eol, typename Char, Char Lo, Char Hi, Char... Cs > + struct ranges_impl< Eol, Char, Lo, Hi, Cs... > + { + static_assert( Lo <= Hi, "invalid range detected" ); + + static constexpr bool can_match_eol = ( ( ( Lo <= Eol ) && ( Eol <= Hi ) ) || ranges_impl< Eol, Char, Cs... >::can_match_eol ); + + static bool match( const Char c ) noexcept + { + return ( ( Lo <= c ) && ( c <= Hi ) ) || ranges_impl< Eol, Char, Cs... >::match( c ); + } + }; + + template< typename Peek, typename Peek::data_t... Cs > + struct ranges + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< int Eol > + struct can_match_eol + { + static constexpr bool value = ranges_impl< Eol, typename Peek::data_t, Cs... >::can_match_eol; + }; + + template< typename Input > + static bool match( Input& in ) + { + if( !in.empty() ) { + if( const auto t = Peek::peek( in ) ) { + if( ranges_impl< Input::eol_t::ch, typename Peek::data_t, Cs... >::match( t.data ) ) { + bump_impl< can_match_eol< Input::eol_t::ch >::value >::bump( 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... Cs > + struct skip_control< ranges< Peek, Cs... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/read_uint.hpp b/packages/PEGTL/include/tao/pegtl/internal/read_uint.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6e9d3aeb694e3426fccd1dd1a14fa5ae825c227e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/read_uint.hpp @@ -0,0 +1,85 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_READ_UINT_HPP +#define TAO_PEGTL_INTERNAL_READ_UINT_HPP + +#include <cstdint> + +#include "../config.hpp" + +#include "endian.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct read_uint16_be + { + using type = std::uint16_t; + + 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; + + 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; + + 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; + + 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; + + 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; + + static std::uint64_t read( const void* d ) noexcept + { + return le_to_h< std::uint64_t >( d ); + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rep.hpp b/packages/PEGTL/include/tao/pegtl/internal/rep.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1e7e600da768c8c06812cfde68ffa7d93eb85472 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rep.hpp @@ -0,0 +1,75 @@ +// Copyright (c) 2014-2018 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 "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Num, typename... Rules > + struct rep; + + template< unsigned Num > + struct rep< Num > + : trivial< true > + { + }; + + template< typename Rule, typename... Rules > + struct rep< 0, Rule, Rules... > + : trivial< true > + { + }; + + template< unsigned Num, typename... Rules > + struct rep + { + using analyze_t = analysis::counted< analysis::rule_type::SEQ, Num, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< M >(); + using m_t = decltype( m ); + + for( unsigned i = 0; i != Num; ++i ) { + if( !rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { + return false; + } + } + return m( true ); + } + }; + + template< unsigned Num, typename... Rules > + struct skip_control< rep< Num, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rep_min.hpp b/packages/PEGTL/include/tao/pegtl/internal/rep_min.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f48b542a667e6f36f113a638802bf5cd5543cb4f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rep_min.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Min, typename Rule, typename... Rules > + using rep_min = seq< rep< Min, Rule, Rules... >, star< Rule, Rules... > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rep_min_max.hpp b/packages/PEGTL/include/tao/pegtl/internal/rep_min_max.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d50a47f351a62e749eebc3b7b36daa41a53f5862 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rep_min_max.hpp @@ -0,0 +1,88 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "../config.hpp" + +#include "duseltronik.hpp" +#include "not_at.hpp" +#include "rule_conjunction.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Min, unsigned Max, typename... Rules > + struct rep_min_max; + + template< unsigned Min, unsigned Max > + struct rep_min_max< Min, Max > + : trivial< false > + { + static_assert( Min <= Max, "invalid rep_min_max rule (maximum number of repetitions smaller than minimum)" ); + }; + + template< typename Rule, typename... Rules > + struct rep_min_max< 0, 0, Rule, Rules... > + : not_at< Rule, Rules... > + { + }; + + template< unsigned Min, unsigned Max, typename... Rules > + struct rep_min_max + { + using analyze_t = analysis::counted< analysis::rule_type::SEQ, Min, Rules... >; + + static_assert( Min <= Max, "invalid rep_min_max rule (maximum number of repetitions smaller than minimum)" ); + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< M >(); + using m_t = decltype( m ); + + for( unsigned i = 0; i != Min; ++i ) { + if( !rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { + return false; + } + } + for( unsigned i = Min; i != Max; ++i ) { + if( !duseltronik< seq< Rules... >, A, rewind_mode::REQUIRED, Action, Control >::match( in, st... ) ) { + return m( true ); + } + } + return m( duseltronik< not_at< Rules... >, A, m_t::next_rewind_mode, Action, Control >::match( in, st... ) ); // NOTE that not_at<> will always rewind. + } + }; + + template< unsigned Min, unsigned Max, typename... Rules > + struct skip_control< rep_min_max< Min, Max, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rep_opt.hpp b/packages/PEGTL/include/tao/pegtl/internal/rep_opt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3553f896775f0d5c720d538c4ded94a281ef2d18 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rep_opt.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Max, typename... Rules > + struct rep_opt + { + using analyze_t = analysis::generic< analysis::rule_type::OPT, Rules... >; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + for( unsigned i = 0; ( i != Max ) && duseltronik< seq< Rules... >, A, rewind_mode::REQUIRED, Action, Control >::match( in, st... ); ++i ) { + } + return true; + } + }; + + template< unsigned Max, typename... Rules > + struct skip_control< rep_opt< Max, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/require.hpp b/packages/PEGTL/include/tao/pegtl/internal/require.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f03821e46f344523bab4aa73dfd419b992536dd0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/require.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2016-2018 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 "skip_control.hpp" +#include "trivial.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< unsigned Amount > + struct require; + + template<> + struct require< 0 > + : trivial< true > + { + }; + + template< unsigned Amount > + struct require + { + using analyze_t = analysis::generic< analysis::rule_type::OPT >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 0 ) ) ) + { + return in.size( Amount ) >= Amount; + } + }; + + template< unsigned Amount > + struct skip_control< require< Amount > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/result_on_found.hpp b/packages/PEGTL/include/tao/pegtl/internal/result_on_found.hpp new file mode 100644 index 0000000000000000000000000000000000000000..13ec9891c2614ecbfd1d1c31a59d0147c9cf472d --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/result_on_found.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + enum class result_on_found : bool + { + SUCCESS = true, + FAILURE = false + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rule_conjunction.hpp b/packages/PEGTL/include/tao/pegtl/internal/rule_conjunction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d4dd3d171b4f905fda75f178b4b14205ae0f24f6 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rule_conjunction.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_RULE_CONJUNCTION_HPP +#define TAO_PEGTL_INTERNAL_RULE_CONJUNCTION_HPP + +#include "../apply_mode.hpp" +#include "../config.hpp" +#include "../rewind_mode.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct rule_conjunction; + + template<> + struct rule_conjunction<> + { + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& /*unused*/, States&&... /*unused*/ ) noexcept + { + return true; + } + }; + + template< typename... Rules > + struct rule_conjunction + { + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { +#ifdef __cpp_fold_expressions + return ( Control< Rules >::template match< A, M, Action, Control >( in, st... ) && ... ); +#else + bool result = true; + using swallow = bool[]; + (void)swallow{ result = result && Control< Rules >::template match< A, M, Action, Control >( in, st... )... }; + return result; +#endif + } + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/rules.hpp b/packages/PEGTL/include/tao/pegtl/internal/rules.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6f72c0e5cec6c79bb0d5e8f4fd8bd6816a7e46cb --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/rules.hpp @@ -0,0 +1,63 @@ +// Copyright (c) 2014-2018 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 "alnum.hpp" +#include "alpha.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 "eof.hpp" +#include "eol.hpp" +#include "eolf.hpp" +#include "identifier.hpp" +#include "if_apply.hpp" +#include "if_must.hpp" +#include "if_must_else.hpp" +#include "if_then_else.hpp" +#include "istring.hpp" +#include "list.hpp" +#include "list_must.hpp" +#include "list_tail.hpp" +#include "list_tail_pad.hpp" +#include "minus.hpp" +#include "must.hpp" +#include "not_at.hpp" +#include "one.hpp" +#include "opt.hpp" +#include "pad.hpp" +#include "pad_opt.hpp" +#include "plus.hpp" +#include "raise.hpp" +#include "range.hpp" +#include "ranges.hpp" +#include "rep.hpp" +#include "rep_min.hpp" +#include "rep_min_max.hpp" +#include "rep_opt.hpp" +#include "require.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "sor.hpp" +#include "star.hpp" +#include "star_must.hpp" +#include "state.hpp" +#include "string.hpp" +#include "three.hpp" +#include "trivial.hpp" +#include "try_catch_type.hpp" +#include "two.hpp" +#include "until.hpp" + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/seq.hpp b/packages/PEGTL/include/tao/pegtl/internal/seq.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4c751c406fa0e745580a9286e1f4e8d98a8b6a96 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/seq.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2014-2018 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 "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct seq; + + template<> + struct seq<> + : trivial< true > + { + }; + + template< typename Rule > + struct seq< Rule > + { + using analyze_t = typename Rule::analyze_t; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + return Control< Rule >::template match< A, M, Action, Control >( in, st... ); + } + }; + + template< typename... Rules > + struct seq + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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... ) ); + } + }; + + template< typename... Rules > + struct skip_control< seq< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/skip_control.hpp b/packages/PEGTL/include/tao/pegtl/internal/skip_control.hpp new file mode 100644 index 0000000000000000000000000000000000000000..29ce86f07ec8b7a41b50576a73f6042bf86b9aeb --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/skip_control.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_SKIP_CONTROL_HPP +#define TAO_PEGTL_INTERNAL_SKIP_CONTROL_HPP + +#include <type_traits> + +#include "../config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + // This class is a simple tagging mechanism. + // By default, skip_control< Rule >::value + // is 'false'. Each internal (!) rule that should + // be hidden from the control and action class' + // callbacks simply specializes skip_control<> + // to return 'true' for the above expression. + + template< typename Rule > + struct skip_control : std::false_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/sor.hpp b/packages/PEGTL/include/tao/pegtl/internal/sor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3108a649df09d09bc020ccb11b26d41fd4e25726 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/sor.hpp @@ -0,0 +1,74 @@ +// Copyright (c) 2014-2018 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 "../config.hpp" + +#include "integer_sequence.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename... Rules > + struct sor; + + template<> + struct sor<> + : trivial< false > + { + }; + + template< typename... Rules > + struct sor + : sor< index_sequence_for< Rules... >, Rules... > + { + }; + + template< std::size_t... Indices, typename... Rules > + struct sor< index_sequence< Indices... >, Rules... > + { + using analyze_t = analysis::generic< analysis::rule_type::SOR, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { +#ifdef __cpp_fold_expressions + return ( Control< Rules >::template match < A, ( Indices == ( sizeof...( Rules ) - 1 ) ) ? M : rewind_mode::REQUIRED, Action, Control > ( in, st... ) || ... ); +#else + bool result = false; + using swallow = bool[]; + (void)swallow{ result = result || Control< Rules >::template match < A, ( Indices == ( sizeof...( Rules ) - 1 ) ) ? M : rewind_mode::REQUIRED, Action, Control > ( in, st... )... }; + return result; +#endif + } + }; + + template< typename... Rules > + struct skip_control< sor< Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/star.hpp b/packages/PEGTL/include/tao/pegtl/internal/star.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cfa3c8a56216559f71ebe699b60792b587a6a06e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/star.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "../config.hpp" + +#include "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Rule, typename... Rules > + struct star + { + using analyze_t = analysis::generic< analysis::rule_type::OPT, Rule, Rules..., star >; + + template< apply_mode A, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + while( seq< Rule, Rules... >::template match< A, rewind_mode::REQUIRED, Action, Control >( in, st... ) ) { + } + return true; + } + }; + + template< typename Rule, typename... Rules > + struct skip_control< star< Rule, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/star_must.hpp b/packages/PEGTL/include/tao/pegtl/internal/star_must.hpp new file mode 100644 index 0000000000000000000000000000000000000000..41b06575f10915f88140d3e006fd3642759171a6 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/star_must.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 + +#include "../config.hpp" + +#include "if_must.hpp" +#include "star.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Cond, typename... Rules > + using star_must = star< if_must< false, Cond, Rules... > >; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/state.hpp b/packages/PEGTL/include/tao/pegtl/internal/state.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0d8b92afb23a5714628dafd2a85e6eb00a155fe6 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/state.hpp @@ -0,0 +1,85 @@ +// Copyright (c) 2014-2018 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 "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename State, typename... Rules > + struct state + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static auto success( State& s, const Input& in, States&&... st ) + -> decltype( s.template success< A, M, Action, Control >( in, st... ), void() ) + { + s.template success< A, M, Action, Control >( in, st... ); + } + + // NOTE: The additional "int = 0" is a work-around for missing expression SFINAE in VS2015. + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States, + int = 0 > + static auto success( State& s, const Input& in, States&&... st ) + -> decltype( s.success( in, st... ), void() ) + { + s.success( in, st... ); + } + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + State s( static_cast< const Input& >( in ), st... ); + + if( duseltronik< seq< Rules... >, A, M, Action, Control >::match( in, s ) ) { + success< A, M, Action, Control >( s, in, st... ); + return true; + } + return false; + } + }; + + template< typename State, typename... Rules > + struct skip_control< state< State, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/string.hpp b/packages/PEGTL/include/tao/pegtl/internal/string.hpp new file mode 100644 index 0000000000000000000000000000000000000000..49cdf8f3b56e4b1b5253cbb423c7d8aa6e7a459e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/string.hpp @@ -0,0 +1,68 @@ +// Copyright (c) 2014-2018 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 <cstring> +#include <utility> + +#include "../config.hpp" + +#include "bump_help.hpp" +#include "result_on_found.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + 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<> + : trivial< true > + { + }; + + template< char... Cs > + struct string + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, sizeof...( Cs ) >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 0 ) ) ) + { + if( in.size( sizeof...( Cs ) ) >= sizeof...( Cs ) ) { + if( unsafe_equals( in.current(), { Cs... } ) ) { + bump_help< result_on_found::SUCCESS, Input, char, Cs... >( in, sizeof...( Cs ) ); + return true; + } + } + return false; + } + }; + + template< char... Cs > + struct skip_control< string< Cs... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/three.hpp b/packages/PEGTL/include/tao/pegtl/internal/three.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bd6fe525dc2173ad399cbc05668e9c91eb1c4a32 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/three.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_THREE_HPP +#define TAO_PEGTL_INTERNAL_THREE_HPP + +#include <utility> + +#include "../config.hpp" + +#include "bump_help.hpp" +#include "result_on_found.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< char C > + struct three + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 3 ) ) ) + { + if( in.size( 3 ) >= 3 ) { + if( ( in.peek_char( 0 ) == C ) && ( in.peek_char( 1 ) == C ) && ( in.peek_char( 2 ) == C ) ) { + bump_help< result_on_found::SUCCESS, Input, char, C >( in, 3 ); + return true; + } + } + return false; + } + }; + + template< char C > + struct skip_control< three< C > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/trivial.hpp b/packages/PEGTL/include/tao/pegtl/internal/trivial.hpp new file mode 100644 index 0000000000000000000000000000000000000000..38479d27365765018ebe19e794987f5fb5b45e60 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/trivial.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_TRIVIAL_HPP +#define TAO_PEGTL_INTERNAL_TRIVIAL_HPP + +#include "../config.hpp" + +#include "skip_control.hpp" + +#include "../analysis/counted.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< bool Result > + struct trivial + { + using analyze_t = analysis::counted< analysis::rule_type::ANY, unsigned( !Result ) >; + + template< typename Input > + static bool match( Input& /*unused*/ ) noexcept + { + return Result; + } + }; + + template< bool Result > + struct skip_control< trivial< Result > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp b/packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e70e432efb177cbeeff3098311395320a970c085 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/try_catch_type.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2014-2018 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 + +#include <type_traits> + +#include "../config.hpp" + +#include "duseltronik.hpp" +#include "seq.hpp" +#include "skip_control.hpp" +#include "trivial.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Exception, typename... Rules > + struct try_catch_type; + + template< typename Exception > + struct try_catch_type< Exception > + : trivial< true > + { + }; + + template< typename Exception, typename... Rules > + struct try_catch_type + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, Rules... >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + auto m = in.template mark< M >(); + using m_t = decltype( m ); + + try { + return m( duseltronik< seq< Rules... >, A, m_t::next_rewind_mode, Action, Control >::match( in, st... ) ); + } + catch( const Exception& ) { + return false; + } + } + }; + + template< typename Exception, typename... Rules > + struct skip_control< try_catch_type< Exception, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/two.hpp b/packages/PEGTL/include/tao/pegtl/internal/two.hpp new file mode 100644 index 0000000000000000000000000000000000000000..69eaf4b65b3df54803417f06b64e505c4f7e7695 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/two.hpp @@ -0,0 +1,52 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_INTERNAL_TWO_HPP +#define TAO_PEGTL_INTERNAL_TWO_HPP + +#include <utility> + +#include "../config.hpp" + +#include "bump_help.hpp" +#include "result_on_found.hpp" +#include "skip_control.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< char C > + struct two + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< typename Input > + static bool match( Input& in ) noexcept( noexcept( in.size( 2 ) ) ) + { + if( in.size( 2 ) >= 2 ) { + if( ( in.peek_char( 0 ) == C ) && ( in.peek_char( 1 ) == C ) ) { + bump_help< result_on_found::SUCCESS, Input, char, C >( in, 2 ); + return true; + } + } + return false; + } + }; + + template< char C > + struct skip_control< two< C > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/internal/until.hpp b/packages/PEGTL/include/tao/pegtl/internal/until.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c6a002ee8e3bb730a5e40432011d81cf1eb999bf --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/internal/until.hpp @@ -0,0 +1,91 @@ +// Copyright (c) 2014-2018 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 "eof.hpp" +#include "not_at.hpp" +#include "rule_conjunction.hpp" +#include "skip_control.hpp" +#include "star.hpp" + +#include "../apply_mode.hpp" +#include "../rewind_mode.hpp" + +#include "../analysis/generic.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename Cond, typename... Rules > + struct until; + + template< typename Cond > + struct until< Cond > + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, bytes< 1 > >, Cond >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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... Rules > + struct until + { + using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, Rules... >, Cond >; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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( !rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { + return false; + } + } + return m( true ); + } + }; + + template< typename Cond, typename... Rules > + struct skip_control< until< Cond, Rules... > > : std::true_type + { + }; + + } // namespace internal + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/istream_input.hpp b/packages/PEGTL/include/tao/pegtl/istream_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f598753b273ca9e08442f6f2904472cd80517a13 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/istream_input.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2017-2018 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 <istream> + +#include "buffer_input.hpp" +#include "config.hpp" +#include "eol.hpp" + +#include "internal/istream_reader.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Eol = eol::lf_crlf > + struct istream_input + : buffer_input< internal::istream_reader, Eol > + { + 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::forward< T >( in_source ), in_maximum, in_stream ) + { + } + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + istream_input( Ts&&... )->istream_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/memory_input.hpp b/packages/PEGTL/include/tao/pegtl/memory_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..021b21142fe42bd955b36577df8e8068ab47dbaa --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/memory_input.hpp @@ -0,0 +1,366 @@ +// Copyright (c) 2014-2018 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 <cstddef> +#include <cstdint> +#include <cstring> +#include <string> +#include <type_traits> +#include <utility> + +#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_impl.hpp" +#include "internal/eolf.hpp" +#include "internal/iterator.hpp" +#include "internal/marker.hpp" +#include "internal/until.hpp" + +namespace tao +{ + 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::IMMEDIATE, 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< Source, T&& >::value ) + : 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< Source, T&& >::value ) + : 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; + + const char* current() const noexcept + { + return m_current.data; + } + + const char* begin() const noexcept + { + return m_begin; + } + + const char* end( const std::size_t /*unused*/ = 0 ) const noexcept + { + return m_end; + } + + std::size_t byte() const noexcept + { + return m_current.byte; + } + + std::size_t line() const noexcept + { + return m_current.line; + } + + std::size_t byte_in_line() const noexcept + { + return m_current.byte_in_line; + } + + 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 ); + } + + 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_byte_in_line = 0 ) + { + m_current.data = m_begin; + m_current.byte = in_byte; + m_current.line = in_line; + m_current.byte_in_line = in_byte_in_line; + } + + protected: + const char* const m_begin; + iterator_t m_current; + const char* const m_end; + const Source m_source; + }; + + 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< Source, T&& >::value ) + : 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< Source, T&& >::value ) + : 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; + + const char* current() const noexcept + { + return m_current; + } + + const char* begin() const noexcept + { + return m_begin.data; + } + + const char* end( const std::size_t /*unused*/ = 0 ) const noexcept + { + return m_end; + } + + 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; + } + + 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; + } + + protected: + const internal::iterator m_begin; + iterator_t m_current; + const char* const m_end; + const Source m_source; + }; + + } // namespace internal + + template< tracking_mode P = tracking_mode::IMMEDIATE, 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< Source, T&& >::value ) + : 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< Source, T&& >::value ) + : 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< Source, T&& >::value ) + : 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_byte_in_line ) noexcept( std::is_nothrow_constructible< Source, T&& >::value ) + : memory_input( { in_begin, in_byte, in_line, in_byte_in_line }, 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; + + const Source& source() const noexcept + { + return this->m_source; + } + + bool empty() const noexcept + { + return this->current() == this->end(); + } + + std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept + { + return std::size_t( this->end() - this->current() ); + } + + char peek_char( const std::size_t offset = 0 ) const noexcept + { + return this->current()[ offset ]; + } + + std::uint8_t peek_byte( const std::size_t offset = 0 ) const noexcept + { + return static_cast< std::uint8_t >( peek_char( offset ) ); + } + + iterator_t& iterator() noexcept + { + return this->m_current; + } + + const iterator_t& iterator() const noexcept + { + return this->m_current; + } + + using internal::memory_input_base< P, Eol, Source >::position; + + 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 > + internal::marker< iterator_t, M > mark() noexcept + { + return internal::marker< iterator_t, M >( iterator() ); + } + + const char* at( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept + { + return this->begin() + p.byte; + } + + const char* begin_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept + { + return at( p ) - p.byte_in_line; + } + + 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 > >; + normal< grammar >::match< apply_mode::NOTHING, rewind_mode::DONTCARE, nothing, normal >( in ); + return in.current(); + } + + std::string line_as_string( const TAO_PEGTL_NAMESPACE::position& p ) const + { + return std::string( begin_of_line( p ), end_of_line( p ) ); + } + + void* internal_state = nullptr; + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + memory_input( Ts&&... )->memory_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/mmap_input.hpp b/packages/PEGTL/include/tao/pegtl/mmap_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..92c38f69790d27dfcf3c3987897502b723bd0c68 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/mmap_input.hpp @@ -0,0 +1,85 @@ +// Copyright (c) 2014-2018 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 <string> +#include <utility> + +#include "config.hpp" +#include "eol.hpp" +#include "memory_input.hpp" +#include "tracking_mode.hpp" + +#if defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) +#include <unistd.h> // 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct mmap_holder + { + const std::string filename; + const file_mapper data; + + template< typename T > + explicit mmap_holder( T&& in_filename ) + : filename( std::forward< T >( in_filename ) ), + data( filename.c_str() ) + { + } + + mmap_holder( const mmap_holder& ) = delete; + mmap_holder( mmap_holder&& ) = delete; + + ~mmap_holder() = default; + + void operator=( const mmap_holder& ) = delete; + void operator=( mmap_holder&& ) = delete; + }; + + } // namespace internal + + template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > + struct mmap_input + : private internal::mmap_holder, + public memory_input< P, Eol, const char* > + { + template< typename T > + explicit mmap_input( T&& in_filename ) + : internal::mmap_holder( std::forward< T >( in_filename ) ), + memory_input< P, Eol, const char* >( data.begin(), data.end(), filename.c_str() ) + { + } + + mmap_input( const mmap_input& ) = delete; + mmap_input( mmap_input&& ) = delete; + + ~mmap_input() = default; + + void operator=( const mmap_input& ) = delete; + void operator=( mmap_input&& ) = delete; + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + explicit mmap_input( Ts&&... )->mmap_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/normal.hpp b/packages/PEGTL/include/tao/pegtl/normal.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8f7949aae4f5664feb3e28e2bacb3acea51c08ff --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/normal.hpp @@ -0,0 +1,90 @@ +// Copyright (c) 2014-2018 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 <utility> + +#include "apply_mode.hpp" +#include "config.hpp" +#include "nothing.hpp" +#include "parse_error.hpp" +#include "rewind_mode.hpp" + +#include "internal/demangle.hpp" +#include "internal/dusel_mode.hpp" +#include "internal/duseltronik.hpp" +#include "internal/has_apply.hpp" +#include "internal/has_apply0.hpp" +#include "internal/skip_control.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + struct normal + { + template< typename Input, typename... States > + static void start( const Input& /*unused*/, States&&... /*unused*/ ) noexcept + { + } + + template< typename Input, typename... States > + static void success( const Input& /*unused*/, States&&... /*unused*/ ) noexcept + { + } + + template< typename Input, typename... States > + static void failure( const Input& /*unused*/, States&&... /*unused*/ ) noexcept + { + } + + template< typename Input, typename... States > + static void raise( const Input& in, States&&... /*unused*/ ) + { + throw parse_error( "parse error matching " + internal::demangle< Rule >(), in ); + } + + template< template< typename... > class Action, typename Input, typename... States > + static auto apply0( const Input& /*unused*/, States&&... st ) + -> decltype( Action< Rule >::apply0( st... ) ) + { + return Action< Rule >::apply0( st... ); + } + + template< template< typename... > class Action, typename Iterator, typename Input, typename... States > + static auto apply( const Iterator& begin, const Input& in, States&&... st ) + -> decltype( Action< Rule >::apply( std::declval< typename Input::action_t >(), st... ) ) + { + const typename Input::action_t action_input( begin, in ); + return Action< Rule >::apply( action_input, st... ); + } + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& in, States&&... st ) + { + constexpr char use_control = !internal::skip_control< Rule >::value; + constexpr char use_action = use_control && ( A == apply_mode::ACTION ) && ( !is_nothing< Action, Rule >::value ); + constexpr char use_apply_void = use_action && internal::has_apply< Action< Rule >, void, typename Input::action_t, States... >::value; + constexpr char use_apply_bool = use_action && internal::has_apply< Action< Rule >, bool, typename Input::action_t, States... >::value; + constexpr char use_apply0_void = use_action && internal::has_apply0< Action< Rule >, void, States... >::value; + constexpr char use_apply0_bool = use_action && internal::has_apply0< Action< Rule >, bool, States... >::value; + static_assert( !use_action || use_apply_bool || use_apply_void || use_apply0_bool || use_apply0_void, "actions not disabled but no apply() or apply0() found" ); + static_assert( use_apply_void + use_apply_bool + use_apply0_void + use_apply0_bool < 2, "both apply() and apply0() defined" ); + constexpr auto mode = static_cast< dusel_mode >( use_control + use_apply_void + 2 * use_apply_bool + 3 * use_apply0_void + 4 * use_apply0_bool ); + return internal::duseltronik< Rule, A, M, Action, Control, mode >::match( in, st... ); + } + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/nothing.hpp b/packages/PEGTL/include/tao/pegtl/nothing.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9d2ae16c3c225560c730bc5fa30ac07b26e4fa29 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/nothing.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2014-2018 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 <type_traits> + +#include "config.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + struct nothing + { + }; + + template< template< typename... > class Action, typename Rule > + using is_nothing = std::is_base_of< nothing< Rule >, Action< Rule > >; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/parse.hpp b/packages/PEGTL/include/tao/pegtl/parse.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1f3254964e9452dce820435d9232ca0ec1d85eb9 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/parse.hpp @@ -0,0 +1,84 @@ +// Copyright (c) 2014-2018 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 <cassert> + +#include "apply_mode.hpp" +#include "config.hpp" +#include "normal.hpp" +#include "nothing.hpp" +#include "parse_error.hpp" +#include "rewind_mode.hpp" + +#include "internal/action_input.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + template< typename From > + struct copy_internals + { + template< typename To > + static void apply( const From& from, To& to ) noexcept + { + assert( to.internal_state == nullptr ); + to.internal_state = from.internal_state; + } + }; + + template< typename Input > + struct copy_internals< action_input< Input > > + { + template< typename To > + static void apply( const action_input< Input >& from, To& to ) noexcept + { + assert( to.internal_state == nullptr ); + to.internal_state = from.input().internal_state; + } + }; + + } // 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 Input, + typename... States > + bool parse( Input&& 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 Input, + typename... States > + bool parse_nested( const Outer& oi, Input&& in, States&&... st ) + { + try { + internal::copy_internals< Outer >::apply( oi, in ); + return parse< Rule, Action, Control, A, M >( in, st... ); + } + catch( parse_error& e ) { + e.positions.push_back( oi.position() ); + throw; + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/parse_error.hpp b/packages/PEGTL/include/tao/pegtl/parse_error.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4d62811f2dbce758495f9be187bafbc7f6913551 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/parse_error.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2018 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 <stdexcept> +#include <vector> + +#include "config.hpp" +#include "position.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct parse_error + : public std::runtime_error + { + parse_error( const std::string& msg, std::vector< position >&& in_positions ) + : std::runtime_error( msg ), + positions( std::move( in_positions ) ) + { + } + + template< typename Input > + parse_error( const std::string& msg, const Input& in ) + : parse_error( msg, in.position() ) + { + } + + parse_error( const std::string& msg, const position& pos ) + : std::runtime_error( to_string( pos ) + ": " + msg ), + positions( 1, pos ) + { + } + + std::vector< position > positions; + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/position.hpp b/packages/PEGTL/include/tao/pegtl/position.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a7fe2b38fa75dcc28370059213e22eeec5657e4f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/position.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2014-2018 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 <cstdlib> +#include <ostream> +#include <sstream> +#include <string> +#include <utility> + +#include "config.hpp" + +#include "internal/iterator.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct position + { + template< typename T > + position( const internal::iterator& in_iter, T&& in_source ) + : byte( in_iter.byte ), + line( in_iter.line ), + byte_in_line( in_iter.byte_in_line ), + source( std::forward< T >( in_source ) ) + { + } + + std::size_t byte; + std::size_t line; + std::size_t byte_in_line; + std::string source; + }; + + inline std::ostream& operator<<( std::ostream& o, const position& p ) + { + return o << p.source << ':' << p.line << ':' << p.byte_in_line << '(' << p.byte << ')'; + } + + inline std::string to_string( const position& p ) + { + std::ostringstream o; + o << p; + return o.str(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/read_input.hpp b/packages/PEGTL/include/tao/pegtl/read_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8d7eb0481f5f62655f4059bec5503e06a13ca530 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/read_input.hpp @@ -0,0 +1,80 @@ +// Copyright (c) 2014-2018 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 <string> + +#include "config.hpp" +#include "eol.hpp" +#include "string_input.hpp" +#include "tracking_mode.hpp" + +#include "internal/file_reader.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace internal + { + struct filename_holder + { + const std::string filename; + + template< typename T > + explicit filename_holder( T&& in_filename ) + : filename( std::forward< T >( in_filename ) ) + { + } + + filename_holder( const filename_holder& ) = delete; + filename_holder( filename_holder&& ) = delete; + + ~filename_holder() = default; + + void operator=( const filename_holder& ) = delete; + void operator=( filename_holder&& ) = delete; + }; + + } // namespace internal + + template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > + struct read_input + : private internal::filename_holder, + public string_input< P, Eol, const char* > + { + template< typename T > + explicit read_input( T&& in_filename ) + : internal::filename_holder( std::forward< T >( in_filename ) ), + string_input< P, Eol, const char* >( internal::file_reader( filename.c_str() ).read(), filename.c_str() ) + { + } + + template< typename T > + read_input( FILE* in_file, T&& in_filename ) + : internal::filename_holder( std::forward< T >( in_filename ) ), + string_input< P, Eol, const char* >( internal::file_reader( in_file, filename.c_str() ).read(), filename.c_str() ) + { + } + + read_input( const read_input& ) = delete; + read_input( read_input&& ) = delete; + + ~read_input() = default; + + void operator=( const read_input& ) = delete; + void operator=( read_input&& ) = delete; + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + explicit read_input( Ts&&... )->read_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp b/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c12fddc88a8401dd95b3c42d43ebd5de79e4a06e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/rewind_mode.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + enum class rewind_mode : char + { + ACTIVE, + REQUIRED, + DONTCARE + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/rules.hpp b/packages/PEGTL/include/tao/pegtl/rules.hpp new file mode 100644 index 0000000000000000000000000000000000000000..53364a40c75e269b608b301da0291dccc9508006 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/rules.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + // clang-format off + template< typename... Actions > struct apply : internal::apply< Actions... > {}; + template< typename... Actions > struct apply0 : internal::apply0< Actions... > {}; + template< template< typename... > class Action, typename... Rules > struct action : internal::action< Action, Rules... > {}; + 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 failure : internal::trivial< false > {}; + template< typename Rule, typename... Actions > struct if_apply : internal::if_apply< Rule, Actions... > {}; + 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 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_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 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 must : internal::must< Rules... > {}; + template< typename... Rules > struct not_at : internal::not_at< Rules... > {}; + template< typename... Rules > struct opt : internal::opt< Rules... > {}; + template< typename Cond, typename... Rules > struct opt_must : internal::if_must< true, Cond, 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 Exception > struct raise : internal::raise< Exception > {}; + 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 Cond, typename... Rules > struct star_must : internal::star_must< Cond, Rules... > {}; + template< typename State, typename... Rules > struct state : internal::state< State, Rules... > {}; + struct success : internal::trivial< true > {}; + template< typename... Rules > struct try_catch : internal::try_catch_type< parse_error, Rules... > {}; + template< typename Exception, typename... Rules > struct try_catch_type : internal::try_catch_type< Exception, Rules... > {}; + template< typename Cond, typename... Rules > struct until : internal::until< Cond, Rules... > {}; + // clang-format on + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/string_input.hpp b/packages/PEGTL/include/tao/pegtl/string_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ebce2361f9d943d4257e85ee3cfed21686fc6a50 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/string_input.hpp @@ -0,0 +1,72 @@ +// Copyright (c) 2014-2018 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 <string> +#include <utility> + +#include "config.hpp" +#include "eol.hpp" +#include "memory_input.hpp" +#include "tracking_mode.hpp" + +namespace tao +{ + 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; + + void operator=( const string_holder& ) = delete; + void operator=( string_holder&& ) = delete; + }; + + } // namespace internal + + template< tracking_mode P = tracking_mode::IMMEDIATE, 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; + + void operator=( const string_input& ) = delete; + void operator=( string_input&& ) = delete; + }; + +#ifdef __cpp_deduction_guides + template< typename... Ts > + explicit string_input( Ts&&... )->string_input<>; +#endif + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/tracking_mode.hpp b/packages/PEGTL/include/tao/pegtl/tracking_mode.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c470042d52f638865e37dfd088e3050e560e3415 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/tracking_mode.hpp @@ -0,0 +1,23 @@ +// Copyright (c) 2017-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + enum class tracking_mode : bool + { + IMMEDIATE, + LAZY + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/uint16.hpp b/packages/PEGTL/include/tao/pegtl/uint16.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d913ed2f6381ffe14fdeeeb10483a1e289edcd2f --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/uint16.hpp @@ -0,0 +1,66 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UINT16_HPP +#define TAO_PEGTL_UINT16_HPP + +#include "config.hpp" + +#include "internal/peek_mask_uint.hpp" +#include "internal/peek_uint.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/uint32.hpp b/packages/PEGTL/include/tao/pegtl/uint32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..12f5617ceec963aa368a1448cf3c8962a3dd3b55 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/uint32.hpp @@ -0,0 +1,66 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UINT32_HPP +#define TAO_PEGTL_UINT32_HPP + +#include "config.hpp" + +#include "internal/peek_mask_uint.hpp" +#include "internal/peek_uint.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/uint64.hpp b/packages/PEGTL/include/tao/pegtl/uint64.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f6d2f7c49ba96b1f4134c1aad0b9bd6a3615e991 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/uint64.hpp @@ -0,0 +1,67 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UINT64_HPP +#define TAO_PEGTL_UINT64_HPP + +#include "config.hpp" + +#include "internal/peek_mask_uint.hpp" +#include "internal/peek_uint.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/uint8.hpp b/packages/PEGTL/include/tao/pegtl/uint8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..694c40b309c131997803998ad3a91514756d9ff8 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/uint8.hpp @@ -0,0 +1,44 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UINT8_HPP +#define TAO_PEGTL_UINT8_HPP + +#include "config.hpp" + +#include "internal/peek_mask_uint8.hpp" +#include "internal/peek_uint8.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 uint8 + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/utf16.hpp b/packages/PEGTL/include/tao/pegtl/utf16.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cb475971fb6590429126bff7610c8838e67ebe0e --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/utf16.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UTF16_HPP +#define TAO_PEGTL_UTF16_HPP + +#include "config.hpp" + +#include "internal/peek_utf16.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + 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 + + namespace utf16 = TAO_PEGTL_NATIVE_UTF16; // NOLINT(misc-unused-alias-decls) + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/utf32.hpp b/packages/PEGTL/include/tao/pegtl/utf32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..34e102f74a35d0341c8610ce4040b9adf70186af --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/utf32.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#ifndef TAO_PEGTL_UTF32_HPP +#define TAO_PEGTL_UTF32_HPP + +#include "config.hpp" + +#include "internal/peek_utf32.hpp" +#include "internal/result_on_found.hpp" +#include "internal/rules.hpp" + +namespace tao +{ + 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 + + namespace utf32 = TAO_PEGTL_NATIVE_UTF32; // NOLINT(misc-unused-alias-decls) + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/utf8.hpp b/packages/PEGTL/include/tao/pegtl/utf8.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c76e83e3a45c647e299a134275835cccbfca4546 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/utf8.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + 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 > {}; + 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 utf8 + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/include/tao/pegtl/version.hpp b/packages/PEGTL/include/tao/pegtl/version.hpp new file mode 100644 index 0000000000000000000000000000000000000000..491c38b7fe02fdda6256539aa295b36fac5d56c0 --- /dev/null +++ b/packages/PEGTL/include/tao/pegtl/version.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017-2018 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 "2.7.1" + +#define TAO_PEGTL_VERSION_MAJOR 2 +#define TAO_PEGTL_VERSION_MINOR 7 +#define TAO_PEGTL_VERSION_PATCH 1 + +// Compatibility, remove with 3.0 +#define TAOCPP_PEGTL_VERSION TAO_PEGTL_VERSION +#define TAOCPP_PEGTL_VERSION_MAJOR TAO_PEGTL_VERSION_MAJOR +#define TAOCPP_PEGTL_VERSION_MINOR TAO_PEGTL_VERSION_MINOR +#define TAOCPP_PEGTL_VERSION_PATCH TAO_PEGTL_VERSION_PATCH + +#endif diff --git a/packages/PEGTL/src/example/pegtl/CMakeLists.txt b/packages/PEGTL/src/example/pegtl/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c904012ef0698997d172e9b5093f3e8ddffb16ec --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required (VERSION 3.3.0 FATAL_ERROR) + +set (example_sources + abnf2pegtl.cpp + analyze.cpp + calculator.cpp + chomsky_hierarchy.cpp + csv1.cpp + csv2.cpp + dynamic_match.cpp + hello_world.cpp + indent_aware.cpp + json_build_one.cpp + json_build_two.cpp + json_count.cpp + json_parse.cpp + lua53_parse.cpp + modulus_match.cpp + parse_tree.cpp + proto3.cpp + recover.cpp + s_expression.cpp + sum.cpp + symbol_table.cpp + unescape.cpp + uri.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 ${examplesourcefile} NAME_WE) + set (exename "pegtl-example-${exename}") + add_executable (${exename} ${examplesourcefile}) + target_link_libraries (${exename} PRIVATE taocpp::pegtl) + set_target_properties (${exename} PROPERTIES + CXX_STANDARD 11 + 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 (examplesourcefile) + +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 (ignored_source_file) +endif () diff --git a/packages/PEGTL/src/example/pegtl/abnf.abnf b/packages/PEGTL/src/example/pegtl/abnf.abnf new file mode 100644 index 0000000000000000000000000000000000000000..4a76b75bb1307727b31d247a59f8f4a34aeab74b --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/abnf.abnf @@ -0,0 +1,76 @@ +; 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 diff --git a/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp b/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6251172ae34664f15c327845e3d9b8dce655e187 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/abnf2pegtl.cpp @@ -0,0 +1,716 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <algorithm> +#include <iostream> +#include <iterator> +#include <map> +#include <set> +#include <sstream> +#include <string> +#include <utility> +#include <vector> + +#include <cassert> +#include <cctype> +#include <cstdlib> + +#if defined( _MSC_VER ) +#include <string.h> +#define TAO_PEGTL_STRCASECMP _stricmp +#else +#include <strings.h> +#define TAO_PEGTL_STRCASECMP strcasecmp +#endif + +#include <tao/pegtl.hpp> +#include <tao/pegtl/analyze.hpp> +#include <tao/pegtl/contrib/abnf.hpp> +#include <tao/pegtl/contrib/parse_tree.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace abnf + { + using node_ptr = std::unique_ptr< parse_tree::node >; + + namespace + { + std::string prefix = "tao::pegtl::"; // NOLINT + + std::set< std::string > keywords = { // NOLINT + "alignas", + "alignof", + "and", + "and_eq", + "asm", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "char16_t", + "char32_t", + "class", + "compl", + "const", + "constexpr", + "const_cast", + "continue", + "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", + "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; // NOLINT + rules_t rules; // NOLINT + + // 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.byte_in_line += 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 corresponsing 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. + // + // PEG 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 convencience extension: + + // clang-format off + struct CRLF : sor< abnf::CRLF, CR, LF > {}; + + // The rest is according to the RFC(s): + struct comment_cont : until< CRLF, sor< WSP, VCHAR > > {}; + struct comment : if_must< one< ';' >, comment_cont > {}; + struct c_nl : sor< comment, CRLF > {}; + 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 : if_must< 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 : if_must< one< '<' >, prose_val_cont > {}; + + template< char First, typename Digit > + struct gen_val + { + struct value : plus< Digit > {}; + struct range : if_must< one< '-' >, value > {}; + struct next_value : must< value > {}; + struct type : seq< istring< First >, must< 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 : if_must< one< '%' >, num_val_choice > {}; + + struct alternation; + struct option_close : one< ']' > {}; + struct option : seq< one< '[' >, pad< must< alternation >, c_wsp >, must< option_close > > {}; + struct group_close : one< ')' > {}; + struct group : seq< one< '(' >, pad< must< alternation >, c_wsp >, must< 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 and_predicate : if_must< one< '&' >, repetition > {}; + struct not_predicate : if_must< one< '!' >, repetition > {}; + struct predicate : sor< and_predicate, not_predicate, repetition > {}; + + struct concatenation : list< predicate, plus< c_wsp > > {}; + struct alternation : list_must< concatenation, pad< one< '/' >, c_wsp > > {}; + + struct defined_as_op : sor< string< '=', '/' >, one< '=' > > {}; + struct defined_as : pad< defined_as_op, c_wsp > {}; + struct rule : seq< if_must< rulename, defined_as, alternation >, star< c_wsp >, must< c_nl > > {}; + struct rulelist : until< eof, sor< seq< star< c_wsp >, c_nl >, must< rule > > > {}; + + // end of grammar + + template< typename Rule > + struct error_control : normal< Rule > + { + static const std::string error_message; + + template< typename Input, typename... States > + static void raise( const Input& in, States&&... /*unused*/ ) + { + throw parse_error( error_message, in ); + } + }; + + template<> const std::string error_control< comment_cont >::error_message = "unterminated comment"; // NOLINT + + template<> const std::string error_control< quoted_string_cont >::error_message = "unterminated string (missing '\"')"; // NOLINT + template<> const std::string error_control< prose_val_cont >::error_message = "unterminated prose description (missing '>')"; // NOLINT + + template<> const std::string error_control< hex_val::value >::error_message = "expected hexadecimal value"; // NOLINT + template<> const std::string error_control< dec_val::value >::error_message = "expected decimal value"; // NOLINT + template<> const std::string error_control< bin_val::value >::error_message = "expected binary value"; // NOLINT + template<> const std::string error_control< num_val_choice >::error_message = "expected base specifier (one of 'bBdDxX')"; // NOLINT + + template<> const std::string error_control< option_close >::error_message = "unterminated option (missing ']')"; // NOLINT + template<> const std::string error_control< group_close >::error_message = "unterminated group (missing ')')"; // NOLINT + + template<> const std::string error_control< repetition >::error_message = "expected element"; // NOLINT + template<> const std::string error_control< concatenation >::error_message = "expected element"; // NOLINT + template<> const std::string error_control< alternation >::error_message = "expected element"; // NOLINT + + template<> const std::string error_control< defined_as >::error_message = "expected '=' or '=/'"; // NOLINT + template<> const std::string error_control< c_nl >::error_message = "unterminated rule"; // NOLINT + template<> const std::string error_control< rule >::error_message = "expected rule"; // NOLINT + // clang-format on + + } // namespace grammar + + template< typename Rule > + struct selector + : parse_tree::selector< + Rule, + parse_tree::apply_store_content::to< + 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::apply_remove_content::to< + grammar::option, + grammar::and_predicate, + grammar::not_predicate, + grammar::rule >, + parse_tree::apply_fold_one::to< + grammar::alternation, + grammar::group, + grammar::repetition, + grammar::concatenation > > + { + }; + + template<> + struct selector< grammar::quoted_string > : std::true_type + { + static void transform( node_ptr& n ) + { + shift( n->m_begin, 1 ); + shift( n->m_end, -1 ); + + const std::string content = n->content(); + for( const auto c : content ) { + if( std::isalpha( c ) != 0 ) { + n->id = &typeid( istring_tag ); + return; + } + } + if( content.size() == 1 ) { + n->id = &typeid( one_tag ); + } + else { + n->id = &typeid( string_tag ); + } + } + }; + + template<> + struct selector< grammar::case_sensitive_string > : std::true_type + { + static void transform( node_ptr& n ) + { + n = std::move( n->children.back() ); + if( n->content().size() == 1 ) { + n->id = &typeid( one_tag ); + } + else { + n->id = &typeid( 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< grammar::group >() || n->is< grammar::concatenation >() ) { + return to_string( n->children ); + } + return to_string( n ); + } + + namespace + { + std::string get_rulename( const node_ptr& n ) + { + assert( n->is< grammar::rulename >() ); + std::string v = n->content(); + 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 ) { + throw parse_error( '\'' + n->content() + "' is a reserved rulename", n->begin() ); // NOLINT + } + 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< 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; // NOLINT + + } // namespace + + template<> + struct selector< grammar::rule > : std::true_type + { + static void transform( node_ptr& n ) + { + const auto rname = get_rulename( n->children.front() ); + assert( n->children.at( 1 )->is< grammar::defined_as_op >() ); + const auto op = n->children.at( 1 )->content(); + // when we insert a normal rule, we need to check for duplicates + if( op == "=" ) { + if( !previous_rules.insert( { rname, n.get() } ).second ) { + throw parse_error( "rule '" + rname + "' is already defined", n->begin() ); // NOLINT + } + } + // 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() ) { + throw parse_error( "incremental alternation '" + rname + "' without previous rule definition", n->begin() ); // NOLINT + } + 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< abnf::grammar::alternation >() ) { + node_ptr s( new parse_tree::node ); + s->id = &typeid( 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< 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 { + throw parse_error( "invalid operator '" + op + "', this should not happen!", n->begin() ); // NOLINT + } + } + }; + + struct stringifier + { + using function_t = std::string ( * )( const node_ptr& n ); + function_t default_ = nullptr; + + std::map< const std::type_info*, function_t > map_; + + template< typename T > + void add( const function_t& f ) + { + map_.insert( { &typeid( T ), f } ); + } + + std::string operator()( const node_ptr& n ) const + { + const auto it = map_.find( n->id ); + if( it != map_.end() ) { + return it->second( n ); + } + return default_( n ); + } + }; + + stringifier make_stringifier() + { + stringifier nrv; + nrv.default_ = []( const node_ptr& n ) -> std::string { + throw parse_error( "missing to_string() for " + n->name(), n->begin() ); // NOLINT + }; + + 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 std::string content = n->content(); + 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 std::string content = n->content(); + 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 std::string content = n->content(); + 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->content(); } ); + nrv.add< grammar::dec_val::value >( []( const node_ptr& n ) { return n->content(); } ); + 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 o; + o << v; + return o.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->content() + " */"; } ); + + 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()->content(); + const auto star = rep.find( '*' ); + if( star == std::string::npos ) { + const auto v = remove_leading_zeroes( rep ); + if( v.empty() ) { + throw parse_error( "repetition of zero not allowed", n->begin() ); // NOLINT + } + 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() ) { + throw parse_error( "repetition maximum of zero not allowed", n->begin() ); // NOLINT + } + 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 ) { + throw parse_error( "repetition minimum which is greater than the repetition maximum not allowed", n->begin() ); // NOLINT + } + if( ( min_val == 1 ) && ( max_val == 1 ) ) { + // note: content can not be used here! + return to_string( n->children.back() ); + } + const auto min_element = ( min_val == 1 ) ? content : ( prefix + "rep< " + min + ", " + content + " >" ); + if( min_val == max_val ) { + return min_element; + } + std::ostringstream os; + os << ( max_val - min_val ); + const auto max_element = prefix + ( ( max_val - min_val == 1 ) ? "opt< " : ( "rep_opt< " + os.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 + +} // namespace tao + +int main( int argc, char** argv ) +{ + using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + + if( argc != 2 ) { + analyze< abnf::grammar::rulelist >(); + std::cerr << "Usage: " << argv[ 0 ] << " SOURCE" << std::endl; + return 1; + } + + file_input<> in( argv[ 1 ] ); + try { + const auto root = parse_tree::parse< abnf::grammar::rulelist, abnf::selector, nothing, abnf::grammar::error_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 ) << std::endl; + } + } + catch( const parse_error& e ) { + const auto p = e.positions.front(); + std::cerr << e.what() << std::endl + << in.line_as_string( p ) << std::endl + << std::string( p.byte_in_line, ' ' ) << '^' << std::endl; + } + + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/analyze.cpp b/packages/PEGTL/src/example/pegtl/analyze.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98ad12e7ac5ed1a72f35e401084121198c063290 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/analyze.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl.hpp> +#include <tao/pegtl/analyze.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +struct bar; + +struct foo + : sor< digit, bar > +{ +}; + +struct bar + : plus< foo > +{ +}; + +int main( int /*unused*/, char** /*unused*/ ) +{ + if( analyze< foo >() != 0 ) { + std::cout << "there are problems" << std::endl; + return 1; + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/calculator.cpp b/packages/PEGTL/src/example/pegtl/calculator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5404848ed21370871602f85175f08f4e91468fac --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/calculator.cpp @@ -0,0 +1,366 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <functional> +#include <iostream> +#include <map> +#include <sstream> +#include <vector> + +#include <tao/pegtl.hpp> + +// Include the analyze function that checks +// a grammar for possible infinite cycles. + +#include <tao/pegtl/analyze.hpp> + +namespace pegtl = tao::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.insert( { name, { p, f } } ); + } + + const std::map< std::string, op >& ops() const + { + return m_ops; + } + + private: + std::map< std::string, op > m_ops; + }; + + // Here the actual grammar starts. + + using namespace tao::pegtl; // NOLINT + + // Comments are introduced by a '#' and proceed to the end-of-line/file. + + struct comment + : if_must< 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 analyze_t = analysis::generic< analysis::rule_type::ANY >; + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& in, const operators& b, stacks& s ) + { + // 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 Input > + static bool match( Input& 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 preceeded 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 + : if_must< 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 singlar expression). + + struct expression + : list< atomic, infix, ignored > + { + }; + + // The top-level grammar allows one expression and then expects eof. + + struct grammar + : must< 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 must derive from + // pegtl::nothing (or, alternatively, define an action that does something + // sensible for all rules for which no specialisation exists). + + template< typename Rule > + struct action + : pegtl::nothing< Rule > + { + }; + + // 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 Input > + static void apply( const Input& in, const operators& /*unused*/, stacks& s ) + { + std::stringstream ss; + ss.str( 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 ) +{ + // Check the grammar for some possible issues. + + pegtl::analyze< calculator::grammar >(); + + // 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 ); + pegtl::parse< calculator::grammar, calculator::action >( in, b, s ); + + // ...and print the respective results to std::cout. + + std::cout << s.finish() << std::endl; + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/chomsky_hierarchy.cpp b/packages/PEGTL/src/example/pegtl/chomsky_hierarchy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f60bb2c24e9bd14837a67401c104cde75576defb --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/chomsky_hierarchy.cpp @@ -0,0 +1,128 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <cstring> +#include <iostream> +#include <string> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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 Input > + static bool match( Input& in, std::size_t& count ) + { + 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 + : pegtl::nothing< Rule > + { + }; + + template<> + struct action_2_with_state< pegtl::star< pegtl::one< 'a' > > > + { + template< typename Input > + static void apply( const Input& 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; +} diff --git a/packages/PEGTL/src/example/pegtl/csv1.cpp b/packages/PEGTL/src/example/pegtl/csv1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..109203c1d7c653ab5f982def2afc6a9109c7009d --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/csv1.cpp @@ -0,0 +1,109 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <cstdint> +#include <iostream> +#include <sstream> +#include <string> +#include <vector> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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_must< value_item, pegtl::one< ',' > > {}; + struct value_line : pegtl::if_must< 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 + : pegtl::nothing< Rule > + { + }; + + template<> + struct action< value > + { + template< typename Input > + static void apply( const Input& in, result_data& data ) + { + assert( !data.empty() ); + std::stringstream ss; + 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 Input > + static void start( Input& /*unused*/, result_data& data ) + { + data.emplace_back(); + } + + template< typename Input > + static void failure( Input& /*unused*/, result_data& data ) + { + assert( !data.empty() ); + data.pop_back(); + } + }; + +} // namespace csv1 + +int main( int argc, char** argv ) +{ + for( int i = 1; i < argc; ++i ) { + pegtl::file_input<> in( argv[ i ] ); + csv1::result_data data; + pegtl::parse< pegtl::must< csv1::file >, csv1::action, csv1::control >( in, data ); + 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; +} diff --git a/packages/PEGTL/src/example/pegtl/csv2.cpp b/packages/PEGTL/src/example/pegtl/csv2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4da6dd15fd9afa1ccf9cbd7141cc05b927e68430 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/csv2.cpp @@ -0,0 +1,185 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> +#include <utility> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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< int C > struct string_without : pegtl::star< pegtl::not_one< C, 10, 13 > > {}; + struct plain_value : string_without< ',' > {}; + struct quoted_value : pegtl::if_must< 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, "N must be positive" ); }; + // 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 : pegtl::nothing< Rule > + { + }; + + template<> + struct action< plain_value > + { + template< typename Input, unsigned N > + static void apply( const Input& 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 Input > + static void apply( const Input& in, result_data< N >& data ) + { + if( data.temp.size() != N ) { + throw pegtl::parse_error( "column count mismatch", in ); + } + 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 ) +{ + 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; + pegtl::parse< pegtl::must< csv2::file< number_of_columns > >, csv2::action >( in, data ); + for( const auto& line : data.result ) { + csv2::print_tuple( line ); + } + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/double.hpp b/packages/PEGTL/src/example/pegtl/double.hpp new file mode 100644 index 0000000000000000000000000000000000000000..336da79f33837b277837c1fb0f12dc51b6d1c452 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/double.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_EXAMPLES_PEGTL_DOUBLE_HPP + +#include <tao/pegtl.hpp> + +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::TAO_PEGTL_NAMESPACE; // NOLINT + + // 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 diff --git a/packages/PEGTL/src/example/pegtl/dynamic_match.cpp b/packages/PEGTL/src/example/pegtl/dynamic_match.cpp new file mode 100644 index 0000000000000000000000000000000000000000..990f2d3244f289b37dcd55890f93dd2b96781a39 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/dynamic_match.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cstring> + +#include <iostream> +#include <string> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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 + { + template< pegtl::apply_mode, + pegtl::rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& in, const std::string& id, const std::string& /*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::if_must< long_literal_open, pegtl::until< long_literal_close, long_literal_body >, pegtl::eof > + { + }; + + template< typename Rule > + struct action + : pegtl::nothing< Rule > + { + }; + + template<> + struct action< long_literal_id > + { + template< typename Input > + static void apply( const Input& in, std::string& id, const std::string& /*unused*/ ) + { + id = in.string(); + } + }; + + template<> + struct action< long_literal_body > + { + template< typename Input > + static void apply( const Input& in, const std::string& /*unused*/, std::string& body ) + { + body += in.string(); + } + }; + +} // namespace dynamic + +int main( int argc, char** argv ) +{ + if( argc > 1 ) { + std::string id; + std::string body; + + pegtl::argv_input<> in( argv, 1 ); + 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; +} diff --git a/packages/PEGTL/src/example/pegtl/hello_world.cpp b/packages/PEGTL/src/example/pegtl/hello_world.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a9aacb2f38f2601513a1cd8534ca8d09bbe338d --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/hello_world.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> +#include <string> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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::must< prefix, name, pegtl::one< '!' >, pegtl::eof > {}; + // clang-format on + + template< typename Rule > + struct action + : pegtl::nothing< Rule > + { + }; + + template<> + struct action< name > + { + template< typename Input > + static void apply( const Input& in, std::string& v ) + { + v = in.string(); + } + }; + +} // namespace hello + +int main( int argc, char** argv ) +{ + if( argc > 1 ) { + std::string name; + + pegtl::argv_input<> in( argv, 1 ); + pegtl::parse< hello::grammar, hello::action >( in, name ); + + std::cout << "Good bye, " << name << "!" << std::endl; + } +} diff --git a/packages/PEGTL/src/example/pegtl/indent_aware.cpp b/packages/PEGTL/src/example/pegtl/indent_aware.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef979d1b51fd633183589e1e09163e7c88ae1cb9 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/indent_aware.cpp @@ -0,0 +1,217 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <cstddef> +#include <iostream> + +#include <tao/pegtl.hpp> + +namespace pegtl = tao::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 + : pegtl::nothing< Rule > + { + }; + + 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 Input > + static void apply( const Input& 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 ); // NOLINT + } + 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 Input > + static void apply( const Input& in, state& s ) + { + if( s.minimum_indent > 0 ) { + throw pegtl::parse_error( "expected indented block instead of empty line", in ); // NOLINT + } + s.stack.clear(); + } + }; + + template<> + struct action< indent > + { + template< typename Input > + static void apply( const Input& 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 ); // NOLINT + } + s.minimum_indent = 0; + } + else if( ( !s.stack.empty() ) && ( s.current_indent != s.stack.back().indent ) ) { + throw pegtl::parse_error( "indentation mismatch", in ); // NOLINT + } + } + }; + + template<> + struct action< grammar > + { + template< typename Input > + static void apply( const Input& in, state& s ) + { + if( s.minimum_indent > 0 ) { + throw pegtl::parse_error( "expected indented block instead of eof", in ); // NOLINT + } + } + }; + +} // namespace example + +int main( int argc, char** argv ) +{ + 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; +} diff --git a/packages/PEGTL/src/example/pegtl/json_build_one.cpp b/packages/PEGTL/src/example/pegtl/json_build_one.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17db35a74891b52760957f344fe226e20e7c90e8 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_build_one.cpp @@ -0,0 +1,192 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <sstream> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/changes.hpp> +#include <tao/pegtl/contrib/json.hpp> + +#include "json_classes.hpp" +#include "json_errors.hpp" +#include "json_unescape.hpp" + +namespace examples +{ + // Basic state class that stores the result of a JSON parsing run -- a single JSON object. + + struct result_state + { + result_state() = default; + result_state( const result_state& ) = delete; + result_state( result_state&& ) = delete; + + ~result_state() = default; + + void operator=( const result_state& ) = delete; + void operator=( result_state&& ) = delete; + + std::shared_ptr< json_base > result; + }; + + // Action class for the simple cases... + + template< typename Rule > + struct value_action + : unescape_action< Rule > + { + }; + + struct string_state + : public unescape_state_base + { + void success( result_state& result ) + { + result.result = std::make_shared< string_json >( std::move( unescaped ) ); + } + }; + + template<> + struct value_action< tao::TAO_PEGTL_NAMESPACE::json::null > + { + static void apply0( result_state& result ) + { + result.result = std::make_shared< null_json >(); + } + }; + + template<> + struct value_action< tao::TAO_PEGTL_NAMESPACE::json::true_ > + { + static void apply0( result_state& result ) + { + result.result = std::make_shared< boolean_json >( true ); + } + }; + + template<> + struct value_action< tao::TAO_PEGTL_NAMESPACE::json::false_ > + { + static void apply0( result_state& result ) + { + result.result = std::make_shared< boolean_json >( false ); + } + }; + + template<> + struct value_action< tao::TAO_PEGTL_NAMESPACE::json::number > + { + template< typename Input > + static void apply( const Input& in, result_state& result ) + { + std::stringstream ss; + ss << in.string(); + long double v; + ss >> v; // NOTE: not quite correct for JSON but we'll use it for this simple example. + result.result = std::make_shared< number_json >( v ); + } + }; + + // State and action classes to accumulate the data for a JSON array. + + struct array_state + : public result_state + { + std::shared_ptr< array_json > array = std::make_shared< array_json >(); + + void push_back() + { + array->data.push_back( std::move( result ) ); + result.reset(); + } + + void success( result_state& in_result ) + { + if( this->result ) { + push_back(); + } + in_result.result = array; + } + }; + + template< typename Rule > + struct array_action + : tao::TAO_PEGTL_NAMESPACE::nothing< Rule > + { + }; + + template<> + struct array_action< tao::TAO_PEGTL_NAMESPACE::json::value_separator > + { + static void apply0( array_state& result ) + { + result.push_back(); + } + }; + + // State and action classes to accumulate the data for a JSON object. + + struct object_state + : public result_state + { + std::string unescaped; + std::shared_ptr< object_json > object = std::make_shared< object_json >(); + + void insert() + { + object->data.insert( std::make_pair( std::move( unescaped ), std::move( result ) ) ); + unescaped.clear(); + result.reset(); + } + + void success( result_state& in_result ) + { + if( this->result ) { + insert(); + } + in_result.result = object; + } + }; + + template< typename Rule > + struct object_action + : unescape_action< Rule > + { + }; + + template<> + struct object_action< tao::TAO_PEGTL_NAMESPACE::json::value_separator > + { + static void apply0( object_state& result ) + { + result.insert(); + } + }; + + // Put together a control class that changes the actions and states as required. + + // clang-format off + template< typename Rule > struct control : errors< Rule > {}; // Inherit from json_errors.hpp. + + template<> struct control< tao::TAO_PEGTL_NAMESPACE::json::value > : tao::TAO_PEGTL_NAMESPACE::change_action< tao::TAO_PEGTL_NAMESPACE::json::value, value_action, errors > {}; + template<> struct control< tao::TAO_PEGTL_NAMESPACE::json::string::content > : tao::TAO_PEGTL_NAMESPACE::change_state< tao::TAO_PEGTL_NAMESPACE::json::string::content, string_state, errors > {}; + template<> struct control< tao::TAO_PEGTL_NAMESPACE::json::array::content > : tao::TAO_PEGTL_NAMESPACE::change_state_and_action< tao::TAO_PEGTL_NAMESPACE::json::array::content, array_state, array_action, errors > {}; + template<> struct control< tao::TAO_PEGTL_NAMESPACE::json::object::content > : tao::TAO_PEGTL_NAMESPACE::change_state_and_action< tao::TAO_PEGTL_NAMESPACE::json::object::content, object_state, object_action, errors > {}; + + struct grammar : tao::TAO_PEGTL_NAMESPACE::must< tao::TAO_PEGTL_NAMESPACE::json::text, tao::TAO_PEGTL_NAMESPACE::eof > {}; + // clang-format on + +} // namespace examples + +int main( int argc, char** argv ) +{ + for( int i = 1; i < argc; ++i ) { + examples::result_state result; + tao::TAO_PEGTL_NAMESPACE::file_input<> in( argv[ i ] ); + tao::TAO_PEGTL_NAMESPACE::parse< examples::grammar, tao::TAO_PEGTL_NAMESPACE::nothing, examples::control >( in, result ); + assert( result.result ); + std::cout << result.result << std::endl; + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/json_build_two.cpp b/packages/PEGTL/src/example/pegtl/json_build_two.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67de229cc605abb8d367122c1fa6ea58180fe6be --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_build_two.cpp @@ -0,0 +1,192 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cassert> +#include <sstream> +#include <vector> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/changes.hpp> +#include <tao/pegtl/contrib/json.hpp> + +#include "json_classes.hpp" +#include "json_errors.hpp" +#include "json_unescape.hpp" + +namespace examples +{ + // 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 and Control classes + + template< typename Rule > + struct action : unescape_action< Rule > // Inherit from json_unescape.hpp. + { + }; + + template< typename Rule > + struct control : errors< Rule > // Inherit from json_errors.hpp. + { + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::null > + { + static void apply0( json_state& state ) + { + state.result = std::make_shared< null_json >(); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::true_ > + { + static void apply0( json_state& state ) + { + state.result = std::make_shared< boolean_json >( true ); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::false_ > + { + static void apply0( json_state& state ) + { + state.result = std::make_shared< boolean_json >( false ); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::number > + { + template< typename Input > + static void apply( const Input& in, json_state& state ) + { + std::stringstream ss; + 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 ); + } + }; + + // To parse a string, we change the state to decouple string parsing/unescaping + + struct string_state + : public unescape_state_base + { + void success( json_state& state ) + { + state.result = std::make_shared< string_json >( unescaped ); + } + }; + + template<> + struct control< tao::TAO_PEGTL_NAMESPACE::json::string::content > + : tao::TAO_PEGTL_NAMESPACE::change_state< tao::TAO_PEGTL_NAMESPACE::json::string::content, string_state, errors > + { + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::array::begin > + { + static void apply0( json_state& state ) + { + state.arrays.push_back( std::make_shared< array_json >() ); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::array::element > + { + static void apply0( json_state& state ) + { + state.arrays.back()->data.push_back( std::move( state.result ) ); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::json::array::end > + { + static void apply0( json_state& state ) + { + state.result = std::move( state.arrays.back() ); + state.arrays.pop_back(); + } + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::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 + + struct key_state : unescape_state_base + { + void success( json_state& state ) + { + state.keys.push_back( std::move( unescaped ) ); + } + }; + + template<> + struct control< tao::TAO_PEGTL_NAMESPACE::json::key::content > + : tao::TAO_PEGTL_NAMESPACE::change_state< tao::TAO_PEGTL_NAMESPACE::json::key::content, key_state, errors > + { + }; + + template<> + struct action< tao::TAO_PEGTL_NAMESPACE::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< tao::TAO_PEGTL_NAMESPACE::json::object::end > + { + static void apply0( json_state& state ) + { + state.result = std::move( state.objects.back() ); + state.objects.pop_back(); + } + }; + + using grammar = tao::TAO_PEGTL_NAMESPACE::must< tao::TAO_PEGTL_NAMESPACE::json::text, tao::TAO_PEGTL_NAMESPACE::eof >; + +} // namespace examples + +int main( int argc, char** argv ) +{ + if( argc != 2 ) { + std::cerr << "usage: " << argv[ 0 ] << " <json>"; + } + else { + examples::json_state state; + tao::TAO_PEGTL_NAMESPACE::file_input<> in( argv[ 1 ] ); + tao::TAO_PEGTL_NAMESPACE::parse< examples::grammar, examples::action, examples::control >( in, state ); + assert( state.keys.empty() ); + assert( state.arrays.empty() ); + assert( state.objects.empty() ); + std::cout << state.result << std::endl; + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/json_classes.hpp b/packages/PEGTL/src/example/pegtl/json_classes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1d09e1fb760ce3a44f8081eac85d2ae6d0497e3f --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_classes.hpp @@ -0,0 +1,221 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_CLASSES_HPP + +#include <iostream> +#include <map> +#include <memory> +#include <string> +#include <vector> + +namespace examples +{ + 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; + + void operator=( const json_base& ) = delete; + void 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 = static_cast< const unsigned char* >( static_cast< const void* >( 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 ) // NOLINT + : 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 examples + +#endif diff --git a/packages/PEGTL/src/example/pegtl/json_count.cpp b/packages/PEGTL/src/example/pegtl/json_count.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce8f26a6c27e03700a3d2b95eb7d8a4f56489931 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_count.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iomanip> +#include <iostream> + +#define TAO_PEGTL_PRETTY_DEMANGLE + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/counter.hpp> +#include <tao/pegtl/contrib/json.hpp> +#include <tao/pegtl/file_input.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT +using grammar = must< json::text, eof >; + +int main( int argc, char** argv ) +{ + 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; +} diff --git a/packages/PEGTL/src/example/pegtl/json_errors.hpp b/packages/PEGTL/src/example/pegtl/json_errors.hpp new file mode 100644 index 0000000000000000000000000000000000000000..77668ea0a4131c97c528cb219d5cecd8af5e2892 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_errors.hpp @@ -0,0 +1,62 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_ERRORS_HPP + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/json.hpp> + +namespace examples +{ + // This file shows how to throw exceptions with + // custom error messages for parse errors. A custom + // control class is created that delegates everything + // to the PEGTL default control class tao::TAO_PEGTL_NAMESPACE::normal<> + // except for the throwing of exceptions: + + template< typename Rule > + struct errors + : public tao::TAO_PEGTL_NAMESPACE::normal< Rule > + { + static const std::string error_message; + + template< typename Input, typename... States > + static void raise( const Input& in, States&&... /*unused*/ ) + { + throw tao::TAO_PEGTL_NAMESPACE::parse_error( error_message, in ); + } + }; + + // The following specialisations of the static string + // member are then used in the exception messages: + + // clang-format off + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::text >::error_message = "no valid JSON"; // NOLINT + + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::end_array >::error_message = "incomplete array, expected ']'"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::end_object >::error_message = "incomplete object, expected '}'"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::member >::error_message = "expected member"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::name_separator >::error_message = "expected ':'"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::array_element >::error_message = "expected value"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::value >::error_message = "expected value"; // NOLINT + + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::digits >::error_message = "expected at least one digit"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::xdigit >::error_message = "incomplete universal character name"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::escaped >::error_message = "unknown escape sequence"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::char_ >::error_message = "invalid character in string"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::string::content >::error_message = "unterminated string"; // NOLINT + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::json::key::content >::error_message = "unterminated key"; // NOLINT + + template<> const std::string errors< tao::TAO_PEGTL_NAMESPACE::eof >::error_message = "unexpected character after JSON value"; // NOLINT + // clang-format on + + // The raise()-function-template is instantiated exactly + // for the specialisations of errors< Rule > for which a + // parse error can be generated, therefore the string + // error_message needs to be supplied only for these rules + // (and the compiler will complain if one is missing). + +} // namespace examples + +#endif diff --git a/packages/PEGTL/src/example/pegtl/json_parse.cpp b/packages/PEGTL/src/example/pegtl/json_parse.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b41924d7cb3695000d810ee3ab5f6725b40d329 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_parse.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl.hpp> + +#include "json_errors.hpp" + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT +using grammar = must< json::text, eof >; + +int main( int argc, char** argv ) +{ + for( int i = 1; i < argc; ++i ) { + argv_input<> in( argv, i ); + parse< grammar, nothing, examples::errors >( in ); + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/json_unescape.hpp b/packages/PEGTL/src/example/pegtl/json_unescape.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2f067b6cd1e581334c85c59f4eae95f80a78cd69 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/json_unescape.hpp @@ -0,0 +1,47 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_EXAMPLES_PEGTL_JSON_UNESCAPE_HPP + +#include <string> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/json.hpp> +#include <tao/pegtl/contrib/unescape.hpp> + +namespace examples +{ + // State base class to store an unescaped string + + struct unescape_state_base + { + unescape_state_base() = default; + + unescape_state_base( const unescape_state_base& ) = delete; + unescape_state_base( unescape_state_base&& ) = delete; + + ~unescape_state_base() = default; + + void operator=( const unescape_state_base& ) = delete; + void operator=( unescape_state_base&& ) = delete; + + std::string unescaped; + }; + + // Action class for parsing literal strings, uses the PEGTL unescape utilities, cf. unescape.cpp. + + template< typename Rule, template< typename... > class Base = tao::TAO_PEGTL_NAMESPACE::nothing > + struct unescape_action : Base< Rule > + { + }; + + // clang-format off + template<> struct unescape_action< tao::TAO_PEGTL_NAMESPACE::json::unicode > : tao::TAO_PEGTL_NAMESPACE::unescape::unescape_j {}; + template<> struct unescape_action< tao::TAO_PEGTL_NAMESPACE::json::escaped_char > : tao::TAO_PEGTL_NAMESPACE::unescape::unescape_c< tao::TAO_PEGTL_NAMESPACE::json::escaped_char, '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' > {}; + template<> struct unescape_action< tao::TAO_PEGTL_NAMESPACE::json::unescaped > : tao::TAO_PEGTL_NAMESPACE::unescape::append_all {}; + // clang-format on + +} // namespace examples + +#endif diff --git a/packages/PEGTL/src/example/pegtl/lua53_parse.cpp b/packages/PEGTL/src/example/pegtl/lua53_parse.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcb48f37833d148480bf42ae07b8036102573a16 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/lua53_parse.cpp @@ -0,0 +1,347 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl.hpp> +#include <tao/pegtl/analyze.hpp> +#include <tao/pegtl/contrib/raw_string.hpp> + +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. + + namespace pegtl = tao::TAO_PEGTL_NAMESPACE; + + // clang-format off + struct short_comment : pegtl::until< pegtl::eolf > {}; + struct long_string : pegtl::raw_string< '[', '=', ']' > {}; + struct comment : pegtl::disable< pegtl::two< '-' >, pegtl::sor< long_string, short_comment > > {}; + + struct sep : pegtl::sor< pegtl::ascii::space, comment > {}; + struct seps : 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. + + struct str_keyword : 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 > {}; + + template< typename Key > + struct key : pegtl::seq< Key, pegtl::not_at< pegtl::identifier_other > > {}; + + 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< str_keyword > {}; + + template< typename R > + struct pad : pegtl::pad< R, sep > {}; + + struct three_dots : pegtl::three< '.' > {}; + + struct name : pegtl::seq< pegtl::not_at< keyword >, pegtl::identifier > {}; + + struct single : pegtl::one< 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"', '\'', '0', '\n' > {}; + struct spaces : pegtl::seq< pegtl::one< 'z' >, pegtl::star< pegtl::space > > {}; + struct hexbyte : pegtl::if_must< pegtl::one< 'x' >, pegtl::xdigit, pegtl::xdigit > {}; + struct decbyte : pegtl::if_must< pegtl::digit, pegtl::rep_opt< 2, pegtl::digit > > {}; + struct unichar : pegtl::if_must< pegtl::one< 'u' >, pegtl::one< '{' >, pegtl::plus< pegtl::xdigit >, pegtl::one< '}' > > {}; + struct escaped : pegtl::if_must< pegtl::one< '\\' >, pegtl::sor< hexbyte, decbyte, unichar, single, spaces > > {}; + struct regular : pegtl::not_one< '\r', '\n' > {}; + struct character : pegtl::sor< escaped, regular > {}; + + template< char Q > + struct short_string : pegtl::if_must< pegtl::one< Q >, pegtl::until< pegtl::one< Q >, character > > {}; + struct literal_string : pegtl::sor< short_string< '"' >, short_string< '\'' >, long_string > {}; + + template< typename E > + struct exponent : pegtl::opt_must< E, pegtl::opt< pegtl::one< '+', '-' > >, pegtl::plus< pegtl::digit > > {}; + + template< typename D, typename E > + struct numeral_three : pegtl::seq< pegtl::if_must< pegtl::one< '.' >, pegtl::plus< D > >, exponent< E > > {}; + template< typename D, typename E > + struct numeral_two : pegtl::seq< pegtl::plus< D >, pegtl::opt< pegtl::one< '.' >, pegtl::star< D > >, exponent< E > > {}; + template< typename D, typename E > + struct numeral_one : pegtl::sor< numeral_two< D, E >, numeral_three< D, E > > {}; + + struct decimal : numeral_one< pegtl::digit, pegtl::one< 'e', 'E' > > {}; + struct hexadecimal : pegtl::if_must< pegtl::istring< '0', 'x' >, numeral_one< pegtl::xdigit, pegtl::one< 'p', 'P' > > > {}; + struct numeral : pegtl::sor< hexadecimal, decimal > {}; + + struct label_statement : pegtl::if_must< pegtl::two< ':' >, seps, name, seps, pegtl::two< ':' > > {}; + struct goto_statement : pegtl::if_must< key_goto, seps, name > {}; + + struct statement; + struct expression; + + struct name_list : pegtl::list< name, pegtl::one< ',' >, sep > {}; + struct name_list_must : pegtl::list_must< name, pegtl::one< ',' >, sep > {}; + struct expr_list_must : pegtl::list_must< expression, pegtl::one< ',' >, sep > {}; + + struct statement_return : pegtl::seq< pegtl::pad_opt< expr_list_must, sep >, pegtl::opt< pegtl::one< ';' >, seps > > {}; + + template< typename E > + struct statement_list : pegtl::seq< seps, pegtl::until< pegtl::sor< E, pegtl::if_must< key_return, statement_return, E > >, statement, seps > > {}; + + template< char O, char... N > + struct op_one : pegtl::seq< pegtl::one< O >, pegtl::at< pegtl::not_one< N... > > > {}; + template< char O, char P, char... N > + struct op_two : pegtl::seq< pegtl::string< O, P >, pegtl::at< pegtl::not_one< N... > > > {}; + + struct table_field_one : pegtl::if_must< pegtl::one< '[' >, seps, expression, seps, pegtl::one< ']' >, seps, pegtl::one< '=' >, seps, expression > {}; + struct table_field_two : pegtl::if_must< pegtl::seq< name, seps, op_one< '=', '=' > >, seps, expression > {}; + struct table_field : pegtl::sor< table_field_one, table_field_two, expression > {}; + struct table_field_list : pegtl::list_tail< table_field, pegtl::one< ',', ';' >, sep > {}; + struct table_constructor : pegtl::if_must< pegtl::one< '{' >, pegtl::pad_opt< table_field_list, sep >, pegtl::one< '}' > > {}; + + struct parameter_list_one : pegtl::seq< name_list, pegtl::opt_must< pad< pegtl::one< ',' > >, three_dots > > {}; + struct parameter_list : pegtl::sor< three_dots, parameter_list_one > {}; + + struct function_body : pegtl::seq< pegtl::one< '(' >, pegtl::pad_opt< parameter_list, sep >, pegtl::one< ')' >, seps, statement_list< key_end > > {}; + struct function_literal : pegtl::if_must< key_function, seps, function_body > {}; + + struct bracket_expr : pegtl::if_must< pegtl::one< '(' >, seps, expression, seps, pegtl::one< ')' > > {}; + + struct function_args_one : pegtl::if_must< pegtl::one< '(' >, pegtl::pad_opt< expr_list_must, sep >, pegtl::one< ')' > > {}; + struct function_args : pegtl::sor< function_args_one, table_constructor, literal_string > {}; + + struct variable_tail_one : pegtl::if_must< pegtl::one< '[' >, seps, expression, seps, pegtl::one< ']' > > {}; + struct variable_tail_two : pegtl::if_must< pegtl::seq< pegtl::not_at< pegtl::two< '.' > >, pegtl::one< '.' > >, seps, name > {}; + struct variable_tail : pegtl::sor< variable_tail_one, variable_tail_two > {}; + + struct function_call_tail_one : pegtl::if_must< pegtl::seq< pegtl::not_at< pegtl::two< ':' > >, pegtl::one< ':' > >, seps, name, seps, function_args > {}; + struct function_call_tail : pegtl::sor< function_args, function_call_tail_one > {}; + + struct variable_head_one : pegtl::seq< bracket_expr, seps, variable_tail > {}; + struct variable_head : pegtl::sor< name, variable_head_one > {}; + + struct function_call_head : pegtl::sor< name, bracket_expr > {}; + + struct variable : pegtl::seq< variable_head, pegtl::star< pegtl::star< seps, function_call_tail >, seps, variable_tail > > {}; + struct function_call : pegtl::seq< function_call_head, pegtl::plus< pegtl::until< pegtl::seq< seps, function_call_tail >, seps, variable_tail > > > {}; + + template< typename S, typename O > + struct left_assoc : pegtl::seq< S, seps, pegtl::star_must< O, seps, S, seps > > {}; + template< typename S, typename O > + struct right_assoc : pegtl::seq< S, seps, pegtl::opt_must< O, seps, right_assoc< S, O > > > {}; + + struct unary_operators : pegtl::sor< pegtl::one< '-' >, + pegtl::one< '#' >, + op_one< '~', '=' >, + key_not > {}; + + struct expr_ten; + struct expr_thirteen : pegtl::seq< pegtl::sor< bracket_expr, name >, pegtl::star< seps, pegtl::sor< function_call_tail, variable_tail > > > {}; + struct expr_twelve : pegtl::sor< key_nil, + key_true, + key_false, + three_dots, + numeral, + literal_string, + function_literal, + expr_thirteen, + table_constructor > {}; + struct expr_eleven : pegtl::seq< expr_twelve, seps, pegtl::opt< pegtl::one< '^' >, seps, expr_ten, seps > > {}; + struct unary_apply : pegtl::if_must< unary_operators, seps, expr_ten, seps > {}; + struct expr_ten : pegtl::sor< unary_apply, expr_eleven > {}; + struct operators_nine : pegtl::sor< pegtl::two< '/' >, + pegtl::one< '/' >, + pegtl::one< '*' >, + pegtl::one< '%' > > {}; + struct expr_nine : left_assoc< expr_ten, operators_nine > {}; + struct operators_eight : pegtl::sor< pegtl::one< '+' >, + pegtl::one< '-' > > {}; + struct expr_eight : left_assoc< expr_nine, operators_eight > {}; + struct expr_seven : right_assoc< expr_eight, op_two< '.', '.', '.' > > {}; + struct operators_six : pegtl::sor< pegtl::two< '<' >, + pegtl::two< '>' > > {}; + struct expr_six : left_assoc< expr_seven, operators_six > {}; + struct expr_five : left_assoc< expr_six, pegtl::one< '&' > > {}; + struct expr_four : left_assoc< expr_five, op_one< '~', '=' > > {}; + struct expr_three : left_assoc< expr_four, pegtl::one< '|' > > {}; + struct operators_two : pegtl::sor< pegtl::two< '=' >, + pegtl::string< '<', '=' >, + pegtl::string< '>', '=' >, + op_one< '<', '<' >, + op_one< '>', '>' >, + 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 : pegtl::if_must< key_do, statement_list< key_end > > {}; + struct while_statement : pegtl::if_must< key_while, seps, expression, seps, key_do, statement_list< key_end > > {}; + struct repeat_statement : pegtl::if_must< key_repeat, statement_list< key_until >, seps, expression > {}; + + struct at_elseif_else_end : pegtl::sor< pegtl::at< key_elseif >, pegtl::at< key_else >, pegtl::at< key_end > > {}; + struct elseif_statement : pegtl::if_must< key_elseif, seps, expression, seps, key_then, statement_list< at_elseif_else_end > > {}; + struct else_statement : pegtl::if_must< key_else, statement_list< key_end > > {}; + struct if_statement : pegtl::if_must< key_if, seps, expression, seps, key_then, statement_list< at_elseif_else_end >, seps, pegtl::until< pegtl::sor< else_statement, key_end >, elseif_statement, seps > > {}; + + struct for_statement_one : pegtl::seq< pegtl::one< '=' >, seps, expression, seps, pegtl::one< ',' >, seps, expression, pegtl::pad_opt< pegtl::if_must< pegtl::one< ',' >, seps, expression >, sep > > {}; + struct for_statement_two : pegtl::seq< pegtl::opt_must< pegtl::one< ',' >, seps, name_list_must, seps >, key_in, seps, expr_list_must, seps > {}; + struct for_statement : pegtl::if_must< key_for, seps, name, seps, pegtl::sor< for_statement_one, for_statement_two >, key_do, statement_list< key_end > > {}; + + struct assignment_variable_list : pegtl::list_must< variable, pegtl::one< ',' >, sep > {}; + struct assignments_one : pegtl::if_must< pegtl::one< '=' >, seps, expr_list_must > {}; + struct assignments : pegtl::seq< assignment_variable_list, seps, assignments_one > {}; + struct function_name : pegtl::seq< pegtl::list< name, pegtl::one< '.' >, sep >, seps, pegtl::opt_must< pegtl::one< ':' >, seps, name, seps > > {}; + struct function_definition : pegtl::if_must< key_function, seps, function_name, function_body > {}; + + struct local_function : pegtl::if_must< key_function, seps, name, seps, function_body > {}; + struct local_variables : pegtl::if_must< name_list_must, seps, pegtl::opt< assignments_one > > {}; + struct local_statement : pegtl::if_must< key_local, seps, pegtl::sor< local_function, local_variables > > {}; + + struct semicolon : pegtl::one< ';' > {}; + struct statement : 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 interpreter : pegtl::seq< pegtl::one< '#' >, pegtl::until< pegtl::eolf > > {}; + struct grammar : pegtl::must< pegtl::opt< interpreter >, statement_list< pegtl::eof > > {}; + // clang-format on + +} // namespace lua53 + +int main( int argc, char** argv ) +{ + tao::TAO_PEGTL_NAMESPACE::analyze< lua53::grammar >(); + + for( int i = 1; i < argc; ++i ) { + tao::TAO_PEGTL_NAMESPACE::file_input<> in( argv[ i ] ); + tao::TAO_PEGTL_NAMESPACE::parse< lua53::grammar >( in ); + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/modulus_match.cpp b/packages/PEGTL/src/example/pegtl/modulus_match.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d7e4e9721a7f36e17169236027e5a19014a30d2 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/modulus_match.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +namespace modulus +{ + template< unsigned M, unsigned R = 0 > + struct my_rule + { + using analyze_t = analysis::generic< analysis::rule_type::ANY >; + + static_assert( M > 1, "Modulus must be greater than 1" ); + static_assert( R < M, "Remainder must be less than modulus" ); + + template< typename Input > + static bool match( Input& 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; +} diff --git a/packages/PEGTL/src/example/pegtl/parse_tree.cpp b/packages/PEGTL/src/example/pegtl/parse_tree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..424a3b40e860077ac0ffd81842800b290be8191d --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/parse_tree.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> +#include <string> +#include <type_traits> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/parse_tree.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +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 : if_must< open_bracket, expression, close_bracket > {}; + struct value : sor< integer, variable, bracketed >{}; + struct product : list_must< value, sor< multiply, divide > > {}; + struct expression : list_must< product, sor< plus, minus > > {}; + + struct grammar : seq< expression, eof > {}; + + // after a node is stored successfully, you can add an optional transformer like this: + struct rearrange : std::true_type + { + // 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. + static void transform( std::unique_ptr< parse_tree::node >& n ) + { + 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() ); + } + } + }; + + // select which rules in the grammar will produce parse tree nodes: + + template< typename Rule > + using selector = parse_tree::selector< + Rule, + parse_tree::apply_store_content::to< + integer, + variable >, + parse_tree::apply_remove_content::to< + plus, + minus, + multiply, + divide >, + parse_tree::apply< rearrange >::to< + product, + expression > >; + + // debugging/show result: + + void print_node( const parse_tree::node& n, const std::string& s = "" ) + { + // detect the root node: + if( n.is_root() ) { + std::cout << "ROOT" << std::endl; + } + else { + if( n.has_content() ) { + std::cout << s << n.name() << " \"" << n.content() << "\" at " << n.begin() << " to " << n.end() << std::endl; + } + else { + std::cout << s << n.name() << " at " << n.begin() << std::endl; + } + } + // print all child nodes + if( !n.children.empty() ) { + const auto s2 = s + " "; + for( auto& up : n.children ) { + print_node( *up, s2 ); + } + } + } + +} // namespace example + +int main( int argc, char** argv ) +{ + for( int i = 1; i < argc; ++i ) { + try { + argv_input<> in( argv, i ); + if( const auto root = parse_tree::parse< example::grammar, example::selector >( in ) ) { + example::print_node( *root ); + } + else { + std::cout << "PARSE FAILED" << std::endl; + } + } + catch( const std::exception& e ) { + std::cout << "PARSE FAILED WITH EXCEPTION: " << e.what() << std::endl; + } + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/proto3.cpp b/packages/PEGTL/src/example/pegtl/proto3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b871ef4800b73e137286f24bca1beea2133b0e14 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/proto3.cpp @@ -0,0 +1,146 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#define TAO_PEGTL_PRETTY_DEMANGLE 1 + +#include <tao/pegtl.hpp> +#include <tao/pegtl/analyze.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace proto3 + { + // clang-format off + + struct comment : seq< two< '/' >, until< eolf > > {}; + struct sp : sor< space, comment > {}; + struct sps : star< sp > {}; + + struct comma : one< ',' > {}; + struct dot : one< '.' > {}; + struct equ : one< '=' > {}; + struct semi : one< ';' > {}; + + struct option; + struct message; + + struct odigit : range< '0', '7' > {}; + + 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 oct_lit : seq< one< '0' >, star< odigit > > {}; + struct hex_lit : seq< one< '0' >, one< 'x', 'X' >, plus< xdigit > > {}; + struct dec_lit : seq< range< '1', '9' >, star< digit > > {}; + struct int_lit : sor< dec_lit, hex_lit, oct_lit > {}; + + 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 bool_lit : seq< sor< string< 't', 'r', 'u', 'e' >, string< 'f', 'a', 'l', 's', 'e' > >, not_at< ident_other > > {}; + + struct sign : one< '+', '-' > {}; + struct constant : sor< bool_lit, full_ident, seq< opt< sign >, int_lit >, str_lit > {}; // TODO: Needs sps after sign? + + struct option_name : seq< sor< ident, if_must< one< '(' >, full_ident, one< ')' > > >, star_must< dot, ident > > {}; + struct option : if_must< string< 'o', 'p', 't', 'i', 'o', 'n' >, sps, option_name, sps, equ, sps, constant, sps, semi, sps > {}; + + struct bool_type : string< 'b', 'o', 'o', 'l' > {}; + struct bytes_type : string< 'b', 'y', 't', 'e', 's' > {}; + struct double_type : string< 'd', 'o', 'u', 'b', 'l', 'e' > {}; + struct float_type : string< 'f', 'l', 'o', 'a', 't' > {}; + struct string_type : string< 's', 't', 'r', 'i', 'n', 'g' > {}; + + struct int32_type : string< 'i', 'n', 't', '3', '2' > {}; + struct int64_type : string< 'i', 'n', 't', '6', '4' > {}; + struct sint32_type : string< 's', 'i', 'n', 't', '3', '2' > {}; + struct sint64_type : string< 's', 'i', 'n', 't', '6', '4' > {}; + struct uint32_type : string< 'u', 'i', 'n', 't', '3', '2' > {}; + struct uint64_type : string< 'u', 'i', 'n', 't', '6', '4' > {}; + struct fixed32_type : string< 'f', 'i', 'x', 'e', 'd', '3', '2' > {}; + struct fixed64_type : string< 'f', 'i', 'x', 'e', 'd', '6', '4' > {}; + struct sfixed32_type : string< 's', 'f', 'i', 'x', 'e', 'd', '3', '2' > {}; + struct sfixed64_type : string< 's', 'f', 'i', 'x', 'e', 'd', '6', '4' > {}; + + struct builtin_type : seq< 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 >, not_at< ident_other > > {}; + + 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< string< '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< string< '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< string< '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, string< 't', 'o' >, sps, sor< int_lit, string< 'm', 'a', 'x' > > > {}; + struct ranges : list_must< range, comma, sp > {}; + struct field_names : list_must< field_name, comma, sp > {}; + struct reserved : if_must< string< '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_ : if_must< string< 'e', 'n', 'u', 'm' >, sps, enum_name, sps, enum_body > {}; + + struct message_thing : sor< field, enum_, message, option, oneof, map_field, reserved, semi > {}; + struct message : if_must< string< 'm', 'e', 's', 's', 'a', 'g', 'e' >, sps, ident, sps, one< '{' >, sps, star< message_thing, sps >, one< '}' >, sps > {}; + + struct package : if_must< string< 'p', 'a', 'c', 'k', 'a', 'g', 'e' >, sps, full_ident, sps, semi, sps > {}; + + struct import_option : opt< sor< string< 'w', 'e', 'a', 'k' >, string< 'p', 'u', 'b', 'l', 'i', 'c' > > > {}; + struct import : if_must< string< 'i', 'm', 'p', 'o', 'r', 't' >, sps, import_option, sps, str_lit, sps, semi, sps > {}; + + struct rpc_name : ident {}; + struct rpc_type : if_must< one< '(' >, sps, opt< string< '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< string< 'r', 'p', 'c' >, sps, rpc_name, sps, rpc_type, sps, string< 'r', 'e', 't', 'u', 'r', 'n', 's' >, sps, rpc_type, sor< semi, rpc_options > > {}; + struct service_name : ident {}; + struct service : if_must< string< 's', 'e', 'r', 'v', 'i', 'c', 'e' >, sps, service_name, sps, one< '{' >, sps, list_must< sor< option, rpc, semi >, comma, sp >, sps, one< '}' > > {}; + + struct body : sor< import, package, option, message, enum_, service, semi > {}; + + struct head : if_must< string< 's', 'y', 'n', 't', 'a', 'x' >, sps, equ, sps, string< '"', 'p', 'r', 'o', 't', 'o', '3', '"' >, sps, semi > {}; + struct proto : must< sps, head, sps, star< body, sps >, eof > {}; + + // clang-format on + + } // namespace proto3 + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +int main( int argc, char** argv ) +{ + using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + + analyze< proto3::proto >(); + + for( int i = 1; i < argc; ++i ) { + file_input<> in( argv[ i ] ); + parse< proto3::proto >( in ); + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/recover.cpp b/packages/PEGTL/src/example/pegtl/recover.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb1a56cf526a52629b938ad840f7ca7a30307479 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/recover.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2017-2018 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)' + +#include <iostream> +#include <string> + +#include <tao/pegtl.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +// 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 + : nothing< Rule > +{ +}; + +template< typename T > +struct my_action< skipping< T > > +{ + template< typename Input > + static void apply( const Input& in, bool& error ) + { + if( !error ) { + std::cout << in.position() << ": Invalid expression \"" << in.string() << "\"" << std::endl; + } + error = true; + } +}; + +template< typename R > +struct found +{ + template< typename Input > + static void apply( const Input& in, bool& error ) + { + if( !error ) { + std::cout << in.position() << ": Found " << internal::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 Input > + static void apply( const Input& /*unused*/, bool& error ) + { + error = false; + std::cout << std::string( 79, '-' ) << std::endl; + } +}; + +template< typename Rule > +struct my_control + : normal< Rule > +{ + template< typename Input, typename... States > + static void raise( const Input& in, States&&... /*unused*/ ) + { + std::cout << in.position() << ": Parse error matching " << internal::demangle< Rule >() << std::endl; + throw parse_error( "parse error matching " + internal::demangle< Rule >(), in ); + } +}; + +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; +} diff --git a/packages/PEGTL/src/example/pegtl/s_expression.cpp b/packages/PEGTL/src/example/pegtl/s_expression.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e47b76528e95a632c3dfb468148663b1e7094efb --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/s_expression.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/analyze.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +namespace sexpr +{ + struct hash_comment + : until< eolf > + { + }; + + struct list; + + struct list_comment + : if_must< at< one< '(' > >, disable< list > > + { + }; + + struct read_include + : seq< one< ' ' >, one< '"' >, plus< not_one< '"' > >, one< '"' > > + { + }; + + struct hash_include + : if_must< string< 'i', 'n', 'c', 'l', 'u', 'd', 'e' >, read_include > + { + }; + + struct hashed + : if_must< one< '#' >, sor< hash_include, list_comment, hash_comment > > + { + }; + + struct number + : plus< digit > + { + }; + + struct symbol + : identifier + { + }; + + struct atom + : sor< number, symbol > + { + }; + + struct anything; + + struct list + : if_must< one< '(' >, until< one< ')' >, anything > > + { + }; + + struct normal + : sor< atom, list > + { + }; + + struct anything + : sor< space, hashed, normal > + { + }; + + struct main + : until< eof, must< anything > > + { + }; + + template< typename Rule > + struct action + : nothing< Rule > + { + }; + + template<> + struct action< plus< not_one< '"' > > > + { + template< typename Input > + static void apply( const Input& in, std::string& fn ) + { + fn = in.string(); + } + }; + + template<> + struct action< hash_include > + { + template< typename Input > + static void apply( const Input& 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...) + file_input<> i2( fn ); + parse_nested< main, sexpr::action >( in, i2, f2 ); + } + }; + +} // namespace sexpr + +int main( int argc, char** argv ) +{ + analyze< sexpr::main >(); + + for( int i = 1; i < argc; ++i ) { + std::string fn; + argv_input<> in( argv, i ); + parse< sexpr::main, sexpr::action >( in, fn ); + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/sum.cpp b/packages/PEGTL/src/example/pegtl/sum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef3440db4b4adb4cecc49b4ccfc347ba9cccca4a --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/sum.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cstdlib> +#include <iostream> +#include <sstream> +#include <string> + +#include <tao/pegtl.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +#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 + : nothing< Rule > + { + }; + + template<> + struct action< double_::grammar > + { + template< typename Input > + static void apply( const Input& in, double& sum ) + { + // assume all values will fit into a C++ double + std::stringstream ss; + 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; + } + } +} diff --git a/packages/PEGTL/src/example/pegtl/symbol_table.cpp b/packages/PEGTL/src/example/pegtl/symbol_table.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f51b16889106d34f1e88d317cb4a08106576cc2 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/symbol_table.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cstring> +#include <iostream> +#include <map> +#include <string> + +#include <tao/pegtl.hpp> + +#include <tao/pegtl/contrib/integer.hpp> + +namespace pegtl = tao::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 + : pegtl::nothing< Rule > + { + }; + + template<> + struct action< value > + : public pegtl::integer::unsigned_action + { + // Sets st.converted to the integer value of the matched string. + }; + + template<> + struct action< name > + { + template< typename Input > + static void apply( const Input& in, state& st ) + { + st.temporary = in.string(); + } + }; + + template<> + struct action< definition > + { + template< typename Input > + static void apply( const Input& in, state& st ) + { + if( !st.symbol_table.insert( { st.temporary, 0 } ).second ) { + throw pegtl::parse_error( "duplicate symbol " + st.temporary, in ); // NOLINT + } + } + }; + + template<> + struct action< assignment > + { + template< typename Input > + static void apply( const Input& 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 ); // NOLINT + } + i->second = st.converted; + } + }; + +} // namespace example + +int main( int argc, char** argv ) +{ + 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; +} diff --git a/packages/PEGTL/src/example/pegtl/unescape.cpp b/packages/PEGTL/src/example/pegtl/unescape.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fca7a66c2d690d71f37f3cba9c37fc25fadf161f --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/unescape.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> + +#include <tao/pegtl.hpp> + +#include <tao/pegtl/contrib/unescape.hpp> + +using namespace tao::TAO_PEGTL_NAMESPACE; // NOLINT + +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 Unicdoe 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, must< xdigit > > > {}; + struct escaped_u : seq< one< 'u' >, rep< 4, must< xdigit > > > {}; + struct escaped_U : seq< one< 'U' >, rep< 8, must< 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_must_else< one< '\\' >, escaped, utf8::range< 0x20, 0x10FFFF > > {}; + struct literal : if_must< one< '"' >, until< one< '"' >, character > > {}; + + struct padded : must< 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 : nothing< Rule > {}; + + 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 ) +{ + for( int i = 1; i < argc; ++i ) { + unescape::state s; + argv_input<> in( argv, i ); + parse< example::padded, example::action >( in, s ); + std::cout << "argv[ " << i << " ] = " << s.unescaped << std::endl; + } + return 0; +} diff --git a/packages/PEGTL/src/example/pegtl/uri.cpp b/packages/PEGTL/src/example/pegtl/uri.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21f51b78b0721083bb719b20644e92509e8e05b3 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/uri.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/uri.hpp> + +#include <iostream> + +namespace pegtl = tao::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 Input > + static void apply( const Input& in, URI& uri ) + { + uri.*Field = in.string(); + } + }; + + // clang-format off + template< typename Rule > struct action : tao::pegtl::nothing< Rule > {}; + + 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 Input > + static void apply( const Input& 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; +} diff --git a/packages/PEGTL/src/example/pegtl/uri_trace.cpp b/packages/PEGTL/src/example/pegtl/uri_trace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b1c43e3d9883d100c2ce5be5caa5b332e682ba74 --- /dev/null +++ b/packages/PEGTL/src/example/pegtl/uri_trace.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <iostream> + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/tracer.hpp> +#include <tao/pegtl/contrib/uri.hpp> + +namespace pegtl = tao::TAO_PEGTL_NAMESPACE; + +using grammar = pegtl::must< pegtl::uri::URI >; + +int main( int argc, char** argv ) +{ + for( int i = 1; i < argc; ++i ) { + std::cout << "Parsing " << argv[ i ] << std::endl; + pegtl::argv_input<> in( argv, i ); + pegtl::parse< grammar, pegtl::nothing, pegtl::tracer >( in ); + } + return 0; +} diff --git a/packages/PEGTL/src/test/pegtl/CMakeLists.txt b/packages/PEGTL/src/test/pegtl/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f2c45acd050c4ba8f04b0a232d18e14a86a38cbf --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/CMakeLists.txt @@ -0,0 +1,129 @@ +cmake_minimum_required (VERSION 3.3.0 FATAL_ERROR) + +set (test_sources + actions_one.cpp + actions_three.cpp + actions_two.cpp + analyze_cycles.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 + contrib_alphabet.cpp + contrib_integer.cpp + contrib_if_then.cpp + contrib_json.cpp + contrib_parse_tree.cpp + contrib_raw_string.cpp + contrib_rep_one_min_max.cpp + contrib_to_string.cpp + contrib_tracer.cpp + contrib_unescape.cpp + contrib_uri.cpp + data_cstring.cpp + demangle.cpp + file_cstream.cpp + file_file.cpp + file_istream.cpp + file_mmap.cpp + file_read.cpp + internal_endian.cpp + internal_file_mapper.cpp + internal_file_opener.cpp + pegtl_string_t.cpp + position.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_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_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 + tester.cpp + uint16_general.cpp + uint32_general.cpp + uint64_general.cpp + uint8_general.cpp + utf16_general.cpp + utf32_general.cpp + utf8_general.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 ${testsourcefile} NAME_WE) + set (exename "pegtl-test-${exename}") + add_executable (${exename} ${testsourcefile}) + target_link_libraries (${exename} PRIVATE taocpp::pegtl) + set_target_properties (${exename} PROPERTIES + CXX_STANDARD 11 + 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_SOURCE_DIR}/../../.. COMMAND ${CMAKE_COMMAND} -DANDROID_NDK=${ANDROID_NDK} "-DTEST_RESOURCES=src/test/pegtl/data;src/test/pegtl/file_data.txt;Makefile" -DTEST_RESOURCES_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../../.. -DUNITTEST=${CMAKE_CURRENT_BINARY_DIR}/${exename} -DTEST_PARAMETER=-all -P ${CMAKE_CURRENT_SOURCE_DIR}/ExecuteOnAndroid.cmake) + else () + add_test (NAME ${exename} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../.. COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${exename}) + endif () +endforeach (testsourcefile) + +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 (ignored_source_file) +endif () diff --git a/packages/PEGTL/src/test/pegtl/ExecuteOnAndroid.cmake b/packages/PEGTL/src/test/pegtl/ExecuteOnAndroid.cmake new file mode 100644 index 0000000000000000000000000000000000000000..7f15007d04739e545018fba8b0081f5d38fc36af --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ExecuteOnAndroid.cmake @@ -0,0 +1,35 @@ + +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} 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 ...") +execute_process(COMMAND ${ANDROID_NDK}/../platform-tools/adb push ${UNITTEST} /data/local/tmp/ OUTPUT_QUIET) +message(STATUS "Execute ${UNITTEST_FILENAME} ${TEST_PARAMETER} 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} ${TEST_PARAMETER};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() diff --git a/packages/PEGTL/src/test/pegtl/actions_one.cpp b/packages/PEGTL/src/test/pegtl/actions_one.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb964a00823c65b66a658b6887bbcd0ab26b2235 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/actions_one.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace test1 + { + struct fiz : if_must< 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 == internal::demangle< one< 'b' > >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 1 ].first == internal::demangle< foo >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 2 ].first == internal::demangle< at< one< 'a' > > >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 3 ].first == internal::demangle< two< 'a' > >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 4 ].first == internal::demangle< fiz >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 5 ].first == internal::demangle< foo >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 6 ].first == internal::demangle< one< 'b' > >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 7 ].first == internal::demangle< foo >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 8 ].first == internal::demangle< eof >() ); + TAO_PEGTL_TEST_ASSERT( applied[ 9 ].first == internal::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 + + 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 == internal::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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/actions_three.cpp b/packages/PEGTL/src/test/pegtl/actions_three.cpp new file mode 100644 index 0000000000000000000000000000000000000000..378025cc73c13355255a3f1559d4a716dbfdde47 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/actions_three.cpp @@ -0,0 +1,102 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace test1 + { + bool apply_result; + + struct grammar + : test_rule< 2, apply_mode::ACTION, rewind_mode::ACTIVE, any > + { + }; + + template< typename Rule > + struct apply_bool_action : nothing< Rule > + { + }; + + template<> + struct apply_bool_action< grammar > + { + template< typename Input > + static bool apply( const Input& /*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 : nothing< Rule > + { + }; + + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/actions_two.cpp b/packages/PEGTL/src/test/pegtl/actions_two.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5d5b6be23422fc1804e82481a196e58dd0344fb --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/actions_two.cpp @@ -0,0 +1,141 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace test1 + { + struct state1 + { + char c; + + template< typename Input > + state1( const Input& /*unused*/, std::string& /*unused*/ ) + : c() + { + } + + template< typename Input > + void success( const Input& /*unused*/, std::string& s ) const + { + s += c; + } + }; + + struct fobble : sor< state< state1, alpha >, digit > + { + }; + + struct fibble : until< eof, fobble > + { + }; + + template< typename Rule > + struct action1 : nothing< Rule > + { + }; + + template<> + struct action1< alpha > + { + template< typename Input > + static void apply( const Input& 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 : nothing< Rule > + { + }; + + 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_byte_in_line = 12; + + const char* count_source = "count_source"; + + template< typename Rule > + struct count_action + { + template< typename Input > + static void apply( const Input& 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().byte_in_line == count_byte_in_line ); + 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_byte() == 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_byte_in_line ); + const auto result = parse< must< alpha >, count_action >( in ); + TAO_PEGTL_TEST_ASSERT( result ); + } + + } // namespace test1 + + void unit_test() + { + test1::state_test(); + test1::apply0_test(); + test1::count_test(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/analyze_cycles.cpp b/packages/PEGTL/src/test/pegtl/analyze_cycles.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1625b3e82522ca16e8edaf3c08a68e7ea714766a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/analyze_cycles.cpp @@ -0,0 +1,311 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename... Rules > + struct any_seq + : public seq< Rules... > + { + using analyze_t = analysis::generic< analysis::rule_type::ANY, Rules... >; + }; + + void unit_test() + { + 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 ); + { + 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< star< any >, star< any > > + { + }; + verify_analyze< any_seq< tst > >( __LINE__, __FILE__, true, 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 ); + } + { + 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 ); + } + { + 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 ); + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/argv_input.cpp b/packages/PEGTL/src/test/pegtl/argv_input.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0755211af5e418c33241f17990982ef9d86ad1a4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/argv_input.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <cstring> + +#include "test.hpp" + +#include <tao/pegtl.hpp> + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_classes.cpp b/packages/PEGTL/src/test/pegtl/ascii_classes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..406b567356813f8408513157eefca173ca148f28 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_classes.cpp @@ -0,0 +1,119 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_eol.cpp b/packages/PEGTL/src/test/pegtl/ascii_eol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5808c4cd3e90d1748c270b36cafbb60d2b707bb --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_eol.cpp @@ -0,0 +1,92 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_eolf.cpp b/packages/PEGTL/src/test/pegtl/ascii_eolf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53baa0d86371d905a3c212750860d585bc2b0a79 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_eolf.cpp @@ -0,0 +1,92 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp b/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp new file mode 100644 index 0000000000000000000000000000000000000000..258feea7bf9f86516045dde18f929d4e873220ac --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_forty_two.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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, 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, 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, i - 42 ); + } + verify_rule< forty_two< 'a', 'z' > >( __LINE__, __FILE__, "azzaazaazaaazzzaaaazzaaazzaazazzzaazzazaza", result_type::SUCCESS ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_identifier.cpp b/packages/PEGTL/src/test/pegtl/ascii_identifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d384fde2d49f8949f4073eb8516dde910b121e0e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_identifier.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_istring.cpp b/packages/PEGTL/src/test/pegtl/ascii_istring.cpp new file mode 100644 index 0000000000000000000000000000000000000000..054c1aa3f3d79e446b866a11ecf9f04313bf7ecd --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_istring.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_keyword.cpp b/packages/PEGTL/src/test/pegtl/ascii_keyword.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55f17b61b5500dfa8817c809f97a8ba52e239aa4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_keyword.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_shebang.cpp b/packages/PEGTL/src/test/pegtl/ascii_shebang.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e03e9b8e3c9e910567a78778a63a135d0848d5b2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_shebang.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_string.cpp b/packages/PEGTL/src/test/pegtl/ascii_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89796aaab95214d5d90eddd9da8b4c73b757b62b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_string.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_three.cpp b/packages/PEGTL/src/test/pegtl/ascii_three.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a71d3598b883d4c3a7375f2956da2aa2de4abe19 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_three.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/ascii_two.cpp b/packages/PEGTL/src/test/pegtl/ascii_two.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f547ca044690620612f26f186e6dc41e360826a4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/ascii_two.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_alphabet.cpp b/packages/PEGTL/src/test/pegtl/contrib_alphabet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d12656af7b8b3dc77664f13cfd6ac8970553431 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_alphabet.cpp @@ -0,0 +1,73 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +#include <tao/pegtl/contrib/alphabet.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + static_assert( alphabet::a == 'a', "a" ); + static_assert( alphabet::b == 'b', "b" ); + static_assert( alphabet::c == 'c', "c" ); + static_assert( alphabet::d == 'd', "d" ); + static_assert( alphabet::e == 'e', "e" ); + static_assert( alphabet::f == 'f', "f" ); + static_assert( alphabet::g == 'g', "g" ); + static_assert( alphabet::h == 'h', "h" ); + static_assert( alphabet::i == 'i', "i" ); + static_assert( alphabet::j == 'j', "j" ); + static_assert( alphabet::k == 'k', "k" ); + static_assert( alphabet::l == 'l', "l" ); + static_assert( alphabet::m == 'm', "m" ); + static_assert( alphabet::n == 'n', "n" ); + static_assert( alphabet::o == 'o', "o" ); + static_assert( alphabet::p == 'p', "p" ); + static_assert( alphabet::q == 'q', "q" ); + static_assert( alphabet::r == 'r', "r" ); + static_assert( alphabet::s == 's', "s" ); + static_assert( alphabet::t == 't', "t" ); + static_assert( alphabet::u == 'u', "u" ); + static_assert( alphabet::v == 'v', "v" ); + static_assert( alphabet::w == 'w', "w" ); + static_assert( alphabet::x == 'x', "x" ); + static_assert( alphabet::y == 'y', "y" ); + static_assert( alphabet::z == 'z', "z" ); + + static_assert( alphabet::A == 'A', "A" ); + static_assert( alphabet::B == 'B', "B" ); + static_assert( alphabet::C == 'C', "C" ); + static_assert( alphabet::D == 'D', "D" ); + static_assert( alphabet::E == 'E', "E" ); + static_assert( alphabet::F == 'F', "F" ); + static_assert( alphabet::G == 'G', "G" ); + static_assert( alphabet::H == 'H', "H" ); + static_assert( alphabet::I == 'I', "I" ); + static_assert( alphabet::J == 'J', "J" ); + static_assert( alphabet::K == 'K', "K" ); + static_assert( alphabet::L == 'L', "L" ); + static_assert( alphabet::M == 'M', "M" ); + static_assert( alphabet::N == 'N', "N" ); + static_assert( alphabet::O == 'O', "O" ); + static_assert( alphabet::P == 'P', "P" ); + static_assert( alphabet::Q == 'Q', "Q" ); + static_assert( alphabet::R == 'R', "R" ); + static_assert( alphabet::S == 'S', "S" ); + static_assert( alphabet::T == 'T', "T" ); + static_assert( alphabet::U == 'U', "U" ); + static_assert( alphabet::V == 'V', "V" ); + static_assert( alphabet::W == 'W', "W" ); + static_assert( alphabet::X == 'X', "X" ); + static_assert( alphabet::Y == 'Y', "Y" ); + static_assert( alphabet::Z == 'Z', "Z" ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_if_then.cpp b/packages/PEGTL/src/test/pegtl/contrib_if_then.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8af618797c59c938b7b79fdeb40bffaa4aa5aa98 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_if_then.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2018 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/if_then.hpp> + +namespace tao +{ + 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' > >; + + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_integer.cpp b/packages/PEGTL/src/test/pegtl/contrib_integer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba5104f592bd04db384ba2a5cd5e263654c40831 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_integer.cpp @@ -0,0 +1,150 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <limits> +#include <sstream> + +#include "test.hpp" + +#include <tao/pegtl/contrib/integer.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename I > + struct int_state + { + I converted = 55; + }; + + template< typename Rule > + struct int_action + : nothing< Rule > + { + }; + + template<> + struct int_action< integer::signed_rule > + : integer::signed_action + { + }; + + template<> + struct int_action< integer::unsigned_rule > + : integer::unsigned_action + { + }; + + template< typename S > + void test_signed( const std::string& i, const S s ) + { + int_state< S > st; + memory_input<> in( i, __FUNCTION__ ); + parse< must< integer::signed_rule, eof >, int_action >( in, st ); + TAO_PEGTL_TEST_ASSERT( st.converted == s ); + } + + template< typename S > + void test_signed( const std::string& i ) + { + int_state< S > st; + memory_input<> in( i, __FUNCTION__ ); + TAO_PEGTL_TEST_THROWS( parse< must< integer::signed_rule, eof >, int_action >( in, st ) ); + } + + template< typename S > + std::string lexical_cast( const S s ) + { + std::ostringstream o; + o << s; + return o.str(); + } + + template< typename S > + void test_signed( const S s ) + { + int_state< S > st; + const auto i = lexical_cast( s ); + memory_input<> in( i, __FUNCTION__ ); + parse< must< integer::signed_rule, eof >, int_action >( in, st ); + TAO_PEGTL_TEST_ASSERT( st.converted == s ); + } + + template< typename S > + void test_unsigned( const std::string& i, const S s ) + { + int_state< S > st; + memory_input<> in( i, __FUNCTION__ ); + parse< must< integer::unsigned_rule, eof >, int_action >( in, st ); + TAO_PEGTL_TEST_ASSERT( st.converted == s ); + } + + template< typename S > + void test_unsigned( const std::string& i ) + { + int_state< S > st; + memory_input<> in( i, __FUNCTION__ ); + TAO_PEGTL_TEST_THROWS( parse< must< integer::unsigned_rule, eof >, int_action >( in, st ) ); + } + + template< typename S > + void test_unsigned( const S s ) + { + int_state< S > st; + const auto i = lexical_cast( s ); + memory_input<> in( i, __FUNCTION__ ); + parse< must< integer::unsigned_rule, eof >, int_action >( in, st ); + TAO_PEGTL_TEST_ASSERT( st.converted == s ); + } + + void unit_test() + { + 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", 0 ); + test_signed< signed char >( "+000", 0 ); + test_signed< signed char >( "-000", 0 ); + + test_signed< signed char >( "127", 127 ); + + test_signed< signed char >( "-1", -1 ); + test_signed< signed char >( "-001", -1 ); + + 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 >( "00128" ); + test_signed< signed char >( "-00129" ); + + test_unsigned< unsigned char >( "-0" ); + test_unsigned< unsigned char >( "+1" ); + + test_unsigned< unsigned char >( "0", 0 ); + test_unsigned< unsigned char >( "000", 0 ); + test_unsigned< unsigned char >( "0", 0 ); + test_unsigned< unsigned char >( "255", 255 ); + test_unsigned< unsigned char >( "000255", 255 ); + test_unsigned< unsigned char >( "256" ); + 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() ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_json.cpp b/packages/PEGTL/src/test/pegtl/contrib_json.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5688748f45019b1441c4797f8b69cb5785f4c676 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_json.cpp @@ -0,0 +1,141 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_fail.hpp" +#include "verify_rule.hpp" + +#include <tao/pegtl/analyze.hpp> +#include <tao/pegtl/contrib/json.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + void verify_file_fail( const std::size_t line, const char* file, const std::string& s ) + { + file_input<> in( s ); + try { + parse< Rule >( in ); + TAO_PEGTL_TEST_FAILED( "expected exception" ); + } + catch( ... ) { + } + } + + using GRAMMAR = must< 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 + + verify_fail< GRAMMAR >( __LINE__, __FILE__, "" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " [" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " ]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[ " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "] " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " [ " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, " ] " ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\a\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\c\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\d\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\e\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\v\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\'\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\b\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\f\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\n\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\r\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\t\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\\\\\\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\\u12\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\xFF\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\xF4\x90\x80\x80\"]" ); + verify_fail< GRAMMAR >( __LINE__, __FILE__, "[\"\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" ) ) ); + + // verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail1.json" ); // disabled as it is valid now + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail2.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail3.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail4.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail5.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail6.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail7.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail8.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail9.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail10.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail11.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail12.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail13.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail14.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail15.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail16.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail17.json" ); + // verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail18.json" ); // disabled as deep nesting is allowed + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail19.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail20.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail21.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail22.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail23.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail24.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail25.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail26.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail27.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail28.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail29.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail30.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail31.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail32.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail33.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail34.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail35.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail36.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail37.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail38.json" ); + verify_file_fail< GRAMMAR >( __LINE__, __FILE__, "src/test/pegtl/data/fail39.json" ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp b/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..984f4506cb9f00edc219a28a67a384a211dcc112 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_parse_tree.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +#include <tao/pegtl/contrib/parse_tree.hpp> + +namespace tao +{ + 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 > > {}; + // clang-format on + + template< typename Rule > + struct selector + : parse_tree::selector< Rule, parse_tree::apply_store_content::to< A, B, C, D > > + { + }; + + void unit_test() + { + memory_input<> in( "ac", "input" ); + const auto r = parse_tree::parse< D, selector >( in ); + 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->id == &typeid( D ) ); + TAO_PEGTL_TEST_ASSERT( d->is< D >() ); +#if !defined( _MSC_VER ) + TAO_PEGTL_TEST_ASSERT( d->name() == "tao::pegtl::D" ); +#endif + + TAO_PEGTL_TEST_ASSERT( d->has_content() ); + TAO_PEGTL_TEST_ASSERT( d->begin().byte == 0 ); + TAO_PEGTL_TEST_ASSERT( d->end().byte == 2 ); + TAO_PEGTL_TEST_ASSERT( d->content() == "ac" ); + + TAO_PEGTL_TEST_ASSERT( d->children.size() == 2 ); + TAO_PEGTL_TEST_ASSERT( d->children.front()->is< A >() ); + TAO_PEGTL_TEST_ASSERT( d->children.back()->is< C >() ); + + memory_input<> in2( "x", "input" ); + const auto r2 = parse_tree::parse< D, selector >( in2 ); + TAO_PEGTL_TEST_ASSERT( !r2 ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_raw_string.cpp b/packages/PEGTL/src/test/pegtl/contrib_raw_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd17847ced04b0259f478448206e3e60c226a53e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_raw_string.cpp @@ -0,0 +1,137 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_fail.hpp" + +#include <tao/pegtl/contrib/raw_string.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + std::string content; // NOLINT + + using rstring = raw_string< '[', '=', ']' >; + using qstring = raw_string< '[', '=', ']', alpha, digit >; + + template< typename Rule > + struct raction + : nothing< Rule > + { + }; + + template<> + struct raction< rstring::content > + { + template< typename Input, typename... States > + static void apply( const Input& in, const States&... /*unused*/ ) + { + content.assign( in.begin(), in.end() ); + } + }; + + template< typename Rule > + struct qaction + : nothing< Rule > + { + }; + + template<> + struct qaction< qstring::content > + { + template< typename Input, typename... States > + static void apply( const Input& in, const States&... /*unused*/ ) + { + content.assign( in.begin(), in.end() ); + } + }; + + struct rgrammar + : must< rstring, eof > + { + }; + + struct qgrammar + : must< 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, 0 ); + const auto r = parse< Rule, Action >( in ); + if( ( !r ) || ( content != std::string( n, N - 1 ) ) ) { + TAO_PEGTL_TEST_FAILED( "input data [ '" << m << "' ] expected success with [ '" << n << "' ] but got [ '" << content << "' ] result [ " << r << " ]" ); + } + content.clear(); + memory_input< tracking_mode::LAZY > in2( m, m + M - 1, file, 0, line, 0 ); + const auto r2 = parse< Rule, Action >( in2 ); + if( ( !r2 ) || ( content != std::string( n, N - 1 ) ) ) { + TAO_PEGTL_TEST_FAILED( "input data [ '" << m << "' ] with tracking_mode::LAZY expected success with [ '" << n << "' ] but got [ '" << content << "' ] result [ " << r2 << " ]" ); + } + } + + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_rep_one_min_max.cpp b/packages/PEGTL/src/test/pegtl/contrib_rep_one_min_max.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2243f9d4841b1d6d4762ba9b7b0ef992cd00b629 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_rep_one_min_max.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +#include <tao/pegtl/contrib/rep_one_min_max.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_analyze< ellipsis >( __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< ellipsis >( __LINE__, __FILE__, "", result_type::LOCAL_FAILURE, 0 ); + verify_rule< ellipsis >( __LINE__, __FILE__, ".", result_type::LOCAL_FAILURE, 1 ); + verify_rule< ellipsis >( __LINE__, __FILE__, "..", result_type::LOCAL_FAILURE, 2 ); + verify_rule< ellipsis >( __LINE__, __FILE__, "....", result_type::LOCAL_FAILURE, 4 ); + verify_rule< ellipsis >( __LINE__, __FILE__, "...", result_type::SUCCESS, 0 ); + verify_rule< ellipsis >( __LINE__, __FILE__, "... ", result_type::SUCCESS, 1 ); + verify_rule< ellipsis >( __LINE__, __FILE__, "...+", result_type::SUCCESS, 1 ); + verify_rule< ellipsis >( __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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_to_string.cpp b/packages/PEGTL/src/test/pegtl/contrib_to_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c92b96598465683187d6872e8ee62478e71b870 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_to_string.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +#include <tao/pegtl.hpp> +#include <tao/pegtl/contrib/to_string.hpp> + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_tracer.cpp b/packages/PEGTL/src/test/pegtl/contrib_tracer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..429631650f86ce48cbc97a93b3aaa50606702a6c --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_tracer.cpp @@ -0,0 +1,81 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" + +#include <tao/pegtl/contrib/tracer.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + using GRAMMAR = sor< failure, one< 'a' > >; + + template< typename Rule > + struct tracer_action + : nothing< Rule > + { + }; + + unsigned a0 = 0; + unsigned a = 0; + + template<> + struct tracer_action< one< 'a' > > + { + template< typename... Ts > + static void apply0( Ts&&... /*unused*/ ) + { + ++a0; + } + }; + + template<> + struct tracer_action< GRAMMAR > + { + template< typename... Ts > + static void apply( Ts&&... /*unused*/ ) + { + ++a; + } + }; + + void unit_test() + { + { + memory_input<> in( "ab", "trace test please ignore" ); + const auto result = parse< GRAMMAR, nothing, tracer >( 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 = parse< GRAMMAR, tracer_action, tracer >( in ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( a0 == 1 ); + TAO_PEGTL_TEST_ASSERT( a == 1 ); + } + { + trace_state ts; + memory_input<> in( "ab", "trace test please ignore" ); + const auto result = parse< GRAMMAR, nothing, tracer >( in, ts ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( a0 == 1 ); + TAO_PEGTL_TEST_ASSERT( a == 1 ); + } + { + trace_state ts; + memory_input<> in( "ab", "trace test please ignore" ); + const auto result = parse< GRAMMAR, tracer_action, tracer >( in, ts ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( a0 == 2 ); + TAO_PEGTL_TEST_ASSERT( a == 2 ); + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_unescape.cpp b/packages/PEGTL/src/test/pegtl/contrib_unescape.cpp new file mode 100644 index 0000000000000000000000000000000000000000..254afe5238e0d37518a43e36e4672e3a9a9c51b0 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_unescape.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_fail.hpp" + +#include <tao/pegtl/contrib/unescape.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + // clang-format off + struct escaped_c : one< '"', '\\', 't' > {}; + struct escaped_u : seq< one< 'u' >, rep< 4, must< xdigit > > > {}; + struct escaped_U : seq< one< 'U' >, rep< 8, must< xdigit > > > {}; + struct escaped_j : list< seq< one< 'j' >, rep< 4, must< xdigit > > >, one< '\\' > > {}; + struct escaped_x : seq< one< 'x' >, rep< 2, must< xdigit > > > {}; + struct escaped : sor< escaped_c, escaped_u, escaped_U, escaped_j, escaped_x > {}; + struct character : if_then_else< one< '\\' >, must< escaped >, utf8::any > {}; + struct unstring : until< eof, character > {}; + + template< typename Rule > struct unaction : nothing< Rule > {}; + + 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 > + void verify_data( const char ( &m )[ M ], const char ( &n )[ N ] ) + { + unescape::state st; + memory_input<> in( m, M - 1, __FUNCTION__ ); + parse< unstring, unaction >( in, st ); + if( st.unescaped != std::string( n, N - 1 ) ) { + throw std::runtime_error( "test failed!" ); // NOLINT + } + } + + void unit_test() + { + verify_data( "\\t", "\t" ); + verify_data( "\\\\", "\\" ); + verify_data( "abc", "abc" ); + verify_data( "\\\"foo\\\"", "\"foo\"" ); + verify_data( "\\x20", " " ); + verify_data( "\\x30", "0" ); + verify_data( "\\x2000", " 00" ); + verify_data( "\\u0020", " " ); + verify_data( "\\u0020\\u0020", " " ); + verify_data( "\\u00e4", "\xc3\xa4" ); + verify_data( "\\u00E4", "\xC3\xA4" ); + verify_data( "\\u20ac", "\xe2\x82\xac" ); + + TAO_PEGTL_TEST_THROWS( verify_data( "\\ud800", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\ud800X", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\ud800\\u0020", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\ud800\\udc00", "" ) ); // unescape_u does not support surrogate pairs. + TAO_PEGTL_TEST_THROWS( verify_data( "\\udc00\\ud800", "" ) ); + + verify_data( "\\j0020", " " ); + verify_data( "\\j0020\\j0020", " " ); + verify_data( "\\j20ac", "\xe2\x82\xac" ); + + verify_data( "\\jd800\\jdc00", "\xf0\x90\x80\x80" ); // unescape_j does support proper surrogate pairs. + + TAO_PEGTL_TEST_THROWS( verify_data( "\\jd800", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\jd800X", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\jd800\\j0020", "" ) ); + TAO_PEGTL_TEST_THROWS( verify_data( "\\jdc00\\jd800", "" ) ); + + verify_data( "\\j0000\\u0000\x00", "\x00\x00\x00" ); + + unescape::state st; + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\\\\\", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\x", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\xx", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\xa", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\x1", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\x1h", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\x", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\xx", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\xa", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\x1", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "a\\x1h", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\a", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\_", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\z", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\1", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\a00", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\_1111", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\z22222222", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\13333333333333333", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\u", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\uu", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\uuuu", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\u123", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\u999", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\u444h", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\j", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\ju", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\juuu", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\j123", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\j999", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\j444h", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\U00110000", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\U80000000", st ); + verify_fail< unstring, unaction >( __LINE__, __FILE__, "\\Uffffffff", st ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/contrib_uri.cpp b/packages/PEGTL/src/test/pegtl/contrib_uri.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d502a843e5c5afaabb2fa459abbb586e4cc9d46 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/contrib_uri.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_fail.hpp" +#include "verify_rule.hpp" + +#include <tao/pegtl/contrib/uri.hpp> + +namespace tao +{ + 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, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "ftp://ftp.is.co.za/rfc/rfc1808.txt", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///C:/Users/Benutzer/Desktop/Uniform%20Resource%20Identifier.html", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "file:///etc/fstab", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "geo:48.33,14.122;u=22.5", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "ldap://[2001:db8::7]/c=GB?objectClass?one", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "gopher://gopher.floodgap.com", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "mailto:John.Doe@example.com", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "sip:911@pbx.mycompany.com", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "news:comp.infosystems.www.servers.unix", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "data:text/plain;charset=iso-8859-7,%be%fa%be", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "tel:+1-816-555-1212", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "telnet://192.0.2.16:80/", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "git://github.com/rails/rails.git", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "crid://broadcaster.com/movies/BestActionMovieEver", result_type::SUCCESS, 0 ); + verify_rule< GRAMMAR >( __LINE__, __FILE__, "http://nobody:password@example.org:8080/cgi-bin/script.php?action=submit&pageid=86392001#section_2", result_type::SUCCESS, 0 ); + + verify_fail< GRAMMAR >( __LINE__, __FILE__, "" ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/data/README.txt b/packages/PEGTL/src/test/pegtl/data/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..69ce1a21252e031433b676cec2d26711b1e0fcd3 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/README.txt @@ -0,0 +1,44 @@ +pass1 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. diff --git a/packages/PEGTL/src/test/pegtl/data/blns.json b/packages/PEGTL/src/test/pegtl/data/blns.json new file mode 100755 index 0000000000000000000000000000000000000000..ed832d4d178d92460cdaf460829fb5154ae3db62 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/blns.json @@ -0,0 +1,496 @@ +[ + "", + "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‡°·‚—±", + "⅛⅜⅝⅞", + "ЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя", + "٠١٢٣٤٥٦٧٨٩", + "⁰⁴⁵", + "₀₁₂", + "⁰⁴⁵₀₁₂", + "ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็", + "'", + "\"", + "''", + "\"\"", + "'\"'", + "\"''''\"'\"", + "\"'\"'\"''''\"", + "<foo val=“bar” />", + "<foo val=“bar” />", + "<foo val=”bar“ />", + "<foo val=`bar' />", + "田中さんにあげて下さい", + "パーティーへ行かないか", + "和製漢語", + "部落格", + "사회과학원 어학연구소", + "찦차를 타고 온 펲시맨과 쑛다리 똠방각하", + "社會科學院語學研究所", + "울란바토르", + "𠜎𠜱𠝹𠱓𠱸𠲖𠳏", + "ヽ༼ຈل͜ຈ༽ノ ヽ༼ຈل͜ຈ༽ノ ", + "(。◕ ∀ ◕。)", + "`ィ(´∀`∩", + "__ロ(,_,*)", + "・( ̄∀ ̄)・:*:", + "゚・✿ヾ╲(。◕‿◕。)╱✿・゚", + ",。・:*:・゜’( ☻ ω ☻ )。・:*:・゜’", + "(╯°□°)╯︵ ┻━┻) ", + "(ノಥ益ಥ)ノ ┻━┻", + "┬─┬ノ( º _ ºノ)", + "( ͡° ͜ʖ ͡°)", + "😍", + "👩🏽", + "👾 🙇 💁 🙅 🙆 🙋 🙎 🙍 ", + "🐵 🙈 🙉 🙊", + "❤️ 💔 💌 💕 💞 💓 💗 💖 💘 💝 💟 💜 💛 💚 💙", + "✋🏿 💪🏿 👐🏿 🙌🏿 👏🏿 🙏🏿", + "🚾 🆒 🆓 🆕 🆖 🆗 🆙 🏧", + "0️⃣ 1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟", + "🇺🇸🇷🇺🇸 🇦🇫🇦🇲🇸 ", + "🇺🇸🇷🇺🇸🇦🇫🇦🇲", + "🇺🇸🇷🇺🇸🇦", + "123", + "١٢٣", + "ثم نفس سقطت وبالتحديد،, جزيرتي باستخدام أن دنو. إذ هنا؟ الستار وتنصيب كان. أهّل ايطاليا، بريطانيا-فرنسا قد أخذ. سليمان، إتفاقية بين ما, يذكر الحدود أي بعد, معاملة بولندا، الإطلاق عل إيو.", + "בְּרֵאשִׁית, בָּרָא אֱלֹהִים, אֵת הַשָּׁמַיִם, וְאֵת הָאָרֶץ", + "הָיְתָהtestالصفحات التّحول", + "﷽", + "ﷺ", + "مُنَاقَشَةُ سُبُلِ اِسْتِخْدَامِ اللُّغَةِ فِي النُّظُمِ الْقَائِمَةِ وَفِيم يَخُصَّ التَّطْبِيقَاتُ الْحاسُوبِيَّةُ، ", + "", + " ", + "", + " ", + "", + "␣", + "␢", + "␡", + "test", + "test", + " test ", + "testtest", + "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>alert('123');</script>", + "<img src=x onerror=alert(123) />", + "<svg><script>123<1>alert(123)</script> ", + "\"><script>alert(123)</script>", + "'><script>alert(123)</script>", + "><script>alert(123)</script>", + "</script><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>", + "<sc<script>ript>alert(123)</sc</script>ript>", + "--><script>alert(123)</script>", + "\";alert(123);t=\"", + "';alert(123);t='", + "JavaSCript:alert(123)", + ";alert(123);", + "src=JaVaSCript:prompt(132)", + "\"><script>alert(123);</script x=\"", + "'><script>alert(123);</script x='", + "><script>alert(123);</script x=", + "\" autofocus onkeyup=\"javascript:alert(123)", + "' autofocus onkeyup='javascript:alert(123)", + "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", + "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", + "'`\"><\\x3Cscript>javascript:alert(1)</script> ", + "'`\"><\\x00script>javascript:alert(1)</script>", + "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", + "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", + "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", + "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", + "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", + "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", + "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", + "\"`'><script>\\x3Bjavascript:alert(1)</script>", + "\"`'><script>\\x0Djavascript:alert(1)</script>", + "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", + "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", + "\"`'><script>\\x09javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", + "\"`'><script>\\x00javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", + "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", + "\"`'><script>\\x0Cjavascript:alert(1)</script>", + "\"`'><script>\\x2Bjavascript:alert(1)</script>", + "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", + "\"`'><script>-javascript:alert(1)</script>", + "\"`'><script>\\x0Ajavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", + "\"`'><script>\\x7Ejavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", + "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", + "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", + "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", + "\"`'><script>\\x21javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", + "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", + "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", + "\"`'><script>\\x0Bjavascript:alert(1)</script>", + "\"`'><script>\\x20javascript:alert(1)</script>", + "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", + "<img \\x00src=x onerror=\"alert(1)\">", + "<img \\x47src=x onerror=\"javascript:alert(1)\">", + "<img \\x11src=x onerror=\"javascript:alert(1)\">", + "<img \\x12src=x onerror=\"javascript:alert(1)\">", + "<img\\x47src=x onerror=\"javascript:alert(1)\">", + "<img\\x10src=x onerror=\"javascript:alert(1)\">", + "<img\\x13src=x onerror=\"javascript:alert(1)\">", + "<img\\x32src=x onerror=\"javascript:alert(1)\">", + "<img\\x47src=x onerror=\"javascript:alert(1)\">", + "<img\\x11src=x onerror=\"javascript:alert(1)\">", + "<img \\x47src=x onerror=\"javascript:alert(1)\">", + "<img \\x34src=x onerror=\"javascript:alert(1)\">", + "<img \\x39src=x onerror=\"javascript:alert(1)\">", + "<img \\x00src=x onerror=\"javascript:alert(1)\">", + "<img src\\x09=x onerror=\"javascript:alert(1)\">", + "<img src\\x10=x onerror=\"javascript:alert(1)\">", + "<img src\\x13=x onerror=\"javascript:alert(1)\">", + "<img src\\x32=x onerror=\"javascript:alert(1)\">", + "<img src\\x12=x onerror=\"javascript:alert(1)\">", + "<img src\\x11=x onerror=\"javascript:alert(1)\">", + "<img src\\x00=x onerror=\"javascript:alert(1)\">", + "<img src\\x47=x onerror=\"javascript:alert(1)\">", + "<img src=x\\x09onerror=\"javascript:alert(1)\">", + "<img src=x\\x10onerror=\"javascript:alert(1)\">", + "<img src=x\\x11onerror=\"javascript:alert(1)\">", + "<img src=x\\x12onerror=\"javascript:alert(1)\">", + "<img src=x\\x13onerror=\"javascript:alert(1)\">", + "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", + "<img src=x onerror=\\x09\"javascript:alert(1)\">", + "<img src=x onerror=\\x10\"javascript:alert(1)\">", + "<img src=x onerror=\\x11\"javascript:alert(1)\">", + "<img src=x onerror=\\x12\"javascript:alert(1)\">", + "<img src=x onerror=\\x32\"javascript:alert(1)\">", + "<img src=x onerror=\\x00\"javascript:alert(1)\">", + "<a href=javascript:javascript:alert(1)>XXX</a>", + "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", + "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", + "<title onpropertychange=javascript:alert(1)></title><title title=>", + "<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 ॣ ॣ冗" +] diff --git a/packages/PEGTL/src/test/pegtl/data/fail1.json b/packages/PEGTL/src/test/pegtl/data/fail1.json new file mode 100644 index 0000000000000000000000000000000000000000..6216b865f10219c51c6af21e7a68641bab77ee4f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail10.json b/packages/PEGTL/src/test/pegtl/data/fail10.json new file mode 100644 index 0000000000000000000000000000000000000000..5d8c0047bd522dfa9fbc642051ed76bd3162d936 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail11.json b/packages/PEGTL/src/test/pegtl/data/fail11.json new file mode 100644 index 0000000000000000000000000000000000000000..76eb95b4583c8ee74eee3bdc25e1db69e1aaf4bb --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail12.json b/packages/PEGTL/src/test/pegtl/data/fail12.json new file mode 100644 index 0000000000000000000000000000000000000000..77580a4522d8c79245851e72a3644a0709b3d28c --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail13.json b/packages/PEGTL/src/test/pegtl/data/fail13.json new file mode 100644 index 0000000000000000000000000000000000000000..379406b59bdb943f145afea98ff1bbc45d43ff45 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail14.json b/packages/PEGTL/src/test/pegtl/data/fail14.json new file mode 100644 index 0000000000000000000000000000000000000000..0ed366b38a34f551c25735bdcb9282d27beae026 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail15.json b/packages/PEGTL/src/test/pegtl/data/fail15.json new file mode 100644 index 0000000000000000000000000000000000000000..fc8376b605da69dda23f3fcdd9816dcbf2e736cc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail16.json b/packages/PEGTL/src/test/pegtl/data/fail16.json new file mode 100644 index 0000000000000000000000000000000000000000..3fe21d4b532498c8b90872ef571c6867f45e645f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail17.json b/packages/PEGTL/src/test/pegtl/data/fail17.json new file mode 100644 index 0000000000000000000000000000000000000000..62b9214aeda6d74a72ebeceedf0aae3609f1c638 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail18.json b/packages/PEGTL/src/test/pegtl/data/fail18.json new file mode 100644 index 0000000000000000000000000000000000000000..edac92716f186e39d0e3c818b8b110b9a2c4add5 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail19.json b/packages/PEGTL/src/test/pegtl/data/fail19.json new file mode 100644 index 0000000000000000000000000000000000000000..3b9c46fa9a296c9d8c35ce4a6592d8bb7ffe748a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail2.json b/packages/PEGTL/src/test/pegtl/data/fail2.json new file mode 100644 index 0000000000000000000000000000000000000000..6b7c11e5a56537f81e651980359c62e263f7399f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail2.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail20.json b/packages/PEGTL/src/test/pegtl/data/fail20.json new file mode 100644 index 0000000000000000000000000000000000000000..27c1af3e72ee37bbf64ccd7b77c5bad8cdea1557 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail21.json b/packages/PEGTL/src/test/pegtl/data/fail21.json new file mode 100644 index 0000000000000000000000000000000000000000..62474573b2160adefc3dc669b39200ea659d6e59 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail22.json b/packages/PEGTL/src/test/pegtl/data/fail22.json new file mode 100644 index 0000000000000000000000000000000000000000..a7752581bcf7f3b901aef052a2df541c1285b6c2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail23.json b/packages/PEGTL/src/test/pegtl/data/fail23.json new file mode 100644 index 0000000000000000000000000000000000000000..494add1ca190e12acd1c8e34ac819a6316c927bc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail24.json b/packages/PEGTL/src/test/pegtl/data/fail24.json new file mode 100644 index 0000000000000000000000000000000000000000..caff239bfc36297da08828095105bb497b8aef2a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail25.json b/packages/PEGTL/src/test/pegtl/data/fail25.json new file mode 100644 index 0000000000000000000000000000000000000000..8b7ad23e010314591d914519996c28483b5dadc8 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail26.json b/packages/PEGTL/src/test/pegtl/data/fail26.json new file mode 100644 index 0000000000000000000000000000000000000000..845d26a6a54398c49cd492e6836c0d1987f554e4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail27.json b/packages/PEGTL/src/test/pegtl/data/fail27.json new file mode 100644 index 0000000000000000000000000000000000000000..6b01a2ca4a97ec36604771dcc3175bbcda865d85 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail28.json b/packages/PEGTL/src/test/pegtl/data/fail28.json new file mode 100644 index 0000000000000000000000000000000000000000..621a0101c664a619457d16f1107a677c911481b4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail29.json b/packages/PEGTL/src/test/pegtl/data/fail29.json new file mode 100644 index 0000000000000000000000000000000000000000..47ec421bb6242648e80b2b465049acbae1e6e44a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail3.json b/packages/PEGTL/src/test/pegtl/data/fail3.json new file mode 100644 index 0000000000000000000000000000000000000000..168c81eb78537ea4006ea0a46b67851d9995564d --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail30.json b/packages/PEGTL/src/test/pegtl/data/fail30.json new file mode 100644 index 0000000000000000000000000000000000000000..8ab0bc4b8b2c73b616a45931d05720555a2f7762 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail31.json b/packages/PEGTL/src/test/pegtl/data/fail31.json new file mode 100644 index 0000000000000000000000000000000000000000..1cce602b518fc6e7f164a58cc710def27e64b8a5 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail32.json b/packages/PEGTL/src/test/pegtl/data/fail32.json new file mode 100644 index 0000000000000000000000000000000000000000..45cba7396ff7462dd6de005c32fd2a95c5318e5f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail33.json b/packages/PEGTL/src/test/pegtl/data/fail33.json new file mode 100644 index 0000000000000000000000000000000000000000..ca5eb19dc97f5ca363ff33a4c3644ad28e612679 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail34.json b/packages/PEGTL/src/test/pegtl/data/fail34.json new file mode 100644 index 0000000000000000000000000000000000000000..857f065e4154176c98f4274d223066861e8e3d80 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail34.json @@ -0,0 +1 @@ +00 \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail35.json b/packages/PEGTL/src/test/pegtl/data/fail35.json new file mode 100644 index 0000000000000000000000000000000000000000..f215b126e7255557201e86af79872c3ef2a753b7 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail35.json @@ -0,0 +1 @@ +["bracket mismatch"} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail36.json b/packages/PEGTL/src/test/pegtl/data/fail36.json new file mode 100644 index 0000000000000000000000000000000000000000..26b891a4a9ef7feb2549b950f40db3fe58982634 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail36.json @@ -0,0 +1 @@ +{"bracket":"mismatch"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail37.json b/packages/PEGTL/src/test/pegtl/data/fail37.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/packages/PEGTL/src/test/pegtl/data/fail38.json b/packages/PEGTL/src/test/pegtl/data/fail38.json new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail38.json @@ -0,0 +1 @@ + diff --git a/packages/PEGTL/src/test/pegtl/data/fail39.json b/packages/PEGTL/src/test/pegtl/data/fail39.json new file mode 100644 index 0000000000000000000000000000000000000000..5f7630ecaf55ad2220ca5479d8b06c94d6933eb4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail39.json @@ -0,0 +1 @@ +"invalid utf-8 sequence �" \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail4.json b/packages/PEGTL/src/test/pegtl/data/fail4.json new file mode 100644 index 0000000000000000000000000000000000000000..9de168bf34e2e368d044bccc099d44b02316de66 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail4.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail5.json b/packages/PEGTL/src/test/pegtl/data/fail5.json new file mode 100644 index 0000000000000000000000000000000000000000..ddf3ce3d2409467011ec7545551d5d078bce1bfd --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail5.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail6.json b/packages/PEGTL/src/test/pegtl/data/fail6.json new file mode 100644 index 0000000000000000000000000000000000000000..ed91580e1b1c15194a9a758f1b231575074722db --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail7.json b/packages/PEGTL/src/test/pegtl/data/fail7.json new file mode 100644 index 0000000000000000000000000000000000000000..8a96af3e4ee6c7fffd8da641dedcd750a5cc4d9d --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail7.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail8.json b/packages/PEGTL/src/test/pegtl/data/fail8.json new file mode 100644 index 0000000000000000000000000000000000000000..b28479c6ecb21a801d6988b9ea39a4eb00a64702 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail8.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/fail9.json b/packages/PEGTL/src/test/pegtl/data/fail9.json new file mode 100644 index 0000000000000000000000000000000000000000..5815574f363e58cf91578e909ef4dabb402a75de --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/pass1.json b/packages/PEGTL/src/test/pegtl/data/pass1.json new file mode 100644 index 0000000000000000000000000000000000000000..70e26854369282e625e75b302782f581e610f2b3 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/pass1.json @@ -0,0 +1,58 @@ +[ + "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"] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/pass2.json b/packages/PEGTL/src/test/pegtl/data/pass2.json new file mode 100644 index 0000000000000000000000000000000000000000..d3c63c7ad845e4cedd0c70d13102b38c51ec197a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/packages/PEGTL/src/test/pegtl/data/pass3.json b/packages/PEGTL/src/test/pegtl/data/pass3.json new file mode 100644 index 0000000000000000000000000000000000000000..4528d51f1ac615e7e11dbb1321dc99187705f0d8 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/packages/PEGTL/src/test/pegtl/data_cstring.cpp b/packages/PEGTL/src/test/pegtl/data_cstring.cpp new file mode 100644 index 0000000000000000000000000000000000000000..978a1af36f21dc6ee550d1dd0675a3d1248e36a2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/data_cstring.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2016-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule, + template< typename... > class Action = nothing, + template< typename... > class Control = normal, + typename... States > + bool parse_cstring( const char* string, const char* source, const std::size_t maximum, States&&... st ) + { + buffer_input< internal::cstring_reader > in( source, maximum, string ); + return parse< Rule, Action, Control >( in, st... ); + } + + struct test_grammar : seq< string< 'a', 'b' >, discard, string< 'c', 'd' >, discard, any, any, discard, eof > + { + }; + + void unit_test() + { + const char* test_data = "abcdef"; + TAO_PEGTL_TEST_ASSERT( parse_cstring< test_grammar >( test_data, "test data", 2 ) ); + TAO_PEGTL_TEST_ASSERT( !parse_cstring< test_grammar >( test_data, "test data", 1 ) ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/demangle.cpp b/packages/PEGTL/src/test/pegtl/demangle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..526724dc8cf4dd1b8bba4cdfa92ddd02cf61054e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/demangle.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2017-2018 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/demangle_sanitise.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void test_chars( std::string a, const std::string& b ) + { + internal::demangle_sanitise_chars( a ); + TAO_PEGTL_TEST_ASSERT( a == b ); + } + + void unit_test() + { + const std::string s = "something that can't be demangled"; + const std::string a = internal::demangle( s.c_str() ); + TAO_PEGTL_TEST_ASSERT( a == s ); + const std::string b = internal::demangle< std::string >(); + (void)b; // Not standardised. + + test_chars( "zzz(char)1xxx", "zzz1xxx" ); + test_chars( "zzz(char)32xxx", "zzz' 'xxx" ); + test_chars( "zzz(char)48xxx", "zzz'0'xxx" ); + test_chars( "zzz(char)39xxx", "zzz'\\''xxx" ); + test_chars( "zzz(char)92xxx", "zzz'\\\\'xxx" ); + test_chars( "frobnicate<> (char)1 (char)32 (char)48 ***", "frobnicate<> 1 ' ' '0' ***" ); + test_chars( "tao::pegtl::internal::until<tao::pegtl::at<tao::pegtl::ascii::one<(char)34> >", "tao::pegtl::internal::until<tao::pegtl::at<tao::pegtl::ascii::one<'\"'> >" ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/file_cstream.cpp b/packages/PEGTL/src/test/pegtl/file_cstream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e06b6e2d2316236ff79eb171e7077b7a1b1b6550 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_cstream.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2016-2018 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 +{ + 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" ); // NOLINT +#else + std::FILE* stream = std::fopen( filename, "rb" ); // NOLINT +#endif + TAO_PEGTL_TEST_ASSERT( stream != nullptr ); + TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( cstream_input<>( stream, 16, filename ) ) ); + std::fclose( stream ); // NOLINT(cppcoreguidelines-owning-memory) + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/file_data.txt b/packages/PEGTL/src/test/pegtl/file_data.txt new file mode 100644 index 0000000000000000000000000000000000000000..d1c7bba09c907f77a6eb263e90b8a5d5b7873a7e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_data.txt @@ -0,0 +1,11 @@ +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content +dummy content diff --git a/packages/PEGTL/src/test/pegtl/file_file.cpp b/packages/PEGTL/src/test/pegtl/file_file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73af0546e67a1d72ee75e6ef9292a6ab945721fc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_file.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2015-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_file< file_input<> >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/file_istream.cpp b/packages/PEGTL/src/test/pegtl/file_istream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b1938e439deff5d2fb6e1ac13e7bb038aa599a48 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_istream.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <fstream> + +#include "test.hpp" + +namespace tao +{ + 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() + { + try { + const char* filename = "src/test/pegtl/no_such_file.txt"; + std::ifstream stream( filename ); + parse< file_grammar >( istream_input<>( stream, 16, filename ) ); + TAO_PEGTL_TEST_ASSERT( false ); + } + catch( const input_error& e ) { + TAO_PEGTL_TEST_ASSERT( std::string( e.what() ).find( "error in istream.read()" ) != std::string::npos ); + } + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/file_mmap.cpp b/packages/PEGTL/src/test/pegtl/file_mmap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4320bb0056cc42b2f912444cd4ac2603d026bb70 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_mmap.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_file< mmap_input<> >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" + +#else + +int main( int, char** ) +{ + return 0; +} + +#endif diff --git a/packages/PEGTL/src/test/pegtl/file_read.cpp b/packages/PEGTL/src/test/pegtl/file_read.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2178cacbc1329ecbe4eb0249bcce2b39a377dc63 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/file_read.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf > + struct open_input + : public read_input< P, Eol > + { + explicit open_input( const char* in_filename ) + : read_input< P, Eol >( internal::file_open( in_filename ), in_filename ) + { + } + + explicit open_input( const std::string& in_filename ) + : open_input( in_filename.c_str() ) + { + } + }; + + void unit_test() + { + verify_file< read_input<> >(); + verify_file< open_input<> >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/internal_endian.cpp b/packages/PEGTL/src/test/pegtl/internal_endian.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b0629421b359198daa120451f723013dbef4d10 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/internal_endian.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl/internal/endian.hpp> + +#include "test.hpp" + +namespace tao +{ + 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 ) ); + + const std::uint16_t a = 1; + if( *static_cast< const std::uint8_t* >( static_cast< const void* >( &a ) ) != 1 ) { + 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 { + 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 ) ); + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp b/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e6eb95c0f0d29d4c61f4996656b67c04fca0c53 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/internal_file_mapper.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl/file_input.hpp> + +#if defined( _POSIX_MAPPED_FILES ) + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + try { + internal::file_mapper dummy( "include" ); + std::cerr << "pegtl: unit test failed for [ internal::file_mapper ]" << std::endl; + ++failed; + } + catch( const input_error& ) { + } + catch( ... ) { + std::cerr << "pegtl: unit test failed for [ internal::file_mapper ] with unexpected exception" << std::endl; + ++failed; + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" + +#else + +int main( int, char** ) +{ + return 0; +} + +#endif diff --git a/packages/PEGTL/src/test/pegtl/internal_file_opener.cpp b/packages/PEGTL/src/test/pegtl/internal_file_opener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0641b8a52bd1492efbcb6a14ea3ce978e1e0fdb --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/internal_file_opener.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2015-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include <tao/pegtl/file_input.hpp> + +#if defined( _POSIX_MAPPED_FILES ) + +#include "test.hpp" + +namespace tao +{ + 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 { + fo.size(); + std::cerr << "pegtl: unit test failed for [ internal::file_opener ] " << std::endl; + ++failed; + } + catch( const std::exception& ) { + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" + +#else + +int main( int, char** ) +{ + return 0; +} + +#endif diff --git a/packages/PEGTL/src/test/pegtl/main.hpp b/packages/PEGTL/src/test/pegtl/main.hpp new file mode 100644 index 0000000000000000000000000000000000000000..92a79e4fc76994b127715dc8bb446e285d278e4a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/main.hpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_MAIN_HPP + +#include <cstdlib> +#include <iostream> + +int main( int /*unused*/, char** argv ) +{ + tao::TAO_PEGTL_NAMESPACE::unit_test(); + + if( tao::TAO_PEGTL_NAMESPACE::failed != 0 ) { + std::cerr << "pegtl: unit test " << argv[ 0 ] << " failed " << tao::TAO_PEGTL_NAMESPACE::failed << std::endl; + } + return ( tao::TAO_PEGTL_NAMESPACE::failed == 0 ) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +#endif diff --git a/packages/PEGTL/src/test/pegtl/pegtl_string_t.cpp b/packages/PEGTL/src/test/pegtl/pegtl_string_t.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8bde77e2a57b1103d41c8c0f6d22c31ae94b251 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/pegtl_string_t.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2015-2018 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::TAO_PEGTL_NAMESPACE::sor< TAO_PEGTL_STRING( "foo" ), TAO_PEGTL_STRING( "bar" ) > + { + }; + + static_assert( std::is_same< TAO_PEGTL_STRING( "Hello" ), tao::TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o' > >::value, "TAO_PEGTL_STRING broken" ); + static_assert( !std::is_same< TAO_PEGTL_ISTRING( "Hello" ), tao::TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o' > >::value, "TAO_PEGTL_ISTRING broken" ); + static_assert( std::is_same< TAO_PEGTL_ISTRING( "Hello" ), tao::TAO_PEGTL_NAMESPACE::istring< 'H', 'e', 'l', 'l', 'o' > >::value, "TAO_PEGTL_ISTRING broken" ); + + static_assert( std::is_same< TAO_PEGTL_KEYWORD( "private" ), tao::TAO_PEGTL_NAMESPACE::keyword< 'p', 'r', 'i', 'v', 'a', 't', 'e' > >::value, "TAO_PEGTL_KEYWORD broken" ); + + // Strings may even contain embedded nulls + + static_assert( std::is_same< TAO_PEGTL_STRING( "Hello, w\0rld!" ), tao::TAO_PEGTL_NAMESPACE::string< 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 0, 'r', 'l', 'd', '!' > >::value, "TAO_PEGTL_STRING broken" ); + + // The strings currently have a maximum length of 512 characters. + + using namespace tao::TAO_PEGTL_NAMESPACE::alphabet; // NOLINT + static_assert( std::is_same< TAO_PEGTL_STRING( "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" ), + tao::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 > >::value, + "TAO_PEGTL_STRING broken" ); + +} // namespace test + +int main() +{ + return 0; +} diff --git a/packages/PEGTL/src/test/pegtl/position.cpp b/packages/PEGTL/src/test/pegtl/position.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2aa309c325cbfb93ff03cf3b4faf03f37809b9e9 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/position.cpp @@ -0,0 +1,182 @@ +// Copyright (c) 2016-2018 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 +{ + 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 Input = memory_input<> > + void test_matches_lf() + { + static const std::string s1 = "\n"; + + Input i1( s1, __FUNCTION__ ); + + TAO_PEGTL_TEST_ASSERT( parse< Rule >( i1 ) ); + TAO_PEGTL_TEST_ASSERT( i1.line() == 2 ); + TAO_PEGTL_TEST_ASSERT( i1.byte_in_line() == 0 ); + } + + template< typename Rule, typename Input = memory_input<> > + void test_matches_other( const std::string& s2 ) + { + TAO_PEGTL_TEST_ASSERT( s2.size() == 1 ); + + Input i2( s2, __FUNCTION__ ); + + TAO_PEGTL_TEST_ASSERT( parse< Rule >( i2 ) ); + TAO_PEGTL_TEST_ASSERT( i2.line() == 1 ); + TAO_PEGTL_TEST_ASSERT( i2.byte_in_line() == 1 ); + } + + template< typename Rule, typename Input = memory_input<> > + void test_mismatch( const std::string& s3 ) + { + TAO_PEGTL_TEST_ASSERT( s3.size() == 1 ); + + Input i3( s3, __FUNCTION__ ); + + TAO_PEGTL_TEST_ASSERT( !parse< Rule >( i3 ) ); + TAO_PEGTL_TEST_ASSERT( i3.line() == 1 ); + TAO_PEGTL_TEST_ASSERT( i3.byte_in_line() == 0 ); + } + + 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 + : nothing< Rule > + { + }; + + template<> + struct outer_action< two< 'b' > > + { + template< typename Input > + static void apply( const Input& oi ) + { + 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.byte_in_line == 2 ); + memory_input<> in( "dFF", "inner" ); + parse_nested< inner_grammar >( oi, in ); + } + }; + + template< typename Input = memory_input<> > + void test_nested() + { + try { + memory_input<> oi( "aabbcc", "outer" ); + parse< outer_grammar, outer_action >( oi ); + } + catch( 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 ].byte_in_line == 1 ); + 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 ].byte_in_line == 2 ); + } + } + + 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 >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/result_type.hpp b/packages/PEGTL/src/test/pegtl/result_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..80473913458bba60925adbab2309af8bb03771a2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/result_type.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_RESULT_TYPE_HPP + +#include <ostream> + +#include <tao/pegtl/config.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + enum class result_type + { + 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 << int( t ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/rule_action.cpp b/packages/PEGTL/src/test/pegtl/rule_action.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c4dce78c2a79d3185fe6b9bbd231b7b2720d5ee --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_action.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename... Rules > + using test_action_rule = action< nothing, Rules... >; + + void unit_test() + { + verify_seqs< test_action_rule >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_apply.cpp b/packages/PEGTL/src/test/pegtl/rule_apply.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4dab0a779b418d7c79b7fb1444140f6c0528e778 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_apply.cpp @@ -0,0 +1,98 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace test1 + { + struct action_a + { + template< typename Input > + static void apply( const Input& /*unused*/, int& r, int& s ) + { + TAO_PEGTL_TEST_ASSERT( !r ); + TAO_PEGTL_TEST_ASSERT( !s ); + r += 1; + } + }; + + struct action_b + { + template< typename Input > + static bool apply( const Input& /*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 Input > + static void apply( const Input& /*unused*/, bool& state_b ) + { + TAO_PEGTL_TEST_ASSERT( !state_b ); + } + }; + + struct action2_b + { + template< typename Input > + static bool apply( const Input& /*unused*/, bool& state_b ) + { + TAO_PEGTL_TEST_ASSERT( !state_b ); + state_b = true; + return false; + } + }; + + struct action2_c + { + template< typename Input > + static void apply( const Input& /*unused*/, bool& /*unused*/ ) + { + TAO_PEGTL_TEST_ASSERT( false ); + } + }; + + } // namespace test1 + + void unit_test() + { + int state_r = 0; + int state_s = 0; + parse< must< 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 ); + parse< must< 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; + const bool result = parse< apply< test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input<>( "", __FUNCTION__ ), state_b ); + TAO_PEGTL_TEST_ASSERT( !result ); + TAO_PEGTL_TEST_ASSERT( state_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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_apply0.cpp b/packages/PEGTL/src/test/pegtl/rule_apply0.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83dc519cefe9bb491a4c1d6d370a187bebecbd65 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_apply0.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + { + static void apply0( bool& /*unused*/ ) + { + TAO_PEGTL_TEST_ASSERT( false ); + } + }; + + } // namespace test1 + + void unit_test() + { + int state_r = 0; + int state_s = 0; + parse< must< 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 ); + parse< must< 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; + const bool result = parse< apply0< test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input<>( "", __FUNCTION__ ), state_b ); + TAO_PEGTL_TEST_ASSERT( !result ); + TAO_PEGTL_TEST_ASSERT( state_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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_at.cpp b/packages/PEGTL/src/test/pegtl/rule_at.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd4f5d63e2cb6e5612e12fa699de1d87d8e5e0da --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_at.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + int at_counter = 0; + + template< typename Rule > + struct at_action + : public nothing< Rule > + { + }; + + template<> + struct at_action< any > + { + template< typename Input > + static void apply( const Input& /*unused*/ ) + { + ++at_counter; + } + }; + + void unit_test() + { + TAO_PEGTL_TEST_ASSERT( at_counter == 0 ); + + 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 ); + 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 ); + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_bof.cpp b/packages/PEGTL/src/test/pegtl/rule_bof.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2fc690ad6ee2426a30666e3a2e82ba8c0a8b57b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_bof.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_bol.cpp b/packages/PEGTL/src/test/pegtl/rule_bol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0e14d8982734fd3d70a2afd827f250617c5e1b2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_bol.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_bytes.cpp b/packages/PEGTL/src/test/pegtl/rule_bytes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bd3d8515ca50e0e50334812985c1551178da373 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_bytes.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_control.cpp b/packages/PEGTL/src/test/pegtl/rule_control.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e70fa1faecfcd20c05b99024e876638c397aeb15 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_control.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename... Rules > + using test_control_rule = control< normal, Rules... >; + + void unit_test() + { + verify_seqs< test_control_rule >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_disable.cpp b/packages/PEGTL/src/test/pegtl/rule_disable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..638a423943a371bd730cf7fadbf50a02beea721b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_disable.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_seqs< disable >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_enable.cpp b/packages/PEGTL/src/test/pegtl/rule_enable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1eef732da74ff3967e88b22992f2a723c1383833 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_enable.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_seqs< enable >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_eof.cpp b/packages/PEGTL/src/test/pegtl/rule_eof.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e991870943faf2c1d7a703d61a708491a3f55ae --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_eof.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_failure.cpp b/packages/PEGTL/src/test/pegtl/rule_failure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..169ad72458812bd0a38aaaaa43f49fc2dd519833 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_failure.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_char.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_if_apply.cpp b/packages/PEGTL/src/test/pegtl/rule_if_apply.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef05b7ff31512ee57ea96573887bed4f6c7d3e02 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_if_apply.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2017-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace test1 + { + struct action_a + { + template< typename Input > + static void apply( const Input& 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 Input > + static void apply( const Input& in, std::string& r, std::string& s ) + { + TAO_PEGTL_TEST_ASSERT( s.empty() ); + s += in.string(); + s += "*"; + s += r; + } + }; + + struct action2_a + { + template< typename Input > + static void apply( const Input& in, bool& state_b ) + { + TAO_PEGTL_TEST_ASSERT( in.string() == "foo" ); + TAO_PEGTL_TEST_ASSERT( !state_b ); + } + }; + + struct action2_b + { + template< typename Input > + static bool apply( const Input& in, bool& state_b ) + { + TAO_PEGTL_TEST_ASSERT( in.string() == "foo" ); + TAO_PEGTL_TEST_ASSERT( !state_b ); + state_b = true; + return false; + } + }; + + struct action2_c + { + template< typename Input > + static void apply( const Input& /*unused*/, bool& /*unused*/ ) + { + TAO_PEGTL_TEST_ASSERT( false ); + } + }; + + template< typename Rule > + struct action : nothing< Rule > + { + }; + + 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__ ); + parse< must< 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__ ); + parse< must< 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; + const bool result = 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( !result ); + TAO_PEGTL_TEST_ASSERT( state_b ); + } + + { + bool state_b = false; + const bool result = parse< if_apply< plus< alpha >, test1::action2_a, test1::action2_b, test1::action2_c > >( memory_input<>( "", __FUNCTION__ ), state_b ); + TAO_PEGTL_TEST_ASSERT( !result ); + TAO_PEGTL_TEST_ASSERT( !state_b ); + } + + verify_seqs< if_apply_seq >(); + verify_seqs< if_apply_disable >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_if_must.cpp b/packages/PEGTL/src/test/pegtl/rule_if_must.cpp new file mode 100644 index 0000000000000000000000000000000000000000..797c4d63d051b88c81d3fe359e43ba293fa6f508 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_if_must.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_if_must_else.cpp b/packages/PEGTL/src/test/pegtl/rule_if_must_else.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d360bb6beb4fc2e619d92e8a120dadfe21fe47dd --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_if_must_else.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_ifmt< if_must_else >( result_type::GLOBAL_FAILURE ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_if_then_else.cpp b/packages/PEGTL/src/test/pegtl/rule_if_then_else.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29a2717b7db5fd991ace7addb93d1dce439a6f5b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_if_then_else.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_ifmt< if_then_else >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_list.cpp b/packages/PEGTL/src/test/pegtl/rule_list.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d423602dc5d56129385d3da237a92a2a7609579d --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_list.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_list_must.cpp b/packages/PEGTL/src/test/pegtl/rule_list_must.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1290d763cac0ee386e0ee34b8f7d5ca5cca5d01 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_list_must.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_list_tail.cpp b/packages/PEGTL/src/test/pegtl/rule_list_tail.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d44afb94581b6616b0651dc688b150fc844f4d04 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_list_tail.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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_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_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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_minus.cpp b/packages/PEGTL/src/test/pegtl/rule_minus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de8f5258d2be0ed3f08f3933a4952d03629ab521 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_minus.cpp @@ -0,0 +1,54 @@ +// Copyright (c) 2016-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 ); + + 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 ); + + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_must.cpp b/packages/PEGTL/src/test/pegtl/rule_must.cpp new file mode 100644 index 0000000000000000000000000000000000000000..60d793096482ef4eaaf9c34556a3203e3ca1c45f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_must.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_seqs< must >( result_type::GLOBAL_FAILURE ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_not_at.cpp b/packages/PEGTL/src/test/pegtl/rule_not_at.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74dbd86bd0fa9fedbc04a1aa8e38e674b3f1cdcc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_not_at.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + int at_counter = 0; + + template< typename Rule > + struct at_action + : public nothing< Rule > + { + }; + + template<> + struct at_action< alpha > + { + template< typename Input > + static void apply( const Input& /*unused*/ ) + { + ++at_counter; + } + }; + + void unit_test() + { + TAO_PEGTL_TEST_ASSERT( at_counter == 0 ); + + 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 ); + 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 ); + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_opt.cpp b/packages/PEGTL/src/test/pegtl/rule_opt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1fd4dc7b638d8857570b71f6a7840ddf03754f31 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_opt.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + struct my_action : nothing< Rule > + { + }; + + template<> + struct my_action< eof > + { + static void apply0( bool& b ) + { + b = true; + } + }; + + void unit_test() + { + 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 ); + + 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 ); + + bool success = false; + const bool result = parse< opt< eof >, my_action >( memory_input<>( "", __FUNCTION__ ), success ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( success ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_opt_must.cpp b/packages/PEGTL/src/test/pegtl/rule_opt_must.cpp new file mode 100644 index 0000000000000000000000000000000000000000..279e40804a1eec1ebe6bd67aca1862c15c9b9e76 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_opt_must.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_pad.cpp b/packages/PEGTL/src/test/pegtl/rule_pad.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67c3cdc92859473c4da7e594d04ff0b00ff1c5a5 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_pad.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_pad_opt.cpp b/packages/PEGTL/src/test/pegtl/rule_pad_opt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..198d0f3ed258aff576f3d0c155826ce15ea80642 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_pad_opt.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_plus.cpp b/packages/PEGTL/src/test/pegtl/rule_plus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..113f2739a5a8de0abe8c2ae93e5db88855ed04de --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_plus.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_rep.cpp b/packages/PEGTL/src/test/pegtl/rule_rep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa76d0ca552e1cb7d8cda9b60be6f05cf149f338 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_rep.cpp @@ -0,0 +1,78 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 ); + + 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 ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_rep_max.cpp b/packages/PEGTL/src/test/pegtl/rule_rep_max.cpp new file mode 100644 index 0000000000000000000000000000000000000000..30d19ae6c13bbd283601c3e6d39ccbf63ce9669a --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_rep_max.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_rep_min.cpp b/packages/PEGTL/src/test/pegtl/rule_rep_min.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0db1afde31783a7c96abb3dec89c2e0cf636e025 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_rep_min.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp b/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp new file mode 100644 index 0000000000000000000000000000000000000000..446cd6cd8a9fc7a09320199afb188f03024d149e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_rep_min_max.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 ); + + 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 ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_rep_opt.cpp b/packages/PEGTL/src/test/pegtl/rule_rep_opt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..56764e0729bc050b6f9d5bca6c979dc7791eb732 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_rep_opt.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_require.cpp b/packages/PEGTL/src/test/pegtl/rule_require.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f020edd3fb09eac1c2aa02120327eb2c73724e8e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_require.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_seq.cpp b/packages/PEGTL/src/test/pegtl/rule_seq.cpp new file mode 100644 index 0000000000000000000000000000000000000000..405ba67982dc1fc1570d0fefa8b9bc12fcbca424 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_seq.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + verify_seqs< seq >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_sor.cpp b/packages/PEGTL/src/test/pegtl/rule_sor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d14c20b0c30b79cff1cb3cb1b61ea72931a33d2b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_sor.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_star.cpp b/packages/PEGTL/src/test/pegtl/rule_star.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4bf89e78faf8bb2c428608fe5b4481abb0a334d4 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_star.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_star_must.cpp b/packages/PEGTL/src/test/pegtl/rule_star_must.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed72bb6dc731682f685d80ec1f2046c268494e7b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_star_must.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_state.cpp b/packages/PEGTL/src/test/pegtl/rule_state.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2db82feb26213d5e878177e6f83b8b9b26f3dca0 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_state.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2014-2018 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 +{ + namespace TAO_PEGTL_NAMESPACE + { + struct test_state_state + { + template< typename Input > + explicit test_state_state( const Input& /*unused*/ ) + { + } + + template< typename Input > + void success( const Input& /*unused*/ ) const + { + } + }; + + struct test_state_with_template_parameters_state + { + template< typename Input > + explicit test_state_with_template_parameters_state( const Input& /*unused*/ ) + { + } + + template< apply_mode, + rewind_mode, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + void success( const Input& /*unused*/ ) const + { + } + }; + + template< typename... Rules > + using test_state_rule = state< test_state_state, Rules... >; + + template< typename... Rules > + using test_state_with_template_parameters_rule = state< test_state_with_template_parameters_state, Rules... >; + + void unit_test() + { + verify_seqs< test_state_rule >(); + verify_seqs< test_state_with_template_parameters_rule >(); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_success.cpp b/packages/PEGTL/src/test/pegtl/rule_success.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d927f708ea45ce67b8679ea7c5f2acb6d1433717 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_success.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + void unit_test() + { + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_try_catch.cpp b/packages/PEGTL/src/test/pegtl/rule_try_catch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f6fbc4ff8744c6663282aea4f8b740a7a64ed10 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_try_catch.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2014-2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/rule_until.cpp b/packages/PEGTL/src/test/pegtl/rule_until.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ade660ac4826a53f220b70951033375e037da7c2 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/rule_until.cpp @@ -0,0 +1,120 @@ +// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey +// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ + +#include "test.hpp" +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + struct my_rule + { + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input > + static bool match( Input& /*unused*/, bool& v ) + { + return v; + } + }; + + template< typename Rule > + struct my_action : nothing< Rule > + { + }; + + 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 ); + + verify_rule< must< until< one< 'a' > > > >( __LINE__, __FILE__, "bbb", result_type::GLOBAL_FAILURE, 0 ); + + verify_rule< try_catch< must< until< one< 'a' > > > > >( __LINE__, __FILE__, "bbb", result_type::LOCAL_FAILURE, 3 ); + + verify_rule< 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 ); + + 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 ); + + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/test.hpp b/packages/PEGTL/src/test/pegtl/test.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6094d02af525ee9f6787cd54ddae9e1fbbbdc6cc --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/test.hpp @@ -0,0 +1,113 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_TEST_HPP + +#include <cstddef> +#include <iostream> +#include <string> +#include <utility> +#include <vector> + +#include <tao/pegtl.hpp> + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + std::size_t failed = 0; // NOLINT + std::vector< std::pair< std::string, std::string > > applied; // NOLINT + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#define TAO_PEGTL_TEST_UNWRAP( ... ) __VA_ARGS__ + +#define TAO_PEGTL_TEST_FAILED( MeSSaGe ) \ + do { \ + std::cerr << "pegtl: unit test failed for [ " \ + << internal::demangle< Rule >() \ + << " ] " \ + << TAO_PEGTL_TEST_UNWRAP( MeSSaGe ) \ + << " in line [ " \ + << line \ + << " ] file [ " \ + << file << " ]" \ + << std::endl; \ + ++failed; \ + } while( false ) + +#define TAO_PEGTL_TEST_ASSERT( eXPReSSioN ) \ + do { \ + if( !( eXPReSSioN ) ) { \ + std::cerr << "pegtl: unit test assert [ " \ + << ( #eXPReSSioN ) \ + << " ] failed in line [ " \ + << __LINE__ \ + << " ] file [ " \ + << __FILE__ << " ]" \ + << std::endl; \ + ++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; \ + ++failed; \ + } \ + catch( ... ) { \ + } \ + } while( false ) + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< unsigned Size, apply_mode B, rewind_mode N, typename... Rules > + struct test_rule + { + using analyze_t = typename seq< Rules... >::analyze_t; + + template< apply_mode A, + rewind_mode M, + template< typename... > class Action, + template< typename... > class Control, + typename Input, + typename... States > + static bool match( Input& 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... ); + } + }; + + template< typename Rule > + struct test_action + { + template< typename Input > + static void apply( const Input& in ) + { + applied.push_back( std::make_pair( internal::demangle< Rule >(), in.string() ) ); + } + }; + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/tester.cpp b/packages/PEGTL/src/test/pegtl/tester.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d8ffbf7cd852f972fcee1ea3960c27fa6203409 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/tester.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2018 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 + +#ifdef __cplusplus + std::cout << "__cplusplus: " << __cplusplus << std::endl; +#endif +#ifdef __cpp_constexpr + std::cout << "__cpp_constexpr: " << __cpp_constexpr << std::endl; +#endif +#ifdef __cpp_variadic_templates + std::cout << "__cpp_variadic_templates: " << __cpp_variadic_templates << std::endl; +#endif +#ifdef __cpp_variable_templates + std::cout << "__cpp_variable_templates: " << __cpp_variable_templates << std::endl; +#endif +#ifdef __cpp_fold_expressions + std::cout << "__cpp_fold_expressions: " << __cpp_fold_expressions << std::endl; +#endif +#ifdef __cpp_deduction_guides + std::cout << "__cpp_deduction_guides: " << __cpp_deduction_guides << std::endl; +#endif +#ifdef __cpp_lib_integer_sequence + std::cout << "__cpp_lib_integer_sequence: " << __cpp_lib_integer_sequence << std::endl; +#endif +} diff --git a/packages/PEGTL/src/test/pegtl/uint16_general.cpp b/packages/PEGTL/src/test/pegtl/uint16_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e1fbd88b9b41d644c07911dbf98fcf49f9dc955 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/uint16_general.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/uint32_general.cpp b/packages/PEGTL/src/test/pegtl/uint32_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c4c6f3ce20c14250ec3d5553de17d1c7b55172f --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/uint32_general.cpp @@ -0,0 +1,183 @@ +// Copyright (c) 2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/uint64_general.cpp b/packages/PEGTL/src/test/pegtl/uint64_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc0eb0d63fff1d211766e3ab8fa7b5181035aefb --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/uint64_general.cpp @@ -0,0 +1,187 @@ +// Copyright (c) 2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/uint8_general.cpp b/packages/PEGTL/src/test/pegtl/uint8_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1642686fc1bfa2ccf350478dd4574bb12e6adae --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/uint8_general.cpp @@ -0,0 +1,251 @@ +// Copyright (c) 2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/utf16_general.cpp b/packages/PEGTL/src/test/pegtl/utf16_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..38eb6a18ee018b4c75c63c56087669578c1eae3e --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/utf16_general.cpp @@ -0,0 +1,157 @@ +// Copyright (c) 2015-2018 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" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace + { + std::string u16s( const char16_t u ) + { + return std::string( static_cast< const char* >( static_cast< const void* >( &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( static_cast< const char* >( static_cast< const void* >( &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( static_cast< const char* >( static_cast< const void* >( &u ) ), sizeof( u ) ); + } + + } // namespace + + void test_utf16() + { + verify_rule< utf16::any >( __LINE__, __FILE__, "", result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, "\x01", result_type::LOCAL_FAILURE, 1 ); + verify_rule< utf16::any >( __LINE__, __FILE__, "\xff", result_type::LOCAL_FAILURE, 1 ); + + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 1 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, " ", result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x00ff ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0100 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x0fff ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0x1000 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd900 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xde00 ), result_type::LOCAL_FAILURE, 0 ); + 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, 4 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0x0020 ), result_type::LOCAL_FAILURE, 4 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xff20 ), result_type::LOCAL_FAILURE, 4 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdf00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xd800 ) + u16s( 0xdfff ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdc00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::any >( __LINE__, __FILE__, u16s( 0xdbff ) + u16s( 0xdfff ), result_type::SUCCESS, 0 ); + + verify_rule< utf16::one< 0x20 > >( __LINE__, __FILE__, u16s( 0x20 ), result_type::SUCCESS, 0 ); + verify_rule< utf16::one< 0x20ac > >( __LINE__, __FILE__, u16s( 0x20ac ), result_type::SUCCESS, 0 ); + verify_rule< utf16::one< 0x10437 > >( __LINE__, __FILE__, u16s( 0xd801 ) + u16s( 0xdc37 ), result_type::SUCCESS, 0 ); + + verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfeff ), result_type::SUCCESS, 0 ); + verify_rule< utf16::bom >( __LINE__, __FILE__, u16s( 0xfffe ), result_type::LOCAL_FAILURE, 2 ); + + 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, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, "\x01", result_type::LOCAL_FAILURE, 1 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, "\xff", result_type::LOCAL_FAILURE, 1 ); + + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 1 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, " ", result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x00ff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0100 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x0fff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0x1000 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd900 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xde00 ), result_type::LOCAL_FAILURE, 0 ); + 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, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0x0020 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xff20 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdf00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xd800 ) + u16s_be( 0xdfff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdc00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::any >( __LINE__, __FILE__, u16s_be( 0xdbff ) + u16s_be( 0xdfff ), result_type::SUCCESS, 0 ); + + verify_rule< utf16_be::one< 0x20 > >( __LINE__, __FILE__, u16s_be( 0x20 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::one< 0x20ac > >( __LINE__, __FILE__, u16s_be( 0x20ac ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::one< 0x10437 > >( __LINE__, __FILE__, u16s_be( 0xd801 ) + u16s_be( 0xdc37 ), result_type::SUCCESS, 0 ); + + verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfeff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_be::bom >( __LINE__, __FILE__, u16s_be( 0xfffe ), result_type::LOCAL_FAILURE, 2 ); + + 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, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, "\x01", result_type::LOCAL_FAILURE, 1 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, "\xff", result_type::LOCAL_FAILURE, 1 ); + + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 1 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, " ", result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x00ff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0100 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x0fff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0x1000 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd900 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xde00 ), result_type::LOCAL_FAILURE, 0 ); + 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, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0x0020 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xff20 ), result_type::LOCAL_FAILURE, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdf00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xd800 ) + u16s_le( 0xdfff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdc00 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::any >( __LINE__, __FILE__, u16s_le( 0xdbff ) + u16s_le( 0xdfff ), result_type::SUCCESS, 0 ); + + verify_rule< utf16_le::one< 0x20 > >( __LINE__, __FILE__, u16s_le( 0x20 ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::one< 0x20ac > >( __LINE__, __FILE__, u16s_le( 0x20ac ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::one< 0x10437 > >( __LINE__, __FILE__, u16s_le( 0xd801 ) + u16s_le( 0xdc37 ), result_type::SUCCESS, 0 ); + + verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfeff ), result_type::SUCCESS, 0 ); + verify_rule< utf16_le::bom >( __LINE__, __FILE__, u16s_le( 0xfffe ), result_type::LOCAL_FAILURE, 2 ); + + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/utf32_general.cpp b/packages/PEGTL/src/test/pegtl/utf32_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9fc058a915f8782bbdce05e4c04eedad9eab45c --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/utf32_general.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2014-2018 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" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + namespace + { + std::string u32s( const char32_t u ) + { + return std::string( static_cast< const char* >( static_cast< const void* >( &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( static_cast< const char* >( static_cast< const void* >( &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( static_cast< const char* >( static_cast< const void* >( &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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/utf8_general.cpp b/packages/PEGTL/src/test/pegtl/utf8_general.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d3267e231667cfee36bcc69879e58f9b8bdc9f6 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/utf8_general.cpp @@ -0,0 +1,267 @@ +// Copyright (c) 2014-2018 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 +{ + 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 + +} // namespace tao + +#include "main.hpp" diff --git a/packages/PEGTL/src/test/pegtl/verify_analyze.hpp b/packages/PEGTL/src/test/pegtl/verify_analyze.hpp new file mode 100644 index 0000000000000000000000000000000000000000..703ce0bba6538bac2e764f543442e14bb299b8d7 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_analyze.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2014-2018 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_ANALYZE_HPP // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_ANALYZE_HPP + +#include <tao/pegtl/analyze.hpp> + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + void verify_analyze( const unsigned line, const char* file, const bool expect_consume, const bool expect_problems ) + { + analysis::analyze_cycles< Rule > a( false ); + + const bool has_problems = ( a.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 << " ]" ); + } + if( does_consume != expect_consume ) { + TAO_PEGTL_TEST_FAILED( "analyze -- consumes received/expected [ " << does_consume << " / " << expect_consume << " ]" ); + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_char.hpp b/packages/PEGTL/src/test/pegtl/verify_char.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e8159107627249191641c4e72ba4a5c6476b6b26 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_char.hpp @@ -0,0 +1,33 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_CHAR_HPP + +#include <cstdlib> +#include <string> + +#include "result_type.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_fail.hpp b/packages/PEGTL/src/test/pegtl/verify_fail.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a843b7e6fa836fa46c9ace2b9994cf4dba2fcd51 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_fail.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2015-2018 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_FAIL_HPP // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_FAIL_HPP + +#include <cstddef> +#include <string> + +#include <tao/pegtl/memory_input.hpp> +#include <tao/pegtl/nothing.hpp> +#include <tao/pegtl/parse.hpp> + +#include "test.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule, template< typename > class Action = nothing, typename... States > + void verify_fail( const std::size_t line, const char* file, const std::string& s, States&&... st ) + { + try { + memory_input<> in( s, "expect exception" ); + parse< Rule, Action >( in, st... ); + TAO_PEGTL_TEST_FAILED( "expected exception" ); + } + catch( ... ) { + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_file.hpp b/packages/PEGTL/src/test/pegtl/verify_file.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ad581503c6987754bf0cdf5d71f4a953ebef6690 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_file.hpp @@ -0,0 +1,159 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_FILE_HPP + +#include <tao/pegtl.hpp> + +#include "test.hpp" + +namespace tao +{ + 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 + : nothing< Rule > + { + }; + + 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 Input > + static void success( const Input& /*unused*/, bool& flag ) + { + flag = true; + } + }; + + template< typename T > + void verify_file() + { + { + const std::string f{ "src/test/pegtl/no_such_file.txt" }; + try { + T in( f ); + parse< file_grammar >( in ); + TAO_PEGTL_TEST_ASSERT( !"no error on opening non-existing file" ); + } + catch( const input_error& ) { + } + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + std::cout << in.source() << std::endl; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in ) ); + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = true; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in, flag ) ); + TAO_PEGTL_TEST_ASSERT( flag == true ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse< file_grammar >( in, flag ) ); + TAO_PEGTL_TEST_ASSERT( flag == false ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + const bool result = parse< file_grammar, file_action >( in, flag ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( flag == true ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + 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 ); + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in ) ); + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = true; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in, flag ) ); + TAO_PEGTL_TEST_ASSERT( flag == true ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + TAO_PEGTL_TEST_ASSERT( parse_nested< file_grammar >( m, in, flag ) ); + TAO_PEGTL_TEST_ASSERT( flag == false ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + const bool result = parse_nested< file_grammar, file_action >( m, in, flag ); + TAO_PEGTL_TEST_ASSERT( result ); + TAO_PEGTL_TEST_ASSERT( flag == true ); + } + { + const std::string f{ "src/test/pegtl/file_data.txt" }; + T in( f ); + bool flag = false; + TAO_PEGTL_TEST_ASSERT( in.source() == f ); + 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 + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_ifmt.hpp b/packages/PEGTL/src/test/pegtl/verify_ifmt.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4b7c265d5d14f0e9525c0a07555a54edabbaed4b --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_ifmt.hpp @@ -0,0 +1,47 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_IFMT_HPP + +#include <tao/pegtl.hpp> + +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 ); + + 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 ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_impl.hpp b/packages/PEGTL/src/test/pegtl/verify_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..255fbe61ea417c4dbd229ca02c0f48e02de14822 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_impl.hpp @@ -0,0 +1,56 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#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 +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule, template< typename... > class Action, typename Input > + result_type verify_impl_two( Input& in ) + { + 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; + } + catch( ... ) { + std::cerr << "Code should be unreachable in " << __FUNCTION__ << " (" << __FILE__ << ':' << __LINE__ << ')' << std::endl; + std::abort(); + } + } + + template< typename Rule, template< typename... > class Action, typename Input > + void verify_impl_one( const std::size_t line, const char* file, const std::string& data, Input& 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 << " ]" ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_rule.hpp b/packages/PEGTL/src/test/pegtl/verify_rule.hpp new file mode 100644 index 0000000000000000000000000000000000000000..522cc2a75d094254dbc40214e57d25fcf05c8784 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_rule.hpp @@ -0,0 +1,84 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#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 "result_type.hpp" +#include "verify_impl.hpp" + +namespace tao +{ + namespace TAO_PEGTL_NAMESPACE + { + template< typename Rule > + struct verify_action_impl + { + template< typename Input, typename... States > + static void apply( const Input& /*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, std::size_t remain = 0 ) + { + remain = ( expected == result_type::SUCCESS ) ? remain : data.size(); + { + memory_input< tracking_mode::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + 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::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + 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::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + 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::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + verify_impl_one< Rule, nothing >( line, file, data, in, expected, remain ); + } + { + memory_input< tracking_mode::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + verify_impl_one< Rule, verify_action_impl >( line, file, data, in, expected, remain ); + } + { + memory_input< tracking_mode::IMMEDIATE, Eol > in( data.data(), data.data() + data.size(), file, 0, line, 0 ); + verify_impl_one< Rule, verify_action_impl0 >( line, file, data, in, expected, remain ); + } + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/packages/PEGTL/src/test/pegtl/verify_seqs.hpp b/packages/PEGTL/src/test/pegtl/verify_seqs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..70b7e39c3c07cdfcd4a6fdda7c775df28cfa0b65 --- /dev/null +++ b/packages/PEGTL/src/test/pegtl/verify_seqs.hpp @@ -0,0 +1,71 @@ +// Copyright (c) 2014-2018 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 // NOLINT +#define TAO_PEGTL_SRC_TEST_PEGTL_VERIFY_SEQS_HPP + +#include <tao/pegtl.hpp> + +#include "verify_analyze.hpp" +#include "verify_rule.hpp" + +namespace tao +{ + 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 ); + + 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 ); + } + + } // namespace TAO_PEGTL_NAMESPACE + +} // namespace tao + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebf2a69d275051fcd7e0bdfd6a0a0718ae8e37ea..2c8b15598515bd6049bb81dffd6122a752c953de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_subdirectory(utils) include_directories(utils) +# Pastis language +add_subdirectory(language) +include_directories(language) + # Pastis algebra #add_subdirectory(algebra) include_directories(algebra) diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..31b2bb1bc08fc66071514385b52fbddfb3e271ea --- /dev/null +++ b/src/language/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# ------------------- Source files -------------------- + +add_library( + PastisLanguage + PastisParser.cpp) + +#include_directories(${PASTIS_SOURCE_DIR}/utils) + +# Additional dependencies +#add_dependencies(PastisMesh) diff --git a/src/language/PastisParser.cpp b/src/language/PastisParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5805839c7b01e050019320b83e1a09d7619adc8c --- /dev/null +++ b/src/language/PastisParser.cpp @@ -0,0 +1,158 @@ +#include <PastisParser.hpp> +#include <iostream> + +#include <rang.hpp> + +#define TAO_PEGTL_NAMESPACE language +#include <pegtl.hpp> +#include <pegtl/analyze.hpp> + +namespace language +{ +using namespace tao::language; + +// clang-format off + +struct comment + : sor< if_must< + string< '/', '/' >, + until< eolf > + >, + if_must< + string< '/', '*' >, + until< string< '*', '/' > > + > + > {}; + +struct ignored + : star< sor< space, comment> >{}; + +// struct ignored : star< space >{}; + +struct integer + : seq< opt< one< '+', '-' > >, plus< digit > >{}; +struct INTEGER : seq< integer, ignored >{}; + +struct real + : seq< opt< one< '+', + '-' > + >, + sor< seq< + plus< digit >, + one < '.' >, + star< digit > + >, + seq< + one < '.' >, + plus< digit > + > + >, + opt< + seq< + one< 'E', + 'e' >, + opt< one< '+', + '-' > + >, + plus<digit> + > + > + >{}; + +struct REAL : seq< real, ignored >{}; + +struct expression : sor< REAL, INTEGER > {}; + +struct semicol : one< ';' >{}; +struct SEMICOL : seq< semicol , ignored > {}; + +struct instruction + : sor<seq< expression , SEMICOL>, + SEMICOL> +{}; + +struct grammar + : must<ignored, star<instruction>,eof>{}; +// clang-format on + +template< typename Rule > +struct action : nothing< Rule > {}; + +template<> +struct action< integer > +{ + template< typename Input > + static void apply( const Input& in, std::string& v ) + { + if (v.size() > 0) { + v += std::string(", I:") + in.string(); + } else { + v = std::string("I:") + in.string(); + } + } +}; + +template<> +struct action< real > +{ + template< typename Input > + static void apply( const Input& in, std::string& v ) + { + if (v.size() > 0) { + v += std::string(", R:") + in.string(); + } else { + v = std::string("R:") + in.string(); + } + } +}; + + +template< typename Rule > +struct errors + : public normal< Rule > +{ + static const std::string error_message; + + template< typename Input, typename... States > + static void raise( const Input& in, States&&... /*unused*/ ) + { + throw parse_error(error_message, std::vector{in.position()} ); + } +}; + +template <typename Rule> +const std::string errors<Rule>::error_message = "parse error..."; + +template <> +const std::string errors<eolf>::error_message = "parse error expecting expression"; + +} + +void parser(const std::string& filename) { + std::string name; + + const size_t grammar_issues = language::analyze< language::grammar >(); + + std::cout << "grammar_issues=" << grammar_issues << '\n'; + language::read_input in(filename); + try { + language::parse< language::grammar, language::action//, language::errors + >( in, name ); + } + catch(const language::parse_error& e) { + const auto p = e.positions.front(); + std::cerr << rang::style::bold + << p.source << ':' << p.line << ':' << p.byte_in_line<< ": " + << rang::style::reset + << rang::fgB::red << "error: " << rang::fg::reset + << rang::style::bold << e.what() << rang::style::reset << '\n' + << in.line_as_string( p ) << '\n' + << std::string( p.byte_in_line, ' ' ) + << rang::fgB::yellow << '^' << rang::fg::reset + << std::endl; + std::exit(1); + } + + std::cout << "Good bye, " << name << "!" << std::endl; + std::exit(0); +} diff --git a/src/language/PastisParser.hpp b/src/language/PastisParser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e746e608c383b055cab5981fd974665ca36e791a --- /dev/null +++ b/src/language/PastisParser.hpp @@ -0,0 +1,8 @@ +#ifndef PASTIS_PARSER_HPP +#define PASTIS_PARSER_HPP + +#include <string> + +void parser(const std::string& filename); + +#endif // PASTIS_PARSER_HPP diff --git a/src/main.cpp b/src/main.cpp index 951eddd4362b509cb2eadde3f97b470895473163..6620cf4c68e3fdd41ec11b665a363d17ef20f9f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,15 +21,24 @@ #include <MeshNodeBoundary.hpp> #include <GmshReader.hpp> +#include <PastisParser.hpp> #include <SynchronizerManager.hpp> #include <limits> #include <map> +#include <regex> int main(int argc, char *argv[]) { std::string filename = initialize(argc, argv); + + std::regex gmsh_regex("(.*).msh"); + if (not std::regex_match(filename, gmsh_regex)) { + parser(filename); + return 0; + } + std::map<std::string, double> method_cost_map; SynchronizerManager::create();