a87bcae0457c217d1677e1246c33af2fbccc9c9c
[ginac.git] / ginac / parser / parser.hpp
1 #ifndef GINAC_PARSER_HPP_
2 #define GINAC_PARSER_HPP_
3
4 #include "parse_context.hpp"
5 #include <stdexcept>
6 #include "ex.h"
7
8 namespace GiNaC
9 {
10
11 class lexer;
12
13 class parse_error : public std::invalid_argument
14 {
15 public:
16         const std::size_t line;
17         const std::size_t column;
18         parse_error(const std::string& what_,
19                     const std::size_t line_ = 0,
20                     const std::size_t column_ = 0) throw () :
21                 std::invalid_argument(what_), line(line_), column(column_)
22         { }
23 };
24
25 /**
26  * Recursive descent parser for GiNaC expressions.
27  */
28 class parser
29 {
30         // The actual parser rules (in EBNF-alike notation):
31
32         /// expression: primary binoprhs
33         ex parse_expression();
34
35         /// primary: indentifier_expr | number_expr | paren_expr | unary_expr
36         ex parse_primary();
37
38         /// binoprhs: ([+*/^-] primary)*
39         ex parse_binop_rhs(int, ex&);
40
41         /// identifier_expr: identifier |
42         ///                  identifier '(' expression (',' expression)* ')'
43         ex parse_identifier_expr();
44
45         /// paren_expr: '(' expression ')'
46         ex parse_paren_expr();
47
48         /// number_expr: number
49         ex parse_number_expr();
50
51         /// unary_expr: [+-] expression
52         ex parse_unary_expr(const int c);
53
54         /// literal_expr: 'I' | 'Pi' | 'Euler' | 'Catalan'
55         ex parse_literal_expr();
56
57 public:
58         /**
59          * @param syms_ symbol table.
60          * @param funcs_ function/ctors table.
61          * @param strict_ if true, throw an exception if unknown
62          *        symbol is encountered.
63          */
64         parser(const symtab& syms_ = symtab(),
65                 const prototype_table& funcs_ = get_default_reader(),
66                 const bool strict_ = false);
67         ~parser();
68
69         /// parse the stream @a input
70         ex operator()(std::istream& input);
71         /// parse the string @a input
72         ex operator()(const std::string& input);
73
74         /// report the symbol table used by parser
75         symtab get_syms() const 
76         { 
77                 return syms; 
78         }
79
80 private:
81         /// If true, throw an exception if an unknown symbol is encountered.
82         const bool strict;
83         /**
84          * Function/ctor table, maps a prototype (which is a name and number
85          * arguments) to a C++ function. Used for parsing identifier_expr's
86          * (see parse_identifier_expr). If expression contains unknown
87          * prototype, an exception will be thrown.
88          */
89         const prototype_table funcs;
90         /**
91          * Symbol (variable) table. Used for parsing identifier_expr's
92          * (see parse_identifier_expr). If parser is strict, exception is
93          * thrown if an unknown symbol is encountered. Non-strict parser
94          * appends unknown symbols to the symbol table.
95          */
96         symtab syms;
97         /// token scanner
98         lexer* scanner;
99         /// current token the parser is looking at
100         int token;
101         /// read the next token from the scanner
102         int get_next_tok();
103 };
104
105 } // namespace GiNaC
106
107 #endif // GINAC_PARSER_HPP_
108