Use the new parser in the ex(const string&, lst&) ctor.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Sun, 14 Sep 2008 02:24:29 +0000 (06:24 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Fri, 19 Sep 2008 09:15:50 +0000 (13:15 +0400)
Note: this is certainly not the optimal way to use the parser. It's provided
for backward compatibility only.

ginac/Makefile.am
ginac/ex.cpp
ginac/parser/parser_compat.cpp [new file with mode: 0644]

index 17b272f..2614c45 100644 (file)
@@ -16,6 +16,7 @@ libginac_la_SOURCES = add.cpp archive.cpp basic.cpp clifford.cpp color.cpp \
   parser/builtin_fcns.cpp \
   parser/lexer.cpp \
   parser/lexer.hpp \
+  parser/parser_compat.cpp \
   parser/debug.hpp
   
 libginac_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -release $(LT_RELEASE)
index 377b15b..7becb3e 100644 (file)
@@ -553,17 +553,6 @@ basic & ex::construct_from_double(double d)
        return *bp;
 }
 
-ptr<basic> ex::construct_from_string_and_lst(const std::string &s, const ex &l)
-{
-       set_lexer_string(s);
-       set_lexer_symbols(l);
-       ginac_yyrestart(NULL);
-       if (ginac_yyparse())
-               throw (std::runtime_error(get_parser_error()));
-       else
-               return parsed_ex.bp;
-}
-       
 //////////
 // static member variables
 //////////
diff --git a/ginac/parser/parser_compat.cpp b/ginac/parser/parser_compat.cpp
new file mode 100644 (file)
index 0000000..d0723ee
--- /dev/null
@@ -0,0 +1,49 @@
+/// @file parser_compat.cpp Parser interface compatible with the old
+///       (bison/flex based) parser.
+#include "ex.h"
+#include "idx.h"
+#include "lst.h"
+#include "parser.hpp"
+#include <string>
+#include <iostream>
+
+namespace GiNaC
+{
+static symtab make_symtab(const ex& l);
+
+ptr<basic> ex::construct_from_string_and_lst(const std::string &s, const ex &l)
+{
+       static const bool strict = true;
+       symtab syms = make_symtab(l);
+       parser reader(syms, strict); 
+       ex parsed_ex = reader(s);
+       return parsed_ex.bp;
+}
+
+static std::string get_symbol_name(const ex & s);
+
+static symtab make_symtab(const ex& l)
+{
+       symtab syms;
+       if (is_exactly_a<lst>(l)) {
+               for (std::size_t i = 0; i < l.nops(); i++) {
+                       const ex &o = l.op(i);
+                       if (is_a<symbol>(o) || (is_a<idx>(o) && is_a<symbol>(o.op(0))))
+                               syms[get_symbol_name(o)] = o;
+               }
+       }
+       return syms;
+}
+
+static std::string get_symbol_name(const ex & s)
+{
+       if (is_a<symbol>(s))
+               return ex_to<symbol>(s).get_name();
+       else if (is_a<idx>(s) && is_a<symbol>(s.op(0)))
+               return ex_to<symbol>(s.op(0)).get_name();
+       else
+               throw (std::invalid_argument("get_symbol_name(): unexpected expression type"));
+}
+
+}
+