// Copyright {Jagger Software Limited} 2003 #ifndef GRAMMAR_BASE_INCLUDED #define GRAMMAR_BASE_INCLUDED #include "grammar/key_generator.hpp" #include "grammar/none_of_symbol_definition.hpp" #include "grammar/one_of_symbol_definition.hpp" #include "grammar/qualified_symbol_definition.hpp" #include "grammar/terminal_symbol_definition.hpp" #include #include #include namespace grammar { class non_terminal_symbol_definition; class base // {abstract} { protected: // 'tors base(); ~base(); protected: // associative lookup struct c_str_less { bool operator()(const char * lhs, const char * rhs) const { return ::std::strcmp(lhs, rhs) < 0; } }; ::std::map symbols; protected: // qualified non-terminals template qualified_symbol_definition create(const symbol_definition & symbol, size_t lo, const hi_type & hi) { return qualified_symbol_definition(symbol, lo, hi); } protected: // qualified terminals struct terminal { explicit terminal(const char * symbol); const char * const literal; }; template qualified_symbol_definition create(const terminal & symbol, size_t lo, const hi_type & hi) { terminal_cache.push_back(terminal_symbol_definition(key(), symbol.literal)); return qualified_symbol_definition(terminal_cache.back(), lo, hi); } protected: // qualified none-ofs struct none_of { explicit none_of(const char * symbol); const char * const literal; }; template qualified_symbol_definition create(const none_of & symbol, size_t lo, const hi_type & hi) { none_of_cache.push_back(none_of_symbol_definition(key(), symbol.literal)); return qualified_symbol_definition(none_of_cache.back(), lo, hi); } protected: // qualified one-ofs struct one_of { explicit one_of(const char * symbol); const char * const literal; }; template qualified_symbol_definition create(const one_of & symbol, size_t lo, const hi_type & hi) { one_of_cache.push_back(one_of_symbol_definition(key(), symbol.literal)); return qualified_symbol_definition(one_of_cache.back(), lo, hi); } protected: // key generation key_generator key; private: // inappropriate base(const base &); void operator=(const base &); private: // state ::std::deque terminal_cache; ::std::deque< none_of_symbol_definition> none_of_cache; ::std::deque< one_of_symbol_definition> one_of_cache; // NOTE: cache iterator lifetime dependency // cache iterators are passed as arguments to // qualified-symbol-definition constructors. }; } // if I used a sequential container here I could iterate through it // as part of the operator<< implementation and retain the input // order of the non-terminals. Loss in speed for associative lookup // but this is mainly for testing anyway... // base is used as a private hoisted base class for grammars. #endif