/** @file DExpectQDictSsm.hpp * * @author Roland Conybeare, Mar 2026 **/ #pragma once #include "DSyntaxStateMachine.hpp" #include #include namespace xo { namespace scm { /** * When this syntax is active, parser is already in a quoted-literal context * * { key(1) : value(1) ; ... ; } * ^ ^ ^ ^ ^ ^ ^ ^ * | | | qdict_1c | | | qdict_2(done) * | | qdict_1b | | qdict_1d * | qdict_1a | qdict_1a * qdict_0 qdict_1d * * qdict_0 --on_leftbrace_token()--> qdict_1a [push ExpectSymbolSsm] * qdict_1a --on_parsed_symbol()--> qdict_1b [remember key] * qdict_1a --onrightbace_token()--> qdictZ(done) * qdict_1b --on_colon_token()--> qdict_1c [push ExpectQLiteralSsm] * qdict_1c --on_quoted_literal()--> qdict_1d [remember value] * qdict_1d --on_semicolon_token()--> qdict_1a [loop] * qdict_1d --on_rightbrace_token()--> qdict_2(done) **/ class QDictXst { public: enum class code { invalid = -1, qdict_0, qdict_1a, qdict_1b, qdict_1c, qdict_1d, qdict_2, N }; explicit QDictXst(code x) : code_{x} {} /** @return string representation for enum @p x **/ static const char * _descr(code x); code code() const noexcept { return code_; } enum code code_; }; inline std::ostream & operator<< (std::ostream & os, QDictXst x) { os << QDictXst::_descr(x.code_); return os; } class DExpectQDictSsm : public DSyntaxStateMachine { public: using Super = DSyntaxStateMachine; using AGCObjectVisitor = xo::mm::AGCObjectVisitor; using VisitReason = xo::mm::VisitReason; using DArena = xo::mm::DArena; using ppindentinfo = xo::print::ppindentinfo; public: /** @defgroup scm-expectqdictssm-ctors constructors **/ ///@{ DExpectQDictSsm(); /** create instance using memory from @parser_mm **/ static obj make(DArena & parser_mm); /** create instance using memory from @parser_mm **/ static DExpectQDictSsm * _make(DArena & parser_mm); /** start nested syntax for a quoted dictionary **/ static void start(ParserStateMachine * p_psm); ///@} /** @defgroup scm-expectqdictssm-methods general methods **/ ///@{ static const char * ssm_classname() { return "DExpectQDictSsm"; } /** update state on incoming leftbrace token @p tk, * with overall parser state in @p p_psm * * in qdict_0 advance state to qdict_1a; otherwise error **/ void on_leftbrace_token(const Token & tk, ParserStateMachine * p_psm); /** update state on parsed symbol @p sym emitted by nested ssm, * with overall parser state in @p p_psm * * in qdict_1a capture key string + advance to qdict_1b; otherwise error **/ void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); /** update state on incoming colon token @p tk, * with overall parser state in @p p_psm * * in qdict_1b advance to qdict_1c + push ExpectQLiteralSsm; otherwise error **/ void on_colon_token(const Token & tk, ParserStateMachine * p_psm); /** update state in on incoming semicolon token @p tk, * with overall parser state in @p p_psm. * * in qdict_1d advance to qdict_1a (ready for another (key,value) pair); otherwise error **/ void on_semicolon_token(const Token & tk, ParserStateMachine * p_psm); /** update state on incoming rightbrace token @p tk, * with overall parser state in @p p_psm * * in qdict_1a complete syntax + report literal to parent ssm; otherwise error **/ void on_rightbrace_token(const Token & tk, ParserStateMachine * p_psm); ///@} /** @defgroup scm-expectqdictssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ /** identifies the ssm implemented here **/ syntaxstatetype ssm_type() const noexcept; /** mnemonic *for expected input (for this ssm) in current state **/ std::string_view get_expect_str() const; /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ void on_token(const Token & tk, ParserStateMachine * p_psm); /** update state on quoted literal @p lit, with overall parser state in @p p_psm * * in qdict_1c capture (key,value) pair into dictionary + advance to qdict_1d; otherwise error **/ void on_quoted_literal(obj lit, ParserStateMachine * p_psm); ///@} /** @defgroup scm-expectqdictssm-printable-facet printable facet methods **/ ///@{ bool pretty(const ppindentinfo & ppii) const; ///@} /** @defgroup scm-expectqdictssm-gc-support gc support methods **/ ///@{ /** gc support: visit gc-aware child pointers **/ void visit_gco_children(VisitReason reason, obj gc) noexcept; ///@} private: /** @defgroup ssm-expectqdictssm-member-vars **/ ///@{ /** iddentifies qdict parsing state **/ QDictXst state_; /** captured key in next (key,value) pair; * expect to include in @ref dict_ **/ const DString * key_ = nullptr; /** literal dictionary (assembled incrementally) **/ DDictionary * dict_ = nullptr; ///@} }; } /*namespace scm*/ } /*namespace xo*/ /* end DExpectQDictSsm.hpp */