@@ -890,6 +890,10 @@ struct parser_executor {
890890 }
891891 return result;
892892 }
893+
894+ common_peg_parse_result operator ()(const common_peg_gbnf_parser & p) {
895+ return arena.parse (p.child , ctx, start_pos);
896+ }
893897};
894898
895899common_peg_parse_result common_peg_arena::parse (common_peg_parse_context & ctx, size_t start) const {
@@ -957,7 +961,8 @@ void common_peg_arena::resolve_refs() {
957961 std::is_same_v<T, common_peg_and_parser> ||
958962 std::is_same_v<T, common_peg_not_parser> ||
959963 std::is_same_v<T, common_peg_tag_parser> ||
960- std::is_same_v<T, common_peg_atomic_parser>) {
964+ std::is_same_v<T, common_peg_atomic_parser> ||
965+ std::is_same_v<T, common_peg_gbnf_parser>) {
961966 p.child = resolve_ref (p.child );
962967 } else if constexpr (std::is_same_v<T, common_peg_rule_parser>) {
963968 p.child = resolve_ref (p.child );
@@ -1036,6 +1041,8 @@ std::string common_peg_arena::dump_impl(common_peg_parser_id
10361041 return " Not(" + dump_impl (p.child , visited) + " )" ;
10371042 } else if constexpr (std::is_same_v<T, common_peg_atomic_parser>) {
10381043 return " Atomic(" + dump_impl (p.child , visited) + " )" ;
1044+ } else if constexpr (std::is_same_v<T, common_peg_gbnf_parser>) {
1045+ return " Gbnf(" + p.grammar + " , " + dump_impl (p.child , visited) + " )" ;
10391046 } else if constexpr (std::is_same_v<T, common_peg_any_parser>) {
10401047 return " Any" ;
10411048 } else if constexpr (std::is_same_v<T, common_peg_space_parser>) {
@@ -1565,6 +1572,7 @@ static std::unordered_set<std::string> collect_reachable_rules(
15651572 std::is_same_v<T, common_peg_not_parser> ||
15661573 std::is_same_v<T, common_peg_tag_parser> ||
15671574 std::is_same_v<T, common_peg_atomic_parser> ||
1575+ std::is_same_v<T, common_peg_gbnf_parser> ||
15681576 std::is_same_v<T, common_peg_schema_parser>) {
15691577 visit (p.child );
15701578 } else if constexpr (std::is_same_v<T, common_peg_rule_parser>) {
@@ -1651,10 +1659,13 @@ void common_peg_arena::build_grammar(const common_grammar_builder & builder, boo
16511659 } else if constexpr (std::is_same_v<T, common_peg_sequence_parser>) {
16521660 std::string s;
16531661 for (const auto & child : p.children ) {
1662+ auto child_gbnf = to_gbnf (child);
1663+ if (child_gbnf.empty ()) {
1664+ continue ;
1665+ }
16541666 if (!s.empty ()) {
16551667 s += " " ;
16561668 }
1657- auto child_gbnf = to_gbnf (child);
16581669 const auto & child_parser = effective_parser (child);
16591670 if (std::holds_alternative<common_peg_choice_parser>(child_parser) ||
16601671 std::holds_alternative<common_peg_sequence_parser>(child_parser)) {
@@ -1754,6 +1765,8 @@ void common_peg_arena::build_grammar(const common_grammar_builder & builder, boo
17541765 return to_gbnf (p.child );
17551766 } else if constexpr (std::is_same_v<T, common_peg_atomic_parser>) {
17561767 return to_gbnf (p.child );
1768+ } else if constexpr (std::is_same_v<T, common_peg_gbnf_parser>) {
1769+ return p.grammar ;
17571770 } else {
17581771 static_assert (is_always_false_v<T>);
17591772 }
@@ -1888,6 +1901,8 @@ static nlohmann::json serialize_parser_variant(const common_peg_parser_variant &
18881901 {" child" , p.child },
18891902 {" tag" , p.tag }
18901903 };
1904+ } else if constexpr (std::is_same_v<T, common_peg_gbnf_parser>) {
1905+ return json{{" type" , " gbnf" }, {" child" , p.child }, {" grammar" , p.grammar }};
18911906 }
18921907 }, variant);
18931908}
@@ -2050,6 +2065,16 @@ static common_peg_parser_variant deserialize_parser_variant(const nlohmann::json
20502065 };
20512066 }
20522067
2068+ if (type == " gbnf" ) {
2069+ if (!j.contains (" child" ) || !j.contains (" grammar" )) {
2070+ throw std::runtime_error (" gbnf parser missing required fields" );
2071+ }
2072+ return common_peg_gbnf_parser{
2073+ j[" child" ].get <common_peg_parser_id>(),
2074+ j[" grammar" ].get <std::string>(),
2075+ };
2076+ }
2077+
20532078 throw std::runtime_error (" Unknown parser type: " + type);
20542079}
20552080
0 commit comments