]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // node.hpp |
2 | // Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/) | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | #ifndef BOOST_LEXER_NODE_HPP | |
7 | #define BOOST_LEXER_NODE_HPP | |
8 | ||
9 | #include <boost/assert.hpp> | |
10 | #include "../../containers/ptr_vector.hpp" | |
11 | #include "../../runtime_error.hpp" | |
12 | #include "../../size_t.hpp" | |
13 | #include <stack> | |
14 | #include <vector> | |
15 | ||
16 | namespace boost | |
17 | { | |
18 | namespace lexer | |
19 | { | |
20 | namespace detail | |
21 | { | |
22 | class node | |
23 | { | |
24 | public: | |
25 | enum type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; | |
26 | ||
27 | typedef std::stack<bool> bool_stack; | |
28 | typedef std::stack<node *> node_stack; | |
29 | // stack and vector not owner of node pointers | |
30 | typedef std::stack<const node *> const_node_stack; | |
31 | typedef std::vector<node *> node_vector; | |
32 | typedef ptr_vector<node> node_ptr_vector; | |
33 | ||
34 | node () : | |
35 | _nullable (false) | |
36 | { | |
37 | } | |
38 | ||
39 | node (const bool nullable_) : | |
40 | _nullable (nullable_) | |
41 | { | |
42 | } | |
43 | ||
44 | virtual ~node () | |
45 | { | |
46 | } | |
47 | ||
48 | bool nullable () const | |
49 | { | |
50 | return _nullable; | |
51 | } | |
52 | ||
53 | void append_firstpos (node_vector &firstpos_) const | |
54 | { | |
55 | firstpos_.insert (firstpos_.end (), | |
56 | _firstpos.begin (), _firstpos.end ()); | |
57 | } | |
58 | ||
59 | void append_lastpos (node_vector &lastpos_) const | |
60 | { | |
61 | lastpos_.insert (lastpos_.end (), | |
62 | _lastpos.begin (), _lastpos.end ()); | |
63 | } | |
64 | ||
65 | virtual void append_followpos (const node_vector &/*followpos_*/) | |
66 | { | |
67 | throw runtime_error ("Internal error node::append_followpos()"); | |
68 | } | |
69 | ||
70 | node *copy (node_ptr_vector &node_ptr_vector_) const | |
71 | { | |
72 | node *new_root_ = 0; | |
73 | const_node_stack node_stack_; | |
74 | bool_stack perform_op_stack_; | |
75 | bool down_ = true; | |
76 | node_stack new_node_stack_; | |
77 | ||
78 | node_stack_.push (this); | |
79 | ||
80 | while (!node_stack_.empty ()) | |
81 | { | |
82 | while (down_) | |
83 | { | |
84 | down_ = node_stack_.top ()->traverse (node_stack_, | |
85 | perform_op_stack_); | |
86 | } | |
87 | ||
88 | while (!down_ && !node_stack_.empty ()) | |
89 | { | |
90 | const node *top_ = node_stack_.top (); | |
91 | ||
92 | top_->copy_node (node_ptr_vector_, new_node_stack_, | |
93 | perform_op_stack_, down_); | |
94 | ||
95 | if (!down_) node_stack_.pop (); | |
96 | } | |
97 | } | |
98 | ||
99 | BOOST_ASSERT(new_node_stack_.size () == 1); | |
100 | new_root_ = new_node_stack_.top (); | |
101 | new_node_stack_.pop (); | |
102 | return new_root_; | |
103 | } | |
104 | ||
105 | virtual type what_type () const = 0; | |
106 | ||
107 | virtual bool traverse (const_node_stack &node_stack_, | |
108 | bool_stack &perform_op_stack_) const = 0; | |
109 | ||
110 | node_vector &firstpos () | |
111 | { | |
112 | return _firstpos; | |
113 | } | |
114 | ||
115 | const node_vector &firstpos () const | |
116 | { | |
117 | return _firstpos; | |
118 | } | |
119 | ||
120 | // _lastpos modified externally, so not const & | |
121 | node_vector &lastpos () | |
122 | { | |
123 | return _lastpos; | |
124 | } | |
125 | ||
126 | virtual bool end_state () const | |
127 | { | |
128 | return false; | |
129 | } | |
130 | ||
131 | virtual std::size_t id () const | |
132 | { | |
133 | throw runtime_error ("Internal error node::id()"); | |
134 | } | |
135 | ||
136 | virtual std::size_t unique_id () const | |
137 | { | |
138 | throw runtime_error ("Internal error node::unique_id()"); | |
139 | } | |
140 | ||
141 | virtual std::size_t lexer_state () const | |
142 | { | |
143 | throw runtime_error ("Internal error node::state()"); | |
144 | } | |
145 | ||
146 | virtual std::size_t token () const | |
147 | { | |
148 | throw runtime_error ("Internal error node::token()"); | |
149 | } | |
150 | ||
151 | virtual void greedy (const bool /*greedy_*/) | |
152 | { | |
153 | throw runtime_error ("Internal error node::token(bool)"); | |
154 | } | |
155 | ||
156 | virtual bool greedy () const | |
157 | { | |
158 | throw runtime_error ("Internal error node::token()"); | |
159 | } | |
160 | ||
161 | virtual const node_vector &followpos () const | |
162 | { | |
163 | throw runtime_error ("Internal error node::followpos()"); | |
164 | } | |
165 | ||
166 | virtual node_vector &followpos () | |
167 | { | |
168 | throw runtime_error ("Internal error node::followpos()"); | |
169 | } | |
170 | ||
171 | protected: | |
172 | const bool _nullable; | |
173 | node_vector _firstpos; | |
174 | node_vector _lastpos; | |
175 | ||
176 | virtual void copy_node (node_ptr_vector &node_ptr_vector_, | |
177 | node_stack &new_node_stack_, bool_stack &perform_op_stack_, | |
178 | bool &down_) const = 0; | |
179 | ||
180 | private: | |
181 | node (node const &); // No copy construction. | |
182 | node &operator = (node const &); // No assignment. | |
183 | }; | |
184 | } | |
185 | } | |
186 | } | |
187 | ||
188 | #endif |