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