Skip to content

Commit 7789001

Browse files
author
Jan Svoboda
committed
Initial commit
0 parents  commit 7789001

14 files changed

+906
-0
lines changed

.clang-format

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
Language: Cpp
3+
# BasedOnStyle: LLVM
4+
AccessModifierOffset: -2
5+
AlignAfterOpenBracket: Align
6+
AlignConsecutiveMacros: false
7+
AlignConsecutiveAssignments: false
8+
AlignConsecutiveDeclarations: false
9+
AlignEscapedNewlines: Right
10+
AlignOperands: true
11+
AlignTrailingComments: true
12+
AllowAllArgumentsOnNextLine: true
13+
AllowAllConstructorInitializersOnNextLine: true
14+
AllowAllParametersOfDeclarationOnNextLine: true
15+
AllowShortBlocksOnASingleLine: false
16+
AllowShortCaseLabelsOnASingleLine: false
17+
AllowShortFunctionsOnASingleLine: All
18+
AllowShortLambdasOnASingleLine: All
19+
AllowShortIfStatementsOnASingleLine: Never
20+
AllowShortLoopsOnASingleLine: false
21+
AlwaysBreakAfterDefinitionReturnType: None
22+
AlwaysBreakAfterReturnType: None
23+
AlwaysBreakBeforeMultilineStrings: false
24+
AlwaysBreakTemplateDeclarations: MultiLine
25+
BinPackArguments: true
26+
BinPackParameters: true
27+
BraceWrapping:
28+
AfterCaseLabel: false
29+
AfterClass: false
30+
AfterControlStatement: false
31+
AfterEnum: false
32+
AfterFunction: false
33+
AfterNamespace: false
34+
AfterObjCDeclaration: false
35+
AfterStruct: false
36+
AfterUnion: false
37+
AfterExternBlock: false
38+
BeforeCatch: false
39+
BeforeElse: false
40+
IndentBraces: false
41+
SplitEmptyFunction: true
42+
SplitEmptyRecord: true
43+
SplitEmptyNamespace: true
44+
BreakBeforeBinaryOperators: None
45+
BreakBeforeBraces: Attach
46+
BreakBeforeInheritanceComma: false
47+
BreakInheritanceList: BeforeColon
48+
BreakBeforeTernaryOperators: true
49+
BreakConstructorInitializersBeforeComma: false
50+
BreakConstructorInitializers: BeforeColon
51+
BreakAfterJavaFieldAnnotations: false
52+
BreakStringLiterals: true
53+
ColumnLimit: 120
54+
CommentPragmas: '^ IWYU pragma:'
55+
CompactNamespaces: false
56+
ConstructorInitializerAllOnOneLineOrOnePerLine: false
57+
ConstructorInitializerIndentWidth: 4
58+
ContinuationIndentWidth: 4
59+
Cpp11BracedListStyle: true
60+
DerivePointerAlignment: false
61+
DisableFormat: false
62+
ExperimentalAutoDetectBinPacking: false
63+
FixNamespaceComments: true
64+
ForEachMacros:
65+
- foreach
66+
- Q_FOREACH
67+
- BOOST_FOREACH
68+
IncludeBlocks: Preserve
69+
IncludeCategories:
70+
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
71+
Priority: 2
72+
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
73+
Priority: 3
74+
- Regex: '.*'
75+
Priority: 1
76+
IncludeIsMainRegex: '(Test)?$'
77+
IndentCaseLabels: false
78+
IndentPPDirectives: None
79+
IndentWidth: 2
80+
IndentWrappedFunctionNames: false
81+
JavaScriptQuotes: Leave
82+
JavaScriptWrapImports: true
83+
KeepEmptyLinesAtTheStartOfBlocks: true
84+
MacroBlockBegin: ''
85+
MacroBlockEnd: ''
86+
MaxEmptyLinesToKeep: 1
87+
NamespaceIndentation: None
88+
ObjCBinPackProtocolList: Auto
89+
ObjCBlockIndentWidth: 2
90+
ObjCSpaceAfterProperty: false
91+
ObjCSpaceBeforeProtocolList: true
92+
PenaltyBreakAssignment: 2
93+
PenaltyBreakBeforeFirstCallParameter: 19
94+
PenaltyBreakComment: 300
95+
PenaltyBreakFirstLessLess: 120
96+
PenaltyBreakString: 1000
97+
PenaltyBreakTemplateDeclaration: 10
98+
PenaltyExcessCharacter: 1000000
99+
PenaltyReturnTypeOnItsOwnLine: 60
100+
PointerAlignment: Right
101+
ReflowComments: true
102+
SortIncludes: true
103+
SortUsingDeclarations: true
104+
SpaceAfterCStyleCast: false
105+
SpaceAfterLogicalNot: false
106+
SpaceAfterTemplateKeyword: true
107+
SpaceBeforeAssignmentOperators: true
108+
SpaceBeforeCpp11BracedList: false
109+
SpaceBeforeCtorInitializerColon: true
110+
SpaceBeforeInheritanceColon: true
111+
SpaceBeforeParens: ControlStatements
112+
SpaceBeforeRangeBasedForLoopColon: true
113+
SpaceInEmptyParentheses: false
114+
SpacesBeforeTrailingComments: 1
115+
SpacesInAngles: false
116+
SpacesInContainerLiterals: true
117+
SpacesInCStyleCastParentheses: false
118+
SpacesInParentheses: false
119+
SpacesInSquareBrackets: false
120+
Standard: Cpp11
121+
StatementMacros:
122+
- Q_UNUSED
123+
- QT_REQUIRE_VERSION
124+
TabWidth: 8
125+
UseTab: Never
126+
...
127+

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
3+
project(percy)
4+
5+
set(CMAKE_CXX_STANDARD 17)
6+
7+
add_subdirectory(tests)

