#pragma once #include "bnf.h" #include "minicc.h" #include #include namespace Gram { // TreeNodes are only intermediate. Terminal symbols don't get of TreeNodes // token_id: index into token list // node_id: index into tree node list struct TreeNode { index_t parent_node_id{}; // root if parent_node_id == node_id index_t node_id{}; std::string type; index_t variant; // bnf[type][variant] std::deque> alternatives; // [type][value] alternatives that we can consider on fail. Discard after parsing! std::vector child_ids; // < 0: terminal: token_id; >= 0: non-terminal: node_id; fill token by token }; class Compiler { private: // The result index_t root_node_id{}; std::vector nodes; // Input std::vector tokens; // Helper data index_t tokens_used{0}; // number of tokens used, this is also the next token index to use const BNF &bnf; const std::string& Top; std::map> ReverseBNF; // possible parent types of a given type public: // Tree specific void clear(); // Node specific std::string GetTypeOfNode(index_t node_id) const; index_t TrackBack(); void Validate(const std::string& Top, const BNF& bnf) const; void Dump(); Compiler(const BNF& bnf, const std::string& Top); std::pair> compile(std::vector Tokens); }; } // namespace Gram