Changed the parser such that it understands all defined functions
authorJens Vollinga <jensv@nikhef.nl>
Fri, 10 Jul 2009 13:01:04 +0000 (15:01 +0200)
committerJens Vollinga <jensv@nikhef.nl>
Fri, 10 Jul 2009 13:01:04 +0000 (15:01 +0200)
including the user defined ones.

To this end a method has been added to class function to allow the
modified get_default_reader() function to build up a complete prototype
table. The autogen tool is no longer required.

INSTALL
configure.ac
ginac/Makefile.am
ginac/function.pl
ginac/parser/builtin_fcns.def [deleted file]
ginac/parser/default_reader.tpl [deleted file]
ginac/parser/parse_context.cpp
ginac/parser/parse_context.h
ginac/parser/parser.cpp

diff --git a/INSTALL b/INSTALL
index 3be16c1..3c188b6 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -30,8 +30,7 @@ Known not to work with:
    is missing there.
 
 If you install from git, you also need GNU autoconf (>=2.59), automake (>=1.8),
-libtool (>= 1.5), bison (>= 2.3), flex (>= 2.5.33), autogen (>= 5.6.0) to be
-installed.
+libtool (>= 1.5), bison (>= 2.3), flex (>= 2.5.33) to be installed.
 
 
 INSTALLATION
