1 | /// @file |
2 | /// @brief Base class for grammar productions |
3 | |
4 | #include <iostream> |
5 | #include <string> |
6 | |
7 | #ifndef PROD_HH |
8 | #define PROD_HH |
9 | |
10 | /// Base class for walking the AST |
11 | struct prod_visitor { |
12 | virtual void visit(struct prod *p) = 0; |
13 | virtual ~prod_visitor() { |
14 | } |
15 | }; |
16 | |
17 | /// Base class for AST nodes |
18 | struct prod { |
19 | /// Parent production that instanciated this one. May be NULL for |
20 | /// top-level productions. |
21 | struct prod *pprod; |
22 | /// Scope object to model column/table reference visibility. |
23 | struct scope *scope; |
24 | /// Level of this production in the AST. 0 for root node. |
25 | int level; |
26 | /// Number of retries in this production. Child productions are |
27 | /// generated speculatively and may fail. |
28 | long retries = 0; |
29 | /// Maximum number of retries allowed before reporting a failure to |
30 | /// the Parent prod. |
31 | long retry_limit = 100; |
32 | prod(prod *parent); |
33 | virtual ~prod() { |
34 | } |
35 | /// Newline and indent according to tree level. |
36 | virtual void indent(std::ostream &out); |
37 | /// Emit SQL for this production. |
38 | virtual void out(std::ostream &out) = 0; |
39 | /// Check with the impedance matching code whether this production |
40 | /// has been blacklisted and throw an exception. |
41 | virtual void match(); |
42 | /// Visitor pattern for walking the AST. Make sure you visit all |
43 | /// child production when deriving classes. |
44 | virtual void accept(prod_visitor *v) { |
45 | v->visit(this); |
46 | } |
47 | /// Report a "failed to generate" error. |
48 | virtual void fail(const char *reason); |
49 | /// Increase the retry count and throw an exception when retry_limit |
50 | /// is exceeded. |
51 | void retry(); |
52 | }; |
53 | |
54 | inline std::ostream &operator<<(std::ostream &s, prod &p) { |
55 | p.out(s); |
56 | return s; |
57 | } |
58 | |
59 | #endif |
60 | |