From 6f64b39dd25e4d2dcc869995b3d19724fa72afa6 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Sun, 14 Sep 2008 06:41:12 +0400 Subject: [PATCH] Document the new parser, provide an example. --- doc/examples/Makefile.am | 2 +- doc/examples/derivative.cpp | 30 +++++++++++ doc/examples/ginac-examples.texi | 7 +++ doc/tutorial/ginac.texi | 92 ++++++++++++++++++++++++-------- 4 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 doc/examples/derivative.cpp diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index ef8d4d14..2a5a1088 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in EXFILES = archive1.cpp compile1.cpp compile2.cpp compile3.cpp lanczos.cpp \ - mystring.cpp + mystring.cpp derivative.cpp TEXI = ginac-examples.texi diff --git a/doc/examples/derivative.cpp b/doc/examples/derivative.cpp new file mode 100644 index 00000000..c1a09b99 --- /dev/null +++ b/doc/examples/derivative.cpp @@ -0,0 +1,30 @@ +// Input expression containing variable 'x' and compute its derivative +// with respect to 'x'. +// Example from the tutorial (chapter Input/Output, section `Expression +// input'). +#include +#include +#include +#include +using namespace std; +using namespace GiNaC; + +int main() +{ + cout << "Enter an expression containing 'x': " << flush; + parser reader; + + try { + ex e = reader(cin); + symtab table = reader.get_syms(); + + symbol x = table.find("x") != table.end() ? + ex_to(table["x"]) : symbol("x"); + + cout << "The derivative of " << e << " with respect to x is "; + cout << e.diff(x) << "." << endl; + } catch (exception &p) { + cerr << p.what() << endl; + } +} + diff --git a/doc/examples/ginac-examples.texi b/doc/examples/ginac-examples.texi index 8870dafb..2a109daa 100644 --- a/doc/examples/ginac-examples.texi +++ b/doc/examples/ginac-examples.texi @@ -30,6 +30,13 @@ This is a collection of code examples using GiNaC. Two expression are stored in an archive on the disk and are restored again. +@section Input and output of expressions + +@subsection Expression input @uref{derivative.cpp, (source)} + +Interactively input expression and compute its derivative with respect +to the ``x'' variable. + @chapter Monte Carlo Integration @section Example showing compile_ex @uref{compile1.cpp, (source)} diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 72544062..e17d4dfa 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -6380,22 +6380,72 @@ and have the @samp{x} and @samp{y} correspond to the symbols @code{x} and @code{y} you defined in your program and there is no way to specify the desired symbols to the @code{>>} stream input operator. -Instead, GiNaC lets you construct an expression from a string, specifying the -list of symbols to be used: +Instead, GiNaC lets you read an expression from a stream or a string, +specifying the mapping between the input strings and symbols to be used: @example @{ - symbol x("x"), y("y"); - ex e("2*x+sin(y)", lst(x, y)); + symbol x, y; + symtab table; + table["x"] = x; + table["y"] = y; + parser reader(table); + ex e = reader("2*x+sin(y)"); @} @end example The input syntax is the same as that used by @command{ginsh} and the stream -output operator @code{<<}. The symbols in the string are matched by name to -the symbols in the list and if GiNaC encounters a symbol not specified in -the list it will throw an exception. +output operator @code{<<}. Matching between the input strings and expressions +is given by @samp{table}. The @samp{table} in this example instructs GiNaC +to substitute any input substring ``x'' with symbol @code{x}. Likewise, +the substring ``y'' will be replaced with symbol @code{y}. It's also possible +to map input (sub)strings to arbitrary expressions: -With this constructor, it's also easy to implement interactive GiNaC programs: +@example +@{ + symbol x, y; + symtab table; + table["x"] = x+log(y)+1; + parser reader(table); + ex e = reader("5*x^3 - x^2"); + // e = 5*(x+log(y)+1)^3 + (x+log(y)+1)^2 +@} +@end example + +If no mapping is specified for a particular string GiNaC will create a symbol +with corresponding name. Later on you can obtain all parser generated symbols +with @code{get_syms()} method: + +@example +@{ + parser reader; + ex e = reader("2*x+sin(y)"); + symtab table = reader.get_syms(); + symbol x = reader["x"]; + symbol y = reader["y"]; +@} +@end example + +Sometimes you might want to prevent GiNaC from inserting these extra symbols +(for example, you want treat an unexpected string in the input as an error). + +@example +@{ + symtab table; + table["x"] = symbol(); + parser reader(table); + parser.strict = true; + ex e; + try @{ + e = reader("2*x+sin(y)"); + @} catch (parse_error& err) @{ + cerr << err.what() << endl; + // prints "unknown symbol "y" in the input" + @} +@} +@end example + +With this parser, it's also easy to implement interactive GiNaC programs: @example #include @@ -6407,19 +6457,19 @@ using namespace GiNaC; int main() @{ - symbol x("x"); - string s; - - cout << "Enter an expression containing 'x': "; - getline(cin, s); - - try @{ - ex e(s, lst(x)); - cout << "The derivative of " << e << " with respect to x is "; - cout << e.diff(x) << ".\n"; - @} catch (exception &p) @{ - cerr << p.what() << endl; - @} + cout << "Enter an expression containing 'x': " << flush; + parser reader; + + try @{ + ex e = reader(cin); + symtab table = reader.get_syms(); + symbol x = table.find("x") != table.end() ? + ex_to(table["x"]) : symbol("x"); + cout << "The derivative of " << e << " with respect to x is "; + cout << e.diff(x) << "." << endl; + @} catch (exception &p) @{ + cerr << p.what() << endl; + @} @} @end example -- 2.44.0