Home | History | Annotate | Download | only in include
      1 /**
      2  * \file
      3  * Defines the basic structures of an ANTLR3 bitset. this is a C version of the
      4  * cut down Bitset class provided with the java version of antlr 3.
      5  *
      6  *
      7  */
      8 #ifndef	_ANTLR3_BITSET_HPP
      9 #define	_ANTLR3_BITSET_HPP
     10 
     11 // [The "BSD licence"]
     12 // Copyright (c) 2005-2009 Gokulakannan Somasundaram, ElectronDB
     13 
     14 //
     15 // All rights reserved.
     16 //
     17 // Redistribution and use in source and binary forms, with or without
     18 // modification, are permitted provided that the following conditions
     19 // are met:
     20 // 1. Redistributions of source code must retain the above copyright
     21 //    notice, this list of conditions and the following disclaimer.
     22 // 2. Redistributions in binary form must reproduce the above copyright
     23 //    notice, this list of conditions and the following disclaimer in the
     24 //    documentation and/or other materials provided with the distribution.
     25 // 3. The name of the author may not be used to endorse or promote products
     26 //    derived from this software without specific prior written permission.
     27 //
     28 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     29 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     30 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     31 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     32 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     33 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     34 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     35 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     36 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     37 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     38 
     39 #include    "antlr3defs.hpp"
     40 
     41 ANTLR_BEGIN_NAMESPACE()
     42 
     43 /** How many bits in the elements
     44  */
     45 static const ANTLR_UINT32	ANTLR_BITSET_BITS =	64;
     46 
     47 /** How many bits in a nible of bits
     48  */
     49 static const ANTLR_UINT32	ANTLR_BITSET_NIBBLE	= 4;
     50 
     51 /** log2 of ANTLR3_BITSET_BITS 2^ANTLR3_BITSET_LOG_BITS = ANTLR3_BITSET_BITS
     52  */
     53 static const ANTLR_UINT32	ANTLR_BITSET_LOG_BITS =	6;
     54 
     55 /** We will often need to do a mod operator (i mod nbits).
     56  *  For powers of two, this mod operation is the
     57  *  same as:
     58  *   - (i & (nbits-1)).
     59  *
     60  * Since mod is relatively slow, we use an easily
     61  * precomputed mod mask to do the mod instead.
     62  */
     63 static const ANTLR_UINT32	ANTLR_BITSET_MOD_MASK = ANTLR_BITSET_BITS - 1;
     64 
     65 template <class ImplTraits>
     66 class BitsetList : public ImplTraits::AllocPolicyType
     67 {
     68 public:
     69 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
     70 	typedef typename ImplTraits::BitsetType BitsetType;
     71 
     72 private:
     73 	/// Pointer to the allocated array of bits for this bit set, which
     74     /// is an array of 64 bit elements (of the architecture). If we find a
     75     /// machine/C compiler that does not know anything about 64 bit values
     76     ///	then it should be easy enough to produce a 32 bit (or less) version
     77     /// of the bitset code. Note that the pointer here may be static if laid down
     78 	/// by the code generation, and it must be copied if it is to be manipulated
     79 	/// to perform followset calculations.
     80     ///
     81     ANTLR_BITWORD*  m_bits;
     82 
     83     /// Length of the current bit set in ANTLR3_UINT64 units.
     84     ///
     85     ANTLR_UINT32    m_length;
     86 
     87 public:
     88 	BitsetList();
     89 	BitsetList( ANTLR_BITWORD* bits, ANTLR_UINT32 length );
     90 
     91 	ANTLR_BITWORD* get_bits() const;
     92 	ANTLR_UINT32 get_length() const;
     93 	void set_bits( ANTLR_BITWORD* bits );
     94 	void set_length( ANTLR_UINT32 length );
     95 
     96 	///
     97 	/// \brief
     98 	/// Creates a new bitset with at least one 64 bit bset of bits, but as
     99 	/// many 64 bit sets as are required.
    100 	///
    101 	/// \param[in] bset
    102 	/// A variable number of bits to add to the set, ending in -1 (impossible bit).
    103 	///
    104 	/// \returns
    105 	/// A new bit set with all of the specified bitmaps in it and the API
    106 	/// initialized.
    107 	///
    108 	/// Call as:
    109 	///  - pANTLR3_BITSET = antlrBitsetLoad(bset, bset11, ..., -1);
    110 	///  - pANTLR3_BITSET = antlrBitsetOf(-1);  Create empty bitset
    111 	///
    112 	/// \remarks
    113 	/// Stdargs function - must supply -1 as last paremeter, which is NOT
    114 	/// added to the set.
    115 	///
    116 	///
    117 	BitsetType* bitsetLoad();
    118 
    119 	BitsetType* bitsetCopy();
    120 
    121 };
    122 
    123 template <class ImplTraits>
    124 class Bitset : public ImplTraits::AllocPolicyType
    125 {
    126 public:
    127 	typedef typename ImplTraits::AllocPolicyType AllocPolicyType;
    128 	typedef typename AllocPolicyType::template ListType<ANTLR_UINT32> IntListType;
    129 	typedef typename ImplTraits::BitsetListType BitsetListType;
    130 
    131 private:
    132 	/// The actual bits themselves
    133 	///
    134 	BitsetListType		m_blist;
    135 
    136 public:
    137 	Bitset( ANTLR_UINT32 nbits=0 );
    138 	Bitset( const Bitset& bitset );
    139     Bitset*  clone() const;
    140 	Bitset*  bor(Bitset* bitset2);
    141 
    142 	BitsetListType& get_blist();
    143 	void	 borInPlace(Bitset* bitset2);
    144 	ANTLR_UINT32 size() const;
    145 	void	add(ANTLR_INT32 bit);
    146 	void	grow(ANTLR_INT32 newSize);
    147 	bool	equals(Bitset* bitset2) const;
    148 	bool	isMember(ANTLR_UINT32 bit) const;
    149 	ANTLR_UINT32 numBits() const;
    150 	void remove(ANTLR_UINT32 bit);
    151 	bool isNilNode() const;
    152 
    153 	/** Produce an integer list of all the bits that are turned on
    154 	 *  in this bitset. Used for error processing in the main as the bitset
    155 	 *  reresents a number of integer tokens which we use for follow sets
    156 	 *  and so on.
    157 	 *
    158 	 *  The first entry is the number of elements following in the list.
    159 	 */
    160 	ANTLR_INT32* toIntList() const;
    161 
    162 	///
    163 	/// \brief
    164 	/// Creates a new bitset with at least one element, but as
    165 	/// many elements are required.
    166 	///
    167 	/// \param[in] bit
    168 	/// A variable number of bits to add to the set, ending in -1 (impossible bit).
    169 	///
    170 	/// \returns
    171 	/// A new bit set with all of the specified elements added into it.
    172 	///
    173 	/// Call as:
    174 	///  - pANTLR3_BITSET = antlrBitsetOf(n, n1, n2, -1);
    175 	///  - pANTLR3_BITSET = antlrBitsetOf(-1);  Create empty bitset
    176 	///
    177 	/// \remarks
    178 	/// Stdargs function - must supply -1 as last paremeter, which is NOT
    179 	/// added to the set.
    180 	///
    181 	///
    182 	//C++ doesn't like variable length arguments. so use function overloading
    183 	static Bitset* BitsetOf(ANTLR_INT32 bit);
    184 	static Bitset* BitsetOf(ANTLR_INT32 bit1, ANTLR_INT32 bit2);
    185 
    186 	///
    187 	/// \brief
    188 	/// Creates a new bitset with at least one 64 bit bset of bits, but as
    189 	/// many 64 bit sets as are required.
    190 	///
    191 	/// \param[in] bset
    192 	/// A variable number of bits to add to the set, ending in -1 (impossible bit).
    193 	///
    194 	/// \returns
    195 	/// A new bit set with all of the specified bitmaps in it and the API
    196 	/// initialized.
    197 	///
    198 	/// Call as:
    199 	///  - pANTLR3_BITSET = antlrBitsetLoad(bset, bset11, ..., -1);
    200 	///  - pANTLR3_BITSET = antlrBitsetOf(-1);  Create empty bitset
    201 	///
    202 	/// \remarks
    203 	/// Stdargs function - must supply -1 as last paremeter, which is NOT
    204 	/// added to the set.
    205 	///
    206 	///antlr3BitsetList
    207 	static Bitset*  BitsetFromList(const IntListType& list);
    208 	~Bitset();
    209 
    210 private:
    211 	void	growToInclude(ANTLR_INT32 bit);
    212 	static ANTLR_UINT64	BitMask(ANTLR_UINT32 bitNumber);
    213 	static ANTLR_UINT32	NumWordsToHold(ANTLR_UINT32 bit);
    214 	static ANTLR_UINT32	WordNumber(ANTLR_UINT32 bit);
    215 	void bitsetORInPlace(Bitset* bitset2);
    216 
    217 };
    218 
    219 ANTLR_END_NAMESPACE()
    220 
    221 #include "antlr3bitset.inl"
    222 
    223 #endif
    224 
    225