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