boost spirit AST portieren von 1.8 nach 2.4



  • Hallo zusammen!

    Ich habe momentan vor allem ein konzeptionelles Problem, und hoffe hier erst mal Hilfe zu finden bevor ich die Mailingliste nerve 😉

    Ich möchte ein Projekt, welches eine mehr oder weniger umfangreiche Interpretersprache benutzt portieren. Bisher benutzt dieses Projekt boost spirit 1.8 und kompiliert nur unter Visual Studio 2005 vernünftig. Da wir das Buildsystem zu VS 2010 wechseln möchten, überlegen wir auch eine Portierung auf die aktuelle boost version. Nun stellte sich aber heraus, dass die Kompilierung scheitert mit der Verwendung von boost::spirit::classic. Deshalb würden wir den "komplizierten" Weg gehen und zu spirit::qi portieren 😉
    Nun habe ich aber das ein oder andere Verständnisproblem nachdem ich mich nun in qi eingearbeitet habe.

    Das entsprechende Modul hat folgende Schnittstelle:

    using namespace boost::spirit;
    
    typedef node_val_data_factory<const char *>				int_factory_t;
    typedef char const*										iterator_t;
    typedef tree_match<iterator_t, int_factory_t>			parse_tree_match_t;
    typedef parse_tree_match_t::tree_iterator				iter_t;
    typedef	tree_parse_info<const char *, int_factory_t>	tpi_type;
    
    class CGrammar 
    {
    public:
    	CGrammar();
    	~CGrammar();
    	bool ParseString(const CString *s, const SFormula *f, tpi_type *i, int *stopchar); 
    	double EvaluateTree(CFormula * const f, tpi_type info, CEvalInfoFunction **logCallingFunction, int *e);
    	double CalcF$symbol(CFormula * const f, char *symbol, bool log, int *e);
    	double CalcF$symbol(CFormula * const f, char *symbol, int *e);
    	double DoCalcF$symbol(CFormula * const f, char *symbol, CEvalInfoFunction **logCallingFunction, bool skipCache, int *e);
    	static void SetPosition(parse_tree_match_t::node_t &node, const char *begin, const char *end) { node.value.value(begin); } 
    	static void ValidateSymbol(const char *begin, const char *end);
    public:
    	const CArray<std::string, std::string> * parse_symbol_stop_strs() { return &_parse_symbol_stop_strs; }
    private:
    	double EvaluateExpression(CFormula * const f, iter_t const& i, CEvalInfoFunction **logCallingFunction, int *e);
    	double DoEvaluateExpression(CFormula * const f, iter_t const& i, CEvalInfoFunction **logCallingFunction, int *e);
    	double EvaluateSymbol(CFormula * const f, string sym, CEvalInfoFunction **logCallingFunction, int *e);
    	static void SetOffsets(iter_t &i, const char *start);
    
    	unsigned int				_RecursionDepth;	// To detect endless recursion in DoCalcF$symbol(...);
    	static const unsigned int	_MAX_RECURSION_DEPTH = 1000;
    
    	// Result of formula set currently being parsed (this is for symbol validation)
    	CArray<std::string, std::string>  _parse_symbol_stop_strs;
    };
    

    Bei der Benutzung wird zuerst ein AST mit dem Aufruf von ParseString() gebaut (dies ist die einzige Funktion, welche ast_parse() aufruft und die Grammer, sowie Skip-Grammer benutzt).
    Danach ruft der Client EvaluateTree() oder eine direkte CalcF$Symbol() Funktion auf. Nun Frage ich mich, ob es möglich ist, das Interface vorerst zu behalten. Allerdings sehe ich jetzt schon Schwierigkeiten. Muss ich versuchen beim parsen eine Baumstruktur nachzubauen um weiterhin mit EvaluateTree() arbeiten zu können?
    Hat jemand eine Idee wie ich das Vermeiden kann, und vielleicht eleganter lösen könnte?
    Eigentlich möchte ich ja nur das Ergebnis eines Codeblocks bekommen, der zu einem double evaluiert.

    Help! 🙂



  • wenn ich das recht sehe, brauchst du mit qi kein tree_parse_info mehr.
    wenn du die funktionen mit der signatur behalten willst, solltest du den typedef zu etwas "sinnlosem" ändern.



  • Ich glaube Du solltest Dir mal http://www.boost.org/doc/libs/1_41_0/libs/spirit/example/qi/calc2_ast.cpp ansehen.
    Vielleicht kannst du den tree-Iterator ersetzen durch eine clevere Variant-Node.


Anmelden zum Antworten