diff --git a/CMakeLists.txt b/CMakeLists.txt index a00bc2c1..17c3aac7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/reader2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectSymbolSsm + INPUT idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + # ---------------------------------------------------------------- # shared library diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 00000000..01b5c555 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,6 @@ +diagram for parsing stack. +stack growing down for nested ssm's + +`on_if_token` etc going to same state + +`on_parsed_xxx` going back up the stack diff --git a/doc/glossary.rst b/doc/glossary.rst new file mode 100644 index 00000000..67b04538 --- /dev/null +++ b/doc/glossary.rst @@ -0,0 +1,3 @@ +ssm = syntax state machine +psm = parser state machine +ckp = checkpoint diff --git a/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 b/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 new file mode 100644 index 00000000..24b754e4 --- /dev/null +++ b/idl/ISyntaxStateMachine_DExpectSymbolSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectSymbolSsm", + using_doxygen: true, + repr: "DExpectSymbolSsm", + doc: [ "implement ASyntaxStateMachine for DExpectSymbolSsm" ], +} diff --git a/idl/SyntaxStateMachine.json5 b/idl/SyntaxStateMachine.json5 index f2058e9d..2be2a98d 100644 --- a/idl/SyntaxStateMachine.json5 +++ b/idl/SyntaxStateMachine.json5 @@ -45,11 +45,11 @@ nonconst_methods: [ { name: "on_def_token", - doc: ["update state machine for incoming define-keyworkd-token @p tk"], + doc: ["update state machine for incoming define-keyword-token @p tk"], return_type: "void", args: [ {type: "const Token &", name: "tk"}, - {type: "ParserStateMachine *", name: "ps_psm"}, + {type: "ParserStateMachine *", name: "p_psm"}, ], }, { @@ -61,5 +61,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_symbol", + doc: ["update stat machine for incoming parsed symbol @p sym"], + return_type: "void", + args: [ + {type: "std::string_view", name: "sym"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/include/xo/reader2/DDefineSsm.hpp b/include/xo/reader2/DDefineSsm.hpp index 3a34d0a3..37ccc23d 100644 --- a/include/xo/reader2/DDefineSsm.hpp +++ b/include/xo/reader2/DDefineSsm.hpp @@ -6,7 +6,7 @@ #pragma once #include "ParserStateMachine.hpp" -#include "SyntaxStateMachine.hpp" +//#include "SyntaxStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -110,6 +110,12 @@ namespace xo { void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + ///@} private: diff --git a/include/xo/reader2/DExpectSymbolSsm.hpp b/include/xo/reader2/DExpectSymbolSsm.hpp new file mode 100644 index 00000000..dadd1300 --- /dev/null +++ b/include/xo/reader2/DExpectSymbolSsm.hpp @@ -0,0 +1,91 @@ +/* file DExpectSymbolSsm.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "ParserStateMachine.hpp" +//#include "SyntaxStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include + +namespace xo { + namespace scm { + /** @class DExpectSymbolSsm + * @brief state machine to expect + capture a symbol + * + * For example: + * - lhs in a define-expression + **/ + class DExpectSymbolSsm { + public: + using DArena = xo::mm::DArena; + + public: + DExpectSymbolSsm(); + + /** create instance using memory from @p parser_mm **/ + static DExpectSymbolSsm * make(DArena & parser_mm); + + /** start nested parser expecting a symbol, + * on top of parser state machine @p p_psm. + * On success will deliver symbol by invoking + * .on_symbol(sym, p_psm) + * to the state machine on top of the stack + * as of when this start() method invoked + **/ + static void start(DArena & parser_mm, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + static void on_symbol_token(const Token & tk, + ParserStateMachine * p_psm); + + /** @defgroup scm-expectsymbol-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** text describing expected/allowed input to this ssm in current state. + * Intended to drive error mesages + **/ + std::string_view get_expect_str() const noexcept; + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_def_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax on incoming token @p tk, + * overall parser state in @p p_psm + **/ + void on_if_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for this syntax after parsing a symbol @p sym; + * overall parser state in @p p_psm. + * + * NOTE: + * might not be obvious that this is unreachable. + * DExpectSymbolSsm converts a symbol token, + * and delivers it to parent ssm using this entry point. + * This method would only be called if consecutive + * DExpectSymbolSsm instances on parser stack; + * which scenario never occurs in Schematika syntax + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + + ///@} + + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.hpp */ diff --git a/include/xo/reader2/DExprSeqState.hpp b/include/xo/reader2/DExprSeqState.hpp index c0e0d8af..1b611aaf 100644 --- a/include/xo/reader2/DExprSeqState.hpp +++ b/include/xo/reader2/DExprSeqState.hpp @@ -66,6 +66,12 @@ namespace xo { **/ void on_if_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on parsed symbol @p sym + * from immediately-downstream ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm); + ///@} private: diff --git a/include/xo/reader2/ParserStack.hpp b/include/xo/reader2/ParserStack.hpp index 4a87de7f..b63be044 100644 --- a/include/xo/reader2/ParserStack.hpp +++ b/include/xo/reader2/ParserStack.hpp @@ -6,7 +6,7 @@ #pragma once #include "SyntaxStateMachine.hpp" -#include +#include #include namespace xo { @@ -20,22 +20,31 @@ namespace xo { **/ class ParserStack { public: - using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; public: - ParserStack(obj ssm, ParserStack * parent); + ParserStack(DArena::Checkpoint ckp, + obj ssm, + ParserStack * parent); /** create new top of stack for syntax @p ssm, using memory from @p mm. * previous stack given by @p parent **/ static ParserStack * push(ParserStack * stack, - obj mm, + DArena & mm, obj ssm); + /** unwind effect of last call to @ref push **/ + static ParserStack * pop(ParserStack * stack, + DArena & mm); + + DArena::Checkpoint ckp() const noexcept { return ckp_; } obj top() const noexcept { return ssm_; } ParserStack * parent() const noexcept { return parent_; } private: + /** stack pointer: top of stack just before this instance created **/ + DArena::Checkpoint ckp_; /** top of parsing stack: always non-null **/ obj ssm_; /** remainder of parsing stack excluding top **/ diff --git a/include/xo/reader2/ParserStateMachine.hpp b/include/xo/reader2/ParserStateMachine.hpp index 63d761c0..f5293bff 100644 --- a/include/xo/reader2/ParserStateMachine.hpp +++ b/include/xo/reader2/ParserStateMachine.hpp @@ -62,6 +62,9 @@ namespace xo { /** push syntax @p ssm onto @ref stack_ **/ void push_ssm(obj ssm); + /** pop syntax state machine from top of @ref stack_ **/ + void pop_ssm(); + /** reset result to none **/ void reset_result(); @@ -73,6 +76,9 @@ namespace xo { /** @defgroup scm-parserstatemachine-inputmethods input methods **/ ///@{ + /** update state to respond to prsed symbol @p sym **/ + void on_parsed_symbol(std::string_view sym); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ @@ -99,12 +105,19 @@ namespace xo { /** report illegal input from syntax state machine @p ssm_name * recognized on input token @p tk. @p expect_str describes - * expected input in that state + * expected input in current ssm state **/ void illegal_input_on_token(std::string_view ssm_name, const Token & tk, std::string_view expect_str); + /** report illegal input from syntax state machine @p ssm_name + * receiving parsed symbol @p sym. @p expect_str describes + * expected input in current ssm state + **/ + void illegal_input_on_symbol(std::string_view ssm_name, + std::string_view sym, + std::string_view expect_str); ///@} private: diff --git a/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index a6586263..b181fd8d 100644 --- a/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -54,8 +54,10 @@ public: virtual std::string_view get_expect_str(Copaque data) const noexcept = 0; // nonconst methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) = 0; + /** update stat machine for incoming parsed symbol @p sym **/ + virtual void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming define-keyword-token @p tk **/ + virtual void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; /** update state machine for incoming if-keyword-token @p tk **/ virtual void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) = 0; ///@} diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 35efd49e..046adacb 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -59,6 +59,7 @@ namespace scm { [[noreturn]] std::string_view get_expect_str(Copaque) const noexcept override { _fatal(); } // nonconst methods + [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_def_token(Opaque, const Token &, ParserStateMachine *) override; [[noreturn]] void on_if_token(Opaque, const Token &, ParserStateMachine *) override; diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index adb39c48..cfb38fa7 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -53,8 +53,10 @@ namespace xo { static std::string_view get_expect_str(const DDefineSsm & self) noexcept; // non-const methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * ps_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm); ///@} diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp new file mode 100644 index 00000000..44cb6de4 --- /dev/null +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -0,0 +1,68 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectSymbolSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectSymbolSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectSymbolSsm + **/ + class ISyntaxStateMachine_DExpectSymbolSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectsymbolssm-type-traits **/ + ///@{ + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectsymbolssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectSymbolSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectSymbolSsm & self) noexcept; + + // non-const methods + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for incoming if-keyword-token @p tk **/ + static void on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index c3a540a8..4da00f95 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -53,8 +53,10 @@ namespace xo { static std::string_view get_expect_str(const DExprSeqState & self) noexcept; // non-const methods - /** update state machine for incoming define-keyworkd-token @p tk **/ - static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * ps_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm); + /** update state machine for incoming define-keyword-token @p tk **/ + static void on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); /** update state machine for incoming if-keyword-token @p tk **/ static void on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm); ///@} diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index ad48c7af..7de32e25 100644 --- a/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -50,8 +50,11 @@ namespace scm { } // non-const methods - void on_def_token(Opaque data, const Token & tk, ParserStateMachine * ps_psm) override { - return I::on_def_token(_dcast(data), tk, ps_psm); + void on_parsed_symbol(Opaque data, std::string_view sym, ParserStateMachine * p_psm) override { + return I::on_parsed_symbol(_dcast(data), sym, p_psm); + } + void on_def_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { + return I::on_def_token(_dcast(data), tk, p_psm); } void on_if_token(Opaque data, const Token & tk, ParserStateMachine * p_psm) override { return I::on_if_token(_dcast(data), tk, p_psm); diff --git a/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 8841e242..f35f4e72 100644 --- a/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -55,8 +55,11 @@ public: } // non-const methods (still const in router!) - void on_def_token(const Token & tk, ParserStateMachine * ps_psm) { - return O::iface()->on_def_token(O::data(), tk, ps_psm); + void on_parsed_symbol(std::string_view sym, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_symbol(O::data(), sym, p_psm); + } + void on_def_token(const Token & tk, ParserStateMachine * p_psm) { + return O::iface()->on_def_token(O::data(), tk, p_psm); } void on_if_token(const Token & tk, ParserStateMachine * p_psm) { return O::iface()->on_if_token(O::data(), tk, p_psm); diff --git a/include/xo/reader2/syntaxstatetype.hpp b/include/xo/reader2/syntaxstatetype.hpp index ae02cad4..bf3e03f1 100644 --- a/include/xo/reader2/syntaxstatetype.hpp +++ b/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, + /** expecting a s symbol. See @ref DExpectSymbolSsm **/ + expect_symbol, + /** handle define-expression. See @ref DDefineSsm **/ defexpr, diff --git a/src/reader2/CMakeLists.txt b/src/reader2/CMakeLists.txt index 290f75cc..655ac7e9 100644 --- a/src/reader2/CMakeLists.txt +++ b/src/reader2/CMakeLists.txt @@ -17,6 +17,9 @@ set(SELF_SRCS DDefineSsm.cpp ISyntaxStateMachine_DDefineSsm.cpp + DExpectSymbolSsm.cpp + ISyntaxStateMachine_DExpectSymbolSsm.cpp + reader2_register_facets.cpp reader2_register_types.cpp ) diff --git a/src/reader2/DDefineSsm.cpp b/src/reader2/DDefineSsm.cpp index 87d1af35..8ac919e4 100644 --- a/src/reader2/DDefineSsm.cpp +++ b/src/reader2/DDefineSsm.cpp @@ -46,12 +46,7 @@ namespace xo { // ----- define_xs ----- -#ifdef NOT_YET - std::unique_ptr - define_xs::make() { - return std::make_unique(define_xs(DefineExprAccess::make_empty())); - } -#endif + // DDefineSsm::make // DDefineSsm::start @@ -410,6 +405,15 @@ namespace xo { return "?expect"; } + void + DDefineSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DDefineSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + void DDefineSsm::on_def_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/src/reader2/DExpectSymbolSsm.cpp b/src/reader2/DExpectSymbolSsm.cpp new file mode 100644 index 00000000..6afe337c --- /dev/null +++ b/src/reader2/DExpectSymbolSsm.cpp @@ -0,0 +1,109 @@ +/** @file DExpectSymbolSsm.cpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#include "DExpectSymbolSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" +#include "SyntaxStateMachine.hpp" +#include "ParserStateMachine.hpp" +#include "syntaxstatetype.hpp" +#include +//#include + +namespace xo { + using xo::facet::with_facet; + using xo::facet::typeseq; + + namespace scm { + DExpectSymbolSsm::DExpectSymbolSsm() + {} + + DExpectSymbolSsm * + DExpectSymbolSsm::make(DArena & mm) + { + void * mem = mm.alloc(typeseq::id(), + sizeof(DExpectSymbolSsm)); + + return new (mem) DExpectSymbolSsm(); + } + + void + DExpectSymbolSsm::start(DArena & parser_alloc, + ParserStateMachine * p_psm) + { + DExpectSymbolSsm * sym_ssm + = DExpectSymbolSsm::make(parser_alloc); + + // note: + // relying on [ISyntaxStateMachine_DExpectedSymbolSsm.hpp] + // + obj ssm + = with_facet::mkobj(sym_ssm); + + p_psm->push_ssm(ssm); + } + + syntaxstatetype + DExpectSymbolSsm::ssm_type() const noexcept + { + return syntaxstatetype::expect_symbol; + } + + std::string_view + DExpectSymbolSsm::get_expect_str() const noexcept + { + return "symbol"; + } + + void + DExpectSymbolSsm::on_symbol_token(const Token & tk, + ParserStateMachine * p_psm) + { +#ifdef NOT_YET + constexpr bool c_debug_flag = false; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("tk", tk)); + + assert(&p_psm->top_exprstate() == this); +#endif + + /* have to do pop first, before sending symbol to + * the o.g. symbol-requester + */ + p_psm->pop_ssm(); + + p_psm->on_parsed_symbol(std::string_view(tk.text())); + } + + void + DExpectSymbolSsm::on_def_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_def_token", + tk, + this->get_expect_str()); + } + + void + DExpectSymbolSsm::on_if_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectSymbolSsm::on_if_token", + tk, + this->get_expect_str()); + } + + void + DExpectSymbolSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectSymbolSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectSymbolSsm.cpp */ diff --git a/src/reader2/DExprSeqState.cpp b/src/reader2/DExprSeqState.cpp index 2922dd7f..cca208f6 100644 --- a/src/reader2/DExprSeqState.cpp +++ b/src/reader2/DExprSeqState.cpp @@ -109,6 +109,15 @@ namespace xo { break; } } + + void + DExprSeqState::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExprSeqState::on_parsed_symbol", + sym, + this->get_expect_str()); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/reader2/ISyntaxStateMachine_Any.cpp b/src/reader2/ISyntaxStateMachine_Any.cpp index ce85a9e0..2076aa5f 100644 --- a/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/src/reader2/ISyntaxStateMachine_Any.cpp @@ -34,6 +34,12 @@ ISyntaxStateMachine_Any::_valid // nonconst methods +auto +ISyntaxStateMachine_Any::on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) -> void +{ + _fatal(); +} + auto ISyntaxStateMachine_Any::on_def_token(Opaque, const Token &, ParserStateMachine *) -> void { diff --git a/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index bf17c9b5..96020a95 100644 --- a/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -16,30 +16,29 @@ namespace xo { namespace scm { auto - ISyntaxStateMachine_DDefineSsm::ssm_type(const DDefineSsm & self) noexcept - -> syntaxstatetype + ISyntaxStateMachine_DDefineSsm::ssm_type(const DDefineSsm & self) noexcept -> syntaxstatetype { return self.ssm_type(); } auto - ISyntaxStateMachine_DDefineSsm::get_expect_str(const DDefineSsm & self) noexcept - -> std::string_view + ISyntaxStateMachine_DDefineSsm::get_expect_str(const DDefineSsm & self) noexcept -> std::string_view { return self.get_expect_str(); } auto - ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, - const Token & tk, - ParserStateMachine * ps_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_parsed_symbol(DDefineSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void { - self.on_def_token(tk, ps_psm); + self.on_parsed_symbol(sym, p_psm); } auto - ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DDefineSsm::on_def_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DDefineSsm::on_if_token(DDefineSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_if_token(tk, p_psm); } @@ -47,4 +46,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DDefineSsm.cpp */ +/* end ISyntaxStateMachine_DDefineSsm.cpp */ \ No newline at end of file diff --git a/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp new file mode 100644 index 00000000..b2efaab5 --- /dev/null +++ b/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -0,0 +1,49 @@ +/** @file ISyntaxStateMachine_DExpectSymbolSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectSymbolSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectSymbolSsm::ssm_type(const DExpectSymbolSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectSymbolSsm::get_expect_str(const DExpectSymbolSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_symbol(DExpectSymbolSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_def_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_def_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_if_token(DExpectSymbolSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_if_token(tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectSymbolSsm.cpp */ \ No newline at end of file diff --git a/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index a3abc520..2279ea88 100644 --- a/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -28,16 +28,17 @@ namespace xo { } auto - ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_parsed_symbol(DExprSeqState & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExprSeqState::on_def_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_def_token(tk, p_psm); } auto - ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, - const Token & tk, - ParserStateMachine * p_psm) -> void + ISyntaxStateMachine_DExprSeqState::on_if_token(DExprSeqState & self, const Token & tk, ParserStateMachine * p_psm) -> void { self.on_if_token(tk, p_psm); } @@ -45,4 +46,4 @@ namespace xo { } /*namespace scm*/ } /*namespace xo*/ -/* end ISyntaxStateMachine_DExprSeqState.cpp */ +/* end ISyntaxStateMachine_DExprSeqState.cpp */ \ No newline at end of file diff --git a/src/reader2/ParserStack.cpp b/src/reader2/ParserStack.cpp index 5b416c54..ba39517d 100644 --- a/src/reader2/ParserStack.cpp +++ b/src/reader2/ParserStack.cpp @@ -10,21 +10,35 @@ namespace xo { using xo::facet::typeseq; namespace scm { - ParserStack::ParserStack(obj ssm, + ParserStack::ParserStack(DArena::Checkpoint ckp, + obj ssm, ParserStack * parent) - : ssm_{ssm}, parent_{parent} + : ckp_{ckp}, ssm_{ssm}, parent_{parent} {} ParserStack * ParserStack::push(ParserStack * stack, - obj mm, + DArena & mm, obj ssm) { + DArena::Checkpoint ckp = mm.checkpoint(); + void * mem = mm.alloc(typeseq::id(), sizeof(ParserStack)); - return new (mem) ParserStack(ssm, stack); + return new (mem) ParserStack(ckp, ssm, stack); + } + + ParserStack * + ParserStack::pop(ParserStack * stack, + DArena & mm) + { + assert(stack); + + mm.restore(stack->ckp()); + + return stack->parent(); } } /*namespace scm*/ diff --git a/src/reader2/ParserStateMachine.cpp b/src/reader2/ParserStateMachine.cpp index 25765466..c05ab217 100644 --- a/src/reader2/ParserStateMachine.cpp +++ b/src/reader2/ParserStateMachine.cpp @@ -46,9 +46,7 @@ namespace xo { assert(stack_ == nullptr); - auto alloc = with_facet::mkobj(&parser_alloc_); - - this->stack_ = ParserStack::push(nullptr /*stack*/, alloc, ssm); + this->stack_ = ParserStack::push(nullptr /*stack*/, parser_alloc_, ssm); this->parser_alloc_ckp_ = parser_alloc_.checkpoint(); } @@ -59,9 +57,17 @@ namespace xo { // note: using parser_alloc_ for parser stack, since stacklike behavior - auto alloc = with_facet::mkobj(&parser_alloc_); + this->stack_ = ParserStack::push(stack_, parser_alloc_, ssm); + } - this->stack_ = ParserStack::push(stack_, alloc, ssm); + void + ParserStateMachine::pop_ssm() + { + scope log(XO_DEBUG(debug_flag_)); + + assert(this->stack_); + + this->stack_ = ParserStack::pop(stack_, parser_alloc_); } void @@ -81,6 +87,16 @@ namespace xo { this->parser_alloc_.restore(parser_alloc_ckp_); } + void + ParserStateMachine::on_parsed_symbol(std::string_view sym) + { + scope log(XO_DEBUG(debug_flag_), xtag("sym", sym)); + + assert(stack_); + + this->stack_->top().on_parsed_symbol(sym, this); + } + void ParserStateMachine::on_token(const Token & tk) { @@ -194,6 +210,29 @@ namespace xo { this->capture_error(ssm_name, errmsg); } + + void + ParserStateMachine::illegal_input_on_symbol(std::string_view ssm_name, + std::string_view sym, + std::string_view expect_str) + { + // TODO: + // - want to write error message using DArena + // - need something like log_streambuf and/or tostr() that's arena-aware + + auto errmsg_string = tostr("Unexpected symbol for parsing state", + xtag("symbol", sym), + xtag("expecting", expect_str), + xtag("ssm", ssm_name), + xtag("via", "ParserStateMachine::illegal_input_on_symbol")); + + assert(expr_alloc_); + + auto errmsg = DString::from_view(*expr_alloc_, + std::string_view(errmsg_string)); + + this->capture_error(ssm_name, errmsg); + } } /*namespace scm*/ } /*namespace xo*/