| 944 | } |
| 945 | |
| 946 | void common_peg_arena::resolve_refs() { |
| 947 | // Walk through all parsers and replace refs with their corresponding rule IDs |
| 948 | for (auto & parser : parsers_) { |
| 949 | std::visit([this](auto & p) { |
| 950 | using T = std::decay_t<decltype(p)>; |
| 951 | |
| 952 | if constexpr (std::is_same_v<T, common_peg_sequence_parser>) { |
| 953 | for (auto & child : p.children) { |
| 954 | child = resolve_ref(child); |
| 955 | } |
| 956 | } else if constexpr (std::is_same_v<T, common_peg_choice_parser>) { |
| 957 | for (auto & child : p.children) { |
| 958 | child = resolve_ref(child); |
| 959 | } |
| 960 | } else if constexpr (std::is_same_v<T, common_peg_repetition_parser> || |
| 961 | std::is_same_v<T, common_peg_and_parser> || |
| 962 | std::is_same_v<T, common_peg_not_parser> || |
| 963 | std::is_same_v<T, common_peg_tag_parser> || |
| 964 | std::is_same_v<T, common_peg_atomic_parser> || |
| 965 | std::is_same_v<T, common_peg_gbnf_parser>) { |
| 966 | p.child = resolve_ref(p.child); |
| 967 | } else if constexpr (std::is_same_v<T, common_peg_rule_parser>) { |
| 968 | p.child = resolve_ref(p.child); |
| 969 | } else if constexpr (std::is_same_v<T, common_peg_schema_parser>) { |
| 970 | p.child = resolve_ref(p.child); |
| 971 | } else if constexpr (std::is_same_v<T, common_peg_epsilon_parser> || |
| 972 | std::is_same_v<T, common_peg_start_parser> || |
| 973 | std::is_same_v<T, common_peg_end_parser> || |
| 974 | std::is_same_v<T, common_peg_ref_parser> || |
| 975 | std::is_same_v<T, common_peg_until_parser> || |
| 976 | std::is_same_v<T, common_peg_literal_parser> || |
| 977 | std::is_same_v<T, common_peg_string_parser> || |
| 978 | std::is_same_v<T, common_peg_chars_parser> || |
| 979 | std::is_same_v<T, common_peg_any_parser> || |
| 980 | std::is_same_v<T, common_peg_space_parser>) { |
| 981 | // These rules do not have children |
| 982 | } else { |
| 983 | static_assert(is_always_false_v<T>); |
| 984 | } |
| 985 | }, parser); |
| 986 | } |
| 987 | |
| 988 | // Also flatten root if it's a ref |
| 989 | if (root_ != COMMON_PEG_INVALID_PARSER_ID) { |
| 990 | root_ = resolve_ref(root_); |
| 991 | } |
| 992 | } |
| 993 | |
| 994 | std::string common_peg_arena::dump(common_peg_parser_id id) const { |
| 995 | std::unordered_set<common_peg_parser_id> visited; |
no outgoing calls