Introduction to Spear Parser
Spear Parser (hereinafter referred to as Spear) contains the training part of Collins Model 1. It is a good entry code for understanding and implementing the Collins Model. Because the Code provided by thesis of M Collins only contains the part of Parsing and does not have the part of Training, it may be a bit difficult to understand the code of Parsing. Dan Bikel seems to be a little huge, and it is not necessary for beginners to look so complicated. So, based on the principle of laziness, I found a fairly good Spear for Google Collins Model implementation.
The Spear Parser is open-source.
To better understand Spear and record learning progress, make a series of study notes. You can see from the top down. When you remember, you can start from the bottom to the top. First, you can talk about some peripheral classes, and finally you can talk about the overall implementation ideas.
This section describes some auxiliary classes of Spear. The first class is the Smart Pointer class ).
Introduction to smart pointers
Smart pointers are a common technology in C ++. They are mainly used to prevent a pointer from pointing to a non-existent object. The core is to control the deletion time of an object. For details, refer to the introduction in C ++ Primer. The Chinese version of the fourth edition is in section 13.5.1.
Implementation of the smart pointer class in Spear
The intelligent pointer class in Spear has two main classes: RCObject and RCIPtr. RCIPtr is an implementation class of a specific smart pointer. RCObject is the parent class of all objects it can point. RCObject encapsulates the management behavior of count so that RCIPtr can use the use-count technology to implement Smart Pointer.
The code for RCObject is as follows:
- class RCObject
- {
- public:
- void addReference();
- void removeReference();
- protected:
- RCObject();
- RCObject(const RCObject& rhs);
- RCObject& operator=(const RCObject& rhs);
- virtual ~RCObject() = 0;
- public:
- unsigned short refCount;
- };
- inline RCObject::RCObject()
- : refCount(0){} // std::cout << "RCObject constr\n"; }
- inline RCObject::RCObject(const RCObject&)
- : refCount(0){} // std::cout << "RCObject copy constr\n"; }
- inline RCObject& RCObject::operator=(const RCObject&)
- {
- return *this;
- }
- inline RCObject::~RCObject() {}
- inline void RCObject::addReference()
- {
- ++refCount;
- }
- inline void RCObject::removeReference()
- {
- if (--refCount == 0) delete this;
- }
This code is quite simple, that is, common construction, copy construction, assignment, structure analysis, and refCount operations. Note that when refCount is 0 in removeReference, the current object is deleted. This is actually a Smart Pointer implementation idea. In the future, we can see that many classes inherit RCObject, so that you can use smart pointer technology to manage pointers to their objects.
RCIPtr is the implementation of Smart Pointer. It mainly involves the implementation of copy construction, assignment operators, and destructor. At the same time, it also loads various = ,! =, But these loads are not the focus.
The RCIPrt code is as follows:
- template<class T>
- class RCIPtr
- {
- public:
- explicit RCIPtr(T* realPtr = 0);
- RCIPtr(const RCIPtr& rhs);
- ~RCIPtr();
- RCIPtr& operator=(const RCIPtr& rhs);
- T* operator->() const;
- T& operator*() const;
- void clear() {
- *this = RCIPtr<T>(0);
- };
- private:
- T *pointee;
- void init() {
- if(pointee != 0) pointee->addReference();
- }
- };
Core code implementation:
- template<class T>
- RCIPtr<T>::RCIPtr(T* realPtr)
- : pointee(realPtr)
- {
- init();
- }
- template<class T>
- RCIPtr<T>::RCIPtr(const RCIPtr& rhs)
- : pointee(rhs.pointee)
- {
- init();
- }
- template<class T>
- RCIPtr<T>::~RCIPtr()
- {
- if(pointee != 0) pointee->removeReference();
- }
- template<class T>
- RCIPtr<T>& RCIPtr<T>::operator=(const RCIPtr& rhs)
- {
- if (pointee != rhs.pointee) {
- if(pointee != 0) pointee->removeReference();
- pointee = rhs.pointee;
- init();
- }
- return *this;
- }
Use of the Spear smart pointer class
RCIPtr <BankEdge> _ head; this can be considered as: BankEdge * _ head. The usage is basically the same as _ head-& gt;, and * _ head can be used as the original pointer, because all of them have been reloaded.
This article is from the "Qinghe" blog, please be sure to keep this source http://snowteng17.blog.51cto.com/1532294/541344