523964d80a2ce033bb5ce1b8ef727d045c362b2d
[ginac.git] / ginac / parser / parser.h
1 #ifndef GINAC_PARSER_HPP_
2 #define GINAC_PARSER_HPP_
3
4 #include "parse_context.h"
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();
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 bool strict_ = false,
66                 const prototype_table& funcs_ = get_default_reader());
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         /// read/write access to the symbol table
80         symtab& get_syms()
81         {
82                 return syms;
83         }
84
85         /// If true, throw an exception if an unknown symbol is encountered.
86         bool strict;
87 private:
88         /**
89          * Function/ctor table, maps a prototype (which is a name and number
90          * arguments) to a C++ function. Used for parsing identifier_expr's
91          * (see parse_identifier_expr). If expression contains unknown
92          * prototype, an exception will be thrown.
93          */
94         const prototype_table funcs;
95         /**
96          * Symbol (variable) table. Used for parsing identifier_expr's
97          * (see parse_identifier_expr). If parser is strict, exception is
98          * thrown if an unknown symbol is encountered. Non-strict parser
99          * appends unknown symbols to the symbol table.
100          */
101         symtab syms;
102         /// token scanner
103         lexer* scanner;
104         /// current token the parser is looking at
105         int token;
106         /// read the next token from the scanner
107         int get_next_tok();
108 };
109
110 } // namespace GiNaC
111
112 #endif // GINAC_PARSER_HPP_
113