xref: /aosp_15_r20/external/antlr/runtime/Cpp/include/antlr3rewritestreams.hpp (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot #ifndef	ANTLR3REWRITESTREAM_HPP
2*16467b97STreehugger Robot #define	ANTLR3REWRITESTREAM_HPP
3*16467b97STreehugger Robot 
4*16467b97STreehugger Robot // [The "BSD licence"]
5*16467b97STreehugger Robot // Copyright (c) 2005-2009 Gokulakannan Somasundaram, ElectronDB
6*16467b97STreehugger Robot 
7*16467b97STreehugger Robot //
8*16467b97STreehugger Robot // All rights reserved.
9*16467b97STreehugger Robot //
10*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
11*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
12*16467b97STreehugger Robot // are met:
13*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
14*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
15*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
16*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
17*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
18*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
19*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
20*16467b97STreehugger Robot //
21*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*16467b97STreehugger Robot 
32*16467b97STreehugger Robot #include    "antlr3defs.hpp"
33*16467b97STreehugger Robot 
34*16467b97STreehugger Robot /// A generic list of elements tracked in an alternative to be used in
35*16467b97STreehugger Robot /// a -> rewrite rule.
36*16467b97STreehugger Robot ///
37*16467b97STreehugger Robot /// In the C implementation, all tree oriented streams return a pointer to
38*16467b97STreehugger Robot /// the same type: pANTLR3_BASE_TREE. Anything that has subclassed from this
39*16467b97STreehugger Robot /// still passes this type, within which there is a super pointer, which points
40*16467b97STreehugger Robot /// to it's own data and methods. Hence we do not need to implement this as
41*16467b97STreehugger Robot /// the equivalent of an abstract class, but just fill in the appropriate interface
42*16467b97STreehugger Robot /// as usual with this model.
43*16467b97STreehugger Robot ///
44*16467b97STreehugger Robot /// Once you start next()ing, do not try to add more elements.  It will
45*16467b97STreehugger Robot /// break the cursor tracking I believe.
46*16467b97STreehugger Robot ///
47*16467b97STreehugger Robot ///
48*16467b97STreehugger Robot /// \see #pANTLR3_REWRITE_RULE_NODE_STREAM
49*16467b97STreehugger Robot /// \see #pANTLR3_REWRITE_RULE_ELEMENT_STREAM
50*16467b97STreehugger Robot /// \see #pANTLR3_REWRITE_RULE_SUBTREE_STREAM
51*16467b97STreehugger Robot ///
52*16467b97STreehugger Robot /// TODO: add mechanism to detect/puke on modification after reading from stream
53*16467b97STreehugger Robot ///
54*16467b97STreehugger Robot ANTLR_BEGIN_NAMESPACE()
55*16467b97STreehugger Robot 
56*16467b97STreehugger Robot template<class ImplTraits, class SuperType>
57*16467b97STreehugger Robot class RewriteRuleElementStream  : public ImplTraits::AllocPolicyType
58*16467b97STreehugger Robot {
59*16467b97STreehugger Robot public:
60*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeType TreeType;
61*16467b97STreehugger Robot 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
62*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeAdaptorType TreeAdaptorType;
63*16467b97STreehugger Robot 
64*16467b97STreehugger Robot 	typedef typename ImplTraits::template RecognizerType< typename SuperType::StreamType > RecognizerType;
65*16467b97STreehugger Robot 	typedef typename ImplTraits::StringType StringType;
66*16467b97STreehugger Robot 	typedef typename SuperType::TokenType TokenType;
67*16467b97STreehugger Robot 	typedef typename AllocPolicyType::template VectorType< TokenType* > ElementsType;
68*16467b97STreehugger Robot 
69*16467b97STreehugger Robot protected:
70*16467b97STreehugger Robot 	/// Track single elements w/o creating a list.  Upon 2nd add, alloc list
71*16467b97STreehugger Robot     ///
72*16467b97STreehugger Robot     TokenType*			m_singleElement;
73*16467b97STreehugger Robot 
74*16467b97STreehugger Robot     /// The list of tokens or subtrees we are tracking
75*16467b97STreehugger Robot     ///
76*16467b97STreehugger Robot     ElementsType		m_elements;
77*16467b97STreehugger Robot 
78*16467b97STreehugger Robot     /// The element or stream description; usually has name of the token or
79*16467b97STreehugger Robot     /// rule reference that this list tracks.  Can include rulename too, but
80*16467b97STreehugger Robot     /// the exception would track that info.
81*16467b97STreehugger Robot     ///
82*16467b97STreehugger Robot     StringType			m_elementDescription;
83*16467b97STreehugger Robot 
84*16467b97STreehugger Robot 	/// Pointer to the tree adaptor in use for this stream
85*16467b97STreehugger Robot 	///
86*16467b97STreehugger Robot     TreeAdaptorType*	m_adaptor;
87*16467b97STreehugger Robot 
88*16467b97STreehugger Robot 	// Pointer to the recognizer shared state to which this stream belongs
89*16467b97STreehugger Robot 	//
90*16467b97STreehugger Robot 	RecognizerType*			m_rec;
91*16467b97STreehugger Robot 
92*16467b97STreehugger Robot 	/// Cursor 0..n-1.  If singleElement!=NULL, cursor is 0 until you next(),
93*16467b97STreehugger Robot     /// which bumps it to 1 meaning no more elements.
94*16467b97STreehugger Robot     ///
95*16467b97STreehugger Robot     ANTLR_UINT32		m_cursor;
96*16467b97STreehugger Robot 
97*16467b97STreehugger Robot 	/// Once a node / subtree has been used in a stream, it must be dup'ed
98*16467b97STreehugger Robot 	/// from then on.  Streams are reset after sub rules so that the streams
99*16467b97STreehugger Robot 	/// can be reused in future sub rules.  So, reset must set a dirty bit.
100*16467b97STreehugger Robot 	/// If dirty, then next() always returns a dup.
101*16467b97STreehugger Robot 	///
102*16467b97STreehugger Robot 	bool				m_dirty;
103*16467b97STreehugger Robot 
104*16467b97STreehugger Robot public:
105*16467b97STreehugger Robot 	RewriteRuleElementStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description);
106*16467b97STreehugger Robot 	RewriteRuleElementStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, TokenType* oneElement);
107*16467b97STreehugger Robot 	RewriteRuleElementStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, const ElementsType& elements);
108*16467b97STreehugger Robot 
109*16467b97STreehugger Robot 	~RewriteRuleElementStream();
110*16467b97STreehugger Robot     //   Methods
111*16467b97STreehugger Robot 
112*16467b97STreehugger Robot     /// Reset the condition of this stream so that it appears we have
113*16467b97STreehugger Robot     ///  not consumed any of its elements.  Elements themselves are untouched.
114*16467b97STreehugger Robot     ///
115*16467b97STreehugger Robot     void	reset();
116*16467b97STreehugger Robot 
117*16467b97STreehugger Robot     /// Add a new pANTLR3_BASE_TREE to this stream
118*16467b97STreehugger Robot     ///
119*16467b97STreehugger Robot     void	add(TokenType* el);
120*16467b97STreehugger Robot 
121*16467b97STreehugger Robot     /// Return the next element in the stream.  If out of elements, throw
122*16467b97STreehugger Robot     /// an exception unless size()==1.  If size is 1, then return elements[0].
123*16467b97STreehugger Robot     ///
124*16467b97STreehugger Robot 	TokenType*	next();
125*16467b97STreehugger Robot     TreeType*	nextTree();
126*16467b97STreehugger Robot     TokenType*	nextToken();
127*16467b97STreehugger Robot     TokenType*	_next();
128*16467b97STreehugger Robot 
129*16467b97STreehugger Robot 	/// When constructing trees, sometimes we need to dup a token or AST
130*16467b97STreehugger Robot     ///	subtree.  Dup'ing a token means just creating another AST node
131*16467b97STreehugger Robot     /// around it.  For trees, you must call the adaptor.dupTree().
132*16467b97STreehugger Robot     ///
133*16467b97STreehugger Robot 	TokenType* dup( TokenType* el );
134*16467b97STreehugger Robot 
135*16467b97STreehugger Robot     /// Ensure stream emits trees; tokens must be converted to AST nodes.
136*16467b97STreehugger Robot     /// AST nodes can be passed through unmolested.
137*16467b97STreehugger Robot     ///
138*16467b97STreehugger Robot     TreeType*	toTree(TreeType* el);
139*16467b97STreehugger Robot 
140*16467b97STreehugger Robot     /// Returns true if there is a next element available
141*16467b97STreehugger Robot     ///
142*16467b97STreehugger Robot     bool	hasNext();
143*16467b97STreehugger Robot 
144*16467b97STreehugger Robot     /// Treat next element as a single node even if it's a subtree.
145*16467b97STreehugger Robot     /// This is used instead of next() when the result has to be a
146*16467b97STreehugger Robot     /// tree root node.  Also prevents us from duplicating recently-added
147*16467b97STreehugger Robot     /// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
148*16467b97STreehugger Robot     /// must dup the type node, but ID has been added.
149*16467b97STreehugger Robot     ///
150*16467b97STreehugger Robot     /// Referencing to a rule result twice is ok; dup entire tree as
151*16467b97STreehugger Robot     /// we can't be adding trees; e.g., expr expr.
152*16467b97STreehugger Robot     ///
153*16467b97STreehugger Robot     TreeType*	nextNode();
154*16467b97STreehugger Robot 
155*16467b97STreehugger Robot     /// Number of elements available in the stream
156*16467b97STreehugger Robot     ///
157*16467b97STreehugger Robot     ANTLR_UINT32	size();
158*16467b97STreehugger Robot 
159*16467b97STreehugger Robot     /// Returns the description string if there is one available (check for NULL).
160*16467b97STreehugger Robot     ///
161*16467b97STreehugger Robot     StringType getDescription();
162*16467b97STreehugger Robot 
163*16467b97STreehugger Robot protected:
164*16467b97STreehugger Robot 	void init(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description);
165*16467b97STreehugger Robot };
166*16467b97STreehugger Robot 
167*16467b97STreehugger Robot /// This is an implementation of a token stream, which is basically an element
168*16467b97STreehugger Robot ///  stream that deals with tokens only.
169*16467b97STreehugger Robot ///
170*16467b97STreehugger Robot template<class ImplTraits>
171*16467b97STreehugger Robot class RewriteRuleTokenStream : public ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::ParserType>
172*16467b97STreehugger Robot {
173*16467b97STreehugger Robot public:
174*16467b97STreehugger Robot 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
175*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeAdaptorType TreeAdaptorType;
176*16467b97STreehugger Robot 	typedef typename ImplTraits::ParserType ComponentType;
177*16467b97STreehugger Robot 	typedef typename ComponentType::StreamType StreamType;
178*16467b97STreehugger Robot 	typedef typename ImplTraits::CommonTokenType TokenType;
179*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeType TreeType;
180*16467b97STreehugger Robot 	typedef typename AllocPolicyType::template VectorType< TokenType* > ElementsType;
181*16467b97STreehugger Robot 	typedef typename ImplTraits::template RecognizerType< StreamType > RecognizerType;
182*16467b97STreehugger Robot 	typedef typename ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::ParserType> BaseType;
183*16467b97STreehugger Robot 
184*16467b97STreehugger Robot public:
185*16467b97STreehugger Robot 	RewriteRuleTokenStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description);
186*16467b97STreehugger Robot 	RewriteRuleTokenStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, TokenType* oneElement);
187*16467b97STreehugger Robot 	RewriteRuleTokenStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, const ElementsType& elements);
188*16467b97STreehugger Robot 	TreeType*	nextNode();
189*16467b97STreehugger Robot 
190*16467b97STreehugger Robot private:
191*16467b97STreehugger Robot 	TreeType*	nextNodeToken();
192*16467b97STreehugger Robot };
193*16467b97STreehugger Robot 
194*16467b97STreehugger Robot /// This is an implementation of a subtree stream which is a set of trees
195*16467b97STreehugger Robot ///  modelled as an element stream.
196*16467b97STreehugger Robot ///
197*16467b97STreehugger Robot template<class ImplTraits>
198*16467b97STreehugger Robot class RewriteRuleSubtreeStream : public ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::TreeParserType>
199*16467b97STreehugger Robot {
200*16467b97STreehugger Robot public:
201*16467b97STreehugger Robot 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
202*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeAdaptorType TreeAdaptorType;
203*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeParserType ComponentType;
204*16467b97STreehugger Robot 	typedef typename ComponentType::StreamType StreamType;
205*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeType TreeType;
206*16467b97STreehugger Robot 	typedef TreeType TokenType;
207*16467b97STreehugger Robot 	typedef typename ImplTraits::template RecognizerType< StreamType > RecognizerType;
208*16467b97STreehugger Robot 	typedef typename AllocPolicyType::template VectorType< TokenType* > ElementsType;
209*16467b97STreehugger Robot 	typedef typename ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::TreeParserType>  BaseType;
210*16467b97STreehugger Robot 
211*16467b97STreehugger Robot public:
212*16467b97STreehugger Robot 	RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description);
213*16467b97STreehugger Robot 	RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, TokenType* oneElement);
214*16467b97STreehugger Robot 	RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, const ElementsType& elements);
215*16467b97STreehugger Robot 
216*16467b97STreehugger Robot 	TreeType* dup( TreeType* el );
217*16467b97STreehugger Robot 
218*16467b97STreehugger Robot private:
219*16467b97STreehugger Robot 	TreeType* dupTree( TreeType* el );
220*16467b97STreehugger Robot };
221*16467b97STreehugger Robot 
222*16467b97STreehugger Robot /// This is an implementation of a node stream, which is basically an element
223*16467b97STreehugger Robot ///  stream that deals with tree nodes only.
224*16467b97STreehugger Robot ///
225*16467b97STreehugger Robot template<class ImplTraits>
226*16467b97STreehugger Robot class RewriteRuleNodeStream : public ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::TreeParserType>
227*16467b97STreehugger Robot {
228*16467b97STreehugger Robot public:
229*16467b97STreehugger Robot 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
230*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeAdaptorType TreeAdaptorType;
231*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeParserType ComponentType;
232*16467b97STreehugger Robot 	typedef typename ComponentType::StreamType StreamType;
233*16467b97STreehugger Robot 	typedef typename ImplTraits::TreeType TreeType;
234*16467b97STreehugger Robot 	typedef TreeType TokenType;
235*16467b97STreehugger Robot 	typedef typename ImplTraits::template RecognizerType< StreamType > RecognizerType;
236*16467b97STreehugger Robot 	typedef typename AllocPolicyType::template VectorType< TokenType* > ElementsType;
237*16467b97STreehugger Robot 	typedef typename ImplTraits::template RewriteRuleElementStreamType< typename ImplTraits::TreeParserType>  BaseType;
238*16467b97STreehugger Robot 
239*16467b97STreehugger Robot public:
240*16467b97STreehugger Robot 	RewriteRuleNodeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description);
241*16467b97STreehugger Robot 	RewriteRuleNodeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, TokenType* oneElement);
242*16467b97STreehugger Robot 	RewriteRuleNodeStream(TreeAdaptorType* adaptor, RecognizerType* rec, ANTLR_UINT8* description, const ElementsType& elements);
243*16467b97STreehugger Robot 
244*16467b97STreehugger Robot 	TreeType*	toTree(TreeType* element);
245*16467b97STreehugger Robot 
246*16467b97STreehugger Robot private:
247*16467b97STreehugger Robot 	TreeType*	toTreeNode(TreeType* element);
248*16467b97STreehugger Robot };
249*16467b97STreehugger Robot 
250*16467b97STreehugger Robot ANTLR_END_NAMESPACE()
251*16467b97STreehugger Robot 
252*16467b97STreehugger Robot #include "antlr3rewritestreams.inl"
253*16467b97STreehugger Robot 
254*16467b97STreehugger Robot #endif
255