+ };
+
+ class Parser {
+ public:
+ typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
+ Parser* parser);
+ void addParser(const std::string& name, exp_parser parser)
+ {
+ getParserMap().insert(std::make_pair(name, parser));
+ }
+ Expression* read(const SGPropertyNode* exp)
+ {
+ ParserMap& map = getParserMap();
+ ParserMap::iterator itr = map.find(exp->getName());
+ if (itr == map.end())
+ throw ParseError(string("unknown expression ") + exp->getName());
+ exp_parser parser = itr->second;
+ return (*parser)(exp, this);
+ }
+ // XXX vector of SGSharedPtr?
+ bool readChildren(const SGPropertyNode* exp,
+ std::vector<Expression*>& result);
+ /**
+ * Function that parses a property tree, producing an expression.
+ */
+ typedef std::map<const std::string, exp_parser> ParserMap;
+ virtual ParserMap& getParserMap() = 0;
+ /**
+ * After an expression is parsed, the binding layout may contain
+ * references that need to be bound during evaluation.
+ */
+ BindingLayout& getBindingLayout() { return _bindingLayout; }
+ protected:
+ BindingLayout _bindingLayout;
+ };
+
+ class ExpressionParser : public Parser
+ {
+ public:
+ ParserMap& getParserMap() { return _parserTable; }
+ static void addExpParser(const std::string&, exp_parser);
+ protected:
+ static ParserMap _parserTable;
+ };
+
+ /**
+ * Constructor for registering parser functions.
+ */
+ struct ExpParserRegistrar
+ {
+ ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
+ {
+ ExpressionParser::addExpParser(token, parser);
+ }
+ };
+