#include "TechsetFileParser.h" #include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" using namespace techset; namespace { class SequenceTechniqueTypeName final : public TechsetParser::sequence_t { static constexpr auto CAPTURE_TYPE_NAME = 1; public: SequenceTechniqueTypeName() { const SimpleMatcherFactory create(this); AddMatchers({ create.String().Capture(CAPTURE_TYPE_NAME), create.Char(':'), }); } protected: void ProcessMatch(TechsetParserState* state, SequenceResult& result) const override { const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE_NAME); const auto maybeTechniqueTypeIndex = state->m_technique_type_names.GetTechniqueTypeByName(typeNameToken.StringValue()); if (!maybeTechniqueTypeIndex.has_value()) throw ParsingException(typeNameToken.GetPos(), "Unknown technique type name"); state->m_current_technique_types.push_back(maybeTechniqueTypeIndex.value()); } }; class SequenceTechniqueName final : public TechsetParser::sequence_t { static constexpr auto CAPTURE_NAME = 1; public: SequenceTechniqueName() { const SimpleMatcherFactory create(this); AddMatchers({ create .Or({ create.Identifier(), create.String(), }) .Capture(CAPTURE_NAME), create.Char(';'), }); } protected: void ProcessMatch(TechsetParserState* state, SequenceResult& result) const override { assert(!state->m_current_technique_types.empty()); const auto& techniqueNameToken = result.NextCapture(CAPTURE_NAME); const auto& techniqueName = techniqueNameToken.m_type == SimpleParserValueType::STRING ? techniqueNameToken.StringValue() : techniqueNameToken.IdentifierValue(); for (const auto techniqueTypeIndex : state->m_current_technique_types) state->m_definition->m_technique_names[techniqueTypeIndex] = techniqueName; state->m_current_technique_types.clear(); } }; } // namespace namespace techset { TechsetParser::TechsetParser(SimpleLexer& lexer, const CommonTechniqueTypeNames& techniqueTypeNames) : AbstractParser(&lexer, std::make_unique(techniqueTypeNames)) { } const std::vector& TechsetParser::GetTestsForState() { static std::vector allTests({ new SequenceTechniqueTypeName(), new SequenceTechniqueName(), }); static std::vector techniqueTypeNameOnlyTests({ new SequenceTechniqueTypeName(), }); return m_state->m_current_technique_types.empty() ? techniqueTypeNameOnlyTests : allTests; } std::unique_ptr TechsetParser::GetParsingResult() const { return std::move(m_state->m_definition); } } // namespace techset