include/percy/parser.hpp

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#ifndef PERCY_PARSER
2+
#define PERCY_PARSER
3+
4+
#include <percy/result.hpp>
5+
#include <percy/rules.hpp>
6+
#include <percy/type_traits.hpp>
7+
8+
#include <tuple>
9+
#include <variant>
10+
#include <vector>
11+
12+
namespace percy {
13+
template <typename Rule>
14+
struct parser {
15+
template <typename Input>
16+
constexpr static auto parse(Input input) {
17+
using result_type = result<action_return_t<Rule>>;
18+
19+
auto raw_result = parser<typename Rule::rule>::parse(input);
20+
21+
if (raw_result.is_failure()) {
22+
return result_type::failure(raw_result.span());
23+
}
24+
25+
return result_type::success(Rule::action(raw_result), raw_result.span());
26+
}
27+
};
28+
29+
template <>
30+
struct parser<end> {
31+
template <typename Input>
32+
constexpr static auto parse(Input input) {
33+
using result_type = result<std::true_type>;
34+
35+
if (!input.ended()) {
36+
return result_type::failure({input.position(), input.position()});
37+
}
38+
39+
return result_type::success(std::true_type(), {input.position(), input.position()});
40+
}
41+
};
42+
43+
template <char Symbol>
44+
struct parser<symbol<Symbol>> {
45+
template <typename Input>
46+
constexpr static auto parse(Input input) {
47+
using result_type = result<char>;
48+
49+
if (input.ended()) {
50+
return result_type::failure({input.position(), input.position()});
51+
}
52+
53+
if (input.peek() != Symbol) {
54+
return result_type::failure({input.position(), input.position() + 1});
55+
}
56+
57+
return result_type::success(Symbol, {input.position(), input.position() + 1});
58+
}
59+
};
60+
61+
template <typename Rule>
62+
struct parser<sequence<Rule>> {
63+
template <typename Input>
64+
constexpr static auto parse(Input input) {
65+
using result_type = result<std::tuple<result_value_t<parser_result_t<Input, Rule>>>>;
66+
67+
auto result = parser<Rule>::parse(input);
68+
69+
if (result.is_failure()) {
70+
return result_type::failure(result.span());
71+
}
72+
73+
return result_type::success(result.get(), result.span());
74+
}
75+
};
76+
77+
template <typename Rule, typename FollowingRule, typename ...FollowingRules>
78+
struct parser<sequence<Rule, FollowingRule, FollowingRules...>> {
79+
template <typename Input>
80+
constexpr static auto parse(Input input) {
81+
using result_type = result_followed_by_t<parser_result_t<Input, Rule>,
82+
parser_result_t<Input, sequence<FollowingRule, FollowingRules...>>>;
83+
84+
auto result = parser<Rule>::parse(input);
85+
86+
if (result.is_failure()) {
87+
return result_type::failure(result.span());
88+
}
89+
90+
auto result_following = parser<sequence<FollowingRule, FollowingRules...>>::parse(input.advanced_to(result.end()));
91+
92+
if (result_following.is_failure()) {
93+
return result_type::failure({input.position(), result_following.end()});
94+
}
95+
96+
return result.followed_by(result_following);
97+
}
98+
};
99+
100+
template <typename Rule>
101+
struct parser<repeat<Rule>> {
102+
template <typename Input>
103+
constexpr static auto parse(Input input) {
104+
using result_type = result<std::vector<result_value_t<parser_result_t<Input, Rule>>>>;
105+
using vector_type = result_value_t<result_type>;
106+
107+
vector_type values;
108+
auto input_current = input;
109+
110+
while (auto result = parser<Rule>::parse(input_current)) {
111+
auto value = result.get();
112+
values.push_back(value);
113+
input_current = input.advanced_after(result);
114+
}
115+
116+
return result_type::success(values, {input.position(), input_current.position()});
117+
}
118+
};
119+
120+
template <typename ResultType, std::size_t Index, typename Input, typename ...Rules>
121+
struct one_of_parser {};
122+
123+
template <typename ResultType, std::size_t Index, typename Input, typename Rule>
124+
struct one_of_parser<ResultType, Index, Input, Rule> {
125+
constexpr static auto parse(Input input) {
126+
using variant_type = result_value_t<ResultType>;
127+
128+
auto result = parser<Rule>::parse(input);
129+
130+
if (result.is_failure()) {
131+
return ResultType::failure(result.span());
132+
}
133+
134+
auto value = variant_type(std::in_place_index<Index>, result.get());
135+
return ResultType::success(value, result.span());
136+
}
137+
};
138+
139+
template <typename ResultType, std::size_t Index, typename Input, typename Rule, typename AlternativeRule, typename ...AlternativeRules>
140+
struct one_of_parser<ResultType, Index, Input, Rule, AlternativeRule, AlternativeRules...> {
141+
constexpr static auto parse(Input input) {
142+
using variant_type = result_value_t<ResultType>;
143+
144+
if (auto result = one_of_parser<ResultType, Index, Input, Rule>::parse(input)) {
145+
return result;
146+
}
147+
148+
return one_of_parser<ResultType, Index + 1, Input, AlternativeRule, AlternativeRules...>::parse(input);
149+
}
150+
};
151+
152+
template <typename ...Rules>
153+
struct parser<one_of<Rules...>> {
154+
template <typename Input>
155+
constexpr static auto parse(Input input) {
156+
using result_type = result<std::variant<result_value_t<parser_result_t<Input, Rules>>...>>;
157+
158+
return one_of_parser<result_type, 0, Input, Rules...>::parse(input);
159+
}
160+
};
161+
162+
template <typename Rule>
163+
struct parser<unwrap<Rule>> {
164+
template <typename Input>
165+
constexpr static auto parse(Input input) {
166+
auto result = parser<Rule>::parse(input);
167+
return result.get();
168+
}
169+
};
170+
}
171+
172+
#endif

0 commit comments

Comments
 (0)