index 551f4f9..14b888f 100644 (file)
@@ -119,10 +119,6 @@ AM_CONDITIONAL(CONFIG_TEX, [test ! \( -z "$LATEX" -o -z $"PDFLATEX" -o -z "$MAKE
 AC_PATH_PROG(FIG2DEV, fig2dev, "")
 AM_CONDITIONAL(CONFIG_FIG2DEV, [test ! -z "$FIG2DEV"])
 
-dnl generate boilerplate code for the (new) parser.
-dnl Only developers need this tool.
-AC_PATH_PROG(AUTOGEN, autogen, "")
-
 dnl Output makefiles etc.
 AC_CONFIG_FILES([
 Makefile
index bf20afc..03e1845 100644 (file)
@@ -13,7 +13,6 @@ libginac_la_SOURCES = add.cpp archive.cpp basic.cpp clifford.cpp color.cpp \
   parser/parse_binop_rhs.cpp \
   parser/parser.cpp \
   parser/parse_context.cpp \
-  parser/builtin_fcns.cpp \
   parser/lexer.cpp \
   parser/lexer.h \
   parser/parser_compat.cpp \
@@ -67,22 +66,7 @@ ginacinclude_HEADERS = ginac.h add.h archive.h assertion.h basic.h class_info.h
   parser/parser.h \
   parser/parse_context.h
 
-EXTRA_DIST = function.pl version.h.in \
-parser/default_reader.tpl parser/builtin_fcns.def
-
-# Files produced by autogen(1) from templates
-$(srcdir)/parser/builtin_fcns.cpp: $(srcdir)/parser/builtin_fcns.def $(srcdir)/parser/default_reader.tpl
-       set -e; if [ -n "$(AUTOGEN)" ]; then \
-               cd $(srcdir)/parser; \
-               $(AUTOGEN) -T default_reader.tpl builtin_fcns.def; \
-       elif [ -f $@ ]; then \
-               echo "WARNING: AutoGen is not available, the \"$@\" file WON'T be re-generated"; \
-       else \
-               echo "*** ERROR: the \"$@\" file does not exist, and AutoGen is not installed on your system"; \
-               echo "***        Please install AutoGen (http://www.gnu.org/software/autogen)"; \
-               exit 1; \
-       fi
-               
+EXTRA_DIST = function.pl version.h.in
 
 # Files which are generated by perl scripts
 $(srcdir)/function.h $(srcdir)/function.cpp: $(srcdir)/function.pl
index e1533be..af14a75 100644 (file)
@@ -536,6 +536,7 @@ public:
        static unsigned register_new(function_options const & opt);
        static unsigned current_serial;
        static unsigned find_function(const std::string &name, unsigned nparams);
+       static std::vector<function_options> get_registered_functions() { return registered_functions(); };
        unsigned get_serial() const {return serial;}
        std::string get_name() const;
 
diff --git a/ginac/parser/builtin_fcns.def b/ginac/parser/builtin_fcns.def
deleted file mode 100644 (file)
index 897b1f7..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-Autogen definitions ginacfcns;
-
-function = { name = "log"; };
-function = { name = "exp"; };
-function = { name = "sin"; };
-function = { name = "cos"; };
-function = { name = "tan"; };
-function = { name = "asin"; };
-function = { name = "acos"; };
-function = { name = "atan"; };
-
-function = { name = "sinh"; };
-function = { name = "cosh"; };
-function = { name = "tanh"; };
-function = { name = "asinh"; };
-function = { name = "acosh"; };
-function = { name = "atanh"; };
-
-function = { 
-       name = "atan2";
-       args = 2;
-};
-
-function = { 
-       name = "Li2";
-       comment = "Dilogarithm";
-};
-
-function = {
-       name = "Li3";
-       comment = "Trilogarithm";
-};
-
-function = {
-       name = "zetaderiv";
-       comment = "Derivatives of Riemann's Zeta-function";
-       args = 2;
-};
-
-function = {
-       name = "Li";
-       args = 2;
-       comment = "Polylogarithm and multiple polylogarithm";
-};
-
-function = {
-       name =  "S";
-       args = 3;
-       comment = "Nielsen's generalized polylogarithm";
-};
-
-function = {
-       name =  "H";
-       args = 2;
-       comment = "Harmonic polylogarithm";
-};
-
-function = { name = "lgamma"; };
-function = { name = "tgamma"; };
-
-function = {
-       name = "beta";
-       args = 2;
-       comment = "Beta-function";
-};
-
-function = { name = "factorial"; };
-
-function = {
-       name = "binomial";
-       args = 2;
-};
-
-function = {
-       name = "Order";
-       comment = "Order term function (for truncated power series)";
-};
-
-/* Thease are not functions, but anyway ... */
-function = { name = "sqrt"; };
-
-function = { 
-       name = "pow";
-       args = 2;
-};
-
-function = {
-       name = "power";
-       args = 2;
-};
diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl
deleted file mode 100644 (file)
index 3ae6ff8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-[+ AutoGen5 template .cpp +][+ 
-COMMENT a part of GiNaC parser -- construct functions from a byte stream.
-+][+
-(use-modules (ice-9 format))
-
-(define (sequence start end . step)
-  (let ((step (if (null? step) 1 (car step))))
-    (let loop ((n start))
-      (if (> n end) '() (cons n (loop (+ step n)))))))
-+]/*
-[+ (dne " * " " * " ) +]
- *
- * If you want to change this file, edit either `[+ (def-file) +]' or
- * `[+ (tpl-file) +]' file, and run the following command:
- *
- * autogen -T [+ (tpl-file) +] [+ (def-file) +]
- */
-#include "parse_context.h"
-#include "power.h"
-#include "operators.h"
-#include "inifcns.h"
-
-namespace GiNaC
-{
-[+ FOR function +]
-static ex [+ (get "name") +]_reader(const exvector& ev)
-{
-       return GiNaC::[+ (get "name") +]([+
-               (let ((nargs (if (exist? "args")
-                                (string->number (get "args")) 1)))
-                 (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
-}[+ ENDFOR +]
-
-const prototype_table& get_default_reader()
-{
-       using std::make_pair;
-       static bool initialized = false;
-       static prototype_table reader;
-       if (!initialized) {
-[+ FOR function +]
-               reader[make_pair("[+ (get "name") +]", [+ 
-                                   (if (exist? "args") (get "args") "1")
-                                +])] = [+ (get "name") +]_reader;[+
-   ENDFOR +]
-               initialized = true;
-       }
-       return reader;
-}
-} // namespace GiNaC
-
index 5c44202..d979027 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "parse_context.h"
 
+#include "function.h"
+
 #include <sstream>
 #include <stdexcept>
 
@@ -51,4 +53,22 @@ find_or_insert_symbol(const std::string& name, symtab& syms, const bool strict)
        return sy;
 }
 
+const prototype_table& get_default_reader(bool force_init)
+{
+       using std::make_pair;
+       static bool initialized = false;
+       static prototype_table reader;
+       if ( !initialized || force_init ) {
+               std::vector<function_options> flist = function::get_registered_functions();
+               std::vector<function_options>::iterator i = flist.begin(), end = flist.end();
+               for ( ; i != end; ++i ) {
+                       std::string name = i->get_name();
+                       unsigned narg = i->get_nparams();
+                       reader[make_pair(name, narg)] = function::find_function(name, narg);
+               }
+               initialized = true;
+       }
+       return reader;
+}
+
 } // namespace GiNaC
index 15dfcd6..c7360dd 100644 (file)
@@ -72,25 +72,18 @@ typedef ex (*reader_func)(const exvector& args);
  * foo(x+y, z^2, t)), it looks up such a table to find out which
  * function (or class) corresponds to the given name and has the given
  * number of the arguments.
- *
- * N.B.
- *
- * 1. The function don't have to return a (GiNaC) function or class, it
- *    can return any expression.
- * 2. Overloaded functions/ctors are paritally supported, i.e. there might
- *    be several functions with the same name, but they should take different
- *    number of arguments.
- * 3. User can extend the parser via custom prototype tables. It's possible
- *    to read user defined classes, create abbreviations, etc.
  */
-typedef std::map<prototype, reader_func> prototype_table;
+typedef std::map<prototype, unsigned> prototype_table;
 
 /**
- * Default prototype table.
+ * Creates a default prototype table containing all defined GiNaC functions.
  *
- * It supports most of builtin GiNaC functions.
+ * The data referenced by the return value is only created once when this
+ * function is called for the first time. This might cause problems in very
+ * rare stituations (i.e. if functions are added after this first call). In
+ * that case, a new initialization can be forced with an "true" argument.
  */
-extern const prototype_table& get_default_reader();
+extern const prototype_table& get_default_reader(bool force_init = false);
 
 } // namespace GiNaC
 
index 42edf5b..2bc2182 100644 (file)
@@ -24,6 +24,7 @@
 #include "lexer.h"
 #include "debug.h"
 #include "mul.h"
+#include "function.h"
 #include "constant.h"
 
 #include <sstream>
@@ -65,7 +66,7 @@ ex parser::parse_identifier_expr()
                Parse_error_("no function \"" << name << "\" with " <<
                             args.size() << " arguments");
        }
-       ex ret = reader->second(args);
+       ex ret = function(reader->second, args);
        return ret;
 }