File Annotation

Not logged in
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #include "stdafx.h"
dcdd144598 2011-02-23        kinaba: #include "RSearch.h"
dcdd144598 2011-02-23        kinaba: #include "kilib/ktlaptr.h"
dcdd144598 2011-02-23        kinaba: using namespace ki;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	文字の種類
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: enum RegToken
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	R_Char,  // 普通の文字
dcdd144598 2011-02-23        kinaba: 	R_Any,   // '.'
dcdd144598 2011-02-23        kinaba: 	R_Lcl,   // '['
dcdd144598 2011-02-23        kinaba: 	R_Rcl,   // ']'
dcdd144598 2011-02-23        kinaba: 	R_Ncl,   // '^'
dcdd144598 2011-02-23        kinaba: 	R_Range, // '-'
dcdd144598 2011-02-23        kinaba: 	R_Lbr,   // '('
dcdd144598 2011-02-23        kinaba: 	R_Rbr,   // ')'
dcdd144598 2011-02-23        kinaba: 	R_Bar,   // '|'
dcdd144598 2011-02-23        kinaba: 	R_Star,  // '*'
dcdd144598 2011-02-23        kinaba: 	R_Plus,  // '+'
dcdd144598 2011-02-23        kinaba: 	R_Quest, // '?'
dcdd144598 2011-02-23        kinaba: 	R_End    // '\0'
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	トークンに分解
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //	行頭を表す^と行末を表す$については上位層で頑張る
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: class RegLexer
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 	RegLexer( const wchar_t* pat, ulong len );
dcdd144598 2011-02-23        kinaba: 	RegToken GetToken();
dcdd144598 2011-02-23        kinaba: 	wchar_t  GetChar() { return chr_; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	const wchar_t* pat_;
dcdd144598 2011-02-23        kinaba: 	const wchar_t* end_;
dcdd144598 2011-02-23        kinaba: 	const wchar_t* sub_;
dcdd144598 2011-02-23        kinaba: 	wchar_t        chr_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	トークンに分解:実装
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline RegLexer::RegLexer( const wchar_t* pat, ulong len )
dcdd144598 2011-02-23        kinaba: 	: pat_( pat )
dcdd144598 2011-02-23        kinaba: 	, end_( pat+len )
dcdd144598 2011-02-23        kinaba: 	, sub_( L"" )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegToken RegLexer::GetToken()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	const wchar_t*& x = (*sub_ ? sub_ : pat_);
dcdd144598 2011-02-23        kinaba: 	if( x == end_ ) return R_End;
dcdd144598 2011-02-23        kinaba: 	switch( *x++ )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case L'.': return R_Any;
dcdd144598 2011-02-23        kinaba: 	case L'[': return R_Lcl;
dcdd144598 2011-02-23        kinaba: 	case L']': return R_Rcl;
dcdd144598 2011-02-23        kinaba: 	case L'^': return R_Ncl;
dcdd144598 2011-02-23        kinaba: 	case L'-': return R_Range;
dcdd144598 2011-02-23        kinaba: 	case L'(': return R_Lbr;
dcdd144598 2011-02-23        kinaba: 	case L')': return R_Rbr;
dcdd144598 2011-02-23        kinaba: 	case L'|': return R_Bar;
dcdd144598 2011-02-23        kinaba: 	case L'*': return R_Star;
dcdd144598 2011-02-23        kinaba: 	case L'+': return R_Plus;
dcdd144598 2011-02-23        kinaba: 	case L'?': return R_Quest;
dcdd144598 2011-02-23        kinaba: 	case L'\\': if( x==end_ ) return R_End; switch( *x++ ) {
dcdd144598 2011-02-23        kinaba: 		case L't': chr_=L'\t';            return R_Char;
dcdd144598 2011-02-23        kinaba: 		case L'w': sub_=L"[0-9a-zA-Z_]";  return GetToken();
dcdd144598 2011-02-23        kinaba: 		case L'W': sub_=L"[^0-9a-zA-Z_]"; return GetToken();
dcdd144598 2011-02-23        kinaba: 		case L'd': sub_=L"[0-9]";         return GetToken();
dcdd144598 2011-02-23        kinaba: 		case L'D': sub_=L"[^0-9]";        return GetToken();
dcdd144598 2011-02-23        kinaba: 		case L's': sub_=L"[\t ]";         return GetToken();
dcdd144598 2011-02-23        kinaba: 		case L'S': sub_=L"[^\t ]";        return GetToken();
dcdd144598 2011-02-23        kinaba: 		} // fall through...
dcdd144598 2011-02-23        kinaba: 	default:
dcdd144598 2011-02-23        kinaba: 		chr_ = *(x-1);
dcdd144598 2011-02-23        kinaba: 		return R_Char;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	構文木のノードに振られる値の種類
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: enum RegType
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	N_Char,     // 普通の文字 (ch)
dcdd144598 2011-02-23        kinaba: 	N_Class,    // [...] など (cls)
dcdd144598 2011-02-23        kinaba: 	N_Concat,   // 連接       (left, right)
dcdd144598 2011-02-23        kinaba: 	N_Or,       // |          (left, right)
dcdd144598 2011-02-23        kinaba: 	N_Closure,  // *          (left)
dcdd144598 2011-02-23        kinaba: 	N_Closure1, // +          (left)
dcdd144598 2011-02-23        kinaba: 	N_01,       // ?          (left)
dcdd144598 2011-02-23        kinaba: 	N_Empty     // 空         (--)
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct RegClass
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	struct OneRange
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		wchar_t stt;
dcdd144598 2011-02-23        kinaba: 		wchar_t end;
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 	OneRange      range;
dcdd144598 2011-02-23        kinaba: 	aptr<RegClass> next;
dcdd144598 2011-02-23        kinaba: 	RegClass( wchar_t s, wchar_t e, RegClass* n )
dcdd144598 2011-02-23        kinaba: 		{ aptr<RegClass> an(n); range.stt=s, range.end=e, next=an; }
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct RegNode
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegType           type; // このノードの種類
dcdd144598 2011-02-23        kinaba: 	wchar_t             ch; // 文字
dcdd144598 2011-02-23        kinaba: 	aptr<RegClass>     cls; // 文字集合
dcdd144598 2011-02-23        kinaba: 	bool            cmpcls; // ↑補集合かどうか
dcdd144598 2011-02-23        kinaba: 	dptr<RegNode>     left; // 左の子
dcdd144598 2011-02-23        kinaba: 	dptr<RegNode>    right; // 右の子
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	構文木作成
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: class RegParser
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 	RegParser( const unicode* pat );
dcdd144598 2011-02-23        kinaba: 	RegNode* root() { return root_.get(); }
dcdd144598 2011-02-23        kinaba: 	bool err() { return err_; }
dcdd144598 2011-02-23        kinaba: 	bool isHeadType() const { return isHeadType_; }
dcdd144598 2011-02-23        kinaba: 	bool isTailType() const { return isTailType_; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	RegNode* make_empty_leaf();
dcdd144598 2011-02-23        kinaba: 	RegNode* make_char_leaf( wchar_t c );
dcdd144598 2011-02-23        kinaba: 	RegNode* make_node( RegType t, RegNode* lft, RegNode* rht );
dcdd144598 2011-02-23        kinaba: 	void eat_token();
dcdd144598 2011-02-23        kinaba: 	RegNode* expr();
dcdd144598 2011-02-23        kinaba: 	RegNode* term();
dcdd144598 2011-02-23        kinaba: 	RegNode* factor();
dcdd144598 2011-02-23        kinaba: 	RegNode* primary();
dcdd144598 2011-02-23        kinaba: 	RegNode* reclass();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	bool    err_;
dcdd144598 2011-02-23        kinaba: 	bool    isHeadType_;
dcdd144598 2011-02-23        kinaba: 	bool    isTailType_;
dcdd144598 2011-02-23        kinaba: 	dptr<RegNode> root_;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegLexer lex_;
dcdd144598 2011-02-23        kinaba: 	RegToken nextToken_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	構文木作成:実装
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: namespace { static int tmp; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline RegParser::RegParser( const unicode* pat )
dcdd144598 2011-02-23        kinaba: 	: err_       ( false )
dcdd144598 2011-02-23        kinaba: 	, isHeadType_( *pat==L'^' )
dcdd144598 2011-02-23        kinaba: 	, isTailType_( (tmp=my_lstrlenW(pat), tmp && pat[tmp-1]==L'$') )
dcdd144598 2011-02-23        kinaba: 	, lex_(
dcdd144598 2011-02-23        kinaba: 		(isHeadType_ ? pat+1 : pat),
dcdd144598 2011-02-23        kinaba: 		(my_lstrlenW(pat) - (isHeadType_ ? 1 : 0)
dcdd144598 2011-02-23        kinaba: 		                  - (isTailType_ ? 1 : 0)) )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	eat_token();
dcdd144598 2011-02-23        kinaba: 	root_ = expr();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void RegParser::eat_token()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	nextToken_ = lex_.GetToken();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline RegNode* RegParser::make_empty_leaf()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegNode* node = new RegNode;
dcdd144598 2011-02-23        kinaba: 	node->type = N_Empty;
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline RegNode* RegParser::make_char_leaf( wchar_t c )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegNode* node = new RegNode;
dcdd144598 2011-02-23        kinaba: 	node->type = N_Char;
dcdd144598 2011-02-23        kinaba: 	node->ch   = c;
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::make_node( RegType t, RegNode* lft, RegNode* rht )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegNode* node = new RegNode;
dcdd144598 2011-02-23        kinaba: 	node->type = t;
dcdd144598 2011-02-23        kinaba: 	node->left = lft;
dcdd144598 2011-02-23        kinaba: 	node->right= rht;
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::reclass()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //	CLASS   ::= '^'? CHAR (CHAR | -CHAR)*
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	bool neg = false;
dcdd144598 2011-02-23        kinaba: 	if( nextToken_ == R_Ncl )
dcdd144598 2011-02-23        kinaba: 		neg=true, eat_token();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegClass* cls = NULL;
dcdd144598 2011-02-23        kinaba: 	while( nextToken_ == R_Char )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		wchar_t ch = lex_.GetChar();
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		if( nextToken_ == R_Range )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			eat_token();
dcdd144598 2011-02-23        kinaba: 			if( nextToken_ != R_Char )
dcdd144598 2011-02-23        kinaba: 				err_ = true;
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				wchar_t ch2 = lex_.GetChar();
dcdd144598 2011-02-23        kinaba: 				cls = new RegClass( Min(ch,ch2), Max(ch,ch2), cls );
dcdd144598 2011-02-23        kinaba: 				eat_token();
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			cls = new RegClass( ch, ch, cls );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNode* node = new RegNode;
dcdd144598 2011-02-23        kinaba: 	node->type   = N_Class;
dcdd144598 2011-02-23        kinaba: 	aptr<RegClass> ncls(cls);
dcdd144598 2011-02-23        kinaba: 	node->cls    = ncls;
dcdd144598 2011-02-23        kinaba: 	node->cmpcls = neg;
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::primary()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //	PRIMARY ::= CHAR
dcdd144598 2011-02-23        kinaba: //              '.'
dcdd144598 2011-02-23        kinaba: //	            '[' CLASS ']'
dcdd144598 2011-02-23        kinaba: //				'(' REGEXP ')'
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNode* node;
dcdd144598 2011-02-23        kinaba: 	switch( nextToken_ )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case R_Char:
dcdd144598 2011-02-23        kinaba: 		node = make_char_leaf( lex_.GetChar() );
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case R_Any:{
dcdd144598 2011-02-23        kinaba: 		node         = new RegNode;
dcdd144598 2011-02-23        kinaba: 		node->type   = N_Class;
dcdd144598 2011-02-23        kinaba: 		aptr<RegClass> ncls(new RegClass( 0, 65535, NULL ));
dcdd144598 2011-02-23        kinaba: 		node->cls    = ncls;
dcdd144598 2011-02-23        kinaba: 		node->cmpcls = false;
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		}break;
dcdd144598 2011-02-23        kinaba: 	case R_Lcl:
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		node = reclass();
dcdd144598 2011-02-23        kinaba: 		if( nextToken_ == R_Rcl )
dcdd144598 2011-02-23        kinaba: 			eat_token();
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 			err_ = true;
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case R_Lbr:
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		node = expr();
dcdd144598 2011-02-23        kinaba: 		if( nextToken_ == R_Rbr )
dcdd144598 2011-02-23        kinaba: 			eat_token();
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 			err_ = true;
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	default:
dcdd144598 2011-02-23        kinaba: 		node = make_empty_leaf();
dcdd144598 2011-02-23        kinaba: 		err_ = true;
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::factor()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //	FACTOR  ::= PRIMARY
dcdd144598 2011-02-23        kinaba: //	            PRIMARY '*'
dcdd144598 2011-02-23        kinaba: //			    PRIMARY '+'
dcdd144598 2011-02-23        kinaba: //			    PRIMARY '?'
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNode* node = primary();
dcdd144598 2011-02-23        kinaba: 	switch( nextToken_ )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case R_Star: node=make_node(N_Closure,node,NULL); eat_token();break;
dcdd144598 2011-02-23        kinaba: 	case R_Plus: node=make_node(N_Closure1,node,NULL);eat_token();break;
dcdd144598 2011-02-23        kinaba: 	case R_Quest:node=make_node(N_01,node,NULL );     eat_token();break;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::term()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //	TERM    ::= EMPTY
dcdd144598 2011-02-23        kinaba: //	            FACTOR TERM
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( nextToken_ == R_End )
dcdd144598 2011-02-23        kinaba: 		return make_empty_leaf();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNode* node = factor();
dcdd144598 2011-02-23        kinaba: 	if( nextToken_==R_Lbr || nextToken_==R_Lcl
dcdd144598 2011-02-23        kinaba: 	 || nextToken_==R_Char|| nextToken_==R_Any )
dcdd144598 2011-02-23        kinaba: 		node = make_node( N_Concat, node, term() );
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNode* RegParser::expr()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //	REGEXP  ::= TERM
dcdd144598 2011-02-23        kinaba: //	            TERM '|' REGEXP
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNode* node = term();
dcdd144598 2011-02-23        kinaba: 	if( nextToken_ == R_Bar )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		eat_token();
dcdd144598 2011-02-23        kinaba: 		node = make_node( N_Or, node, expr() );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	return node;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	状態遷移
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct RegTrans
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	enum {
dcdd144598 2011-02-23        kinaba: 		Epsilon,
dcdd144598 2011-02-23        kinaba: 		Class,
dcdd144598 2011-02-23        kinaba: 		Char
dcdd144598 2011-02-23        kinaba: 	}              type;
dcdd144598 2011-02-23        kinaba: 	aptr<RegClass>  cls; // この文字集合
dcdd144598 2011-02-23        kinaba: 	                     // orEpsilon が来たら
dcdd144598 2011-02-23        kinaba: 	bool         cmpcls;
dcdd144598 2011-02-23        kinaba: 	int              to; // 状態番号toの状態へ遷移
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	aptr<RegTrans> next; // 連結リスト
dcdd144598 2011-02-23        kinaba: /*
dcdd144598 2011-02-23        kinaba: 	template<class Cmp>
dcdd144598 2011-02-23        kinaba: 	bool match_i( wchar_t c, Cmp )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		c = Cmp::map(c);
dcdd144598 2011-02-23        kinaba: 		RegClass* p = cls.get();
dcdd144598 2011-02-23        kinaba: 		while( p )
dcdd144598 2011-02-23        kinaba: 			if( Cmp::map(p->range.stt)<=c && c<=Cmp::map(p->range.end) )
dcdd144598 2011-02-23        kinaba: 				return true;
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 				p = p->next.get();
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: */
dcdd144598 2011-02-23        kinaba: 	bool match_c( wchar_t c )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		for( RegClass* p=cls.get(); p; p=p->next.get() )
dcdd144598 2011-02-23        kinaba: 			if( p->range.stt<=c && c<=p->range.end )
dcdd144598 2011-02-23        kinaba: 				return true;
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	bool match_i( wchar_t c )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		c = IgnoreCase::map(c);
dcdd144598 2011-02-23        kinaba: 		for( RegClass* p=cls.get(); p; p=p->next.get() )
dcdd144598 2011-02-23        kinaba: 			if( IgnoreCase::map(p->range.stt)<=c
dcdd144598 2011-02-23        kinaba: 			 && c<=IgnoreCase::map(p->range.end) )
dcdd144598 2011-02-23        kinaba: 				return true;
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	bool match( wchar_t c, bool caseS )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		bool m = caseS ? match_c( c ) : match_i( c );
dcdd144598 2011-02-23        kinaba: 		return cmpcls ? !m : m;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	構文木->NFA変換
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: class RegNFA
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: public:
dcdd144598 2011-02-23        kinaba: 	RegNFA( const wchar_t* pat );
dcdd144598 2011-02-23        kinaba: 	~RegNFA();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int match( const wchar_t* str, int len, bool caseS );
dcdd144598 2011-02-23        kinaba: 	bool isHeadType() const { return parser.isHeadType(); }
dcdd144598 2011-02-23        kinaba: 	bool isTailType() const { return parser.isTailType(); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	// マッチング処理
dcdd144598 2011-02-23        kinaba: 	int dfa_match( const wchar_t* str, int len, bool caseS );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	struct st_ele { int st, ps; };
dcdd144598 2011-02-23        kinaba: 	void push(storage<st_ele>& stack, int curSt, int pos);
dcdd144598 2011-02-23        kinaba: 	st_ele pop(storage<st_ele>& stack);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	void add_transition( int from, wchar_t ch, int to );
dcdd144598 2011-02-23        kinaba: 	void add_transition( int from, aptr<RegClass> cls, bool cmp, int to );
dcdd144598 2011-02-23        kinaba: 	void add_e_transition( int from, int to );
dcdd144598 2011-02-23        kinaba: 	int gen_state();
dcdd144598 2011-02-23        kinaba: 	void gen_nfa( int entry, RegNode* t, int exit );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: private:
dcdd144598 2011-02-23        kinaba: 	RegParser      parser;
dcdd144598 2011-02-23        kinaba: 	storage<RegTrans*> st;
dcdd144598 2011-02-23        kinaba: 	int      start, final;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNFA::RegNFA( const wchar_t* pat )
dcdd144598 2011-02-23        kinaba: 	: parser( pat )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	start = gen_state();
dcdd144598 2011-02-23        kinaba: 	final = gen_state();
dcdd144598 2011-02-23        kinaba: 	gen_nfa( start, parser.root(), final );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline RegNFA::~RegNFA()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	for( ulong i=0,e=st.size(); i<e; ++i )
dcdd144598 2011-02-23        kinaba: 		delete st[i];
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void RegNFA::add_transition
dcdd144598 2011-02-23        kinaba: 	( int from, aptr<RegClass> cls, bool cmp, int to )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegTrans* x = new RegTrans;
dcdd144598 2011-02-23        kinaba: 	aptr<RegTrans> nn( st[from] );
dcdd144598 2011-02-23        kinaba: 	x->next  = nn;
dcdd144598 2011-02-23        kinaba: 	x->to    = to;
dcdd144598 2011-02-23        kinaba: 	x->type  = RegTrans::Class;
dcdd144598 2011-02-23        kinaba: 	x->cls   = cls;
dcdd144598 2011-02-23        kinaba: 	x->cmpcls= cmp;
dcdd144598 2011-02-23        kinaba: 	st[from] = x;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void RegNFA::add_transition( int from, wchar_t ch, int to )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	aptr<RegClass> cls(new RegClass(ch,ch,NULL));
dcdd144598 2011-02-23        kinaba: 	add_transition( from, cls, false, to );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void RegNFA::add_e_transition( int from, int to )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RegTrans* x = new RegTrans;
dcdd144598 2011-02-23        kinaba: 	aptr<RegTrans> nn( st[from] );
dcdd144598 2011-02-23        kinaba: 	x->next  = nn;
dcdd144598 2011-02-23        kinaba: 	x->to    = to;
dcdd144598 2011-02-23        kinaba: 	x->type  = RegTrans::Epsilon;
dcdd144598 2011-02-23        kinaba: 	st[from] = x;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline int RegNFA::gen_state()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	st.Add( NULL );
dcdd144598 2011-02-23        kinaba: 	return st.size() - 1;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void RegNFA::gen_nfa( int entry, RegNode* t, int exit )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	switch( t->type )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case N_Char:
dcdd144598 2011-02-23        kinaba: 		//         ch
dcdd144598 2011-02-23        kinaba: 		//  entry ----> exit
dcdd144598 2011-02-23        kinaba: 		add_transition( entry, t->ch, exit );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case N_Class:
dcdd144598 2011-02-23        kinaba: 		//         cls
dcdd144598 2011-02-23        kinaba: 		//  entry -----> exit
dcdd144598 2011-02-23        kinaba: 		add_transition( entry, t->cls, t->cmpcls, exit );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case N_Concat: {
dcdd144598 2011-02-23        kinaba: 		//         left         right
dcdd144598 2011-02-23        kinaba: 		//  entry ------> step -------> exit
dcdd144598 2011-02-23        kinaba: 		int step = gen_state();
dcdd144598 2011-02-23        kinaba: 		gen_nfa( entry, t->left.get(), step );
dcdd144598 2011-02-23        kinaba: 		gen_nfa( step, t->right.get(), exit );
dcdd144598 2011-02-23        kinaba: 		} break;
dcdd144598 2011-02-23        kinaba: 	case N_Or:
dcdd144598 2011-02-23        kinaba: 		//          left
dcdd144598 2011-02-23        kinaba: 		//         ------>
dcdd144598 2011-02-23        kinaba: 		//  entry ------->--> exit
dcdd144598 2011-02-23        kinaba: 		//          right
dcdd144598 2011-02-23        kinaba: 		gen_nfa( entry, t->left.get(), exit );
dcdd144598 2011-02-23        kinaba: 		gen_nfa( entry, t->right.get(), exit );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case N_Closure:
dcdd144598 2011-02-23        kinaba: 		//                       e
dcdd144598 2011-02-23        kinaba: 		//         e          <------        e
dcdd144598 2011-02-23        kinaba: 		//  entry ---> before ------> after ---> exit
dcdd144598 2011-02-23        kinaba: 		//    |                left                ^
dcdd144598 2011-02-23        kinaba: 		//    >------->------------------->------>-|
dcdd144598 2011-02-23        kinaba: 		//                      e
dcdd144598 2011-02-23        kinaba: 	case N_Closure1: {
dcdd144598 2011-02-23        kinaba: 		//                       e
dcdd144598 2011-02-23        kinaba: 		//         e          <------        e
dcdd144598 2011-02-23        kinaba: 		//  entry ---> before ------> after ---> exit
dcdd144598 2011-02-23        kinaba: 		//                     left
dcdd144598 2011-02-23        kinaba: 		int before = gen_state();
dcdd144598 2011-02-23        kinaba: 		int after = gen_state();
dcdd144598 2011-02-23        kinaba: 		add_e_transition( entry, before );
dcdd144598 2011-02-23        kinaba: 		add_e_transition( after, exit );
dcdd144598 2011-02-23        kinaba: 		add_e_transition( after, before );
dcdd144598 2011-02-23        kinaba: 		gen_nfa( before, t->left.get(), after );
dcdd144598 2011-02-23        kinaba: 		if( t->type != N_Closure1 )
dcdd144598 2011-02-23        kinaba: 			add_e_transition( entry, exit );
dcdd144598 2011-02-23        kinaba: 		} break;
dcdd144598 2011-02-23        kinaba: 	case N_01:
dcdd144598 2011-02-23        kinaba: 		//           e
dcdd144598 2011-02-23        kinaba: 		//        ------>
dcdd144598 2011-02-23        kinaba: 		//  entry ------> exit
dcdd144598 2011-02-23        kinaba: 		//         left
dcdd144598 2011-02-23        kinaba: 		add_e_transition( entry, exit );
dcdd144598 2011-02-23        kinaba: 		gen_nfa( entry, t->left.get(), exit );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	case N_Empty:
dcdd144598 2011-02-23        kinaba: 		//         e
dcdd144598 2011-02-23        kinaba: 		//  entry ---> exit
dcdd144598 2011-02-23        kinaba: 		add_e_transition( entry, exit );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	マッチング
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void RegNFA::push(storage<st_ele>& stack, int curSt, int pos)
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// ε無限ループ防止策。同じ状態には戻らないように…
dcdd144598 2011-02-23        kinaba: 	for( int i=stack.size()-1; i>=0; --i )
dcdd144598 2011-02-23        kinaba: 		if( stack[i].ps != pos )
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		else if( stack[i].st == curSt )
dcdd144598 2011-02-23        kinaba: 			return;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	st_ele nw = {curSt,pos};
dcdd144598 2011-02-23        kinaba: 	stack.Add( nw );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RegNFA::st_ele RegNFA::pop(storage<st_ele>& stack)
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	st_ele se = stack[stack.size()-1];
dcdd144598 2011-02-23        kinaba: 	stack.ForceSize( stack.size()-1 );
dcdd144598 2011-02-23        kinaba: 	return se;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: int RegNFA::match( const wchar_t* str, int len, bool caseS )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	if( parser.err() )
dcdd144598 2011-02-23        kinaba: 		return -1; // エラー状態なのでmatchとかできません
dcdd144598 2011-02-23        kinaba: 	//if( st.size() <= 31 )
dcdd144598 2011-02-23        kinaba: 	//	return dfa_match(str,len,caseS); // 状態数が少なければDFAを使う、かも
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int matchpos = -1;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	storage<st_ele> stack;
dcdd144598 2011-02-23        kinaba: 	push(stack, start, 0);
dcdd144598 2011-02-23        kinaba: 	while( stack.size() > 0 )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// スタックからpop
dcdd144598 2011-02-23        kinaba: 		st_ele se = pop(stack);
dcdd144598 2011-02-23        kinaba: 		int curSt = se.st;
dcdd144598 2011-02-23        kinaba: 		int   pos = se.ps;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// マッチ成功してたら記録
dcdd144598 2011-02-23        kinaba: 		if( curSt == final ) // 1==終状態
dcdd144598 2011-02-23        kinaba: 			if( matchpos < pos )
dcdd144598 2011-02-23        kinaba: 				matchpos = pos;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// さらに先の遷移を調べる
dcdd144598 2011-02-23        kinaba: 		if( matchpos < len )
dcdd144598 2011-02-23        kinaba: 			for( RegTrans* tr=st[curSt]; tr!=NULL; tr=tr->next.get() )
dcdd144598 2011-02-23        kinaba: 				if( tr->type == RegTrans::Epsilon )
dcdd144598 2011-02-23        kinaba: 					push(stack, tr->to, pos);
dcdd144598 2011-02-23        kinaba: 				else if( pos<len && tr->match( str[pos], caseS ) )
dcdd144598 2011-02-23        kinaba: 					push(stack, tr->to, pos+1);
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	return matchpos;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: int RegNFA::dfa_match( const wchar_t* str, int len, bool caseS )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	int matchpos = -1;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	unsigned int StateSet = (1<<start);
dcdd144598 2011-02-23        kinaba: 	for(int pos=0; StateSet; ++pos)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// ε-closure
dcdd144598 2011-02-23        kinaba: 		for(uint DifSS=StateSet; DifSS;)
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			unsigned int NewSS = 0;
dcdd144598 2011-02-23        kinaba: 			for(int s=0; (1u<<s)<=DifSS; ++s)
dcdd144598 2011-02-23        kinaba: 				if( (1u<<s) & DifSS )
dcdd144598 2011-02-23        kinaba: 					for( RegTrans* tr=st[s]; tr!=NULL; tr=tr->next.get() )
dcdd144598 2011-02-23        kinaba: 						if( tr->type == RegTrans::Epsilon )
dcdd144598 2011-02-23        kinaba: 						 NewSS |= 1u << tr->to;
dcdd144598 2011-02-23        kinaba: 			DifSS = (NewSS|StateSet) ^ StateSet;
dcdd144598 2011-02-23        kinaba: 			StateSet |= NewSS;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 受理状態を含んでるかどうか判定
dcdd144598 2011-02-23        kinaba: 		if( StateSet & (1<<final) )
dcdd144598 2011-02-23        kinaba: 			matchpos = pos;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 文字列の終わりに達した
dcdd144598 2011-02-23        kinaba: 		if( pos == len )
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 遷移
dcdd144598 2011-02-23        kinaba: 		unsigned int NewSS = 0;
dcdd144598 2011-02-23        kinaba: 		for(int s=0; (1u<<s)<=StateSet; ++s)
dcdd144598 2011-02-23        kinaba: 			if( (1u<<s) & StateSet )
dcdd144598 2011-02-23        kinaba: 				for( RegTrans* tr=st[s]; tr!=NULL; tr=tr->next.get() )
dcdd144598 2011-02-23        kinaba: 					if( tr->type!=RegTrans::Epsilon && tr->match(str[pos], caseS) )
dcdd144598 2011-02-23        kinaba: 					 NewSS |= 1u << tr->to;
dcdd144598 2011-02-23        kinaba: 		StateSet = NewSS;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	return matchpos;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //////////////////////////////////////////////////////////////////////
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: bool reg_match( const wchar_t* pat, const wchar_t* str, bool caseS )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	int len = my_lstrlenW(str);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	RegNFA re( pat );
dcdd144598 2011-02-23        kinaba: 	return len == re.match( str, len, caseS );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //@{
dcdd144598 2011-02-23        kinaba: //	GreenPad用検索オブジェクト
dcdd144598 2011-02-23        kinaba: //@}
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: RSearch::RSearch( const unicode* key, bool caseS, bool down )
dcdd144598 2011-02-23        kinaba: 	: re_    ( new RegNFA(key) )
dcdd144598 2011-02-23        kinaba: 	, caseS_ ( caseS )
dcdd144598 2011-02-23        kinaba: 	, down_  ( down )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: bool RSearch::Search(
dcdd144598 2011-02-23        kinaba: 	const unicode* str, ulong len, ulong stt, ulong* mbg, ulong* med )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	if( down_ && re_->isHeadType() && stt>0 )
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	const int d = (down_ ? 1 : -1);
dcdd144598 2011-02-23        kinaba: 	      int s = (!down_ && re_->isHeadType() ? 0 : stt);
dcdd144598 2011-02-23        kinaba: 	const int e = (down_ ? (re_->isHeadType() ? 1 : (long)len) : -1);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	for( ; s!=e; s+=d )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		const int L = re_->match( str+s, len-s, caseS_ );
dcdd144598 2011-02-23        kinaba: 		if( L > 0 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( re_->isTailType() && L!=static_cast<int>(len-s) )
dcdd144598 2011-02-23        kinaba: 				continue;
dcdd144598 2011-02-23        kinaba: 			*mbg = static_cast<ulong>(s);
dcdd144598 2011-02-23        kinaba: 			*med = static_cast<ulong>(s+L);
dcdd144598 2011-02-23        kinaba: 			return true;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	return false;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: