X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fparser%2Fparser.cpp;h=6ed364ffd5a155ae0bb5abeec567a8f17e3ffbaf;hp=6cac523c38625d8bddad69dcbc648d4b629665c4;hb=5252d38313c423465b9bc37b0618cb8de96d0d4e;hpb=d4593e1981a168677f98e4d3b098696bd31088e2;ds=sidebyside diff --git a/ginac/parser/parser.cpp b/ginac/parser/parser.cpp index 6cac523c..6ed364ff 100644 --- a/ginac/parser/parser.cpp +++ b/ginac/parser/parser.cpp @@ -1,13 +1,36 @@ -#include -#include -#include "parser.hpp" -#include "lexer.hpp" -#include "debug.hpp" +/** @file parser.cpp + * + * Implementation of GiNaC's parser. */ + +/* + * GiNaC Copyright (C) 1999-2009 Johannes Gutenberg University Mainz, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "parser.h" +#include "lexer.h" +#include "debug.h" #include "mul.h" #include "constant.h" +#include "function.h" -namespace GiNaC -{ +#include +#include + +namespace GiNaC { /// identifier_expr: identifier | identifier '(' expression* ')' ex parser::parse_identifier_expr() @@ -43,8 +66,18 @@ ex parser::parse_identifier_expr() Parse_error_("no function \"" << name << "\" with " << args.size() << " arguments"); } - ex ret = reader->second(args); - return ret; + // dirty hack to distinguish between serial numbers of functions and real + // pointers. + GiNaC::function* f = NULL; + try { + f = new GiNaC::function(reinterpret_cast(reader->second), args); + } + catch ( std::runtime_error ) { + if ( f ) delete f; + ex ret = reader->second(args); + return ret; + } + return f->setflag(status_flags::dynallocated); } /// paren_expr: '(' expression ')' @@ -138,6 +171,13 @@ ex parser::operator()(std::istream& input) scanner->switch_input(&input); get_next_tok(); ex ret = parse_expression(); + // parse_expression() stops if it encounters an unknown token. + // This is not a bug: since the parser is recursive checking + // whether the next token is valid is responsibility of the caller. + // Hence make sure nothing is left in the stream: + if (token != lexer::token_type::eof) + Parse_error("expected EOF"); + return ret; }