成员标识 统一于各种链表
处理复用 利用宏

【C】更新时间 ???

typedef struct NestNode
{
    // { tode }
    struct NestNode* right;
    char* addr;
    struct NestNode* left;
    size_t type;// from `class` for C++ keyword compatibility
    size_t row, col;
    //
    struct NestNode* subf;// sub-first item
    union { void* bind; size_t flag; struct NestNode* pare; };
} nnode;// {comb with nnode}

// param:direction [0:L 1:R]#cancelled[2:SubHead 3:SubTail]
nnode* NnodeInsert(nnode* nod, int direction, nnode* parent);
// Set a part of nnode as the sub of a nnode. If subtail is null, this is for all the right part of the nnode string. If only one item, keep subhead and subtail same.
nnode* NnodeBlock(nnode* nod, nnode* subhead, nnode* subtail, nnode* parent);
// Free for self and its addr.
void NnodeReleaseTofreeDefault(void* inp);
// If freefunc is not null, free for memory will be defined by user, or just free the node block. In the direction of right.
void NnodeRelease(nnode* nod, nnode* parent, void(*freefunc)(void*));
// If freefunc is not null, free for memory will be defined by user, or just free the node block. In the direction of right.
void NnodesRelease(nnode* nod, nnode* parent, void(*freefunc)(void*));


【C++】

	class Nnode : public Tnode {
	// In fact is from Anode.h
	public:
		Nnode(void* addr = 0, Nnode* n_left = 0, Nnode* n_right = 0) :
			Tnode(addr, 0, (Tnode*)n_left, (Tnode*)n_right, 0, 0),
			addroffs), left((Nnode*&)Tnode::left), next((Nnode*&)Tnode::next { subf = 0; bind = 0; }
		Nnode(Tnode* nod) : Tnode(*nod), addroffs), left((Nnode*&)Tnode::left), next((Nnode*&)Tnode::next { subf = 0; data = 0; pare = 0; bind = 0; }
		Nnode*& left; // = (Nnode*&)Tnode::left;
		Nnode*& next; // = (Nnode*&)Tnode::next;
		char*& addr ; // = (char*&)Dnode::offs;
		Nnode* subf;
		Nnode* pare;// Want independent version? try Anode(anode.h)
		void* data;
		void* bind;
		//
		Nnode* Head() { // of parallel chain
			// return stepval(this->pare)->subf;// assert( while(...->left) )
			if (this->pare) return this->pare->subf; else {
				Nnode* crt = this; while (crt->left && (crt = crt->left));
				return crt;
			}
		}

		Nnode* Tail() { 
			Nnode* crt = this; while (crt->next && (crt = crt->next)); return crt;
		}

		bool isHead(Nnode* ifthen_reset = 0) {
			// simple: (this->pare) && (this->pare->subf == this)
			if (!this->pare) return (!this->left);
			if (this->pare->subf != this) return false;
			if (ifthen_reset) this->pare->subf = ifthen_reset;
			return true;
		}
		bool difline(Nnode* nod) { return this->row != nod->row; }
		Nnode* ReheapString(const char* str);
	};

	class NnodeChain : public TnodeChain {
	public:
		// INHERI: Count() ...
		NnodeChain(bool need_free);
		~NnodeChain();

		Nnode* Append(const void* addr, stduint typ, stduint col, stduint row);
		Nnode* Append(Tnode* tnode);// from outside of chain

		Nnode* Insert(Nnode* insnod, bool onleft = false, \
			const void* addr = 0, stduint typ = 0);
		Nnode* Insert(Nnode* insnod, Dnode* dnod, bool onleft = false);
		Nnode* Receive(Nnode* insnod, DnodeChain* dnod, bool onleft = false);

		void Sort();

		void Index(void* content);

		// can use by pseudo static (set this zero)
		Nnode* Adopt(Nnode* thisn, Nnode* subhead, Nnode* subtail = (Nnode*)~(stduint)0, bool go_func = true);

		Nnode* Root() { return (Nnode*)root_node; }
		Nnode*& RootAddress() { return root_node; }

		Nnode* Last() { return (Nnode*)last_node; }// of main trunk

		void Remove(const stduint iden);
		void Remove(const void* content);
		Nnode* Remove(Nnode* nod, bool systematic = true) {
			return NnodeRelease(nod, this, systematic);
		}

		void SetFreeContent(bool need_free);

		//[ASSUME] Contents Heaped
		NNODE_DIVSYM_RETYPE DivideSymbols(Nnode* inp, stduint width, stduint idx);
		
	protected:
		Nnode*& root_node; // = (Nnode*&)TnodeChain::root_node;
		Nnode*& last_node; // = (Nnode*&)TnodeChain::last_node;
		//{TODO}
		static Nnode* NnodeRelease(Nnode* nod, NnodeChain* nc, bool systematic = true);
		static void NnodesRelease(Nnode* nods, NnodeChain* nc);
	};

	class NestedParseUnit {
	private:
		NnodeChain* chain;
	public:
		bool parsed;
		/*tofree*/ char* msg_fail;
		stduint linemn_no, column_no;
		NodeChain* TokenOperatorGroupChain;
		NestedParseUnit(TnodeChain& tchain, NodeChain* TOGCChain);// will destructure TnodeChain
		~NestedParseUnit();
		NnodeChain* GetNetwork() { return chain; }
		// Process:
		bool Parse() {
			return NnodeParse(chain->Root(), chain);
		}
	protected:
		bool NnodeParse(Nnode* tnod, NnodeChain* chain, bool merge_parensd = true);
		bool ParseOperator(Nnode* pare, NnodeChain* nc);
	};

	typedef void(*_tok_bindfunc_t)(DnodeChain* io);
	
	struct TokenOperator {
		const char* idnop;
		const char* ident;
		_tok_bindfunc_t bindfn;
	};

	class TokenOperatorGroup {
	public:
		TokenOperator* operators;
		stduint count;
		bool left_to_right;
		stduint condition;// "?:" is ternary conditional operator
		//
		TokenOperatorGroup(TokenOperator* ops, stduint cnt, bool ltr = true, stduint cond = 2) {
			operators = ops; count = cnt; left_to_right = ltr; condition = cond;
		}
	};// usually arranged by levels for its array/chain
}

const char* StrIndexOperator(const char* str, uni::TokenOperator** operators, size_t count, bool left_to_right);