X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fparser%2Fparser.cpp;h=6cac523c38625d8bddad69dcbc648d4b629665c4;hp=0ee682ab7f108bc60a6a47d1141b65208a461abb;hb=d4593e1981a168677f98e4d3b098696bd31088e2;hpb=14d8318d10eb608300e006af3bc261690c14d041 diff --git a/ginac/parser/parser.cpp b/ginac/parser/parser.cpp index 0ee682ab..6cac523c 100644 --- a/ginac/parser/parser.cpp +++ b/ginac/parser/parser.cpp @@ -60,21 +60,25 @@ ex parser::parse_paren_expr() } extern numeric* _num_1_p; +extern ex _ex0; /// unary_expr: [+-] expression -ex parser::parse_unary_expr(const int s) +ex parser::parse_unary_expr() { - // consume '-' (or '+') - get_next_tok(); - ex v = parse_expression(); - switch (s) { - case '-': - return (new mul(v, *_num_1_p))->setflag(status_flags::dynallocated); - case '+': - return v; - default: - Parse_error_("invalid unary operator \"" << char(s) << "\""); - } + // Unlike most other parse_* method this one does NOT consume + // current token so parse_binop_rhs() knows what kind of operator + // is being parsed. + + // There are different kinds of expressions which need to be handled: + // -a+b + // -(a) + // +a + // +(a) + // Delegete the work to parse_binop_rhs(), otherwise we end up + // duplicating it here. + ex lhs = _ex0; // silly trick + ex e = parse_binop_rhs(0, lhs); + return e; } /// primary: identifier_expr | number_expr | paren_expr | unary_expr @@ -88,9 +92,8 @@ ex parser::parse_primary() case '(': return parse_paren_expr(); case '-': - return parse_unary_expr('-'); case '+': - return parse_unary_expr('+'); + return parse_unary_expr(); case lexer::token_type::literal: return parse_literal_expr(); case lexer::token_type::eof: @@ -118,6 +121,7 @@ ex parser::parse_number_expr() /// literal_expr: 'I' | 'Pi' | 'Euler' | 'Catalan' ex parser::parse_literal_expr() { + get_next_tok(); // consume the literal if (scanner->str == "I") return I; else if (scanner->str == "Pi")