Skip to content

Commit b838200

Browse files
committed
Migrate to percy::variant
1 parent 2b91eaf commit b838200

25 files changed

+202
-854
lines changed

CMakeLists.txt

+68-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,73 @@
11
cmake_minimum_required(VERSION 3.15)
22

3-
project(percy)
3+
project(Percy)
44

55
set(CMAKE_CXX_STANDARD 20)
66

7-
add_subdirectory(example)
8-
add_subdirectory(tests)
7+
add_library(Percy INTERFACE)
8+
9+
option(PERCY_BUILD_EXAMPLE "Build example project build with Percy." OFF)
10+
option(PERCY_BUILD_TESTS "Build tests of Percy." OFF)
11+
option(PERCY_RUNTIME_TESTS "Evaluate tests of Percy at run-time instead of compile-time." OFF)
12+
13+
include(cmake/PercyVariant.cmake)
14+
15+
target_link_libraries(Percy INTERFACE Percy::Variant)
16+
17+
target_include_directories(
18+
Percy
19+
INTERFACE
20+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
21+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
22+
)
23+
24+
set(PERCY_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Percy")
25+
26+
include(CMakePackageConfigHelpers)
27+
28+
configure_package_config_file(
29+
${CMAKE_CURRENT_LIST_DIR}/cmake/PercyConfig.cmake.in
30+
${CMAKE_CURRENT_BINARY_DIR}/PercyConfig.cmake
31+
INSTALL_DESTINATION
32+
${PERCY_CMAKE_CONFIG_DESTINATION}
33+
)
34+
35+
install(
36+
TARGETS
37+
Percy
38+
EXPORT
39+
PercyTargets
40+
DESTINATION
41+
${CMAKE_INSTALL_LIBDIR}
42+
)
43+
44+
install(
45+
EXPORT
46+
PercyTargets
47+
NAMESPACE
48+
Percy::
49+
DESTINATION
50+
${PERCY_CMAKE_CONFIG_DESTINATION}
51+
)
52+
53+
install(
54+
DIRECTORY
55+
"include/"
56+
DESTINATION
57+
"${CMAKE_INSTALL_INCLUDEDIR}"
58+
)
59+
60+
install(
61+
FILES
62+
"${CMAKE_CURRENT_BINARY_DIR}/PercyConfig.cmake"
63+
DESTINATION
64+
${PERCY_CMAKE_CONFIG_DESTINATION}
65+
)
66+
67+
if(${PERCY_BUILD_EXAMPLE} STREQUAL ON)
68+
add_subdirectory(example)
69+
endif()
70+
71+
if(${PERCY_BUILD_TESTS} STREQUAL ON)
72+
add_subdirectory(tests)
73+
endif()

LICENSE.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Jan Svoboda
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Percy
2+
3+
Percy is an ergonomic parser combinator library written in `constexpr` C++20.
4+
5+
## TODO
6+
7+
- [ ] Mark tests in `test_all.cpp` and the example as `constexpr` when possible.
8+
- [ ] Properly manage memory in the example.

cmake/Catch2.cmake

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include(FetchContent)
2+
3+
FetchContent_Declare(Catch2
4+
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
5+
GIT_TAG v2.11.3
6+
)
7+
8+
FetchContent_MakeAvailable(Catch2)

cmake/PercyConfig.cmake.in

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@PACKAGE_INIT@
2+
3+
include(${CMAKE_CURRENT_LIST_DIR}/PercyTargets.cmake)

example/CMakeLists.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
include_directories(${percy_SOURCE_DIR}/include/ include/)
2-
31
file(READ input.txt CODE)
42

53
add_definitions(-DINPUT_CODE="${CODE}")
64

5+
include_directories(include/)
6+
77
add_executable(example src/example.cpp)
8+
9+
target_link_libraries(example Percy)

example/include/example/ast.hpp

+9-22
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,34 @@
11
#ifndef PERCY_EXAMPLE_AST
22
#define PERCY_EXAMPLE_AST
33

4-
#include <variant>
5-
6-
#include <cstdint>
4+
#include <percy/variant.hpp>
75

86
namespace example::ast {
97
struct expr;
108

119
struct literal {
12-
constexpr explicit literal(std::uint8_t val) : val(val) {}
13-
std::uint8_t val;
10+
constexpr explicit literal(char value) : value_(value) {}
11+
char value_;
1412
};
1513

1614
struct variable {
17-
constexpr explicit variable(char name) : name(name) {}
18-
char name;
15+
constexpr explicit variable(char name) : name_(name) {}
16+
char name_;
1917
};
2018

2119
struct call {
2220
constexpr explicit call(char name, const expr* arg1, const expr* arg2) : name_(name), arg1_(arg1), arg2_(arg2) {}
2321
char name_;
2422
const expr* arg1_;
2523
const expr* arg2_;
26-
constexpr ~call();
2724
};
2825

2926
struct expr {
30-
constexpr explicit expr(literal value) : value(value) {}
31-
constexpr explicit expr(variable value) : value(value) {}
32-
constexpr explicit expr(call value) : value(value) {}
33-
std::variant<literal, variable, call> value;
27+
constexpr explicit expr(literal l) : value_(l) {}
28+
constexpr explicit expr(variable v) : value_(v) {}
29+
constexpr explicit expr(call c) : value_(c) {}
30+
percy::variant<literal, variable, call> value_;
3431
};
35-
36-
constexpr call::~call() {
37-
if (arg1_) {
38-
delete arg1_;
39-
}
40-
41-
if (arg2_) {
42-
delete arg2_;
43-
}
44-
}
4532
} // namespace example::ast
4633

4734
#endif

example/include/example/grammar.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ struct call {
3737
struct expr {
3838
using rule = percy::one_of<call, literal, variable>;
3939

40-
constexpr static auto action(percy::result<std::variant<ast::call, ast::literal, ast::variable>> parsed) {
41-
return std::visit([](auto item) { return new ast::expr(item); }, parsed.get());
40+
constexpr static auto action(percy::result<percy::variant<ast::call, ast::literal, ast::variable>> parsed) {
41+
return percy::visit([](auto item) { return new ast::expr(item); }, parsed.get());
4242
}
4343
};
4444

example/src/example.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
int main() {
66
using parser = percy::parser<example::grammar::grammar>;
77

8-
constexpr auto exit_code = [](){
8+
auto exit_code = [](){
99
auto input = percy::static_input(INPUT_CODE);
1010
auto result = parser::parse(input);
11-
delete result.get();
1211
return result.is_success() ? 0 : 1;
1312
}();
1413

include/percy.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66
#include "percy/rules.hpp"
77
#include "percy/static_input.hpp"
88
#include "percy/type_traits.hpp"
9-
#include "percy/variant.hpp"
109

1110
#endif

include/percy/parser.hpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
#include "result.hpp"
55
#include "rules.hpp"
66

7+
#include <percy/variant.hpp>
8+
79
#include <string_view>
810
#include <tuple>
9-
#include <variant>
1011
#include <vector>
1112

1213
namespace percy {
@@ -178,7 +179,7 @@ struct parser<either<Rule, AlternativeRule, AlternativeRules...>> {
178179

179180
template <typename Rule>
180181
struct parser<one_of<Rule>> {
181-
using result_type = result<std::variant<result_value_t<parser_result_t<Rule>>>>;
182+
using result_type = result<percy::variant<result_value_t<parser_result_t<Rule>>>>;
182183

183184
template <typename Input>
184185
constexpr static result_type parse(Input input) {
@@ -197,17 +198,17 @@ struct parser<one_of<Rule>> {
197198
template <typename Rule, typename AlternativeRule, typename... AlternativeRules>
198199
struct parser<one_of<Rule, AlternativeRule, AlternativeRules...>> {
199200
// clang-format off
200-
using result_type = result<std::variant<result_value_t<parser_result_t<Rule>>,
201-
result_value_t<parser_result_t<AlternativeRule>>,
202-
result_value_t<parser_result_t<AlternativeRules>>...>>;
201+
using result_type = result<percy::variant<result_value_t<parser_result_t<Rule>>,
202+
result_value_t<parser_result_t<AlternativeRule>>,
203+
result_value_t<parser_result_t<AlternativeRules>>...>>;
203204
// clang-format on
204205

205206
template <typename Input>
206207
constexpr static result_type parse(Input input) {
207208
using variant_type = result_value_t<result_type>;
208209

209210
auto cast_variant = [](auto small_variant) {
210-
return std::visit([](auto item) { return variant_type(item); }, small_variant);
211+
return percy::visit([](auto item) { return variant_type(item); }, small_variant);
211212
};
212213

213214
auto result = parser<one_of<Rule>>::parse(input);

include/percy/result.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef PERCY_RESULT
22
#define PERCY_RESULT
33

4-
#include <variant>
4+
#include <percy/variant.hpp>
55

66
namespace percy {
77
class input_span {
@@ -35,7 +35,7 @@ class error {};
3535

3636
template <typename T>
3737
class result {
38-
std::variant<T, error> value_;
38+
percy::variant<T, error> value_;
3939
input_span span_;
4040

4141
template <typename U>
@@ -51,11 +51,11 @@ class result {
5151
constexpr result(const failure& fail) : value_(error()), span_(fail.span()) {}
5252

5353
constexpr bool is_success() const {
54-
return std::holds_alternative<T>(value_);
54+
return percy::holds_alternative<T>(value_);
5555
}
5656

5757
constexpr bool is_failure() const {
58-
return std::holds_alternative<error>(value_);
58+
return percy::holds_alternative<error>(value_);
5959
}
6060

6161
constexpr operator bool() const {
@@ -75,7 +75,7 @@ class result {
7575
}
7676

7777
constexpr auto get() const {
78-
return std::get<T>(value_);
78+
return percy::get<T>(value_);
7979
}
8080
};
8181

include/percy/type_traits.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ struct contains<U, T, Ts...> {
9696

9797
/// Determines whether the list `Ts...` contains the type `U`.
9898
template <typename U, typename... Ts>
99-
constexpr inline bool contains_v = contains<U, Ts...>::value;
99+
constexpr inline bool has_same_v = contains<U, Ts...>::value;
100100

101101
template <std::size_t N, typename... Ts>
102102
struct nth;

0 commit comments

Comments
 (0)