1 /** @file input_parser.yy
3 * Input grammar definition for reading expressions.
4 * This file must be processed with yacc/bison. */
7 * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "input_lexer.h"
34 #include "relational.h"
42 #ifndef NO_NAMESPACE_GINAC
44 #endif // ndef NO_NAMESPACE_GINAC
46 #define YYERROR_VERBOSE 1
48 #define yylex ginac_yylex
49 #define yyerror ginac_yyerror
51 // Parsed output expression
54 // Last error message returned by parser
55 static string parser_error;
58 /* Tokens (T_LITERAL means a literal value returned by the parser, but not
59 of class numeric or symbol (e.g. a constant or the FAIL object)) */
60 %token T_NUMBER T_SYMBOL T_LITERAL T_DIGITS T_EQUAL T_NOTEQ T_LESSEQ T_GREATEREQ T_MATRIX_BEGIN T_MATRIX_END
62 /* Operator precedence and associativity */
65 %left '<' '>' T_LESSEQ T_GREATEREQ
84 } catch (exception &e) {
85 parser_error = e.what();
89 | error {yyclearin; yyerrok;}
92 exp : T_NUMBER {$$ = $1;}
93 | T_SYMBOL {$$ = $1.eval();}
94 | T_LITERAL {$$ = $1;}
96 | T_SYMBOL '(' exprseq ')' {
97 unsigned i = function::find_function(ex_to_symbol($1).getname(), $3.nops());
98 $$ = function(i, static_cast<const exprseq &>(*($3.bp)));
100 | exp T_EQUAL exp {$$ = $1 == $3;}
101 | exp T_NOTEQ exp {$$ = $1 != $3;}
102 | exp '<' exp {$$ = $1 < $3;}
103 | exp T_LESSEQ exp {$$ = $1 <= $3;}
104 | exp '>' exp {$$ = $1 > $3;}
105 | exp T_GREATEREQ exp {$$ = $1 >= $3;}
106 | exp '+' exp {$$ = $1 + $3;}
107 | exp '-' exp {$$ = $1 - $3;}
108 | exp '*' exp {$$ = $1 * $3;}
109 | exp '/' exp {$$ = $1 / $3;}
110 | exp '%' exp {$$ = $1 % $3;}
111 | '-' exp %prec NEG {$$ = -$2;}
112 | '+' exp %prec NEG {$$ = $2;}
113 | exp '^' exp {$$ = pow($1, $3);}
114 | exp '!' {$$ = factorial($1);}
115 | '(' exp ')' {$$ = $2;}
116 | '[' list_or_empty ']' {$$ = $2;}
117 | T_MATRIX_BEGIN matrix T_MATRIX_END {$$ = lst_to_matrix($2);}
120 exprseq : exp {$$ = exprseq($1);}
121 | exprseq ',' exp {exprseq es(static_cast<exprseq &>(*($1.bp))); $$ = es.append($3);}
124 list_or_empty: /* empty */ {$$ = *new lst;}
128 list : exp {$$ = lst($1);}
129 | list ',' exp {lst l(static_cast<lst &>(*($1.bp))); $$ = l.append($3);}
132 matrix : T_MATRIX_BEGIN row T_MATRIX_END {$$ = lst($2);}
133 | matrix ',' T_MATRIX_BEGIN row T_MATRIX_END {lst l(static_cast<lst &>(*($1.bp))); $$ = l.append($4);}
136 row : exp {$$ = lst($1);}
137 | row ',' exp {lst l(static_cast<lst &>(*($1.bp))); $$ = l.append($3);}
146 // Get last error encountered by parser
147 string get_parser_error(void)
152 #ifndef NO_NAMESPACE_GINAC
155 using GiNaC::parser_error;
156 #endif // ndef NO_NAMESPACE_GINAC
158 // Error print routine (store error string in parser_error)
159 int ginac_yyerror(char *s)
161 parser_error = string(s) + " at " + string(ginac_yytext);