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