--- /dev/null
+unit bmRegExp;
+{******************************************************************************
+\83^\83C\83g\83\8b \81F\90³\8bK\95\\8c»\82ð\8eg\82Á\82½\95¶\8e\9a\97ñ\92T\8dõ/\91\80\8dì\83R\83\93\83|\81[\83l\83\93\83g\8fWver0.17
+\83\86\83j\83b\83g\96¼ \81FbmRegExp.pas
+\83o\81[\83W\83\87\83\93 \81Fversion 0.17
+\93ú\95t \81F2001/09/15
+\93®\8dì\8am\94F\8aÂ\8b« \81F Windows 98 + Borland Delphi6 Japanese Personal edition
+\8dì\8eÒ \81F \95õ\93\87 bmonkey \97Y\8e¡ ggb01164@nifty.ne.jp
+\95Ï\8dX\97\9a\97ð \81F 0.17 \83o\83O\8fC\90³ 2001/09/15
+ \81F \81EMP3\82Ì\96\82\8fp\8et\82³\82ñ\82É\8b³\82¦\82Ä\92¸\82¢\82½\83\81\83\82\83\8a\83\8a\81[\83N\82Ì\8fC\90³\82ð\93K\97p\81B
+ \81F \81E\82¨\82©\82Û\82ñ\82³\82ñ\82É\8b³\82¦\82Ä\92¸\82¢\82½\83\81\83\82\83\8a\83\8a\81[\83N\82Ì\8fC\90³\82ð\93K\97p\81B
+ \81F \8fÚ\8d×\82Í\93¯\8d«\82Ìchangelog.html\82ð\8eQ\8fÆ\81B
+ \81F 0.16 \91æ\93ñ\8e\9f \88ê\94Ê\8cö\8aJ 1998/03/07
+ \81F version 0.15 -> version 0.16
+ \81F \81ETGrep\82Å\89p\91å\95¶\8e\9a/\8f¬\95¶\8e\9a\82ª\90³\82µ\82\8c\9f\8dõ\82Å\82«\82È\82©\82Á\82½\83o\83O\82ð\8fC\90³\81B
+ \81F \81E\8a¿\8e\9a\82Ì\83L\83\83\83\89\83N\83^\83N\83\89\83X\8ew\92è([\88\9f-ê¤]\82È\82Ç)\82Ì\83o\83O\82ð\8fC\90³\81B
+ \81F \81EDelphi3, C++Builder1\82É\91Î\89\9e
+ \81F \81E\83\86\83j\83b\83g\83t\83@\83C\83\8b\96¼\82ðRegExp.pas\82©\82çbmRegExp.pas\82É\95Ï\8dX
+ \81F \81E\83R\83\93\83p\83C\83\89\82Ì\8cµ\82µ\82\82È\82Á\82½\8c^\83`\83F\83b\83N\82É\91Î\89\9e
+ \81F \81EMBUtils.pas\82ð\8eg\82í\82È\82¢\82æ\82¤\82É\95Ï\8dX\81B
+ \81F 0.15B \83o\83O\8fC\90³\81ADelphi3\81AC++Builder1\91Î\89\9e
+ \81F 0.15 \88ê\94Ê\8cö\8aJ
+\8eå\97v\83N\83\89\83X \81F TGrep, TAWKStr
+\8cp\8f³\8aÖ\8cW \81F TObject
+
+*******************************************************************************
+\8eg\97p\95û\96@ \81F\83w\83\8b\83v\83t\83@\83C\83\8b\82Æ\83T\83\93\83v\83\8b\83v\83\8d\83W\83F\83N\83g\82ð\8eQ\8fÆ\82Ì\82±\82Æ
+\95â\91«\90à\96¾ \81F
+
+\92è\8b`\8c^ \81F
+
+******************************************************************************}
+
+interface
+
+uses
+ SysUtils, Classes, Windows, Forms
+{$IFDEF DEBUG}
+ ,OutLine
+{$ENDIF}
+ ;
+
+type
+{ -========================== \97á\8aO\83N\83\89\83X =====================================-}
+{TREParser \82ª\8fo\82·\97á\8aO\81B
+ ErrorPos \82É\82æ\82Á\82Ä\81A\90³\8bK\95\\8c»\95¶\8e\9a\97ñ\82Ì\89½\95¶\8e\9a\96Ú\82Å\97á\8aO\82ª\94\90¶\82µ\82½\82©\82ð\8e¦\82·\81B}
+ ERegExpParser = class(Exception)
+ public
+ ErrorPos: Integer;
+ constructor Create(const Msg: string; ErrorPosition: Word);
+ end;
+{-============================= ====================-}
+{ \82Q\83o\83C\83g\95¶\8e\9a\8c^}
+ WChar_t = Word;
+
+{ \82Q\83o\83C\83g\95¶\8e\9a\8c^\82Ö\82Ì\83|\83C\83\93\83^\8c^}
+ PWChar_t = ^WChar_t;
+
+{ WChar_t\8c^ \82Q\82Â\82Ô\82ñ\82Ì\8c^}
+ DoubleWChar_t = Integer;
+
+{ -====================== \95¶\8e\9a\97ñ\91\80\8dì\8aÖ\90\94 =====================================-}
+ {\90à\96¾ \81F \82P\82U\90i\90\94\82ð\95\\82·\95¶\8e\9a\82ð\8eó\82¯\8eæ\82è\81A\90®\90\94\82É\82µ\82Ä\95Ô\82·\81B
+ \88ø\90\94 \81F WCh: WChar_t; 16\90i\90\94\82ð\95\\82·1\83o\83C\83g\95¶\8e\9a [0-9a-fA-F]
+
+ \95Ô\82è\92l\81F \90³\8fí\8e\9e\81F 0 <= result <= 15
+ \88Ù\8fí\8e\9e\81F -1}
+ function HexWCharToInt(WCh: WChar_t): Integer;
+
+ {\90à\96¾ \81F \82W\90i\90\94\82ð\95\\82·\95¶\8e\9a\82ð\8eó\82¯\8eæ\82è\81A\90®\90\94\82É\82µ\82Ä\95Ô\82·\81B
+ \88ø\90\94 \81F WCh: WChar_t; 8\90i\90\94\82ð\95\\82·1\83o\83C\83g\95¶\8e\9a [0-7]
+
+ \95Ô\82è\92l\81F \90³\8fí\8e\9e\81F 0 <= result <= 7
+ \88Ù\8fí\8e\9e\81F -1}
+ function OctWCharToInt(WCh: WChar_t): Integer;
+
+ {\90à\96¾ \81F 16\90i\90\94\95\\8bL\82Ì\95¶\8e\9a\97ñ\82ðWord\8c^\82Ì\90\94\92l\82É\95Ï\8a·\82·\82é\81B
+ \88ø\90\94 \81F Str: String \95Ï\8a·\8c³\82Ì\95¶\8e\9a\97ñ
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+ \95\9b\8dì\97p\81F \8f\88\97\9d\82µ\82½\83o\83C\83g\90\94\82¾\82¯Index\82ª\83C\83\93\83N\83\8a\83\81\83\93\83g\82³\82ê\82é\81B
+ \95Ô\82è\92l\81F \95¶\8e\9a\97ñ\82ª\95\\82·Word\8c^\82Ì\92l}
+ function HexStrToInt(const Str: String; var Index: Integer): Word;
+
+ {\90à\96¾ \81F \82W\90i\90\94\95\\8bL\82Ì\95¶\8e\9a\97ñ\82ðWord\8c^\82Ì\90\94\92l\82É\95Ï\8a·\82·\82é\81B
+ \88ø\90\94 \81F Str: String \95Ï\8a·\8c³\82Ì\95¶\8e\9a\97ñ
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+ \95\9b\8dì\97p\81F \8f\88\97\9d\82µ\82½\83o\83C\83g\90\94\82¾\82¯Index\82ª\83C\83\93\83N\83\8a\83\81\83\93\83g\82³\82ê\82é\81B
+ \95Ô\82è\92l\81F \95¶\8e\9a\97ñ\82ª\95\\82·Word\8c^\82Ì\92l}
+ function OctStrToInt(const Str: String; var Index: Integer): Word;
+
+ {\90à\96¾ \81F \88ø\90\94Str\82©\82ç\82P\95¶\8e\9a\93Ç\82Ý\8fo\82·\81B
+ \93®\8dì \81F \88ø\90\94Str \82Ì\92\86\82Ì\88ø\90\94Index\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\82P\95¶\8e\9a\93¾\82Ä\81AIndex\82ð\91\9d\82â\82·\81B
+ \88ø\90\94 \81F Str: String; \82Q\83o\83C\83g\95¶\8e\9a\83R\81[\83h\82ð\8aÜ\82ñ\82¾String
+ Index: Integer; \95¶\8e\9a\82ð\93Ç\82Ý\8fo\82·\88Ê\92u\82Ì\90æ\93ª\82©\82ç\82Ì\83o\83C\83g\90\94
+ \95Ô\82è\92l\81F \93Ç\82Ý\8fo\82µ\82½ WChar_t\8c^\82Ì\92l
+ \95\9b\8dì\97p\81F
+ \92\8d\88Ó \81F Index\82ª\95¶\8e\9a\97ñ\82Ì\92·\82³\82æ\82è\82·\82Å\82É\92·\82¢\8fê\8d\87\82Í\8fí\82É WChType.Null\82ð\95Ô\82µ\81AIndex\82ð\91\9d\82â\82³\82È\82¢\81B
+ \82Â\82Ü\82è\81AIndex\82Í\8dÅ\91å\82Å\82à Length(Str)+1 \82Å\82 \82é\81B}
+ function GetWChar(const Str: String;var Index: Integer): WChar_t;
+
+ {\8b@\94\\81F GetWChar\83\81\83\\83b\83h\82É\82æ\82Á\82Ä\90i\82ñ\82¾ Index\82ð\82P\95¶\8e\9a\95ª\96ß\82·(1\81`\82Q\83o\83C\83g)
+ \92\8d\88Ó\81F \83k\83\8b\81E\83L\83\83\83\89\83N\83^(GetWChar\82Ì\95Ô\82è\92l WChType.Null)\82ð\96ß\82·\82±\82Æ\82Í\82Å\82«\82È\82¢\81B}
+ procedure UnGetWChar(const Str: String; var Index: Integer);
+
+
+ {\8b@\94\\81F GetWChar\82ÌPChar\8c^\83o\81[\83W\83\87\83\93}
+ function PCharGetWChar(var pText: PChar): WChar_t;
+
+ {\8b@\94\\81F WChar_t\8c^\82Ì\92l\82ðString\8c^\82Ö\95Ï\8a·\82·\82é\81B}
+ function WCharToStr(WCh: WChar_t): String;
+
+ {\8b@\94\\81F '\' \82Å \88ø\97p\82³\82ê\82½\83L\83\83\83\89\83N\83^\82ð\93¾\82é\81B \n, \t \\ ...
+ \92\8d\88Ó\81F Index\82Í'\'\82Ì\8e\9f\82Ì\95¶\8e\9a\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82·\82é\81B}
+ function GetQuotedWChar(const Str: String; var Index: Integer): WChar_t;
+
+
+ {\90à\96¾ \81F FS:WChar_t\82ð\8bæ\90Ø\82è\95¶\8e\9a\82Æ\82µ\82Ä\81A\83o\83C\83g\88Ê\92uIndex\82©\82ç\8en\82Ü\82é\83g\81[\83N\83\93\82ð\82P\82Â\95Ô\82·\81B
+ \88ø\90\94 \81F Str: String
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+ \95Ô\82è\92l\81F FS\82Å\8bæ\90Ø\82ç\82ê\82½\81A\83o\83C\83g\88Ê\92uIndex\82©\82ç\8en\82Ü\82é\83g\81[\83N\83\93}
+ function WCharGetToken(const Str: String; var Index: Integer; FS: WChar_t): String;
+
+
+ {\90à\96¾ \81F \88ø\90\94Str\92\86\82Ì\83\81\83^\83L\83\83\83\89\83N\83^\82É'\'\82ð\82Â\82¯\82é\81B
+ \88ø\90\94 \81F Str: String
+ \95Ô\82è\92l\81F \83\81\83^\83L\83\83\83\89\83N\83^\82Ì\91O\82É'\'\82ª\82Â\82¢\82½Str}
+ function QuoteMetaWChar(Str: String): String;
+
+const
+ CONST_DOLLAR = $24; // '$'
+ CONST_LPAR = $28; // '('
+ CONST_RPAR = $29; // ')'
+ CONST_STAR = $2A; // '*'
+ CONST_PLUS = $2B; // '+'
+ CONST_DOT = $2E; // '.'
+ CONST_QMARK = $3F; // '?'
+ CONST_VL = $7C; // '|'
+
+ CONST_LBRA = $5B; // '['
+ CONST_RBRA = $5D; // ']'
+ CONST_CARET = $5E; // '^'
+ CONST_YEN = $5C; // '\'
+ CONST_MINUS = $2D; // '-'
+
+ CONST_b = $62; // 'b'
+ CONST_r = $72; // 'r'
+ CONST_n = $6E; // 'n'
+ CONST_t = $74; // 't'
+ CONST_x = $78; // 'x'
+
+ CONST_BS = $08; // BackSpace
+ CONST_CR = $0D; // Carriage Return
+ CONST_LF = $0A; // Line Feed
+ CONST_TAB = $09; // TAB
+
+ CONST_ANP = $26; // '&'
+
+ CONST_NULL = $0000;
+
+ METACHARS: Array[0..11] of WChar_t = (CONST_CARET,
+ CONST_LPAR,
+ CONST_VL,
+ CONST_RPAR,
+ CONST_PLUS,
+ CONST_STAR,
+ CONST_QMARK,
+ CONST_DOT,
+ CONST_LBRA,
+ CONST_RBRA,
+ CONST_DOLLAR,
+ CONST_YEN);
+
+ CONST_EMPTY = $FFFF; {TNFA, TDFA\8fó\91Ô\95\\82Å\81u\95¶\8e\9a\82ª\82È\82¢\81v\82±\82Æ\82ð\95\\82·\83R\81[\83h\82Æ\82µ\82Ä\8eg\82¤}
+ CONST_LINEHEAD = $FFFD; {\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^'^'\82ð\95\\82·\95¶\8e\9a\83R\81[\83h\82Æ\82µ\82Ä\8eg\82¤\81B}
+ CONST_LINETAIL = $FFFE; {\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^'$'\82ð\95\\82·\95¶\8e\9a\83R\81[\83h\82Æ\82µ\82Ä\8eg\82¤\81B}
+
+ REFuzzyWChars: array [0..144] of String =
+ ('\82`,\82\81,A,a',
+ '\82a,\82\82,B,b',
+ '\82b,\82\83,C,c',
+ '\82c,\82\84,D,d',
+ '\82d,\82\85,E,e',
+ '\82e,\82\86,F,f',
+ '\82f,\82\87,G,g',
+ '\82g,\82\88,H,h',
+ '\82h,\82\89,I,i',
+ '\82i,\82\8a,J,j',
+ '\82j,\82\8b,K,k',
+ '\82k,\82\8c,L,l',
+ '\82l,\82\8d,M,m',
+ '\82m,\82\8e,N,n',
+ '\82n,\82\8f,O,o',
+ '\82o,\82\90,P,p',
+ '\82p,\82\91,Q,q',
+ '\82q,\82\92,R,r',
+ '\82r,\82\93,S,s',
+ '\82s,\82\94,T,t',
+ '\82t,\82\95,U,u',
+ '\82u,\82\96,V,v',
+ '\82v,\82\97,W,w',
+ '\82w,\82\98,X,x',
+ '\82x,\82\99,Y,y',
+ '\82y,\82\9a,Z,z',
+ '0,\82O,\97ë',
+ '1,\82P,\88ê,\87@,\87T,\88ë',
+ '2,\82Q,\93ñ,\87A,\87U,\93ó',
+ '3,\82R,\8eO,\87B,\87V,\8eQ',
+ '4,\82S,\8el,\87C,\87W',
+ '5,\82T,\8cÜ,\87D,\87X,\8cÞ',
+ '6,\82U,\98Z,\87E,\87Y',
+ '7,\82V,\8eµ,\87F,\87Z',
+ '8,\82W,\94ª,\87G,\87[',
+ '9,\82X,\8bã,\87H,\87\',
+ '"\81@"," "',
+ '!,\81I',
+ '"""",\81h',
+ '#,\81\94',
+ '$,\81\90',
+ '%,\81\93',
+ '&,\81\95',
+ ''',\81f',
+ '(,\81i',
+ '),\81j',
+ '*,\81\96',
+ '+,\81{',
+ '\81[,\81`,°,', { \92·\89¹\8bL\8d\86\82Í\81A''\83k\83\8b\82Æ\82à\88ê\92v\82³\82¹\82é}
+ '-,\81[,\81|,\81`,°',
+ '¥,\81E',
+ '/,\81^',
+ ':,\81F',
+ ';,\81G',
+ '<,\81\83',
+ '=,\81\81',
+ '>,\81\84',
+ '?,\81H',
+ '@,\81\97',
+ '[,\81m,\81k',
+ '\,\81\8f',
+ '],\81n,\81l',
+ '^,\81O',
+ '_,\81Q',
+ '{,\81o',
+ '|,\81b',
+ '},\81p',
+ '~,\81P',
+ '",",¤,\81A,\81C',
+ '¡,.,\81B,\81D',
+ '\81u,\81w,¢',
+ '\81v,\81x,£',
+ '\82ñ,\83\93,Ý',
+ '\82ª,\83K,¶Þ,\82©\81J,\83J\81J',
+ '\82¬,\83M,·Þ,\82«\81J,\83L\81J',
+ '\82®,\83O,¸Þ,\82\81J,\83N\81J',
+ '\82°,\83Q,¹Þ,\82¯\81J,\83P\81J',
+ '\82²,\83S,ºÞ,\82±\81J,\83R\81J',
+ '\82´,\83U,»Þ,\82³\81J,\83T\81J',
+ '\82¶,\83W,¼Þ,\82µ\81J,\83V\81J,\82À,\83a,ÁÞ,\82¿\81J,\83`\81J',
+ '\82¸,\83Y,½Þ,\83X\81J,\83X\81J,\82Ã,\83d,ÂÞ,\82Â\81J,\83c\81J',
+ '\82º,\83[,¾Þ,\82¹\81J,\83Z\81J',
+ '\82¼,\83],¿Þ,\82»\81J,\83\\81J',
+ '\82¾,\83_,ÀÞ,\82½\81J,\83^\81J',
+ '\82Å,\83f,ÃÞ,\82Ä\81J,\83e\81J',
+ '\82Ç,\83h,ÄÞ,\82Æ\81J,\83g\81J',
+ '\82Î,\83o,ÊÞ,\82Í\81J,\83n\81J,\83\94\83@,\82¤\81J\82\9f,\83E\81J\83@,³Þ§',
+ '\82Ñ,\83r,ËÞ,\82Ð\81J,\83q\81J,\83\94\83B,\82¤\81J\82¡,\83E\81J\83B,³Þ¨',
+ '\82Ô,\83u,ÌÞ,\82Ó\81J,\83t\81J,\83\94,\83E\81J,\82¤\81J,³Þ',
+ '\82×,\83x,ÍÞ,\82Ö\81J,\83w\81J,\83\94\83F,\82¤\81J\82¥,\83E\81J\83F,³Þª',
+ '\82Ú,\83{,ÎÞ,\82Ù\81J,\83z\81J,\83\94\83H,\82¤\81J\82§,\83E\81J\83H,³Þ«',
+ '\82Ï,\83p,Êß,\82Í\81K,\83n\81K',
+ '\82Ò,\83s,Ëß,\82Ð\81K,\83q\81K',
+ '\82Õ,\83v,Ìß,\82Ó\81K,\83t\81K',
+ '\82Ø,\83y,Íß,\82Ö\81K,\83w\81K',
+ '\82Û,\83|,Îß,\82Ù\81K,\83z\81K',
+ '\82 ,\83A,±,\82\9f,\83@,§',
+ '\82¢,\83C,²,\82¡,\83B,¨',
+ '\82¤,\83E,³,\82£,\83D,©',
+ '\82¦,\83G,´,\82¥,\83F,ª',
+ '\82¨,\83I,µ,\82§,\83H,«',
+ '\82©,\83J,¶',
+ '\82«,\83L,·',
+ '\82,\83N,¸',
+ '\82¯,\83P,¹',
+ '\82±,\83R,º',
+ '\82³,\83T,»',
+ '\82µ,\83V,¼',
+ '\82·,\83X,½',
+ '\82¹,\83Z,¾',
+ '\82»,\83\,¿',
+ '\82½,\83^,À',
+ '\82¿,\83`,Á',
+ '\82Â,\83c,Â,\82Á,\83b,¯',
+ '\82Ä,\83e,Ã',
+ '\82Æ,\83g,Ä',
+ '\82È,\83i,Å',
+ '\82É,\83j,Æ',
+ '\82Ê,\83k,Ç',
+ '\82Ë,\83l,È',
+ '\82Ì,\83m,É',
+ '\82Í,\83n,Ê',
+ '\82Ð,\83q,Ë',
+ '\82Ó,\83t,Ì',
+ '\82Ö,\83w,Í',
+ '\82Ù,\83z,Î',
+ '\82Ü,\83},Ï',
+ '\82Ý,\83~,Ð',
+ '\82Þ,\83\80,Ñ',
+ '\82ß,\83\81,Ò',
+ '\82à,\83\82,Ó',
+ '\82â,\83\84,Ô,\82á,\83\83,¬',
+ '\82ä,\83\86,Õ,\82ã,\83\85,',
+ '\82æ,\83\88,Ö,\82å,\83\87,®',
+ '\82ç,\83\89,×',
+ '\82è,\83\8a,Ø',
+ '\82é,\83\8b,Ù',
+ '\82ê,\83\8c,Ú',
+ '\82ë,\83\8d,Û',
+ '\82í,\83\8f,Ü,\82¤\82\9f,\83E\83@,³§',
+ '\83\90,\82î,\82¤\82¡,\83E\83B,³¨',
+ '\83\91,\82ï,\82¤\82¥,\83E\83F,³ª',
+ '\82ð,\83\92,¦,\82¤\82§,\83E\83H,³«',
+ 'Þ,\81J',
+ 'ß,\81K'); {\91÷\93_\81A\94¼\91÷\93_\82Í\82±\82Ì\88Ê\92u\82É\82È\82¢\82Æ \81h\82ª\81h\81¨\81h¶Þ\81h\82É\95Ï\8a·\82³\82ê\82È\82¢\81B}
+
+type
+{ -============================= TREScanner Class ==================================-}
+ { \95¶\8e\9a\82Ì\94Í\88Í\82ð\95\\82·\8c^\81B}
+ RECharClass_t = record
+ case Char of
+ #0: (StartChar: WChar_t; EndChar: WChar_t);
+ #1: (Chars: DoubleWChar_t);
+ end;
+
+const
+ CONST_EMPTYCharClass: RECharClass_t = ( StartChar: CONST_EMPTY;
+ EndChar: CONST_EMPTY);
+
+type
+
+ { RECharClass_t\82Ö\82Ì\83|\83C\83\93\83^\8c^}
+ REpCharClass_t = ^RECharClass_t;
+
+ {\83g\81[\83N\83\93\82Ì\8eí\97Þ\82ð\95\\82·\8c^ }
+ REToken_t = ( retk_Char, {\92Ê\8fí\82Ì\95¶\8e\9a }
+ retk_CharClass, {'[]'\82Å\88Í\82Ü\82ê\82½\83L\83\83\83\89\83N\83^\83N\83\89\83X\90³\8bK\95\\8c»\82Ì\92\86\82Å
+ '-'\82ð\8eg\82Á\82Ä\94Í\88Í\8ew\92è\82³\82ê\82½\95¨ }
+ retk_Union, { '|'}
+ retk_LPar, { '('}
+ retk_RPar, { ')'}
+ retk_Star, { '*'}
+ retk_Plus, { '+'}
+ retk_QMark, { '?'}
+ retk_LBra, { '['}
+ retk_LBraNeg, { '[\81O'}
+ retk_RBra, { ']'}
+ retk_Dot, { '.'}
+ retk_LHead, { '^'}
+ retk_LTail, { '$'}
+ retk_End); { \95¶\8e\9a\97ñ\82Ì\8fI\82í\82è }
+
+ { REToken_t\82Ì\8fW\8d\87\8fW\8d\87\8c^}
+ RETokenSet_t = set of REToken_t;
+
+ RESymbol_t = record
+ case REToken_t of
+ retk_CharClass: (CharClass: RECharClass_t);
+ retk_Char: (WChar: WChar_t);
+ end;
+
+{\81\9c \95¶\8e\9a\97ñ\82©\82ç\83g\81[\83N\83\93\82ð\90Ø\82è\8fo\82·\83N\83\89\83X}
+ TREScanner = class
+ private
+ FRegExpStr: String;
+ FIndex: Integer;
+ FToken: REToken_t;
+ FSymbol: RESymbol_t;
+ FInCharClass: Boolean;
+ protected
+ procedure SetRegExpStr(RegExpStr: String);
+
+ {\8e\9f\82Ì\83g\81[\83N\83\93\82ð\93¾\82é\81B}
+ function GetTokenStd: REToken_t; virtual;
+ {\83L\83\83\83\89\83N\83^\83N\83\89\83X\90³\8bK\95\\8c» "[ ]" \82Ì\92\86\82Ì\83g\81[\83N\83\93\82ð\93¾\82é\81B}
+ function GetTokenCC: REToken_t; virtual;
+ public
+ constructor Create(Str: String);
+
+ function GetToken: REToken_t;
+
+ {\8c»\8dÝ\82Ì\83g\81[\83N\83\93}
+ property Token: REToken_t read FToken;
+
+ { Token\82É\91Î\89\9e\82·\82é\95¶\8e\9a[\97ñ](Lexeme)
+ Token <> retk_CharClass \82Ì\82Æ\82« \8c»\8dÝ\82Ì\83g\81[\83N\83\93\82Ì\95¶\8e\9a\92l WChar_t\8c^
+ Token = retk_CharClass \82Ì\82Æ\82«\82ÍRECharClass_t\83\8c\83R\81[\83h\8c^
+ \81¦FToken = retk_LBraNeg\82Ì\8e\9e\82Í\83u\83\89\83P\83b\83g'['\82P\95¶\8e\9a\95ª\82µ\82©\82È\82¢\81B}
+ property Symbol: RESymbol_t read FSymbol;
+
+ {\8f\88\97\9d\91Î\8fÛ\82Ì\95¶\8e\9a\97ñ}
+ property RegExpStr: String read FRegExpStr write SetRegExpStr;
+
+ {\83C\83\93\83f\83b\83N\83X
+ InputStr\95¶\8e\9a\97ñ\92\86\82Å\8e\9f\82ÌGetWChar\83\81\83\\83b\83h\82Å\8f\88\97\9d\82·\82é\95¶\8e\9a\82Ì\83C\83\93\83f\83b\83N\83X
+ \81¦ Symbol\82Ì\8e\9f\82Ì\95¶\8e\9a\82ð\8ew\82µ\82Ä\82¢\82é\82±\82Æ\82É\92\8d\88Ó}
+ property Index: Integer read FIndex;
+ end;
+
+{-============================= ====================-}
+ {\83g\81[\83N\83\93\82Ì\8fî\95ñ\82ð\82Ð\82Æ\82Ü\82Æ\82ß\82É\82µ\82½\82à\82Ì}
+ RETokenInfo_t = record
+ Token: REToken_t;
+ Symbol: RESymbol_t;
+ FromIndex: Integer;
+ ToIndex: Integer;
+ end;
+
+ REpTokenInfo_t = ^RETokenInfo_t;
+
+ {TREPreProcessor\83N\83\89\83X\93à\95\94\82Å\8eg\97p}
+ TREPreProcessorFindFunc = function(FromTokenIndex, ToTokenIndex: Integer): Integer of object;
+
+ TREPreProcessor = class
+ private
+ FScanner: TREScanner;
+ FProcessedRegExpStr: String;
+ FListOfSynonymDic: TList;
+ FListOfFuzzyCharDic: TList;
+ FTokenList: TList;
+ FSynonymStr: String;
+
+ FUseFuzzyCharDic: Boolean;
+ FUseSynonymDic: Boolean;
+ protected
+ procedure MakeTokenList;
+ procedure DestroyTokenListItems;
+
+ function ReferToOneList(FromTokenIndex, ToTokenIndex: Integer; SynonymDic: TList): Integer;
+ function FindSynonym(FromTokenIndex, ToTokenIndex: Integer): Integer;
+ function FindFuzzyWChar(FromTokenIndex, ToTokenIndex: Integer): Integer;
+
+ procedure Process(FindFunc: TREPreProcessorFindFunc);
+
+ function GetTargetRegExpStr: String;
+ procedure SetTargetRegExpStr(Str: String);
+ public
+ constructor Create(Str: String);
+ destructor Destroy; override;
+ procedure Run;
+
+ property TargetRegExpStr: String read GetTargetRegExpStr write SetTargetRegExpStr;
+ property ProcessedRegExpStr: String read FProcessedRegExpStr;
+
+ property UseSynonymDic: Boolean read FUseSynonymDic write FUseSynonymDic;
+ property ListOfSynonymDic: TList read FListOfSynonymDic;
+ property UseFuzzyCharDic: Boolean read FUseFuzzyCharDic write FUseFuzzyCharDic;
+ property ListOfFuzzyCharDic: TList read FListOfFuzzyCharDic;
+ end;
+
+{-=========================== TREParseTree Class ===============================-}
+{**************************************************************************
+\81\9c \8d\\95¶\96Ø\82ð\8aÇ\97\9d\82·\82é\83N\83\89\83X TREParseTree
+
+\93Á\92¥\81F \92\86\8aÔ\90ß(Internal node)\82Æ\97t(Leaf)\82ð\8dì\82é\82Æ\82«\82Í\81A\82»\82ê\82¼\82êMakeInternalNode
+ \83\81\83\\83b\83h\82ÆMakeLeaf\83\81\83\\83b\83h\82ð\8eg\82¤\81B
+ \82Ü\82½\81A\8d\\95¶\96Ø\82Æ\82Í\95Ê\82É\81AFNodeList\82ÆFLeafList\82©\82ç\92\86\8aÔ\90ß\82Æ\97t\82Ö\83\8a\83\93\83N\82µ\82Ä
+ \82¨\82\82±\82Æ\82É\82æ\82è\81A\93r\92\86\82Å\83G\83\89\81[\82ª\94\90¶\82µ\82Ä\82à\95K\82¸\83\81\83\82\83\8a\82ð\8aJ\95ú\82·\82é\81B
+**************************************************************************}
+ { TREParseTree\82Ì\90ß\82Ì\8eí\97Þ\82ð\95\\82·\8c^}
+ REOperation_t = (reop_Char, { \95¶\8e\9a\82»\82Ì\82à\82Ì }
+ reop_LHead, { \95¶\93ª }
+ reop_LTail, { \95¶\94ö }
+ reop_Concat, { XY }
+ reop_Union, { X|Y}
+ reop_Closure, { X* }
+ reop_Empty); { \8bó }
+
+ { RENode_t\82Ö\82Ì\83|\83C\83\93\83^\8c^}
+ REpNode_t = ^RENode_t;
+
+ { TREParseTree\82Ì\8eq\90ß\82Ö\82Ì\83|\83C\83\93\83^\8c^}
+ REChildren_t = record
+ pLeft: REpNode_t;
+ pRight: REpNode_t;
+ end;
+
+ { TREParseTree\82Ì\90ß}
+ RENode_t = record
+ Op: REOperation_t;
+ case Char of
+ #0: (CharClass: RECharClass_t);
+ #1: (Children: REChildren_t);
+ end;
+
+{\81\9c \8d\\95¶\96Ø\82ð\8aÇ\97\9d\82·\82é\83N\83\89\83X}
+ TREParseTree = class
+ private
+ FpHeadNode: REpNode_t;{\8d\\95¶\96Ø\82Ì\92¸\93_\82É\82 \82é\90ß}
+ FNodeList: TList; {\92\86\8aÔ\90ß\82Ì\83\8a\83X\83g\81B}
+ FLeafList: TList; {\97t\82Ì\83\8a\83X\83g\81B}
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ {\8d\\95¶\96Ø\82Ì\93à\95\94\90ß\82ð\8dì\90¬\81B
+ op \82Í\83m\81[\83h\82ª\95\\82·\89\89\8eZ\81Aleft\82Í\8d¶\82Ì\8eq\81Aright\82Í\89E\82Ì\8eq }
+ function MakeInternalNode(TheOp: REOperation_t; pLeft, pRight: REpNode_t): REpNode_t;
+
+ {\8d\\95¶\96Ø\82Ì\97t\82ð\8dì\90¬\81B
+ aStartChar, aEndChar \82Å\83L\83\83\83\89\83N\83^\83N\83\89\83X\82ð\95\\82·}
+ function MakeLeaf(aStartChar, aEndChar: WChar_t): REpNode_t;
+
+ {\94C\88Ó\82Ì\88ê\95¶\8e\9a\82ð\95\\82·'.'\83\81\83^\83L\83\83\83\89\83N\83^\82É\91Î\89\9e\82·\82é\95\94\95ª\96Ø\82ð\8dì\82é\81B
+ \81¦CR LF\82ð\8f\9c\82\91S\82Ä\82Ì\83L\83\83\83\89\83N\83^\82ð\95\\82·\97t\82ðreop_Union\91\80\8dì\82ð\95\\82·\92\86\8aÔ\90ß\82Å\8c\8b\82ñ\82¾\82à\82Ì}
+ function MakeAnyCharsNode: REpNode_t; virtual;
+
+ {\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\97t\82ð\8dì\90¬
+ \81¦ \97t\82ð\95Ô\82·\82ª\81AMakeInternalNode\82ð\8eg\82¤\81B}
+ function MakeLHeadNode(WChar: WChar_t): REpNode_t;
+
+ {\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\97t\82ð\8dì\90¬
+ \81¦ \97t\82ð\95Ô\82·\82ª\81AMakeInternalNode\82ð\8eg\82¤\81B}
+ function MakeLTailNode(WChar: WChar_t): REpNode_t;
+
+ {\88ø\90\94\82ª aStartChar <= aEndChar \82Ì\8aÖ\8cW\82ð\96\9e\82½\82µ\82Ä\82¢\82é\82Æ\82«\82É\81AMakeLeaf\82ð\8cÄ\82Ô
+ \82»\82ê\88È\8aO\82Í\81Anil \82ð\95Ô\82·\81B}
+ function Check_and_MakeLeaf(aStartChar, aEndChar: WChar_t):REpNode_t;
+
+ {\97t\82ð\93à\95\94\90ß\82É\95Ï\82¦\82é\81B}
+ procedure ChangeLeaftoNode(pLeaf, pLeft, pRight: REpNode_t);
+
+ {\91S\82Ä\82Ì\97t\82ª\8e\9d\82Â\83L\83\83\83\89\83N\83^\83N\83\89\83X\82Ì\94Í\88Í\82ª\82»\82ê\82¼\82ê\8fd\95¡\82µ\82È\82¢\82æ\82¤\82É\95ª\8a\84\82·\82é\81B}
+ procedure ForceCharClassUnique;
+
+ {\82·\82×\82Ä\82Ì\90ß\81i\93à\95\94\90ß\81A\97t\81j\82ð\8dí\8f\9c\81B}
+ procedure DisposeTree;
+
+ {\8d\\95¶\96Ø\82Ì\92¸\93_\82É\82 \82é\90ß}
+ property pHeadNode: REpNode_t read FpHeadNode write FpHeadNode;
+
+ {\93à\95\94\90ß\82Ì\83\8a\83X\83g}
+ property NodeList: TList read FNodeList;
+ {\97t\82Ì\83\8a\83X\83g}
+ property LeafList: TList read FLeafList;
+ end;
+
+{-=========================== TREParser Class ===============================-}
+{\81\9c \90³\8bK\95\\8c»\95¶\8e\9a\97ñ\82ð\89ð\90Í\82µ\82Ä\8d\\95¶\96Ø\82É\82·\82é\83p\81[\83T\81[ }
+ TREParser = class
+ private
+ FParseTree: TREParseTree; {\83\86\83j\83b\83gParseTre.pas \82Å\92è\8b`\82³\82ê\82Ä\82¢\82é\8d\\95¶\96Ø\83N\83\89\83X}
+ FScanner: TREScanner; {\83g\81[\83N\83\93\8aÇ\97\9d\83N\83\89\83X}
+
+ protected
+ { <regexp>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \91I\91ð X|Y \82ð\89ð\90Í\82·\82é}
+ function Regexp: REpNode_t;
+
+ { <term>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \98A\8c\8b\82w\82x\82ð\89ð\90Í\82·\82é}
+ function term: REpNode_t;
+
+ { <factor>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \8cJ\82è\95Ô\82µX*, X+\82ð\89ð\90Í\82·\82é}
+ function factor: REpNode_t;
+
+ { <primary>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \95¶\8e\9a\82»\82Ì\82à\82Ì\82Æ\81A\8a\87\8cÊ\82Å\8a\87\82ç\82ê\82½\90³\8bK\95\\8c» (X) \82ð\89ð\90Í\82·\82é}
+ function primary: REpNode_t;
+
+ { <charclass> \82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ [ abcd] \82Å\8a\87\82ç\82ê\82½\90³\8bK\95\\8c»\82ð\89ð\90Í\82·\82é}
+ function CharacterClass(aParseTree: TREParseTree): REpNode_t;
+
+ { <negative charclass>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ [^abcd] \82Å\8a\87\82ç\82ê\82½\90³\8bK\95\\8c»\82ð\89ð\90Í\82·\82é}
+ function NegativeCharacterClass: REpNode_t;
+
+ public
+ constructor Create(RegExpStr: String);
+ destructor Destroy; override;
+
+ {\90³\8bK\95\\8c»\82ð\83p\81[\83X\82·\82é\81B
+ regexp, term, factor, primary, charclass \82Ì\8ae\83\81\83\\83b\83h\82ð\8eg\82¢\8dÄ\8bA\89º\8d~\96@
+ \82É\82æ\82Á\82Ä\89ð\90Í\82·\82é\81B}
+ procedure Run;
+
+ {\8d\\95¶\96Ø\82ð\8aÇ\97\9d\82·\82é\83I\83u\83W\83F\83N\83g}
+ property ParseTree: TREParseTree read FParseTree;
+
+ {\93ü\97Í\95¶\8e\9a\97ñ\82©\82ç\83g\81[\83N\83\93\82ð\90Ø\82è\8fo\82·\83I\83u\83W\83F\83N\83g}
+ property Scanner: TREScanner read FScanner;
+
+{$IFDEF DEBUG}
+ {\83A\83E\83g\83\89\83C\83\93\81E\83R\83\93\83g\83\8d\81[\83\8b\82É\8d\\95¶\96Ø\82Ì\90}\82ð\8f\91\82«\8fo\82·\83\81\83\\83b\83h}
+ procedure WriteParseTreeToOutLine(anOutLine: TOutLine);
+{$ENDIF}
+ end;
+
+{$IFDEF DEBUG}
+ function DebugWCharToStr(WChar: WChar_t): String;
+{$ENDIF}
+
+{ -============================== TRE_NFA Class ==================================-}
+type
+ RE_pNFANode_t = ^RE_NFANode_t;
+
+ { NFA\8fó\91Ô\95\\82Ì\90ß
+ RE_NFANode_t \82Í 1\82Â\82Ì\82m\82e\82`\8fó\91Ô\82ª\81A\83L\83\83\83\89\83N\83^\83N\83\89\83X(CharClass)\93à\82Ì\95¶\8e\9a\82É\82æ\82Á
+ \82Ä\91J\88Ú\82·\82é\82m\82e\82`\8fó\91Ô\82Ì\8fó\91Ô\94Ô\8d\86(TransitTo)\82ð\8ai\94[\82·\82é\81B
+ \82P\82Â\82Ì\82m\82e\82`\8fó\91Ô\82Ö\93ü\97Í\82³\82ê\82é\83L\83\83\83\89\83N\83^\83N\83\89\83X\96\88\82É\83\8a\83\93\83N\81E\83\8a\83X\83g\82ð\8c`\90¬\82·\82é}
+ RE_NFANode_t = record
+ CharClass: RECharClass_t;{ \93ü\97Í : CharClass.StartChar \81` CharClass.EndChar}
+ TransitTo: integer; { \91J\88Ú\90æ\81F FStateList\82Ì\83C\83\93\83f\83b\83N\83X}
+
+ Next: RE_pNFANode_t; { \83\8a\83\93\83N\83\8a\83X\83g\82Ì\8e\9f\90ß}
+ end;
+
+{\81\9c \8d\\95¶\96Ø\82ð\89ð\90Í\82µ\82ÄNFA\8fó\91Ô\95\\82ð\8dì\82é\83N\83\89\83X}
+ TRE_NFA = class
+ private
+ FStateList: TList;
+ FEntryState: Integer;
+ FExitState: Integer;
+ FParser: TREParser;
+ FRegExpHasLHead: Boolean;
+ FRegExpHasLTail: Boolean;
+ FLHeadWChar: WChar_t;
+ FLTailWChar: WChar_t;
+ protected
+ { \83m\81[\83h\82É\94Ô\8d\86\82ð\8a\84\82è\93\96\82Ä\82é}
+ function NumberNode: Integer;
+
+ { NFA\8fó\91Ô\90ß \82ð\82P\82Â\8dì\90¬}
+ function MakeNFANode: RE_pNFANode_t;
+
+ { FStateList\82É\8fó\91Ô\91J\88Ú\82ð\92Ç\89Á\82·\82é\81B
+ \8fó\91Ô TransFrom \82É\91Î\82µ\82Ä\81AChrClass\82Ì\82Æ\82«\82É\8fó\91Ô TransTo \82Ö\82Ì\91J\88Ú\82ð\92Ç\89Á\82·\82é\81B}
+ procedure AddTransition(TransFrom, TransTo: Integer; aCharClass: RECharClass_t);
+
+ { \8d\\95¶\96Ø pTree \82É\91Î\82·\82é StateList\82ð\90¶\90¬\82·\82é
+ NFA\82Ì\93ü\82è\8cû\82ðentry, \8fo\8cû\82ðway_out\82Æ\82·\82é }
+ procedure GenerateStateList(pTree: REpNode_t; entry, way_out: Integer);
+
+ { NFA\8fó\91Ô\95\\82ð\94j\8aü\82·\82é}
+ procedure DisposeStateList;
+
+ public
+ constructor Create(Parser: TREParser; LHeadWChar, LTailWChar: WChar_t);
+ destructor Destroy;override;
+
+ { \8d\\95¶\96Ø Tree\82É\91Î\89\9e\82·\82éNFA\82ð\90¶\90¬\82·\82é}
+ procedure Run;
+
+ {NFA \8fó\91Ô\82Ì\83\8a\83X\83g}
+ property StateList: TList read FStateList;
+
+ {NFA\82Ì\8f\89\8aú\8fó\91Ô\82ÌFStateList\82Ì\83C\83\93\83f\83b\83N\83X}
+ property EntryState: Integer read FEntryState;
+ {NFA\82Ì\8fI\97¹\8fó\91Ô\82ÌFStateList\82Ì\83C\83\93\83f\83b\83N\83X}
+ property ExitState: Integer read FExitState;
+
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property RegExpHasLHead: Boolean read FRegExpHasLHead;
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property RegExpHasLTail: Boolean read FRegExpHasLTail;
+
+ {\95¶\93ª\82ð\95\\82·\83\81\83^\83L\83\83\83\89\83N\83^ '^'\82É\97^\82¦\82é\83\86\83j\81[\83N\82È\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LHeadWChar: WChar_t read FLHeadWChar write FLHeadWChar;
+ {\95¶\94ö\82ð\95\\82·\83\81\83^\83L\83\83\83\89\83N\83^ '$'\82É\97^\82¦\82é\83\86\83j\81[\83N\82È\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LTailWChar: WChar_t read FLTailWChar write FLTailWChar;
+
+{$IFDEF DEBUG}
+ {TStrings\83I\83u\83W\83F\83N\83g\82É\81ANFA \82Ì\93à\97e\82ð\8f\91\82«\8d\9e\82Þ}
+ procedure WriteNFAtoStrings(Strings: TStrings);
+{$ENDIF}
+ end;
+
+{ -========================== TRE_NFAStateSet Class =============================-}
+{\81\9c NFA\82Ì\8fó\91Ô\8fW\8d\87\82ð\95\\82·\83I\83u\83W\83F\83N\83g
+ \93à\95\94\82Å\82Í\83r\83b\83g\83x\83N\83^\82Å\8fó\91Ô\8fW\8d\87\82ð\8eÀ\8c»\82µ\82Ä\82¢\82é\81B}
+ TRE_NFAStateSet = class
+ private
+ FpArray: PByteArray;
+ FCapacity: Integer;
+ public
+ {\83R\83\93\83X\83g\83\89\83N\83^\82É\82Í\81A\8dÅ\91å\8fó\91Ô\90\94\82ð\8ew\92è\82·\82é\81B}
+ constructor Create(StateMax: Integer);
+ destructor Destroy; override;
+
+ {\83I\83u\83W\83F\83N\83g\82Ì\8fW\8d\87\82ª\81AStateIndex\82ð\8aÜ\82Þ\82©\81H}
+ function Has(StateIndex: Integer): Boolean;
+ {\83I\83u\83W\83F\83N\83g\82Ì\8fW\8d\87\82ª\81AAStateSet\82Æ\93¯\82¶\8fW\8d\87\8fó\91Ô\82©\81H}
+ function Equals(AStateSet: TRE_NFAStateSet): Boolean;
+ {\83I\83u\83W\83F\83N\83g\82Ì\8fW\8d\87\82ÉStateIndex\82ð\8aÜ\82ß\82é\81B}
+ procedure Include(StateIndex: Integer);
+ {\83I\83u\83W\83F\83N\83g\82ª\8e\9d\82Â\83o\83C\83g\94z\97ñ\82Ö\82Ì\83|\83C\83\93\83^}
+ property pArray: PByteArray read FpArray;
+ {\83I\83u\83W\83F\83N\83g\82ª\8e\9d\82Â\83o\83C\83g\94z\97ñ\82Ì\97v\91f\90\94}
+ property Capacity: Integer read FCapacity;
+ end;
+
+{ -============================= TRE_DFA Class ==================================-}
+{\81\9c TRE_DFA NFA\8fó\91Ô\95\\82©\82çDFA\8fó\91Ô\95\\82ð\8dì\82é\83N\83\89\83X
+ \83R\83\93\83X\83g\83\89\83N\83^ Create \82É\81A\90³\8bK\95\\8c»\82ð\95\\82·\82m\82e\82`(\94ñ\8c\88\92è\90«\97L\8cÀ\83I\81[\83g\83}\83g\83\93
+ Non-deterministic Finite Automaton)\82Ì\8fó\91Ô\95\\82ð\8e\9d\82ÂTRE_NFA\82ð\8eó\82¯\8eæ\82è\81A
+ \91Î\89\9e\82·\82é\82c\82e\82`(\8c\88\92è\90«\97L\8cÀ\83I\81[\83g\83}\83g\83\93Deterministic Finite Automaton)
+ \82Ì\8fó\91Ô\83\8a\83X\83g\83I\83u\83W\83F\83N\83g\82ð\8d\\92z\82·\82éTRE_DFA\83N\83\89\83X\81B}
+
+ RE_pDFATransNode_t = ^RE_DFATransNode_t;
+
+ {TRE_DFA\82Ì\83\81\83\\83b\83hCompute_Reachable_N_state(DState: PD_state_t): RE_pDFATransNode_t;
+ \82ª\82±\82Ì\8c^\82Ì\92l\82ð\95Ô\82·\81B
+ \83L\83\83\83\89\83N\83^\83N\83\89\83X(CharClass)\82Å\91J\88Ú\89Â\94\\82È\82m\82e\82`\8fó\91Ô\8fW\8d\87(ToNFAStateSet)}
+ RE_DFATransNode_t = record
+ CharClass: RECharClass_t;{Char;}
+ ToNFAStateSet: TRE_NFAStateSet;
+
+ next: RE_pDFATransNode_t;{\83\8a\83\93\83N\83\8a\83X\83g\82ð\8c`\90¬}
+ end;
+
+ RE_pDFAStateSub_t = ^RE_DFAStateSub_t;
+ RE_pDFAState_t = ^RE_DFAState_t;
+
+ { RE_DFAState_t\82É\82æ\82Á\82Ä\8eg\97p\82³\82ê\82é
+ \83L\83\83\83\89\83N\83^\83N\83\89\83X(CharClass)\82É\82æ\82Á\82ÄDFA\8fó\91Ô(TransitTo) \82Ö\91J\88Ú\82·\82é\81B}
+ RE_DFAStateSub_t = record
+ CharClass: RECharClass_t;
+ TransitTo: RE_pDFAState_t; {CharClass\94Í\88Í\93à\82Ì\95¶\8e\9a\82Å DFA \8fó\91Ô TransitTo\82Ö}
+
+ next: RE_pDFAStateSub_t; {\83\8a\83\93\83N\83\8a\83X\83g\82Ì\8e\9f\82Ì\83f\81[\83^}
+ end;
+
+ { RE_DFAState_t\82Í\82c\82e\82`\8fó\91Ô\82ð\95\\82·\8c^}
+ RE_DFAState_t = record
+ StateSet: TRE_NFAStateSet; {\82±\82ÌDFA\8fó\91Ô\82ð\95\\82·NFA\8fó\91Ô\8fW\8d\87}
+ Visited: wordbool; { \8f\88\97\9d\8dÏ\82Ý\82È\82ç\82P}
+ Accepted: wordbool;{ StateSet\83t\83B\81[\83\8b\83h\82ªNFA\82Ì\8fI\97¹\8fó\91Ô\82ð\8aÜ\82Þ\82È\82ç\82P}
+ Next: RE_pDFAStateSub_t; { \83L\83\83\83\89\83N\83^\83N\83\89\83X\96\88\82Ì\91J\88Ú\90æ\82Ì\83\8a\83\93\83N\83\8a\83X\83g}
+ end;
+
+{ \81\9c NFA\8fó\91Ô\95\\82©\82çDFA\8fó\91Ô\95\\82ð\8dì\82é\83N\83\89\83X}
+ TRE_DFA = class
+ private
+ FStateList: TList;
+ FpInitialState: RE_pDFAState_t;
+ FNFA: TRE_NFA;
+
+ FRegExpIsSimple: Boolean;
+ FSimpleRegExpStr: String;
+ FRegExpHasLHead: Boolean;
+ FRegExpHasLTail: Boolean;
+ protected
+ { NFA\8fó\91Ô\8fW\8d\87 StateSet \82É\91Î\82µ\82Ä \83Ã-closure\91\80\8dì\82ð\8eÀ\8ds\82·\82é\81B
+ \83Ã\91J\88Ú\82Å\91J\88Ú\89Â\94\\82È\91S\82Ä\82Ì\82m\82e\82`\8fó\91Ô\82ð\92Ç\89Á\82·\82é}
+ procedure Collect_Empty_Transition(StateSet: TRE_NFAStateSet);
+
+ { NFA\8fó\91Ô\8fW\8d\87 aStateSet \82ð\82c\82e\82`\82É\93o\98^\82µ\82Ä\81A\82c\82e\82`\8fó\91Ô\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·\81B
+ aStateSet\82ª\8fI\97¹\8fó\91Ô\82ð\8aÜ\82ñ\82Å\82¢\82ê\82Î\81Aaccepted\83t\83\89\83O\82ð\83Z\83b\83g\82·\82é\81B
+ \82·\82Å\82ÉaStateSet\82ª\82c\82e\82`\82É\93o\98^\82³\82ê\82Ä\82¢\82½\82ç\89½\82à\82µ\82È\82¢}
+ function Register_DFA_State(var aStateSet: TRE_NFAStateSet): RE_pDFAState_t;
+
+ { \8f\88\97\9d\8dÏ\82Ý\82Ì\88ó\82ª\82Â\82¢\82Ä\82¢\82È\82¢\82c\82e\82`\8fó\91Ô\82ð\92T\82·\81B
+ \8c©\82Â\82©\82ç\82È\82¯\82ê\82Înil\82ð\95Ô\82·\81B}
+ function Fetch_Unvisited_D_state: RE_pDFAState_t;
+
+ { DFA\8fó\91ÔpDFAState\82©\82ç\91J\88Ú\89Â\94\\82ÈNFA\8fó\91Ô\82ð\92T\82µ\82Ä\81A\83\8a\83X\83g\82É\82µ\82Ä\95Ô\82·}
+ function Compute_Reachable_N_state(pDFAState: RE_pDFAState_t): RE_pDFATransNode_t;
+
+ { Compute_Reachable_N_state\83\81\83\\83b\83h\82©\8dì\82é RE_DFATransNode_t\8c^\82Ì\83\8a\83\93\83N\83\8a\83X\83g\82ð
+ \94p\8aü\82·\82é}
+ procedure Destroy_DFA_TransList(pDFA_TransNode: RE_pDFATransNode_t);
+
+ { NFA\82ð\93\99\89¿\82È\82c\82e\82`\82Ö\82Æ\95Ï\8a·\82·\82é}
+ procedure Convert_NFA_to_DFA;
+
+ { StateList\82Ì\8ae\83\8a\83\93\83N\83\8a\83X\83g\82ð\83\\81[\83g\82·\82é}
+ procedure StateListSort;
+
+ procedure CheckIfRegExpIsSimple;
+ procedure DestroyStateList;
+ public
+ constructor Create(NFA: TRE_NFA);
+ destructor Destroy; override;
+
+ procedure Run;
+
+ property StateList: TList read FStateList;
+
+ property pInitialState: RE_pDFAState_t read FpInitialState;
+
+ {\90³\8bK\95\\8c»\82ª\92P\8f\83\82È\95¶\8e\9a\97ñ\82©\81H}
+ property RegExpIsSimple: Boolean read FRegExpIsSimple;
+ {\90³\8bK\95\\8c»\82Æ\93\99\89¿\82È\92P\8f\83\82È\95¶\8e\9a\97ñ}
+ property SimpleRegExpStr: String read FSimpleRegExpStr;
+
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property RegExpHasLHead: Boolean read FRegExpHasLHead;
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property RegExpHasLTail: Boolean read FRegExpHasLTail;
+ {$IFDEF DEBUG}
+ {TStrings\83I\83u\83W\83F\83N\83g\82É\81ADFA \82Ì\93à\97e\82ð\8f\91\82«\8d\9e\82Þ}
+ procedure WriteDFAtoStrings(Strings: TStrings);
+{$ENDIF}
+ end;
+
+{ -=================== TRegularExpression Class ==============================-}
+ {TStringList \82É\8ai\94[\82Å\82«\82é\8d\80\96Ú\90\94\82Ì\94Í\88Í\8c^}
+ RE_IndexRange_t = 1..Classes.MaxListSize;
+
+{\81\9c \90³\8bK\95\\8c»\95¶\8e\9a\97ñ\82©\82ç\82c\82e\82`\8fó\91Ô\95\\82ð\8dì\82é\83N\83\89\83X}
+ TRegularExpression = class(TComponent)
+ private
+ protected
+ FLineHeadWChar: WChar_t;
+ FLineTailWChar: WChar_t;
+ {\83v\83\8a\83v\83\8d\83Z\83b\83T\82ð\92Ê\82é\91O\82Ì\90³\8bK\95\\8c»}
+ FRegExp: String;
+ {\90³\8bK\95\\8c»\82Ì\95¶\8e\9a\97ñ\83\8a\83X\83g\81BObjects\83v\83\8d\83p\83e\83B\82ÉT\82c\82e\82`\83I\83u\83W\83F\83N\83g\82ð\8e\9d\82Â}
+ FRegExpList: TStringList;
+ {FRegExpList\82É\8ai\94[\82·\82é\8d\80\96Ú\90\94\82Ì\8dÅ\91å\92l\81B \83f\83t\83H\83\8b\83g 30}
+ FRegExpListMax: RE_IndexRange_t;
+ {\8c»\8dÝ\8ew\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c» RegExp\82Ì\90³\8bK\95\\8c»\95¶\8e\9a\97ñ\83\8a\83X\83gRegExpList\92\86\82Å\82Ì
+ \83C\83\93\83f\83b\83N\83X
+ \81¦ FRegExpList[FCurrentIndex] = RegExp}
+ FCurrentIndex: Integer;
+ {\93¯\88Ó\8cê\8f\88\97\9d\83v\83\8a\83v\83\8d\83Z\83b\83T}
+ FPreProcessor: TREPreProcessor;
+
+ { \93à\95\94\8eg\97p\82Ì\82½\82ß\82Ì\8eè\91±\82«\81E\8aÖ\90\94}
+ {***** \90³\8bK\95\\8c»\95¶\8e\9a\97ñ\81¨\8d\\95¶\96Ø\8d\\91¢\81¨NFA\81¨DFA \82Ì\95Ï\8a·\82ð\8ds\82¤ *****}
+ procedure Translate(RegExpStr: String); virtual;
+
+ {\90³\8bK\95\\8c»\83\8a\83X\83g(RegExpList: TStringList)\82ÆObjects\83v\83\8d\83p\83e\83B\82É\8c\8b\82Ñ\95t\82¯\82ç\82ê\82½
+ TRE_DFA\83I\83u\83W\83F\83N\83g\82ð\94j\8aü}
+ procedure DisposeRegExpList;
+
+ {\83v\83\8d\83p\83e\83B\81E\83A\83N\83Z\83X\81E\83\81\83\\83b\83h}
+ procedure SetRegExp(Str: String); virtual;
+ function GetProcessedRegExp: String;
+ function GetListOfFuzzyCharDic: TList;
+ function GetListOfSynonymDic: TList;
+ function GetRegExpIsSimple: Boolean;
+ function GetSimpleRegExp: String;
+ function GetHasLHead: Boolean;
+ function GetHasLTail: Boolean;
+ function GetUseFuzzyCharDic: Boolean;
+ procedure SetUseFuzzyCharDic(Val: Boolean);
+ function GetUseSynonymDic: Boolean;
+ procedure SetUseSynonymDic(Val: Boolean);
+ function GetLineHeadWChar: WChar_t; virtual;
+ function GetLineTailWChar: WChar_t; virtual;
+ {DFA\83I\83u\83W\83F\83N\83g\8aÖ\98A\83\81\83\\83b\83h}
+ {\8c»\8dÝ\8ew\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c»\82É\91Î\89\9e\82·\82é\82c\82e\82`\8fó\91Ô\95\\82Ì\8f\89\8aú\8fó\91Ô\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·}
+ function GetpInitialDFAState: RE_pDFAState_t;
+ {\8c»\8dÝ\8ew\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c»\82É\91Î\89\9e\82·\82éTRE_DFA\83I\83u\83W\83F\83N\83g\82ð\95Ô\82·}
+ function GetCurrentDFA: TRE_DFA;
+ {\8fó\91Ô DFAstate\82©\82ç\95¶\8e\9a\82\83\82É\82æ\82Á\82Ä\91J\88Ú\82µ\82Ä\81A\91J\88Ú\8cã\82Ì\8fó\91Ô\82ð\95Ô\82·\81B
+ \95¶\8e\9a\82\83\82É\82æ\82Á\82Ä\91J\88Ú\8fo\97\88\82È\82¯\82ê\82Înil\82ð\95Ô\82·}
+ function NextDFAState(DFAState: RE_pDFAState_t; c: WChar_t): RE_pDFAState_t;
+ {DFA\8fó\91Ô\95\\82Ì\92\86\82Å\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LineHeadWChar: WChar_t read GetLineHeadWChar;
+ {DFA\8fó\91Ô\95\\82Ì\92\86\82Å\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LineTailWChar: WChar_t read GetLineTailWChar;
+
+ {\90³\8bK\95\\8c»\8aÖ\98A\83v\83\8d\83p\83e\83B}
+ {\8c»\8dÝ\8ew\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c»}
+ property RegExp: String read FRegExp write SetRegExp;
+
+ {\8c»\8dÝ\8ew\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c»\82É\93¯\88Ó\8cê\8f\88\97\9d\82ð\8e{\82µ\82½\82à\82Ì}
+ property ProcessedRegExp: String read GetProcessedRegExp;
+
+ {\90³\8bK\95\\8c»\82ª\92P\8f\83\82È\95¶\8e\9a\97ñ\82©\81H}
+ property RegExpIsSimple: Boolean read GetRegExpIsSimple;
+ {\90³\8bK\95\\8c»\82Æ\93\99\89¿\82È\92P\8f\83\82È\95¶\8e\9a\97ñ(\81¦RegExpIsSimple=False\82Ì\8e\9e\82Í\83k\83\8b\95¶\8e\9a\97ñ)}
+ property SimpleRegExp: String read GetSimpleRegExp;
+
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLHead: Boolean read GetHasLHead;
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLTail: Boolean read GetHasLTail;
+
+ {\8e«\8f\91\8aÖ\98A\83v\83\8d\83p\83e\83B}
+ {\95¶\8e\9a\93¯\88ê\8e\8b\8e«\8f\91\82ð\8eg\82¤\81^\8eg\82í\82È\82¢\8ew\92è}
+ property UseFuzzyCharDic: Boolean read GetUseFuzzyCharDic write SetUseFuzzyCharDic;
+ {\95¶\8e\9a\82Ì\93¯\88ê\8e\8b\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfFuzzyCharDic: TList read GetListOfFuzzyCharDic;
+
+ {\93¯\88Ó\8cê\8e«\8f\91\82ð\8eg\82¤\81^\8eg\82í\82È\82¢\8ew\92è}
+ property UseSynonymDic: Boolean read GetUseSynonymDic write SetUseSynonymDic;
+ {\93¯\88Ó\8cê\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfSynonymDic: TList read GetListOfSynonymDic;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ end;
+
+{ -========================== TAWKStr Class ==================================-}
+ TMatchCORE_LineSeparator = (mcls_CRLF, mcls_LF);
+
+ TMatchCORE = class(TRegularExpression)
+ private
+ FLineSeparator: TMatchCORE_LineSeparator;
+ protected
+ function IsLineEnd(WChar: WChar_t): Boolean;
+ property LineSeparator: TMatchCORE_LineSeparator
+ read FLineSeparator write FLineSeparator;
+ protected
+
+ {\90à\96¾ \81F \83}\83b\83`
+ (\90³\8bK\95\\8c»\82ª\8ds\93ª\81^\8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Ü\82È\82¢\82Æ\82«\97p)
+ \93®\8dì \81F
+ \88ø\90\94 \81F pText: PChar \83k\83\8b\83L\83\83\83\89\83N\83^\82Å\8fI\82í\82é\8c\9f\8dõ\91Î\8fÛ\95¶\8e\9a\97ñ\82Ö\82Ì\83|\83C\83\93\83^
+ \95\9b\8dì\97p\81F pStart:PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\90æ\93ª\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ pEnd :PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\8e\9f\82Ì\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ \92\8d\88Ó \81F \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\83o\83C\83g\90\94\82Í\81ApEnd - pStart\82Å\93¾\82ç\82ê\82é\81B}
+ procedure MatchStd(pText: PChar; var pStart, pEnd: PChar);
+
+
+ {\90à\96¾ \81F \83}\83b\83`(\90³\8bK\95\\8c»\82ª\8ds\93ª\81^\8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82Æ\82«\97p)
+ \93®\8dì \81F
+ \88ø\90\94 \81F pText: PChar \83k\83\8b\83L\83\83\83\89\83N\83^\82Å\8fI\82í\82é\8c\9f\8dõ\91Î\8fÛ\95¶\8e\9a\97ñ\82Ö\82Ì\83|\83C\83\93\83^
+ \95\9b\8dì\97p\81F pStart:PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\90æ\93ª\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ pEnd :PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\8e\9f\82Ì\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ \92\8d\88Ó \81F \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\83o\83C\83g\90\94\82Í\81ApEnd - pStart\82Å\93¾\82ç\82ê\82é\81B}
+ procedure MatchEX(pText: PChar; var pStart, pEnd: PChar);
+
+ {\90à\96¾ \81F \83}\83b\83`(\93à\95\94\8f\88\97\9d\97p\81B\90³\8bK\95\\8c»\82ª\8ds\93ª\81^\8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82Æ\82«\97p)
+ \93®\8dì \81F MatchEx_Head\83\81\83\\83b\83h\82Æ\82Ì\88á\82¢\82Í\81A\88ø\90\94pText\82ª\8ds\82Ì\93r\92\86\82ð\83|\83C\83\93\83g\82µ\82Ä
+ \82¢\82é\82à\82Ì\82Æ\82µ\82Ä\81A\8ds\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82É\83}\83b\83`\82µ\82È\82¢\82±\82Æ\81B
+ \88ø\90\94 \81F pText: PChar \83k\83\8b\83L\83\83\83\89\83N\83^\82Å\8fI\82í\82é\8c\9f\8dõ\91Î\8fÛ\95¶\8e\9a\97ñ\82Ö\82Ì\83|\83C\83\93\83^
+ (\8ds\82Ì\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82à\82Ì\82Æ\82µ\82Ä\88µ\82¤\81B)
+ \95\9b\8dì\97p\81F pStart:PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\90æ\93ª\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ pEnd :PChar \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\8e\9f\82Ì\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^
+ \92\8d\88Ó \81F \83}\83b\83`\82µ\82½\95\94\95ª\82Ì\83o\83C\83g\90\94\82Í\81ApEnd - pStart\82Å\93¾\82ç\82ê\82é\81B}
+ procedure MatchEX_Inside(pText: PChar; var pStart, pEnd: PChar);
+
+{----------------\83}\83b\83` \89º\90¿\82¯ -------------}
+{MatchHead, MatchInside\82Í\81A\88ø\90\94 pText\82ª\8ew\82·\95¶\8e\9a\82ð\90æ\93ª\82Æ\82µ\82Ä\83}\83b\83`\82·\82é\82©\82ð\8c\9f\8d¸\82·\82é}
+
+ {\90à\96¾ \81F pText\82Í\81A\82 \82é\95¶\8e\9a\97ñ\82Ì\8ds\93ª\82ð\83|\83C\83\93\83g\82µ\82Ä\82¢\82é\82à\82Ì\82Æ\8c©\82È\82·\81B
+ \82µ\82½\82ª\82Á\82Ä\81ApText\82ª\8ew\82·\95¶\8e\9a\82Í\8ds\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82É\83}\83b\83`\82·\82é\81B
+ \8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8dl\97¶\82·\82é\81B
+ \88ø\90\94 \81F pText: PChar \8c\9f\8dõ\91Î\8fÛ\95¶\8e\9a\97ñ(\8ds\82Ì\8dÅ\8f\89\82Ì\95¶\8e\9a\82ð\8ew\82·)
+ pDFAState \8f\89\8aú\92l\82Æ\82µ\82Ä\8eg\82¤DFA\8fó\91Ô\95\\82Ì\82P\8fó\91Ô
+ \95Ô\82è\92l\81F \83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ\82Ì\8e\9f\82Ì\95¶\8e\9a\81B
+ \83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ\82Ì\83o\83C\83g\92·\82Í\81Aresult - pText
+ \92\8d\88Ó \81F }
+ function MatchHead(pText: PChar; pDFAState: RE_pDFAState_t): PChar;
+
+ {\90à\96¾ \81F pText\82Í\81A\82 \82é\95¶\8e\9a\97ñ\82Ì\92\86(\8ds\93ª\82Å\82Í\82È\82¢)\82ð\83|\83C\83\93\83g\82µ\82Ä\82¢\82é\82à\82Ì\82Æ\8c©\82È\82·\81B
+ \82µ\82½\82ª\82Á\82Ä\81ApText\82ª\8ew\82·\95¶\8e\9a\82Í\8ds\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82É\83}\83b\83`\82µ\82È\82¢\81B
+ \8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8dl\97¶\82·\82é\81B
+ \88ø\90\94 \81F pText: PChar \8c\9f\8dõ\91Î\8fÛ\95¶\8e\9a\97ñ(\8ds\92\86\82Ì\95¶\8e\9a\82ð\8ew\82·)
+ pDFAState \8f\89\8aú\92l\82Æ\82µ\82Ä\8eg\82¤DFA\8fó\91Ô\95\\82Ì\82P\8fó\91Ô
+ \95Ô\82è\92l\81F \83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ\82Ì\8e\9f\82Ì\95¶\8e\9a\81B
+ \83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ\82Ì\83o\83C\83g\92·\82Í\81Aresult - pText
+ \92\8d\88Ó \81F }
+ function MatchInside(pText: PChar; pDFAState: RE_pDFAState_t): PChar;
+ public
+ constructor Create(AOwner: TComponent); override;
+ end;
+
+{ -========================== TAWKStr Class ==================================-}
+ TAWKStrMatchProc = procedure(pText: PChar; var pStart, pEnd: PChar) of object;
+
+{\81\9c AWK\8c¾\8cê\82Ì\95¶\8e\9a\97ñ\91\80\8dì\8aÖ\90\94\8cQ\82ðDelphi\82Å\8eÀ\8c»\82·\82é\83N\83\89\83X TAWKStr}
+ TAWKStr = class(TMatchCORE)
+ private
+ FMatchProc: TAWKStrMatchProc;
+ protected
+ procedure SetRegExp(Str: String); override;
+ {Sub, GSub\83\81\83\\83b\83h\82Å\8eg\97p\81B '&'\82ð\83}\83b\83`\82µ\82½\95¶\8e\9a\97ñ\82É\92u\8a·\82¦\82é}
+ function Substitute_MatchStr_For_ANDChar(Text: String; MatchStr: String): String;
+ public
+ constructor Create(AOwner: TComponent); override;
+ function ProcessEscSeq(Text: String): String;
+
+ {\95¶\8e\9a\82Ì\93¯\88ê\8e\8b\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfFuzzyCharDic;
+ {\93¯\88Ó\8cê\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfSynonymDic;
+
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLHead;
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLTail;
+
+ property ProcessedRegExp;
+
+ {DFA\8fó\91Ô\95\\82Ì\92\86\82Å\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LineHeadWChar;
+ {DFA\8fó\91Ô\95\\82Ì\92\86\82Å\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\83L\83\83\83\89\83N\83^\83R\81[\83h}
+ property LineTailWChar;
+
+ function Match(Text: String; var RStart, RLength: Integer): Integer;
+
+ function Sub(SubText: String; var Text: String): Boolean;
+
+ function GSub(SubText: String; var Text: String): Integer;
+
+ function Split(Text: String; StrList: TStrings): Integer;
+ published
+ property RegExp;
+ {\8ds\82Ì\8bæ\90Ø\82è\95¶\8e\9a\8ew\92è}
+ property LineSeparator;
+
+ {\95¶\8e\9a\82Ì\93¯\88ê\8e\8b\8e«\8f\91\82ð\8eg\82¤\82©}
+ property UseFuzzyCharDic;
+ {\93¯\88Ó\8cê\8e«\8f\91\82ð\8eg\82¤\82©}
+ property UseSynonymDic;
+
+ end;
+
+{ -========================== \97á\8aO\83N\83\89\83X =====================================-}
+ EEndOfFile = class(EInOutError);
+
+ EFileNotFound = class(EInOutError);
+
+ EGrepCancel = class(Exception);
+
+{ -=========================== TTxtFile Class ================================-}
+ {TTextFile\83N\83\89\83X\82ÌGetThisLine\82ª\95Ô\82·\83t\83@\83C\83\8b\92\86\82Ì\82P\8ds\82Ì\8fî\95ñ\82ð\95\\82·\8c^}
+ RE_LineInfo_t = record
+ Line: String;
+ LineNo: Integer; {\8ds\94Ô\8d\86}
+ end;
+
+{\81\9c TTxtFile \83e\83L\83X\83g\83t\83@\83C\83\8b\81E\83A\83N\83Z\83X\81E\83N\83\89\83X}
+ TTxtFile = Class
+ private
+ protected
+ public
+ FBuffSize: Integer; {\83o\83b\83t\83@\82Ì\83T\83C\83Y}
+ FTailMargin: Integer;
+ FpBuff: PChar; {\93Ç\82Ý\8d\9e\82Ý\83o\83b\83t\83@\82Ö\82Ì\83|\83C\83\93\83^}
+
+ FFileName: String; {\8f\88\97\9d\91Î\8fÛ\83t\83@\83C\83\8b\96¼ \81i\83t\83\8b\83p\83X\95\\8bL\81j}
+ FF: File; {FFileName \82É\8aÖ\98A\95t\82¯\82ç\82ê\82é\8c^\82È\82µ\83t\83@\83C\83\8b\95Ï\90\94}
+ FFileOpened: Boolean;
+
+ {\83o\83b\83t\83@\92\86\82Ì\95¶\8e\9a\88Ê\92u\82ð\95\\82·\8fd\97v\82È\83|\83C\83\93\83^\82R\8eí\97Þ}
+ FpBase: PChar; {\95¶\92\86\82Å\8c\9f\8dõ\91Î\8fÛ\82Æ\82È\82é\95\94\95ª\95¶\8e\9a\97ñ\82Ì\90æ\93ª\82ð\8ew\82·}
+ FpLineBegin: PChar; {FpBase\82ª\8ew\82·\95¶\82Ì\90æ\93ª\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^}
+ FpForward: PChar; {\8c\9f\8dõ\92\86\82Ì\95¶\8e\9a\82Ö\82Ì\83|\83C\83\93\83^}
+
+ FLineNo: Integer; {\8c»\8dÝ\82Ì\8ds\94Ô\8d\86}
+ FReadCount: Integer;{BlockRead \82Å\89½\83o\83C\83g\93Ç\82Ý\8d\9e\82ñ\82¾\82©\81B}
+ FBrokenLine: String;{\83o\83b\83t\83@\82Ì\8b«\8aE\82Å\95ª\92f\82³\82ê\82½\95¶\82Ì\91O\94¼\95\94\95ª}
+
+ FpCancelRequest: ^Boolean;
+ {IncPBase\83\81\83\\83b\83h\82ÅFpBase\82ª\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82ð\8ew\82µ\82½\82Æ\82«\82Ì\8f\88\97\9d}
+ procedure IncPBaseNullChar(Ch: Char);
+ {GetChar\83\81\83\\83b\83h\82ÅFpForward\82ª\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82ð\8ew\82µ\82½\82Æ\82«\82Ì\8f\88\97\9d}
+ procedure GetCharNullChar(Ch: Char);
+
+ constructor Create(aFileName: String; var CancelRequest: Boolean);
+ destructor Destroy; override;
+ procedure BuffRead(pBuff: PChar);
+ function IncPBase: Char; {FpBase\82ª\8e\9f\82Ì\83o\83C\83g\82ð\8ew\82·\82æ\82¤\82É\82·\82é}
+ function AdvanceBase: WChar_t;
+ function GetChar: Char;
+ function GetWChar: WChar_t;
+ function GetThisLine: RE_LineInfo_t;{FpBase\82ª\8ew\82µ\82Ä\82¢\82é\95¶\8e\9a\82ð\8aÜ\82Þ\95¶\82ð\93¾\82é}
+ end;
+
+{ -=========================== TGrep Class ==================================-}
+
+ TGrepOnMatch = procedure (Sender: TObject; LineInfo: RE_LineInfo_t) of Object;
+
+ TGrepGrepProc = procedure (FileName: String) of Object;
+
+{\81\9c \83t\83@\83C\83\8b\90³\8bK\95\\8c»\8c\9f\8dõ\83N\83\89\83X TGrep }
+ TGrep = class(TRegularExpression)
+ private
+ FOnMatch: TGrepOnMatch;
+// FDummyIgnoreCase: Boolean;
+ FCancel: Boolean;
+ FGrepProc: TGrepGrepProc;
+ protected
+ procedure SetRegExp(Str: String); override;
+ function GetLineHeadWChar: WChar_t; override;
+ function GetLineTailWChar: WChar_t; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+
+ procedure GrepByRegExp(FileName: String);
+ procedure GrepByStr(FileName: String);
+
+ {\8b@\94\ \8ew\92è\82³\82ê\82½\83e\83L\83X\83g\81E\83t\83@\83C\83\8b\92\86\82Å\90³\8bK\95\\8c»(RegExp\83v\83\8d\83p\83e\83B)\82É\83}\83b\83`
+ \82·\82é\8ds\82ð\92T\82µ\81A\8c©\82Â\82¯\82é\82½\82Ñ\82ÉOnMatch \83C\83x\83\93\83g\83n\83\93\83h\83\89\82ð\8cÄ\82Ñ\8fo\82µ\82Ü\82·\81B
+
+ (RegExp\83v\83\8d\83p\83e\83B\82É\90Ý\92è\82³\82ê\82Ä\82¢\82é\90³\8bK\95\\8c»\82ð\8c\9f\8d¸\82µ\82Ä\81A\95\81\92Ê\82Ì\95¶\8e\9a\97ñ\82È\82ç\82Î
+ GrepByStr\83\81\83\\83b\83h\81A\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82Æ\82«\82ÍGrepByRegExp\83\81\83\\83b\83h\82ð
+ \8cÄ\82Ñ\8fo\82µ\82Ü\82·\81B)
+ \81¦ OnMatch \83C\83x\83\93\83g\83n\83\93\83h\83\89\82ª\8ew\92è\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Í\81A\89½\82à\82µ\82Ü\82¹\82ñ\81B
+
+ \88ø\90\94 FileNmae \8c\9f\8dõ\91Î\8fÛ\82Ì\83e\83L\83X\83g\83t\83@\83C\83\8b\96¼(\83t\83\8b\83p\83X\8ew\92è)
+ CancelRequest \8c\9f\8dõ\82ð\93r\92\86\82Å\8e~\82ß\82½\82¢\82Æ\82«\82ÉTrue\82É\82·\82é\81B
+ \81¦ Grep\83\81\83\\83b\83h\82Í\93à\95\94\82Å\81AApplication.ProcessMessages\82ð\8cÄ\82Ñ\8fo\82·
+ \82Ì\82Å\81A\82»\82Ì\82Æ\82«\82É\81ACancelRequest\82ðTrue\82É\90Ý\92è\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82·\81B}
+
+ {\90³\8bK\95\\8c»\82ª\92P\8f\83\82È\95¶\8e\9a\97ñ\82©\81H}
+ property RegExpIsSimple;
+ {\90³\8bK\95\\8c»\82Æ\93\99\89¿\82È\92P\8f\83\82È\95¶\8e\9a\97ñ(\81¦RegExpIsSimple=False\82Ì\8e\9e\82Í\83k\83\8b\95¶\8e\9a\97ñ)}
+ property SimpleRegExp;
+
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLHead;
+ {\90³\8bK\95\\8c»\82ª\81A\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82Þ\82©}
+ property HasLTail;
+
+ {RegExp\83v\83\8d\83p\83e\83B\82Ì\90³\8bK\95\\8c»\82É\93¯\88Ó\8cê\8f\88\97\9d\82ð\8e{\82µ\82½\82à\82Ì}
+ property ProcessedRegExp;
+ {\95¶\8e\9a\82Ì\93¯\88ê\8e\8b\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfFuzzyCharDic;
+ {\93¯\88Ó\8cê\8e«\8f\91\82Ì\83\8a\83X\83g}
+ property ListOfSynonymDic;
+
+ property Grep: TGrepGrepProc read FGrepProc;
+ published
+ {\90³\8bK\95\\8c»\95¶\8e\9a\97ñ}
+ property RegExp;
+ {\95¶\8e\9a\82Ì\93¯\88ê\8e\8b\8e«\8f\91\82ð\8eg\82¤\82©}
+ property UseFuzzyCharDic;
+ {\93¯\88Ó\8cê\8e«\8f\91\82ð\8eg\82¤\82©}
+ property UseSynonymDic;
+
+ property OnMatch: TGrepOnMatch read FOnMatch write FOnMatch;
+
+ property Cancel: Boolean read FCancel write FCancel;
+ end;
+
+
+
+var
+ RE_FuzzyCharDic: TList;
+
+procedure Register;
+
+implementation
+{************************ Implementation ************************************}
+constructor ERegExpParser.Create(const Msg: string; ErrorPosition: Word);
+begin
+ inherited Create(Msg);
+ ErrorPos := ErrorPosition;
+end;
+{ -====================== \95¶\8e\9a\97ñ\91\80\8dì\8aÖ\90\94 =====================================-}
+{\90à\96¾ \81F \82P\82U\90i\90\94\82ð\95\\82·\95¶\8e\9a\82ð\8eó\82¯\8eæ\82è\81A\90®\90\94\82É\82µ\82Ä\95Ô\82·\81B
+ \88ø\90\94 \81F WCh: WChar_t; 16\90i\90\94\82ð\95\\82·1\83o\83C\83g\95¶\8e\9a [0-9a-fA-F]
+
+ \95Ô\82è\92l\81F \90³\8fí\8e\9e\81F 0 <= result <= 15
+ \88Ù\8fí\8e\9e\81F -1}
+function HexWCharToInt(WCh: WChar_t): Integer;
+begin
+ case WCh of
+ Ord('0')..Ord('9'): result := WCh - Ord('0');
+ Ord('A')..Ord('F'): result := WCh - Ord('A')+10;
+ Ord('a')..Ord('f'): result := WCh - Ord('a')+10;
+ else result := -1;
+ end;
+end;
+
+{\90à\96¾ \81F \82W\90i\90\94\82ð\95\\82·\95¶\8e\9a\82ð\8eó\82¯\8eæ\82è\81A\90®\90\94\82É\82µ\82Ä\95Ô\82·\81B
+ \88ø\90\94 \81F WCh: WChar_t; 8\90i\90\94\82ð\95\\82·1\83o\83C\83g\95¶\8e\9a [0-7]
+
+ \95Ô\82è\92l\81F \90³\8fí\8e\9e\81F 0 <= result <= 7
+ \88Ù\8fí\8e\9e\81F -1}
+function OctWCharToInt(WCh: WChar_t): Integer;
+begin
+ case WCh of
+ Ord('0')..Ord('7'): result := WCh - Ord('0');
+ else result := -1;
+ end;
+end;
+
+{\8b@\94\\81F Str \82©\82ç \82P\95¶\8e\9a \93¾\82é
+ \89ð\90à\81F Str\92\86\82ÅIndex\82ª\8ew\82·\88Ê\92u\82©\82ç1\95¶\8e\9a(\82Q\83o\83C\83g\95¶\8e\9a\8aÜ\82Þ) \93¾\82Ä\82©\82ç\81AIndex\82ª
+ \8e\9f\82Ì\95¶\8e\9a\82ð\8ew\82·\82æ\82¤\82É\90i\82ß\82é
+ \92\8d\88Ó\81F Index\82ª\95¶\8e\9a\97ñ\82Ì\92·\82³\82æ\82è\82·\82Å\82É\92·\82¢\8fê\8d\87\82Í\8fí\82É 0\82ð\95Ô\82µ\81AIndex\82ð\91\9d\82â\82³\82È\82¢\81B
+ \82Â\82Ü\82è\81AIndex\82Í\8dÅ\91å\82Å\82à Length(Str)+1 \82Å\82 \82é\81B}
+function GetWChar(const Str: String; var Index: Integer): WChar_t;
+begin
+ if (Index >= 1) and (Index <= Length(Str)) then begin
+ if IsDBCSLeadByte(Byte(Str[Index])) then begin
+ {Str\82Ì\8dÅ\8cã\82Ì\95¶\8e\9a\82ª\82Q\83o\83C\83g\95¶\8e\9a\83R\81[\83h\82Ì\82P\83o\83C\83g\82Ì\82Æ\82«\82Í\97á\8aO\90¶\90¬}
+ if Index = Length(Str) then
+ raise ERegExpParser.Create('\95s\90³\82È\82Q\83o\83C\83g\95¶\8e\9a\83R\81[\83h\82Å\82·\81B', Index);
+ WordRec(result).Hi := Byte(Str[Index]);
+ WordRec(result).Lo := Byte(Str[Index+1]);
+ Inc(Index, 2);
+ end else begin
+ result := Byte(Str[Index]);
+ Inc(Index);
+ end;
+ end else begin
+ result := CONST_NULL;
+ end;
+end;
+
+//1997/09/25 FIX: MBUtils.pas\82ª\82È\82\82Ä\82à\93®\8dì\82·\82é\82æ\82¤\82É\95Ï\8dX
+function IsTrailByteInStr(pText: PAnsiChar;
+ ptr: PAnsiChar
+ ): Boolean;
+var
+ p: PAnsiChar;
+begin
+ Result := false;
+ if pText = ptr then Exit;
+ p := ptr - 1;
+ while (p <> pText) do
+ begin
+ if not IsDBCSLeadByte(Ord(p^)) then Break;
+ Dec(p);
+ end;
+ if ((ptr - p) mod 2) = 0 then Result := true;
+end;
+
+procedure UnGetWChar(const Str: String; var Index: Integer);
+begin
+ if Index <= 1 then
+ Exit
+ else if (Index > 2) and IsTrailByteInStr(PAnsiChar(Str), PAnsiChar(Str)+Index-2) then
+ Dec(Index, 2)
+ else
+ Dec(Index);
+end;
+
+function PCharGetWChar(var pText: PChar): WChar_t;
+begin
+ if Byte(pText^) <> CONST_NULL then begin
+ if IsDBCSLeadByte(Byte(pText^)) then begin
+ WordRec(result).Hi := Byte(pText^);
+ WordRec(result).Lo := Byte((pText+1)^);
+ Inc(pText, 2);
+ end else begin
+ result := Byte(pText^);
+ Inc(pText);
+ end;
+ end else begin
+ result := CONST_NULL;
+ end;
+end;
+
+{\8b@\94\\81F WChar_t\8c^\82Ì\92l\82ðString\8c^\82Ö\95Ï\8a·\82·\82é\81B}
+function WCharToStr(WCh: WChar_t): String;
+begin
+ if IsDBCSLeadByte(Hi(WCh)) then
+ result := Chr(Hi(WCh))+Chr(Lo(WCh))
+ else
+ result := Chr(Lo(WCh));
+end;
+
+{\8b@\94\\81F '\' \82Å \88ø\97p\82³\82ê\82½\83L\83\83\83\89\83N\83^\82ð\93¾\82é\81B \n, \t \\ ...
+ \92\8d\88Ó\81F Index\82Í'\'\82Ì\8e\9f\82Ì\95¶\8e\9a\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82·\82é\81B}
+function GetQuotedWChar(const Str: String; var Index: Integer): WChar_t;
+var
+ WCh: WChar_t;
+begin
+ WCh := GetWChar(Str, Index);
+ if WCh = 0 then
+ raise ERegExpParser.Create('"\"\82Ì\8e\9f\82É\82Í\95¶\8e\9a\82ª\95K\97v\82Å\82·\81B', Index);
+
+ if WCh = CONST_b then {'b'}
+ result := CONST_BS {back space}
+ else if WCh = CONST_r then {'r'}
+ result := CONST_CR {Carriage Return}
+ else if WCh = CONST_n then {'n'}
+ result := CONST_LF {Line Feed}
+ else if WCh = CONST_t then {'t'}
+ result := CONST_TAB {tab}
+ else if WCh = CONST_x then {'x'}
+ result := HexStrToInt(Str, Index)
+ else if OctWCharToInt(WCh) >= 0 then begin
+ UnGetWChar(Str, Index); {WCh\82ð\96ß\82·}
+ result := OctStrToInt(Str, Index);
+ end else
+ result := WCh;
+end;
+
+{\90à\96¾ \81F 16\90i\90\94\95\\8bL\82Ì\95¶\8e\9a\97ñ\82ðWord\8c^\82Ì\90\94\92l\82É\95Ï\8a·\82·\82é\81B
+\88ø\90\94 \81F Str: String \95Ï\8a·\8c³\82Ì\95¶\8e\9a\97ñ
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+\95Ô\82è\92l\81F \95¶\8e\9a\97ñ\82ª\95\\82·Word\8c^\82Ì\92l}
+function HexStrToInt(const Str: String; var Index: Integer): Word;
+var
+ Val, i: Integer;
+ WCh: WChar_t;
+begin
+ result := 0;
+ i := 1;
+ WCh := GetWChar(Str, Index);
+ Val := HexWCharToInt(WCh);
+ while (WCh <> CONST_NULL) and (Val >= 0) and (i < 5) do begin
+ result := result * 16 + Val;
+ WCh := GetWChar(Str, Index);
+ Val := HexWCharToInt(WCh);
+ Inc(i);
+ end;
+ if i = 1 then
+ raise ERegExpParser.Create('\95s\90³\82È\82P\82U\90i\90\94\83R\81[\83h\95\\8bL\82Å\82·\81B', Index);
+ if WCh <> CONST_NULL then
+ UnGetWChar(Str, Index);
+end;
+
+{\90à\96¾ \81F \82W\90i\90\94\95\\8bL\82Ì\95¶\8e\9a\97ñ\82ðWord\8c^\82Ì\90\94\92l\82É\95Ï\8a·\82·\82é\81B
+\88ø\90\94 \81F Str: String \95Ï\8a·\8c³\82Ì\95¶\8e\9a\97ñ
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+\95Ô\82è\92l\81F \95¶\8e\9a\97ñ\82ª\95\\82·Word\8c^\82Ì\92l}
+function OctStrToInt(const Str: String; var Index: Integer): Word;
+var
+ Val, i: Integer;
+ WCh: WChar_t;
+begin
+ result := 0;
+ i := 1;
+ WCh := GetWChar(Str, Index);
+ Val := OctWCharToInt(WCh);
+ while (WCh <> CONST_NULL) and (Val >= 0) and (i < 7) do begin
+ if (result * 8 + Val) > $FFFF then
+ raise ERegExpParser.Create('\95s\90³\82È\82W\90i\90\94\83R\81[\83h\95\\8bL\82Å\82·\81B', Index);
+ result := result * 8 + Val;
+ WCh := GetWChar(Str, Index);
+ Val := OctWCharToInt(WCh);
+ Inc(i);
+ end;
+ if i = 1 then
+ raise ERegExpParser.Create('\95s\90³\82È\82W\90i\90\94\83R\81[\83h\95\\8bL\82Å\82·\81B', Index);
+ if WCh <> CONST_NULL then
+ UnGetWChar(Str, Index);
+end;
+
+{\90à\96¾ \81F FS:WChar_t\82ð\8bæ\90Ø\82è\95¶\8e\9a\82Æ\82µ\82Ä\81A\83o\83C\83g\88Ê\92uIndex\82©\82ç\8en\82Ü\82é\83g\81[\83N\83\93\82ð\82P\82Â\95Ô\82·\81B
+\88ø\90\94 \81F Str: String
+ Index: Integer \88ø\90\94Str\82ÌIndex\94Ô\96Ú\82Ì\83o\83C\83g\88Ê\92u\82©\82ç\95Ï\8a·\82ð\8en\82ß\82é\81B
+\95Ô\82è\92l\81F FS\82Å\8bæ\90Ø\82ç\82ê\82½\81A\83o\83C\83g\88Ê\92uIndex\82©\82ç\8en\82Ü\82é\83g\81[\83N\83\93}
+function WCharGetToken(const Str: String; var Index: Integer; FS: WChar_t): String;
+var
+ WCh: WChar_t;
+begin
+ result := '';
+ WCh := GetWChar(Str, Index);
+ while WCh <> 0 do begin
+ if WCh = FS then
+ break
+ else begin
+ result := result + WCharToStr(WCh);
+ WCh := GetWChar(Str, Index);
+ end;
+ end;
+end;
+
+{\90à\96¾ \81F \88ø\90\94Str\92\86\82Ì\83\81\83^\83L\83\83\83\89\83N\83^\82É'\'\82ð\82Â\82¯\82é\81B
+\88ø\90\94 \81F Str: String
+\95Ô\82è\92l\81F \83\81\83^\83L\83\83\83\89\83N\83^\82Ì\91O\82É'\'\82ª\82Â\82¢\82½Str}
+function QuoteMetaWChar(Str: String): String;
+var
+ i, j: Integer;
+ WChar: WChar_t;
+begin
+ result := '';
+ i := 1;
+ WChar := GetWChar(Str, i);
+ while WChar <> 0 do begin
+ j := 0;
+ while j <= High(METACHARS) do begin
+ if METACHARS[j] = WChar then
+ break
+ else
+ Inc(j);
+ end;
+ if j <= High(METACHARS) then
+ result := result + '\' + WCharToStr(WChar)
+ else
+ result := result + WCharToStr(WChar);
+ WChar := GetWChar(Str, i);
+ end;
+
+end;
+
+{ -============================ TREScanner Class =================================-}
+constructor TREScanner.Create(Str: String);
+begin
+ inherited Create;
+ Self.SetRegExpStr(Str);
+end;
+
+procedure TREScanner.SetRegExpStr(RegExpStr: String);
+begin
+ FRegExpStr := RegExpStr;
+ FIndex := 1;
+end;
+
+{\8b@\94\\81F \83g\81[\83N\83\93\82ð\93¾\82é
+ \89ð\90à\81F GetWChar\82¨\82æ\82ÑUnGetWChar\83\81\83\\83b\83h\82ð\8eg\82Á\82Ä\83g\81[\83N\83\93\82ð\93¾\82é\81B
+ \92\8d\88Ó\81F \95Ô\82è\92l\82Í\81A\97ñ\8b\93\8c^ REToken_t\82Ì\82¤\82¿retk_CharClass\88È\8aO\82Ì\82Ç\82ê\82©}
+function TREScanner.GetTokenStd: REToken_t;
+var
+ WChar: WChar_t;
+begin
+ WChar := GetWChar(FRegExpStr, FIndex);
+ FSymbol.WChar := WChar;
+
+ { \95¶\8e\9a(\97ñ)\82ð\83g\81[\83N\83\93\82É\95Ï\8a·\82·\82é }
+ if WChar = CONST_NULL then
+ FToken := retk_End
+ else if WChar = CONST_DOLLAR then
+ FToken := retk_LTail
+ else if WChar = CONST_LPAR then
+ FToken := retk_LPar
+ else if WChar = CONST_RPAR then
+ FToken := retk_RPar
+ else if WChar = CONST_STAR then
+ FToken := retk_Star
+ else if WChar = CONST_PLUS then
+ FToken := retk_Plus
+ else if WChar = CONST_DOT then
+ FToken := retk_Dot
+ else if WChar = CONST_QMARK then
+ FToken := retk_QMark
+ else if WChar = CONST_VL then
+ FToken := retk_Union
+ else if WChar = CONST_RBRA then
+ FToken := retk_RBra
+ else if WChar = CONST_LBRA then begin
+ WChar := GetWChar(FRegExpStr, FIndex);
+ if WChar = CONST_NULL then
+ raise ERegExpParser.Create('\89E\83u\83\89\83P\83b\83g"]"\82ª\95K\97v\82Å\82·', FIndex);
+ if WChar = CONST_CARET then
+ FToken := retk_LBraNeg {\95â\83L\83\83\83\89\83N\83^\83N\83\89\83X}
+ else begin
+ UnGetWChar(FRegExpStr, FIndex);
+ FToken := retk_LBra;
+ end;
+ end
+ else if WChar = CONST_YEN then begin
+ FToken := retk_Char;
+ FSymbol.WChar := GetQuotedWChar(FRegExpStr, FIndex);
+ end
+ else if WChar = CONST_CARET then begin
+ FToken := retk_LHead;
+ end else
+ FToken := retk_Char;
+
+ result := FToken;
+end;
+
+{\8b@\94\\81F '[]'\82Å\88Í\82Ü\82ê\82½\83L\83\83\83\89\83N\83^\83N\83\89\83X\90³\8bK\95\\8c»\82Ì\92\86\82Ì\83g\81[\83N\83\93\82ð\93¾\82é\81B
+ \89ð\90à\81F GetWChar\82¨\82æ\82ÑUnGetWChar\83\81\83\\83b\83h\82ð\8eg\82Á\82Ä\83g\81[\83N\83\93\82ð\93¾\82é\81B
+ \92\8d\88Ó\81F \95Ô\82è\92l\82Í\81A\97ñ\8b\93\8c^ REToken_t\82Ì\82¤\82¿
+ retk_Char, retk_CharClass, retk_RBra\82Ì\82Ç\82ê\82©\81B
+ \83k\83\8b\81E\83L\83\83\83\89\83N\83^\82ð\8c©\82Â\82¯\82½\82Æ\82«\82Í\97á\8aO\82ð\90¶\90¬\82·\82é\81B}
+function TREScanner.GetTokenCC: REToken_t;
+var
+ WChar, WChar2, WChar3: WChar_t;
+begin
+ WChar := GetWChar(FRegExpStr, FIndex);
+ FSymbol.WChar := WChar;
+
+ { \95¶\8e\9a(\97ñ)\82ð\83g\81[\83N\83\93\82É\95Ï\8a·\82·\82é }
+ if WChar = CONST_NULL then
+ raise ERegExpParser.Create('\89E\83u\83\89\83P\83b\83g"]"\82ª\95K\97v\82Å\82·', FIndex);
+ if WChar = CONST_RBRA then
+ FToken := retk_RBra
+ else begin
+ if WChar = CONST_YEN then
+ {\83G\83X\83P\81[\83v\83V\81[\83P\83\93\83X\82ð\8f\88\97\9d}
+ WChar := GetQuotedWChar(FRegExpStr, FIndex);
+
+ {\83L\83\83\83\89\83N\83^\94Í\88Í\82ð\95\\82·'-'\82É\8aÖ\82·\82é\8f\88\97\9d\82ð\82·\82é}
+ FToken := retk_Char;
+ WChar2 := GetWChar(FRegExpStr, FIndex);
+ if WChar2 = CONST_MINUS then begin
+ {2\94Ô\96Ú\82Ì\95¶\8e\9a\82ª'-'\82¾\82Á\82½\82Æ\82«}
+ WChar3 := GetWChar(FRegExpStr, FIndex);
+ if WChar3 = CONST_NULL then
+ {3\94Ô\96Ú\82Ì\95¶\8e\9a\82ª\83k\83\8b\83L\83\83\83\89\83N\83^\82Ì\82Æ\82«}
+ raise ERegExpParser.Create('\89E\83u\83\89\83P\83b\83g"]"\82ª\95K\97v\82Å\82·', FIndex);
+
+ if WChar3 = CONST_RBRA then begin
+ {3\94Ô\96Ú\82Ì\95¶\8e\9a\82ª ']'\82Ì\82Æ\82«}
+ UnGetWChar(FRegExpStr, FIndex); { WChar3\82ð\96ß\82· }
+ UnGetWChar(FRegExpStr, FIndex); { WChar2\82ð\96ß\82· }
+ FSymbol.WChar := WChar;
+ end else begin
+ if WChar3 = CONST_YEN then
+ WChar3 := GetQuotedWChar(FRegExpStr, FIndex);
+ FToken := retk_CharClass;
+ if WChar > WChar3 then
+ raise ERegExpParser.Create('\95s\90³\82È\83L\83\83\83\89\83N\83^\94Í\88Í\82Å\82·', FIndex);
+ FSymbol.CharClass.StartChar := WChar;
+ FSymbol.CharClass.EndChar := WChar3;
+ end
+ end else begin
+ {2\94Ô\96Ú\82Ì\95¶\8e\9a\82ª'-'\82Å\82Í\82È\82¢\82Æ\82«}
+ if WChar2 = CONST_NULL then
+ {2\94Ô\96Ú\82Ì\95¶\8e\9a\82ª\83k\83\8b\83L\83\83\83\89\83N\83^\82Ì\82Æ\82«}
+ raise ERegExpParser.Create('\89E\83u\83\89\83P\83b\83g"]"\82ª\95K\97v\82Å\82·', FIndex);
+ UnGetWChar(FRegExpStr, FIndex);{WChar2\82ð\96ß\82·}
+ FSymbol.WChar := WChar;
+ end;
+ end;
+ result := FToken;
+end;
+
+function TREScanner.GetToken: REToken_t;
+begin
+ if FInCharClass then begin
+ result := GetTokenCC;
+ if result = retk_RBra then
+ FInCharClass := False;
+ end else begin
+ result := GetTokenStd;
+ if (result = retk_LBra) or (result = retk_LBraNeg) then
+ FInCharClass := True;
+ end;
+end;
+
+constructor TREPreProcessor.Create(Str: String);
+begin
+ inherited Create;
+ FScanner := TREScanner.Create(Str);
+ FTokenList := TList.Create;
+ FListOfSynonymDic := TList.Create;
+ FListOfFuzzyCharDic := TList.Create;
+end;
+
+destructor TREPreProcessor.Destroy;
+begin
+ FScanner.Free;
+ DestroyTokenListItems;
+ FTokenList.Free;
+ FListOfSynonymDic.Free;
+ FListOfFuzzyCharDic.Free;
+ inherited Destroy;
+end;
+
+{\90à\96¾ \81F FTokenList: TList \82ð\81A\83A\83C\83e\83\80\83f\81[\83^ (RETokenInfo_t\8c^\83\8c\83R\81[\83h)\82Æ\8b¤\82É\94p\8aü\82·\82é\81B
+\92\8d\88Ó \81F MakeTokenList\82Æ\91Î\82Å\8eg\97p\82·\82é\81B}
+procedure TREPreProcessor.DestroyTokenListItems;
+var
+ i: Integer;
+begin
+ if FTokenList = nil then
+ exit;
+
+ i := 0;
+ while i < FTokenList.Count do begin
+ Dispose(REpTokenInfo_t(FTokenList.Items[i]));
+ FTokenList.Items[i] := nil;
+ Inc(i);
+ end;
+ FTokenList.Clear;
+end;
+
+{\90à\96¾ \81F FTokenList: TList\82É RETokenInfo_t\8c^\82Ì\83\8c\83R\81[\83h\82ð\8d\\92z\82·\82é\81B
+\93®\8dì \81F \8dÅ\8cã\94ö\82ÌRETokenInfo_t\8c^\83\8c\83R\81[\83h\82Í\81A\8fí\82ÉToken = retk_End\82Å\82 \82é\81B
+\92\8d\88Ó \81F DestroyTokenList\83\81\83\\83b\83h\82Æ\91Î\82Å\8eg\97p\82·\82é\81B}
+procedure TREPreProcessor.MakeTokenList;
+var
+ pTokenInfo: REpTokenInfo_t;
+ prevIndex: Integer;
+begin
+ prevIndex := FScanner.Index;
+ DestroyTokenListItems;
+ while FScanner.GetToken <> retk_End do begin
+ New(pTokenInfo);
+ try
+ FTokenList.Add(pTokenInfo);
+ except
+ on Exception do begin
+ Dispose(pTokenInfo);
+ raise;
+ end;
+ end;
+ with pTokenInfo^ do begin
+ Token := FScanner.Token;
+ Symbol := FScanner.Symbol;
+ FromIndex := prevIndex;
+ ToIndex := FScanner.Index;
+ end;
+ prevIndex := FScanner.Index;
+ end;
+
+ {\8dÅ\8cã\94ö retk_End}
+ New(pTokenInfo);
+ try
+ FTokenList.Add(pTokenInfo);
+ except
+ on Exception do begin
+ Dispose(pTokenInfo);
+ raise;
+ end;
+ end;
+ with pTokenInfo^ do begin
+ Token := retk_End;
+ Symbol.WChar := CONST_NULL;
+ FromIndex := 0;
+ ToIndex := 0;
+ end;
+end;
+
+function TREPreProcessor.GetTargetRegExpStr: String;
+begin
+ result := FScanner.RegExpStr;
+end;
+
+procedure TREPreProcessor.SetTargetRegExpStr(Str: String);
+begin
+ FScanner.RegExpStr := Str;
+end;
+
+{\90à\96¾ \81F \90³\8bK\95\\8c»\95¶\8e\9a\97ñ\82É\93¯\88Ó\8cê\82ð\91g\82Ý\8d\9e\82Þ\81B}
+procedure TREPreProcessor.Run;
+begin
+ FProcessedRegExpStr := FScanner.RegExpStr;
+ if FUseSynonymDic then begin
+ Self.Process(FindSynonym);
+ FScanner.RegExpStr := FProcessedRegExpStr;
+ end;
+
+ if FUseFuzzyCharDic then
+ Self.Process(FindFuzzyWChar);
+end;
+
+{\90à\96¾ \81F \93¯\88Ó\8cê\96\84\82ß\8d\9e\82Ý\8f\88\97\9d Run\83\81\83\\83b\83h\82Ì\89º\90¿\82¯}
+procedure TREPreProcessor.Process(FindFunc: TREPreProcessorFindFunc);
+var
+ j, k: Integer;
+ TkIndex: Integer;
+ Info: RETokenInfo_t;
+ InCC: Boolean;
+begin
+ FProcessedRegExpStr := '';
+ MakeTokenList;
+ InCC := False;
+ TkIndex := 0;
+ {\82·\82×\82Ä\82Ì\83g\81[\83N\83\93\82ð\8c\9f\8d¸\82·\82é}
+ while TkIndex < FTokenList.Count do begin
+ Info := REpTokenInfo_t(FTokenList[TkIndex])^;
+ {\83L\83\83\83\89\83N\83^\83N\83\89\83X ('[]'\82Å\82\82\82ç\82ê\82½\95\94\95ª)\82É\93ü\82é}
+ if Info.Token = retk_LBra then
+ InCC := True;
+
+ {\83L\83\83\83\89\83N\83^\83N\83\89\83X\82©\82ç\8fo\82½}
+ if Info.Token = retk_RBra then
+ InCC := False;
+
+ {\83g\81[\83N\83\93\82ª\83L\83\83\83\89\83N\83^\88È\8aO\82©\81A\83L\83\83\83\89\83N\83^\83N\83\89\83X '[ ]'\82Ì\92\86\82Ì\8fê\8d\87}
+ if (Info.Token <> retk_Char) or InCC then begin
+ FProcessedRegExpStr := FProcessedRegExpStr +
+ Copy(FScanner.RegExpStr, Info.FromIndex, Info.ToIndex-Info.FromIndex);
+ Inc(TkIndex); {\89½\82à\82¹\82¸\82ÉFProcessedRegExpStr\82Ö\92Ç\89Á}
+ {\83g\81[\83N\83\93\82ª\83L\83\83\83\89\83N\83^\82Ì\8fê\8d\87}
+ end else begin
+ j := TkIndex;
+ {j\82ª\83L\83\83\83\89\83N\83^\88È\8aO\82ð\8ew\82·\82Ü\82Å\83C\83\93\83N\83\8a\83\81\83\93\83g}
+ while REpTokenInfo_t(FTokenList[j])^.Token = retk_Char do
+ Inc(j);
+
+ {\83L\83\83\83\89\83N\83^\82Ì\98A\91±\82ð\82P\82Â\82Ã\82Â\8c\9f\8d¸}
+ while TkIndex < j do begin
+ k := FindFunc(TkIndex, j);
+ if k <> -1 then begin
+ {\83}\83b\83`\82µ\82½\95\94\95ª\82ð\92Ç\89Á}
+ FProcessedRegExpStr := FProcessedRegExpStr + FSynonymStr;
+ TkIndex := k; {\8e\9f\82Ì\83g\81[\83N\83\93\82©\82ç\83}\83b\83`\82·\82é\95\94\95ª\82ð\88ø\82«\91±\82«\82³\82ª\82·\81B}
+ end else begin
+ {\83}\83b\83`\82µ\82È\82¯\82ê\82Î\81A\88ê\95¶\8e\9a\95ª\92Ç\89Á\82µ\82Ä\81A\83C\83\93\83f\83b\83N\83X\82ð\90i\82ß\82é}
+ Info := REpTokenInfo_t(FTokenList[TkIndex])^;
+ FProcessedRegExpStr := FProcessedRegExpStr +
+ Copy(FScanner.RegExpStr, Info.FromIndex, Info.ToIndex-Info.FromIndex);;
+ Inc(TkIndex);
+ end;
+ end;
+ TkIndex := j;
+ end;
+ end;
+end;
+
+{\90à\96¾ \81F \93¯\88Ó\8cê\8e«\8f\91 SynonymDic: TList\82ð\8eg\82Á\82Ä\81A\93¯\88Ó\8cê\82ð\92T\82·\81B
+\95Ô\82è\92l\81F \83g\81[\83N\83\93\83\8a\83X\83g\93à\82Ì\93¯\88Ó\8cê\82Ì\8e\9f\82Ì\83C\83\93\83f\83b\83N\83X
+ \8c©\82Â\82©\82ç\82È\82¯\82ê\82Î -1}
+function TREPreProcessor.ReferToOneList(FromTokenIndex, ToTokenIndex: Integer; SynonymDic: TList): Integer;
+var
+ StrList: TStrings;
+ i, j, k, m: Integer;
+
+ {Str\82ÆFTokenList\82ð\94ä\8ar}
+ function Match(Str: String): Integer;
+ var
+ StrIndex, TkIndex: Integer;
+ WChar: WChar_t;
+ begin
+ if Str = '' then begin
+ result := -1;
+ exit;
+ end;
+
+ TkIndex := FromTokenIndex;
+ StrIndex := 1;
+ WChar := GetWChar(Str, StrIndex);
+ while (WChar <> CONST_NULL) and (TkIndex < ToTokenIndex) do begin
+ if WChar <> REpTokenInfo_t(FTokenList[TkIndex])^.Symbol.WChar then begin
+ result := -1;
+ exit;
+ end else begin
+ Inc(TkIndex);
+ WChar := GetWChar(Str, StrIndex);
+ end;
+ end;
+ if WChar = CONST_NULL then
+ result := TkIndex
+ else
+ result := -1;
+ end;
+begin
+ result := -1;
+ i := 0;
+ while i < SynonymDic.Count do begin
+ StrList := TStrings(SynonymDic[i]);
+ j := 0;
+ while j < StrList.Count do begin
+ k := Match(StrList[j]);
+ if k <> -1 then begin
+ {\83}\83b\83`\82µ\82½}
+ FSynonymStr := '(' + QuoteMetaWChar(StrList[0]);
+ m := 1;
+ while m < StrList.Count do begin
+ FSynonymStr := FSynonymStr + '|' + QuoteMetaWChar(StrList[m]);
+ Inc(m);
+ end;
+ FSynonymStr := FSynonymStr + ')';
+ result := k;
+ exit;
+ end;
+ Inc(j);
+ end;
+ Inc(i);
+ end;
+end;
+
+{\90à\96¾ \81F
+\95Ô\82è\92l\81F \83g\81[\83N\83\93\83\8a\83X\83g\93à\82Ì\93¯\88Ó\8cê\82Ì\8e\9f\82Ì\83C\83\93\83f\83b\83N\83X
+ \8c©\82Â\82©\82ç\82È\82¯\82ê\82Î -1
+\92\8d\88Ó \81F Run\83\81\83\\83b\83h\82ª\83\81\83\\83b\83h\83|\83C\83\93\83^\82ðProcess\83\81\83\\83b\83h\82É\93n\82µ\81A
+ Process\83\81\83\\83b\83h\82ª\8cÄ\82Ñ\8fo\82·\81B}
+function TREPreProcessor.FindSynonym(FromTokenIndex, ToTokenIndex: Integer): Integer;
+var
+ i: Integer;
+begin
+ result := -1;
+ i := 0;
+ while i < FListOfSynonymDic.Count do begin
+ result := ReferToOneList(FromTokenIndex, ToTokenIndex, FListOfSynonymDic[i]);
+ if result <> -1 then
+ exit;
+ Inc(i);
+ end;
+end;
+
+{\90à\96¾ \81F
+\95Ô\82è\92l\81F \83g\81[\83N\83\93\83\8a\83X\83g\93à\82Ì\93¯\88Ó\8cê\82Ì\8e\9f\82Ì\83C\83\93\83f\83b\83N\83X
+ \8c©\82Â\82©\82ç\82È\82¯\82ê\82Î -1
+\92\8d\88Ó \81F Run\83\81\83\\83b\83h\82ª\83\81\83\\83b\83h\83|\83C\83\93\83^\82ðProcess\83\81\83\\83b\83h\82É\93n\82µ\81A
+ Process\83\81\83\\83b\83h\82ª\8cÄ\82Ñ\8fo\82·\81B}
+function TREPreProcessor.FindFuzzyWChar(FromTokenIndex, ToTokenIndex: Integer): Integer;
+var
+ i: Integer;
+begin
+ result := -1;
+ i := 0;
+ while i < FListOfFuzzyCharDic.Count do begin
+ result := ReferToOneList(FromTokenIndex, ToTokenIndex, FListOfFuzzyCharDic[i]);
+ if result <> -1 then
+ exit;
+ Inc(i);
+ end;
+end;
+
+constructor TREParseTree.Create;
+begin
+ inherited Create;
+ FNodeList := TList.Create;
+ FLeafList := TList.Create;
+end;
+
+destructor TREParseTree.Destroy;
+begin
+ DisposeTree;
+ FNodeList.Free;
+ FLeafList.Free;
+ inherited Destroy;
+end;
+
+{\8d\\95¶\96Ø\82Ì\83m\81[\83h\82ð\8dì\90¬\82·\82é\81B
+ op \82Í\83m\81[\83h\82ª\95\\82·\89\89\8eZ\81Aleft\82Í\8d¶\82Ì\8eq\81Aright\82Í\89E\82Ì\8eq }
+function TREParseTree.MakeInternalNode(TheOp: REOperation_t; pLeft,
+ pRight: REpNode_t): REpNode_t;
+begin
+ New(result);
+ with result^ do begin
+ op := TheOp;
+ Children.pLeft := pLeft;
+ Children.pRight := pRight;
+ end;
+ try
+ FNodeList.Add(result);
+ except
+ {TList\82Å\83\81\83\82\83\8a\95s\91«\82Ì\8e\9e\82Í,\90V\82µ\82¢\8d\\95¶\96Ø\82Ì\90ß\82à\8aJ\95ú\82µ\82Ä\82µ\82Ü\82¤}
+ on EOutOfMemory do begin
+ Dispose(result);
+ raise;
+ end;
+ end;
+end;
+
+{\8d\\95¶\96Ø\82Ì\97t\82ð\8dì\82é
+ TheC \82Í\82±\82Ì\97t\82ª\95\\82·\95¶\8e\9a}
+function TREParseTree.MakeLeaf(aStartChar, aEndChar: WChar_t): REpNode_t; {char}
+var
+ i: Integer;
+begin
+ {\8aù\82É\93¯\82¶\83L\83\83\83\89\83N\83^\83N\83\89\83X\82ð\8e\9d\82Â\97t\82ª\91¶\8dÝ\82·\82ê\82Î\81A\82»\82ê\82ð\95Ô\82·\81B}
+ for i := 0 to FLeafList.Count-1 do begin
+ if (REpNode_t(FLeafList[i])^.CharClass.StartChar = aStartChar) and
+ (REpNode_t(FLeafList[i])^.CharClass.EndChar = aEndChar) then begin
+ result := FLeafList[i];
+ exit;
+ end;
+ end;
+
+ New(result);
+ with result^ do begin
+ op := reop_char;
+ CharClass.StartChar := aStartChar;
+ CharClass.EndChar := aEndChar;
+ end;
+ try
+ FLeafList.Add(result);
+ except
+ {TList\82Å\83\81\83\82\83\8a\95s\91«\82Ì\8e\9e\82Í,\90V\82µ\82¢\8d\\95¶\96Ø\82Ì\90ß\82à\8aJ\95ú\82µ\82Ä\82µ\82Ü\82¤}
+ on EOutOfMemory do begin
+ Dispose(result);
+ raise;
+ end;
+ end;
+end;
+
+{\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\90ß\81B \81¦\8eq\82ð\8e\9d\82½\82È\82¢\82ª\81AMakeInternalNode\82ð\8eg\82¤}
+function TREParseTree.MakeLHeadNode(WChar: WChar_t): REpNode_t;
+begin
+ result := MakeInternalNode(reop_LHead, nil, nil);
+ with result^ do begin
+ CharClass.StartChar := WChar;
+ CharClass.EndChar := WChar;
+ end;
+end;
+
+{\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82ð\95\\82·\90ß\81B \81¦\8eq\82ð\8e\9d\82½\82È\82¢\82ª\81AMakeInternalNode\82ð\8eg\82¤}
+function TREParseTree.MakeLTailNode(WChar: WChar_t): REpNode_t;
+begin
+ result := MakeInternalNode(reop_LTail, nil, nil);
+ with result^ do begin
+ CharClass.StartChar := WChar;
+ CharClass.EndChar := WChar;
+ end;
+end;
+
+{\94C\88Ó\82Ì\88ê\95¶\8e\9a\82ð\95\\82·'.'\83\81\83^\83L\83\83\83\89\83N\83^\82É\91Î\89\9e\82·\82é\95\94\95ª\96Ø\82ð\8dì\82é\81B
+ \81¦CR LF\82ð\8f\9c\82\91S\82Ä\82Ì\83L\83\83\83\89\83N\83^\82ð\95\\82·\97t\82ðreop_Union\91\80\8dì\82ð\95\\82·\92\86\8aÔ\90ß\82Å\8c\8b\82ñ\82¾\82à\82Ì}
+function TREParseTree.MakeAnyCharsNode: REpNode_t;
+begin
+ result := MakeInternalNode(reop_Union, MakeLeaf($1, $09), MakeLeaf($0B, $0C));
+ result := MakeInternalNode(reop_Union, result, MakeLeaf($0E, $FCFC));
+end;
+
+{\88ø\90\94\82ª aStartChar <= aEndChar \82Ì\8aÖ\8cW\82ð\96\9e\82½\82µ\82Ä\82¢\82é\82Æ\82«\82É\81AMakeLeaf\82ð\8cÄ\82Ô
+ \82»\82ê\88È\8aO\82Í\81Anil \82ð\95Ô\82·\81B}
+function TREParseTree.Check_and_MakeLeaf(aStartChar, aEndChar: WChar_t):REpNode_t;
+begin
+ if aStartChar <= aEndChar then begin
+ result := MakeLeaf(aStartChar, aEndChar);
+ end else
+ result := nil;
+end;
+
+{\97t\82ð\93à\95\94\90ß\82É\95Ï\82¦\82é\81B}
+procedure TREParseTree.ChangeLeaftoNode(pLeaf, pLeft, pRight: REpNode_t);
+begin
+ if (pLeft = nil) or (pRight = nil) then
+ raise Exception.Create('TREParseTree : \92v\96½\93I\83G\83\89\81[');{ debug }
+ with pLeaf^ do begin
+ op := reop_Union;
+ Children.pLeft := pLeft;
+ Children.pRight := pRight;
+ end;
+ FLeafList.Remove(pLeaf);
+ try
+ FNodeList.Add(pLeaf);
+ except
+ on EOutOfMemory do begin
+ FreeMem(pLeaf, SizeOf(RENode_t));
+ raise;
+ end;
+ end;
+end;
+
+{\8b@\94\\81F \8cÂ\81X\82Ì\97t\82ª\8e\9d\82Â\83L\83\83\83\89\83N\83^\94Í\88Í\82ª\82P\82Â\82à\8fd\95¡\82µ\82È\82¢\82æ\82¤\82É\82·\82é\81B
+ \89ð\90à\81F \97t\82Í\81ACharClass\83t\83B\81[\83\8b\83h\82ð\8e\9d\82¿\81ACharClass\83t\83B\81[\83\8b\83h\82ÍStartChar\82ÆEndChar
+ \82ð\83t\83B\81[\83\8b\83h\82É\8e\9d\82Â\83\8c\83R\81[\83h\82Å\82 \82é\81B
+ \8cÂ\81X\82Ì\97t\82ª\8e\9d\82Â\83L\83\83\83\89\83N\83^\82Ì\94Í\88Í\82ª\8fd\95¡\82µ\82È\82¢\82©\92²\82×\82Ä\81A\8fd\95¡\82·\82é\8fê\8d\87\82É\82Í\81A
+ \82»\82Ì\97t\82ð\95ª\8a\84\82µ\81Areop_Union\82ð\8e\9d\82Â\93à\95\94\90ß\82Å\93\99\89¿\82È\95\94\95ª\96Ø\82É\92¼\82·\81B}
+procedure TREParseTree.ForceCharClassUnique;
+var
+ i, j: Integer;
+ Changed: Boolean;
+
+ {\8b@\94\\81F \8fd\95¡\82·\82é\83L\83\83\83\89\83N\83^\94Í\88Í\82ð\82à\82Â\97t\82Ì\95ª\8a\84
+ \89ð\90à\81F \82Q\82Â\82Ì\97tpCCLeaf1\82ÆpCCLeaf2\82Ì\83L\83\83\83\89\83N\83^\94Í\88Í\82ð\92²\82×\82Ä\81A\8fd\95¡\82·\82é\82Æ\82«\82Í
+ \95ª\8a\84\82·\82é\82µ\82Ä\93\99\89¿\82È\95\94\95ª\96Ø\82É\95Ï\8a·\82·\82é\81B}
+ function SplitCharClass(pCCLeaf1, pCCLeaf2: REpNode_t): Boolean;
+ var
+ pNode1, pNode2, pNode3: REpNode_t;
+ S1, S2, SmallE, BigE: WChar_t;
+ begin
+ result := False;
+ {\91O\8f\88\97\9d\81F pCCLeaf1 \82ÌStartChar <= pCCLeaf2 \82ÌStartChar \82ð\95Û\8fØ\82·\82é}
+ if pCCLeaf1^.CharClass.StartChar > pCCLeaf2^.CharClass.StartChar then begin
+ pNode1 := pCCLeaf1;
+ pCCLeaf1 := pCCLeaf2;
+ pCCLeaf2 := pNode1;
+ end;
+
+ {\83L\83\83\83\89\83N\83^\83N\83\89\83X\82Ì\94Í\88Í\82ª\8fd\95¡\82µ\82È\82¢ \96\94\82Í \93¯\88ê\82È\82ç\82Î Exit
+ \81¦ MakeLeaf\83\81\83\\83b\83h\82Ì\8d\\91¢\82©\82ç\82¢\82Á\82Ä\8dÅ\8f\89\82Í\8fd\95¡\82·\82é\8e\96\82Í\82È\82¢\82ª\81A\95ª\8a\84\82ð\8cJ\82è\95Ô\82·
+ \82Æ\8fd\95¡\82·\82é\89Â\94\\90«\82ª\82 \82é\81B}
+ if (pCCLeaf1^.CharClass.EndChar < pCCLeaf2^.CharClass.StartChar) or
+ (pCCLeaf1^.CharClass.Chars = pCCLeaf2^.CharClass.Chars) then
+ exit;
+
+ {(pCCLeaf1 \82ÌStartChar) S1 <= S2 (pCCLeaf2 \82ÌStartChar)}
+ S1 := pCCLeaf1^.CharClass.StartChar;
+ S2 := pCCLeaf2^.CharClass.StartChar;
+
+ {SmallE \82Í\81ApCCLeaf1, pCCLeaf2 \82Ì EndChar \82Ì\8f¬\82³\82¢\95û
+ SmallE <= E2}
+ if pCCLeaf1^.CharClass.EndChar > pCCLeaf2^.CharClass.EndChar then begin
+ SmallE := pCCLeaf2^.CharClass.EndChar;
+ BigE := pCCLeaf1^.CharClass.EndChar;
+ end else begin
+ SmallE := pCCLeaf1^.CharClass.EndChar;
+ BigE := pCCLeaf2^.CharClass.EndChar;
+ end;
+
+ pNode1 := Check_and_MakeLeaf(S1, S2-1);
+ pNode2 := Check_and_MakeLeaf(S2, SmallE);
+ pNode3 := Check_and_MakeLeaf(SmallE+1, BigE);
+ {if (pNode1 = nil) and (pNode2 = nil) and (pNode3 = nil) then
+ raise ERegExpParser.Create('\92v\96½\93I\82È\83G\83\89\81[', 0); }
+ if pNode1 = nil then begin {S1 = S2 \82Ì\82Æ\82«}
+ if pCCLeaf1^.CharClass.EndChar = BigE then
+ ChangeLeaftoNode(pCCLeaf1, pNode2, pNode3)
+ else
+ ChangeLeaftoNode(pCCLeaf2, pNode2, pNode3);
+ end else if pNode3 = nil then begin {SmallE = BigE \82Ì\8e\9e}
+ ChangeLeaftoNode(pCCLeaf1, pNode1, pNode2);
+ end else begin
+ if pCCLeaf1^.CharClass.EndChar = BigE then begin{pCCLeaf1\82ÉpCCLeaf2\82ª\8aÜ\82Ü\82ê\82é}
+ ChangeLeaftoNode(pCCLeaf1, MakeInternalNode(reop_Union, pNode1, pNode2),
+ pNode3)
+ end else begin {pCCLeaf1 \82Æ pCCLeaf2 \82Ì\82P\95\94\95ª\82ª\8fd\82È\82Á\82Ä\82¢\82é}
+ ChangeLeaftoNode(pCCLeaf1, pNode1, pNode2);
+ ChangeLeaftoNode(pCCLeaf2, pNode2, pNode3);
+ end;
+ end;
+ result := True;
+ end;
+begin {procedure TREParser.ForceCharClassUnique}
+ i := 0;
+ while i < LeafList.Count do begin
+ j := i + 1;
+ Changed := False;
+ while j < LeafList.Count do begin
+ Changed := SplitCharClass(LeafList[j], LeafList[i]);
+ if not Changed then
+ Inc(j)
+ else
+ break;
+ end;
+ if not Changed then
+ Inc(i);
+ end;
+end; {procedure TREParser.ForceCharClassUnique}
+
+procedure TREParseTree.DisposeTree;
+var
+ i: Integer;
+begin
+ if FNodeList <> nil then begin
+ for i := 0 to FNodeList.Count - 1 do begin
+ if FNodeList[i] <> nil then
+ Dispose(REpNode_t(FNodeList.Items[i]));
+ end;
+ FNodeList.Clear;
+ end;
+
+ if FLeafList <> nil then begin
+ for i := 0 to FLeafList.Count -1 do begin
+ if FLeafList[i] <> nil then
+ Dispose(REpNode_t(FLeafList[i]));
+ end;
+ FLeafList.Clear;
+ end;
+ FpHeadNode := nil;
+end;
+
+{-=========================== TREParser Class ===============================-}
+constructor TREParser.Create(RegExpStr: String);
+begin
+ inherited Create;
+ FScanner := TREScanner.Create(RegExpStr);
+ FParseTree := TREParseTree.Create;
+ {\8f\80\94õ\8a®\97¹\81B Run\83\81\83\\83b\83h\82ð\8cÄ\82×\82Î\8d\\95¶\89ð\90Í\82ð\82·\82é\81B}
+end;
+
+destructor TREParser.Destroy;
+begin
+ FScanner.Free;
+ FParseTree.Free;
+ inherited Destroy;
+end;
+
+{**************************************************************************
+ \90³\8bK\95\\8c»\82ð\83p\81[\83X\82·\82é\83\81\83\\83b\83h\8cQ
+ **************************************************************************}
+procedure TREParser.Run;
+begin
+ FParseTree.DisposeTree; {\82·\82Å\82É\82 \82é\8d\\95¶\96Ø\82ð\94p\8aü\82µ\82Ä\8f\89\8aú\89»}
+
+ FScanner.GetToken; {\8dÅ\8f\89\82Ì\83g\81[\83N\83\93\82ð\93Ç\82Ý\8d\9e\82Þ}
+
+ {\90³\8bK\95\\8c»\82ð\83p\81[\83X\82·\82é}
+ FParseTree.pHeadNode := regexp;
+
+ {\8e\9f\82Ì\83g\81[\83N\83\93\82ªretk_End \82Å\82È\82¯\82ê\82Î\83G\83\89\81[}
+ if FScanner.Token <> retk_End then begin
+ raise ERegExpParser.Create('\90³\8bK\95\\8c»\82É\97]\95ª\82È\95¶\8e\9a\82ª\82 \82è\82Ü\82·',
+ FScanner.Index);
+ end;
+
+ FParseTree.ForceCharClassUnique;{\83L\83\83\83\89\83N\83^\83N\83\89\83X\82ð\95ª\8a\84\82µ\82Ä\83\86\83j\81[\83N\82É\82·\82é}
+end;
+
+{ <regexp>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \91I\91ð X|Y \82ð\89ð\90Í\82·\82é }
+function TREParser.regexp: REpNode_t;
+begin
+ result := term;
+ while FScanner.Token = retk_Union do begin
+ FScanner.GetToken;
+ result := FParseTree.MakeInternalNode(reop_union, result, term);
+ end;
+end;
+
+{ <term>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·
+ \98A\8c\8b\82w\82x\82ð\89ð\90Í\82·\82é}
+function TREParser.Term: REpNode_t;
+begin
+ if (FScanner.Token = retk_Union) or
+ (FScanner.Token = retk_RPar) or
+ (FScanner.Token = retk_End) then
+ result := FParseTree.MakeInternalNode(reop_Empty, nil, nil)
+ else begin
+ result := factor;
+ while (FScanner.Token <> retk_Union) and
+ (FScanner.Token <> retk_RPar) and
+ (FScanner.Token <> retk_End) do begin
+ result := FParseTree.MakeInternalNode(reop_concat, result, factor);
+ end;
+ end;
+end;
+
+{ <factor>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·
+ \8cJ\82è\95Ô\82µX*, X+, X?\82ð\89ð\90Í\82·\82é}
+function TREParser.Factor: REpNode_t;
+begin
+ result := primary;
+ if FScanner.Token = retk_Star then begin
+ result := FParseTree.MakeInternalNode(reop_closure, result, nil);
+ FScanner.GetToken;
+ end else if FScanner.Token = retk_Plus then begin
+ result := FParseTree.MakeInternalNode(reop_concat, result,
+ FParseTree.MakeInternalNode(reop_closure, result, nil));
+ FScanner.GetToken;
+ end else if FScanner.Token = retk_QMark then begin
+ result := FParseTree.MakeInternalNode(reop_Union, result,
+ FParseTree.MakeInternalNode(reop_Empty, nil, nil));
+ FScanner.GetToken;
+ end;
+end;
+
+{ <primary>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ \95¶\8e\9a\82»\82Ì\82à\82Ì\81A(X)\82ð\89ð\90Í\82·\82é}
+function TREParser.Primary: REpNode_t;
+begin
+ case FScanner.Token of
+ retk_Char: begin
+ result := FParseTree.MakeLeaf(FScanner.Symbol.WChar, FScanner.Symbol.WChar);
+ FScanner.GetToken;
+ end;
+ retk_LHead: begin
+ result := FParseTree.MakeLHeadNode(FScanner.Symbol.WChar);
+ FScanner.GetToken;
+ end;
+ retk_LTail: begin
+ result := FParseTree.MakeLTailNode(FScanner.Symbol.WChar);
+ FScanner.GetToken;
+ end;
+ retk_Dot: begin
+ result := FParseTree.MakeAnyCharsNode;
+ FScanner.GetToken;
+ end;
+ retk_LPar: begin
+ FScanner.GetToken;
+ result := regexp;
+ if FScanner.Token <> retk_RPar then
+ raise ERegExpParser.Create('\89E(\95Â\82¶)\8a\87\8cÊ\82ª\95K\97v\82Å\82·', FScanner.Index);
+ FScanner.GetToken;
+ end;
+ retk_LBra, retk_LBraNeg: begin
+ if FScanner.Token = retk_LBra then
+ result := CharacterClass(FParseTree)
+ else
+ result := NegativeCharacterClass;
+ if FScanner.Token <> retk_RBra then
+ raise ERegExpParser.Create('\89E\83u\83\89\83P\83b\83g"]"\82ª\95K\97v\82Å\82·', FScanner.Index);
+ FScanner.GetToken;
+ end;
+ else
+ raise ERegExpParser.Create('\95\81\92Ê\82Ì\95¶\8e\9a\81A\82Ü\82½\82Í\8d¶\8a\87\8cÊ"("\82ª\95K\97v\82Å\82·', FScanner.Index);
+ end;
+end;
+
+{ <charclass> \82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ [] \82Å\8a\87\82ç\82ê\82½\90³\8bK\95\\8c»\82ð\89ð\90Í\82·\82é}
+function TREParser.CharacterClass(aParseTree: TREParseTree): REpNode_t;
+ {Token\82É\91Î\89\9e\82µ\82½\97t\82ð\8dì\82é}
+ function WCharToLeaf: REpNode_t;
+ begin
+ result := nil;
+ case FScanner.Token of
+ retk_Char:
+ result := aParseTree.MakeLeaf(FScanner.Symbol.WChar, FScanner.Symbol.WChar);
+
+ retk_CharClass:
+ result := aParseTree.MakeLeaf(FScanner.Symbol.CharClass.StartChar,
+ FScanner.Symbol.CharClass.EndChar);
+ end;
+ end;
+begin {function TREParser.CharacterClass}
+ FScanner.GetToken; {GetScannerCC\82Í\81Aretk_RBra, retk_Char, retk_CharClass\82µ\82©\95Ô\82³\82È\82¢}
+ if FScanner.Token = retk_RBra then
+ raise ERegExpParser.Create('\95s\90³\82È\83L\83\83\83\89\83N\83^\83N\83\89\83X\8ew\92è\82Å\82·\81B', FScanner.Index);
+
+ result := WCharToLeaf;
+ FScanner.GetToken;
+ while FScanner.Token <> retk_RBra do begin
+ result := aParseTree.MakeInternalNode(reop_Union, result, WCharToLeaf);
+ FScanner.GetToken;
+ end;
+
+end;{function TREParser.CharacterClass}
+
+
+{ <negative charclass>\82ð\83p\81[\83X\82µ\82Ä\81A\93¾\82ç\82ê\82½\8d\\95¶\96Ø\82ð\95Ô\82·\81B
+ [^ ] \82Å\8a\87\82ç\82ê\82½\90³\8bK\95\\8c»\82ð\89ð\90Í\82·\82é}
+function TREParser.NegativeCharacterClass: REpNode_t;
+var
+ aParseTree, aNeg_ParseTree: TREParseTree;
+ i: Integer;
+ aCharClass: RECharClass_t;
+ procedure RemoveCC(pLeaf: REpNode_t);
+ var
+ i: Integer;
+ pANode, pNode1, pNode2: REpNode_t;
+ begin
+ i := 0;
+ while i < aNeg_ParseTree.LeafList.Count do begin
+ pANode := aNeg_ParseTree.LeafList[i];
+ if (pLeaf^.CharClass.EndChar < pANode^.CharClass.StartChar) or
+ (pLeaf^.CharClass.StartChar > pANode^.CharClass.EndChar) then
+ Inc(i)
+ else begin
+ pNode1 := aNeg_ParseTree.Check_and_MakeLeaf(pANode^.CharClass.StartChar,
+ pLeaf^.CharClass.StartChar-1);
+ pNode2 := aNeg_ParseTree.Check_and_MakeLeaf(pLeaf^.CharClass.EndChar+1,
+ pANode^.CharClass.EndChar);
+ if (pNode1 <> nil) or (pNode2 <> nil) then begin
+ Dispose(REpNode_t(aNeg_ParseTree.LeafList[i]));
+ aNeg_ParseTree.LeafList.Delete(i);
+//======== 2015/01/07 mod zako ========
+ end else begin
+ Inc(i);
+//======== 2015/01/07 mod zako ========
+ end;
+ end;
+ end;
+ end;
+begin
+{ [^abc] = . - [abc] \82Æ\82¢\82¤\93®\8dì\82ð\82·\82é\81B}
+
+ aParseTree := TREParseTree.Create;
+ try
+ aNeg_ParseTree := TREParseTree.Create;
+ try
+ {aParseTree\82É'[]'\82Å\88Í\82Ü\82ê\82½\83L\83\83\83\89\83N\83^\83N\83\89\83X\90³\8bK\95\\8c»\82Ì\92\86\82É\91Î\89\9e\82·\82é\90ß\82ð\8dì\82é\81B}
+ aParseTree.pHeadNode := CharacterClass(aParseTree);
+ {aParseTree\82Ì\97t\82ª\8e\9d\82Â\83L\83\83\83\89\83N\83^\83N\83\89\83X\82Ì\94Í\88Í\82ª\8fd\95¡\82µ\82È\82¢\82æ\82¤\82É\90®\8c`}
+ aParseTree.ForceCharClassUnique;
+
+ {\94C\88Ó\82Ì\88ê\95¶\8e\9a\82ð\95\\82·\96Ø\82ðaNeg_ParseTree\82É\8dì\90¬}
+ aNeg_ParseTree.MakeAnyCharsNode;
+
+ for i := 0 to aParseTree.LeafList.Count-1 do begin
+ {aNeg_ParseTree\82Ì\97t\82©\82çaParseTree\82Ì\97t\82Æ\93¯\82¶\95¨\82ð\8dí\8f\9c}
+ RemoveCC(aParseTree.LeafList[i]);
+ end;
+
+ {aNeg_ParseTree\82Ì\97t\82ðFParseTree\82É\83R\83s\81[}
+ result := nil;
+ if aNeg_ParseTree.LeafList.Count > 0 then begin
+ aCharClass := REpNode_t(aNeg_ParseTree.LeafList[0])^.CharClass;
+ result := FParseTree.MakeLeaf(aCharClass.StartChar, aCharClass.EndChar);
+ for i := 1 to aNeg_ParseTree.LeafList.Count-1 do begin
+ aCharClass := REpNode_t(aNeg_ParseTree.LeafList[i])^.CharClass;
+ result := FParseTree.MakeInternalNode(reop_Union, result,
+ FParseTree.MakeLeaf(aCharClass.StartChar, aCharClass.EndChar));
+ end;
+ end;
+ finally
+ aNeg_ParseTree.Free;
+ end;
+ finally
+ aParseTree.Free;
+ end;
+end;
+
+{$IFDEF DEBUG}
+function DebugWCharToStr(WChar: WChar_t): String;
+begin
+ if WChar > $FF then
+ result := ' ' + Chr(Hi(WChar))+Chr(Lo(WChar))+'($' + IntToHex(WChar, 4) + ')'
+ else
+ result := ' ' + Chr(Lo(WChar))+' ($00' + IntToHex(WChar, 2) + ')';
+
+end;
+
+{ \83f\83o\83b\83O\97p\83\81\83b\83\\83b\83h\81B\8d\\95¶\96Ø\82ðVCL \82ÌTOutLine\83R\83\93\83|\81[\83l\83\93\83g\82É\8f\91\82«\8d\9e\82Þ}
+{ \8d\\95¶\96Ø\82ª\91å\82«\82·\82¬\82é\82Æ\81ATOutLine\83R\83\93\83|\81[\83l\83\93\83g\82ª\81h\8e\80\82Ê\81h\82Ì\82Å\92\8d\88Ó}
+procedure TREParser.WriteParseTreeToOutLine(anOutLine: TOutLine);
+ procedure SetOutLineRecursive(pTree: REpNode_t; ParentIndex: Integer);
+ var
+ aStr: String;
+ NextParentIndex: Integer;
+ begin
+ if pTree = nil then
+ exit;
+
+ case pTree^.op of
+ reop_Char: begin{ \95¶\8e\9a\82»\82Ì\82à\82Ì }
+ if pTree^.CharClass.StartChar <> pTree^.CharClass.EndChar then
+ aStr := DebugWCharToStr(pTree^.CharClass.StartChar)
+ + ' \81` '+ DebugWCharToStr(pTree^.CharClass.EndChar)
+ else
+ aStr := DebugWCharToStr(pTree^.CharClass.StartChar);
+ end;
+ reop_LHead:
+ aStr := '\95¶\93ª '+DebugWCharToStr(pTree^.CharClass.StartChar);
+ reop_LTail:
+ aStr := '\95¶\94ö '+DebugWCharToStr(pTree^.CharClass.StartChar);
+ reop_Concat:{ XY }
+ aStr := '\98A\8c\8b ';
+ reop_Union:{ X|Y}
+ aStr := '\91I\91ð "|"';
+ reop_Closure:{ X* }
+ aStr := '\95Â\95ï "*"';
+ reop_Empty:{ \8bó }
+ aStr := '\8bó';
+ end;
+
+ NextParentIndex := anOutLine.AddChild(ParentIndex, aStr);
+
+ if pTree^.op in [reop_Concat, reop_Union, reop_Closure] then begin
+ SetOutLineRecursive(pTree^.Children.pLeft, NextParentIndex);
+ SetOutLineRecursive(pTree^.Children.pRight, NextParentIndex);
+ end;
+ end;
+begin
+ anOutLine.Clear;
+ SetOutLineRecursive(FParseTree.pHeadNode, 0);
+end;
+
+{$ENDIF}
+
+{ -============================== TRE_NFA Class ==================================-}
+constructor TRE_NFA.Create(Parser: TREParser; LHeadWChar, LTailWChar: WChar_t);
+begin
+ inherited Create;
+ FStateList := TList.Create;
+ FParser := Parser;
+ FLHeadWChar := LHeadWChar;
+ FLTailWChar := LTailWChar;
+end;
+
+destructor TRE_NFA.Destroy;
+begin
+ DisposeStateList;
+ inherited Destroy;
+end;
+
+{ NFA\8fó\91Ô\95\\82ð\94j\8aü\82·\82é}
+procedure TRE_NFA.DisposeStateList;
+var
+ i: Integer;
+ pNFANode, pNext: RE_pNFANode_t;
+begin
+ if FStateList <> nil then begin
+ for i := 0 to FStateList.Count-1 do begin
+ pNFANode := FStateList.Items[i];
+ while pNFANode <> nil do begin
+ pNext := pNFANode^.Next;
+ Dispose(pNFANode);
+ pNFANode := pNext;
+ end;
+ end;
+ FStateList.Free;
+ FStateList := nil;
+ end;
+end;
+
+{ \8d\\95¶\96Ø Tree\82É\91Î\89\9e\82·\82éNFA\82ð\90¶\90¬\82·\82é}
+procedure TRE_NFA.Run;
+begin
+ { NFA \82Ì\8f\89\8aú\8fó\91Ô\82Ì\83m\81[\83h\82ð\8a\84\82è\93\96\82Ä\82é\81B}
+ FEntryState := NumberNode;
+
+ { NFA \82Ì\8fI\97¹\8fó\91Ô\82Ì\83m\81[\83h\82ð\8a\84\82è\93\96\82Ä\82é }
+ FExitState := NumberNode;
+
+ { NFA \82ð\90¶\90¬\82·\82é }
+ GenerateStateList(FParser.ParseTree.pHeadNode, FEntryState, FExitState);
+end;
+
+{ \83m\81[\83h\82É\94Ô\8d\86\82ð\8a\84\82è\93\96\82Ä\82é}
+function TRE_NFA.NumberNode: Integer;
+begin
+ with FStateList do begin
+ result := Add(nil);
+ end;
+end;
+
+{ NFA\8fó\91Ô\90ß \82ð\82P\82Â\8dì\90¬}
+function TRE_NFA.MakeNFANode: RE_pNFANode_t;
+begin
+ New(result);
+end;
+
+{ FStateList\82É\8fó\91Ô\91J\88Ú\82ð\92Ç\89Á\82·\82é\81B
+ \8fó\91Ô TransFrom \82É\91Î\82µ\82Ä aCharClass\93à\82Ì\95¶\8e\9a\82Å\8fó\91Ô TransTo \82Ö\82Ì\91J\88Ú\82ð\92Ç\89Á\82·\82é\81B}
+procedure TRE_NFA.AddTransition(TransFrom, TransTo: Integer;
+ aCharClass: RECharClass_t); {Char}
+var
+ pNFANode: RE_pNFANode_t;
+begin
+ pNFANode := MakeNFANode;
+
+ with pNFANode^ do begin
+ CharClass := aCharClass;
+ TransitTo := TransTo;
+ Next := RE_pNFANode_t(FStateList.Items[TransFrom]);
+ end;
+ FStateList.Items[TransFrom] := pNFANode;
+end;
+
+{ \8d\\95¶\96Ø pTree \82É\91Î\82·\82é StateList\82ð\90¶\90¬\82·\82é
+ NFA\82Ì\93ü\82è\8cû\82ðentry, \8fo\8cû\82ðway_out\82Æ\82·\82é }
+procedure TRE_NFA.GenerateStateList(pTree: REpNode_t; entry, way_out: Integer);
+var
+ aState1, aState2: Integer;
+ aCharClass: RECharClass_t;
+begin
+ case pTree^.op of
+ reop_Char:
+ AddTransition(entry, way_out, pTree^.CharClass);
+ reop_LHead: begin {'^'}
+ {\95¶\93ª\83\81\83^\83L\83\83\83\89\83N\83^'^' \82Í TransFrom = FEntryState\82Ì\82Æ\82«\88È\8aO\82Í\81A
+ \92Ê\8fí\82Ì\83L\83\83\83\89\83N\83^\82Æ\82µ\82Ä\88µ\82¤\81B}
+ if Entry <> FEntryState then begin
+ AddTransition(entry, way_out, pTree^.CharClass);
+ end else begin
+ FRegExpHasLHead := True;
+ with aCharClass do begin
+ StartChar := FLHeadWChar;
+ EndChar := FLHeadWChar;
+ end;
+ AddTransition(entry, way_out, aCharClass);
+ end;
+ end;
+ reop_LTail: begin
+ {\8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^ '$'\82Í\81ATransTo = FExitState\82Ì\82Æ\82«\88È\8aO\82Í\81A
+ \92Ê\8fí\82Ì\83L\83\83\83\89\83N\83^\82Æ\82µ\82Ä\88µ\82¤\81B}
+ if way_out <> FExitState then begin
+ AddTransition(entry, way_out, pTree^.CharClass);
+ end else begin
+ FRegExpHasLTail := True;
+ with aCharClass do begin
+ StartChar := FLTailWChar;
+ EndChar := FLTailWChar;
+ end;
+ AddTransition(entry, way_out, aCharClass);
+ end;
+ end;
+ reop_Union: begin {'|'}
+ GenerateStateList(pTree^.Children.pLeft, entry, way_out);
+ GenerateStateList(pTree^.Children.pRight, entry, way_out);
+ end;
+ reop_Closure: begin {'*'}
+ aState1 := NumberNode;
+ aState2 := NumberNode;
+ { \8fó\91Ô entry \81¨ \83Ã\91J\88Ú \81¨ \8fó\91Ô aState1}
+ AddTransition(entry, aState1, CONST_EMPTYCharClass);
+ { \8fó\91Ô aState1 \81¨ (pTree^.Children.pLeft)\88È\89º\82Ì\91J\88Ú \81¨ \8fó\91Ô aState2}
+ GenerateStateList(pTree^.Children.pLeft, aState1, aState2);
+ { \8fó\91Ô aState2 \81¨ \83Ã\91J\88Ú \81¨ \8fó\91Ô aState1}
+ AddTransition(aState2, aState1, CONST_EMPTYCharClass);
+ { \8fó\91Ô aState1 \81¨ \83Ã\91J\88Ú \81¨ \8fó\91Ô way_out}
+ AddTransition(aState1, way_out, CONST_EMPTYCharClass);
+ end;
+ reop_Concat: begin {'AB'}
+ aState1 := NumberNode;
+ { \8fó\91Ô entry \81¨ (pTree^.Children.pLeft)\91J\88Ú \81¨ \8fó\91Ô aState1}
+ GenerateStateList(pTree^.Children.pLeft, entry, aState1);
+ { \8fó\91Ô aState1 \81¨ (pTree^.Children.pRight)\91J\88Ú \81¨ \8fó\91Ô way_out}
+ GenerateStateList(pTree^.Children.pRight, aState1, way_out);
+ end;
+ reop_Empty:
+ AddTransition(entry, way_out, CONST_EMPTYCharClass);
+ else begin
+ raise Exception.Create('This cannot happen in TRE_NFA.GenerateStateList');
+ end;
+ end;
+end;
+
+{$IFDEF DEBUG}
+{TStrings\83I\83u\83W\83F\83N\83g\82É\81ANFA \82Ì\93à\97e\82ð\8f\91\82«\8d\9e\82Þ}
+procedure TRE_NFA.WriteNFAtoStrings(Strings: TStrings);
+var
+ i: Integer;
+ pNFANode: RE_pNFANode_t;
+ Str: String;
+begin
+ Strings.clear;
+ Strings.BeginUpDate;
+ for i := 0 to FStateList.Count-1 do begin
+ pNFANode := FStateList.items[i];
+ if i = EntryState then
+ Str := Format('\8aJ\8en %2d : ', [i])
+ else if i = ExitState then
+ Str := Format('\8fI\97¹ %2d : ', [i])
+ else
+ Str := Format('\8fó\91Ô %2d : ', [i]);
+ while pNFANode <> nil do begin
+ if pNFANode^.CharClass.StartChar = CONST_EMPTY then
+ Str := Str + Format('\83Ã\91J\88Ú\82Å \8fó\91Ô %2d \82Ö :',[pNFANode^.TransitTo])
+ else if pNFANode^.CharClass.StartChar <> pNFANode^.CharClass.EndChar then
+ Str := Str + Format('\95¶\8e\9a%s \82©\82ç%s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pNFANode^.CharClass.StartChar),
+ DebugWCharToStr(pNFANode^.CharClass.EndChar), pNFANode^.TransitTo])
+ else if pNFANode^.CharClass.StartChar = FLHeadWChar then begin
+ Str := Str + Format('\95¶\93ª\83R\81[\83h%s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pNFANode^.CharClass.StartChar), pNFANode^.TransitTo]);
+ end else if pNFANode^.CharClass.StartChar = FLTailWChar then begin
+ Str := Str + Format('\95¶\94ö\83R\81[\83h%s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pNFANode^.CharClass.StartChar), pNFANode^.TransitTo]);
+ end else
+ Str := Str + Format('\95¶\8e\9a%s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pNFANode^.CharClass.StartChar), pNFANode^.TransitTo]);
+
+ pNFANode := pNFANode^.Next;
+ end;
+ Strings.Add(Str);
+ end;
+ Strings.EndUpDate;
+end;
+{$ENDIF}
+
+{ -========================== TRE_NFAStateSet Class =============================-}
+constructor TRE_NFAStateSet.Create(StateMax: Integer);
+var
+ i: Integer;
+begin
+ inherited Create;
+ FCapacity := StateMax div 8 + 1;
+ GetMem(FpArray, FCapacity);
+ for i := 0 to FCapacity-1 do
+ FpArray^[i] := 0;
+end;
+
+destructor TRE_NFAStateSet.Destroy;
+begin
+ FreeMem(FpArray, FCapacity);
+ inherited Destroy;
+end;
+
+function TRE_NFAStateSet.Has(StateIndex: Integer): Boolean;
+begin
+ result := (FpArray^[StateIndex div 8] and (1 shl (StateIndex mod 8))) <> 0;
+end;
+
+procedure TRE_NFAStateSet.Include(StateIndex: Integer);
+begin
+ FpArray^[StateIndex div 8] := FpArray^[StateIndex div 8] or
+ (1 shl (StateIndex mod 8));
+end;
+
+function TRE_NFAStateSet.Equals(AStateSet: TRE_NFAStateSet): Boolean;
+var
+ i: Integer;
+begin
+ result := False;
+ for i := 0 to FCapacity - 1 do begin
+ if FpArray^[i] <> AStateSet.pArray^[i] then
+ exit;
+ end;
+ result := True;
+end;
+
+{ -============================= TRE_DFA Class ==================================-}
+constructor TRE_DFA.Create(NFA: TRE_NFA);
+begin
+ inherited Create;
+ FNFA := NFA;
+ FStateList := TList.Create;
+end;
+
+destructor TRE_DFA.Destroy;
+begin
+ DestroyStateList;
+
+ inherited Destroy;
+end;
+
+{DFA\8fó\91Ô\82Ì\83\8a\83X\83g\82ð\94j\8aü}
+procedure TRE_DFA.DestroyStateList;
+var
+ i: Integer;
+ pDFA_State: RE_pDFAState_t;
+ pDFA_StateSub, pNextSub: RE_pDFAStateSub_t;
+begin
+ if FStateList <> nil then begin
+ for i := 0 to FStateList.Count-1 do begin
+ pDFA_State := FStateList.Items[i];
+ if pDFA_State <> nil then begin
+ pDFA_StateSub := pDFA_State^.next;
+ while pDFA_StateSub <> nil do begin
+ pNextSub := pDFA_StateSub^.next;
+ Dispose(pDFA_StateSub);
+ pDFA_StateSub := pNextSub;
+ end;
+ pDFA_State^.StateSet.Free;
+ Dispose(pDFA_State);
+ end;
+ end;
+ FStateList.Free;
+ FStateList := nil;
+ end;
+end;
+
+procedure TRE_DFA.Run;
+begin
+ FRegExpHasLHead := FNFA.RegExpHasLHead;
+ FRegExpHasLTail := FNFA.RegExpHasLTail;
+ Convert_NFA_to_DFA; {NFA\8fó\91Ô\95\\82©\82çDFA\8fó\91Ô\95\\82ð\8dì\82é}
+ StateListSort; {DFA\8fó\91Ô\95\\82Ì\90ß\82ð\93ü\97Í\83L\81[\8f\87\82É\90®\97ñ\82·\82é\81B\81¦\8c\9f\8dõ\82Ì\8d\82\91¬\89»\82Ì\82½\82ß}
+ CheckIfRegExpIsSimple;{\90³\8bK\95\\8c»\82ª\92P\8f\83\82È\95¶\8e\9a\97ñ\82©\83`\83F\83b\83N}
+end;
+
+{ NFA\82ð\93\99\89¿\82È\82c\82e\82`\82Ö\82Æ\95Ï\8a·\82·\82é}
+procedure TRE_DFA.Convert_NFA_to_DFA;
+var
+ Initial_StateSet: TRE_NFAStateSet;
+ t: RE_pDFAState_t;
+ pDFA_TransNode, pTransNodeHead: RE_pDFATransNode_t;
+ pDFA_StateSub: RE_pDFAStateSub_t;
+begin
+{DFA\82Ì\8f\89\8aú\8fó\91Ô\82ð\93o\98^\82·\82é}
+ Initial_StateSet := TRE_NFAStateSet.Create(FNFA.StateList.Count);
+ Initial_StateSet.Include(FNFA.EntryState);
+ {\82m\82e\82`\8f\89\8aú\8fó\91Ô\82Ì\8fW\8d\87\82ð\8b\81\82ß\82é\81i\83Ã\91J\88Ú\82à\8aÜ\82Þ\81j}
+ Collect_Empty_Transition(Initial_StateSet);
+ FpInitialState := Register_DFA_State(Initial_StateSet);
+
+ {\96¢\8f\88\97\9d\82Ì\82c\82e\82`\8fó\91Ô\82ª\82 \82ê\82Î\81A\82»\82ê\82ð\8eæ\82è\8fo\82µ\82Ä\8f\88\97\9d\82·\82é
+ \92\8d\96Ú\82µ\82Ä\82¢\82é\82c\82e\82`\8fó\91Ô\82ð\82\94\82Æ\82·\82é}
+ t := Fetch_Unvisited_D_state;
+ while t <> nil do begin
+
+ {\8f\88\97\9d\8dÏ\82Ý\82Ì\88ó\82ð\95t\82¯\82é}
+ t^.visited := True;
+
+ {\8fó\91Ô\82\94\82©\82ç\91J\88Ú\89Â\94\\82ÈDFA\8fó\91Ô\82ð\82·\82×\82ÄDFA\82É\93o\98^\82·\82é\81B}
+ pTransNodeHead := Compute_Reachable_N_state(t);
+ try
+ pDFA_TransNode := pTransNodeHead;
+ while pDFA_TransNode <> nil do begin
+ { NFA\8fó\91Ô\8fW\8d\87\82Ì\83Ã-closure\82ð\8b\81\82ß\82é}
+ Collect_Empty_Transition(pDFA_TransNode^.ToNFAStateSet);
+
+ { \91J\88Ú\8fî\95ñ\82ðDFA\8fó\91Ô\82É\89Á\82¦\82é}
+ New(pDFA_StateSub);
+ with pDFA_StateSub^ do begin
+ next := nil;
+ CharClass := pDFA_TransNode^.CharClass;
+ next := t^.next;
+ end;
+ t^.next := pDFA_StateSub;
+
+ {\8c»\8dÝ\82ÌDFA\8fó\91Ô\82©\82ç\82Ì\91J\88Ú\90æ\82Ì\90V\82µ\82¢DFA\8fó\91Ô\82ð\93o\98^}
+ pDFA_StateSub^.TransitTo :=
+ Register_DFA_State(pDFA_TransNode^.ToNFAStateSet);
+ {Register_DFA_State\83\81\83\\83b\83h\82É\82æ\82èToNFAStateSet\83I\83u\83W\83F\83N\83g\82ÍDFA_State\82É\8f\8a\97L\82³\82ê\82é}
+ {pDFA_TransNode^.ToNFAStateSet := nil;}
+
+ pDFA_TransNode := pDFA_TransNode^.next;
+ end;
+ t := Fetch_Unvisited_D_state;
+ finally
+ Destroy_DFA_TransList(pTransNodeHead);
+ end;
+ end;
+end;
+
+{ NFA\8fó\91Ô\8fW\8d\87 StateSet \82É\91Î\82µ\82Ä \83Ã-closure\91\80\8dì\82ð\8eÀ\8ds\82·\82é\81B
+ \83Ã\91J\88Ú\82Å\91J\88Ú\89Â\94\\82È\91S\82Ä\82Ì\82m\82e\82`\8fó\91Ô\82ð\92Ç\89Á\82·\82é}
+procedure TRE_DFA.Collect_Empty_Transition(StateSet: TRE_NFAStateSet);
+var
+ i: Integer;
+ { NFA\8fó\91Ô\8fW\8d\87 StateSet\82É\82m\82e\82`\8fó\91Ô \82\93\82ð\92Ç\89Á\82·\82é\81B
+ \93¯\8e\9e\82É\82m\82e\82`\8fó\91Ô\82\93\82©\82ç\83Ã\91J\88Ú\82Å\88Ú\93®\82Å\82«\82é\82m\82e\82`\8fó\91Ô\82à\92Ç\89Á\82·\82é}
+ procedure Mark_Empty_Transition(StateSet: TRE_NFAStateSet; s: Integer);
+ var
+ pNFANode: RE_pNFANode_t;
+ begin
+ StateSet.Include(s);
+ pNFANode := FNFA.StateList[s];
+ while pNFANode <> nil do begin
+ if (pNFANode^.CharClass.StartChar = CONST_EMPTY) and
+ (not StateSet.Has(pNFANode^.TransitTo)) then
+ Mark_Empty_Transition(StateSet, pNFANode^.TransitTo);
+ pNFANode := pNFANode^.next;
+ end;
+ end;
+begin
+ for i := 0 to FNFA.StateList.Count-1 do begin
+ if StateSet.Has(i) then
+ Mark_Empty_Transition(StateSet, i);
+ end;
+end;
+
+{ NFA\8fó\91Ô\8fW\8d\87 aStateSet \82ð\82c\82e\82`\82É\93o\98^\82µ\82Ä\81A\82c\82e\82`\8fó\91Ô\82Ö\82Ì\83|\83C\83\93\83^\82ð\95Ô\82·\81B
+ aStateSet\82ª\8fI\97¹\8fó\91Ô\82ð\8aÜ\82ñ\82Å\82¢\82ê\82Î\81Aaccepted\83t\83\89\83O\82ð\83Z\83b\83g\82·\82é\81B
+ \82·\82Å\82ÉaStateSet\82ª\82c\82e\82`\82É\93o\98^\82³\82ê\82Ä\82¢\82½\82ç\89½\82à\82µ\82È\82¢}
+function TRE_DFA.Register_DFA_State(var aStateSet: TRE_NFAStateSet): RE_pDFAState_t;
+var
+ i: Integer;
+begin
+ { NFA\8fó\91Ô aStateSet \82ª\82·\82Å\82É\82c\82e\82`\82É\93o\98^\82³\82ê\82Ä\82¢\82½\82ç\81A\89½\82à\82µ\82È\82¢\82Å\83\8a\83^\81[\83\93\82·\82é}
+ for i := 0 to FStateList.Count-1 do begin
+ if RE_pDFAState_t(FStateList[i])^.StateSet.Equals(aStateSet) then begin
+ result := RE_pDFAState_t(FStateList[i]);
+ exit;
+ end;
+ end;
+
+ {DFA\82É\95K\97v\82È\8fî\95ñ\82ð\83Z\83b\83g\82·\82é}
+ New(result);
+ with result^ do begin
+ StateSet := aStateSet;
+ visited := False;
+ if aStateSet.Has(FNFA.ExitState) then
+ accepted := True
+ else
+ accepted := False;
+ next := nil;
+ end;
+ aStateSet := nil;
+ FStateList.add(result);
+end;
+
+{ \8f\88\97\9d\8dÏ\82Ý\82Ì\88ó\82ª\82Â\82¢\82Ä\82¢\82È\82¢\82c\82e\82`\8fó\91Ô\82ð\92T\82·\81B
+ \8c©\82Â\82©\82ç\82È\82¯\82ê\82Înil\82ð\95Ô\82·\81B}
+function TRE_DFA.Fetch_Unvisited_D_state: RE_pDFAState_t;
+var
+ i: Integer;
+begin
+
+ for i := 0 to FStateList.Count-1 do begin
+ if not RE_pDFAState_t(FStateList[i])^.visited then begin
+ result := FStateList[i];
+ exit;
+ end;
+ end;
+ result := nil;
+end;
+
+{Compute_Reachable_N_state \82ª\8dì\82é RE_DFATransNode_t\8c^\82Ì\83\8a\83\93\83N\83\8a\83X\83g\82ð\94j\8aü\82·\82é}
+procedure TRE_DFA.Destroy_DFA_TransList(pDFA_TransNode: RE_pDFATransNode_t);
+var
+ pNext: RE_pDFATransNode_t;
+begin
+ if pDFA_TransNode <> nil then begin
+ while pDFA_TransNode <> nil do begin
+ pNext := pDFA_TransNode^.next;
+ if pDFA_TransNode^.ToNFAStateSet <> nil then
+ pDFA_TransNode^.ToNFAStateSet.Free;
+ Dispose(pDFA_TransNode);
+
+ pDFA_TransNode := pNext;
+ end;
+ end;
+end;
+
+{ DFA\8fó\91ÔpDFAState\82©\82ç\91J\88Ú\89Â\94\\82ÈNFA\8fó\91Ô\82ð\92T\82µ\82Ä\81A\83\8a\83\93\83N\83\8a\83X\83g\82É\82µ\82Ä\95Ô\82·}
+function TRE_DFA.Compute_Reachable_N_state(pDFAState: RE_pDFAState_t): RE_pDFATransNode_t;
+var
+ i: Integer;
+ pNFANode: RE_pNFANode_t;
+ a, b: RE_pDFATransNode_t;
+label
+ added;
+begin
+ result := nil;
+try
+ {\82·\82×\82Ä\82Ì\82m\82e\82`\8fó\91Ô\82ð\8f\87\82É\92²\82×\82é}
+ for i := 0 to FNFA.StateList.Count-1 do begin
+
+ { NFA\8fó\91Ôi\82ªDFA\8fó\91Ô pDFAState\82É\8aÜ\82Ü\82ê\82Ä\82¢\82ê\82Î\81A\88È\89º\82Ì\8f\88\97\9d\82ð\8ds\82¤}
+ if pDFAState^.StateSet.Has(i) then begin
+
+ { NFA\8fó\91Ô i \82©\82ç\91J\88Ú\89Â\94\\82È\82m\82e\82`\8fó\91Ô\82ð\82·\82×\82Ä\92²\82×\82Ä\83\8a\83X\83g\82É\82·\82é}
+ pNFANode := RE_pNFANode_t(FNFA.StateList[i]);
+ while pNFANode <> nil do begin
+ if pNFANode^.CharClass.StartChar <> CONST_EMPTY then begin {\83Ã\91J\88Ú\82Í\96³\8e\8b}
+ a := result;
+ while a <> nil do begin
+ if a^.CharClass.Chars = pNFANode^.CharClass.Chars then begin
+ a^.ToNFAStateSet.Include(pNFANode^.TransitTo);
+ goto added;
+ end;
+ a := a^.next;
+ end;
+ {\83L\83\83\83\89\83N\83^ pNFANode^.CharClass.c\82É\82æ\82é\91J\88Ú\82ª\93o\98^\82³\82ê\82Ä\82¢\82È\82¯\82ê\82Î\92Ç\89Á}
+ New(b);
+ with b^ do begin
+ CharClass := pNFANode^.CharClass;
+ ToNFAStateSet := TRE_NFAStateSet.Create(FNFA.StateList.Count);
+ ToNFAStateSet.Include(pNFANode^.TransitTo);
+ next := result;
+ end;
+ result := b;
+ added:
+ ;
+ end;
+ pNFANode := pNFANode^.next;
+ end;
+ end;
+ end;
+except
+ on EOutOfMemory do begin
+ Destroy_DFA_TransList(result); {\8d\\92z\92\86\82Ì\83\8a\83X\83g\94p\8aü}
+ raise;
+ end;
+end;
+end;
+
+{\8fó\91Ô\83\8a\83X\83g\82Ì\83\8a\83\93\83N\83\8a\83X\83g\82ð\90®\97ñ\82·\82é(\83}\81[\83W\81E\83\\81[\83g\82ð\8eg\97p)}
+procedure TRE_DFA.StateListSort;
+var
+ i: Integer;
+ {\83}\81[\83W\81E\83\\81[\83g\8f\88\97\9d\82ð\8dÄ\8bA\93I\82É\8ds\82¤}
+ function DoSort(pCell: RE_pDFAStateSub_t): RE_pDFAStateSub_t;
+ var
+ pMidCell, pACell: RE_pDFAStateSub_t;
+
+ {2\82Â\82Ì\83\8a\83X\83g\82ð\83\\81[\83g\82µ\82È\82ª\82ç\95¹\8d\87\82·\82é}
+ function MergeList(pCell1, pCell2: RE_pDFAStateSub_t): RE_pDFAStateSub_t;
+ var
+ Dummy: RE_DFAStateSub_t;
+ begin
+ Result := @Dummy;
+ {\82Ç\82¿\82ç\82©\82Ì\83\8a\83X\83g\82ª\81A\8bó\82É\82È\82é\82Ü\82Å\94½\95\9c}
+ while (pCell1 <> nil) and (pCell2 <> nil) do begin
+ {pCell1 \82Æ pCell2 \82ð\94ä\8ar\82µ\82Ä\8f¬\82³\82¢\95û\82ðResult\82É\92Ç\89Á\82µ\82Ä\82¢\82}
+ if pCell1^.CharClass.StartChar > pCell2^.CharClass.StartChar then begin
+ {pCell2\82Ì\95û\82ª\8f¬\82³\82¢}
+ Result^.Next := pCell2;
+ Result := pCell2;
+ pCell2 := pCell2^.Next;
+ end else begin
+ {pCell1\82Ì\95û\82ª\8f¬\82³\82¢}
+ Result^.Next := pCell1;
+ Result := pCell1;
+ pCell1 := pCell1^.Next;
+ end;
+ end;
+ {\97]\82Á\82½\83\8a\83X\83g\82ð\82»\82Ì\82Ü\82Üresult \82É\92Ç\89Á}
+ if pCell1 = nil then
+ Result^.Next := pCell2
+ else
+ Result^.Next := pCell1;
+
+ result := Dummy.Next;
+ end;
+
+ {DoSort\96{\91Ì}
+ begin
+ if (pCell = nil) or (pCell^.Next = nil) then begin
+ result := pCell;
+ exit; {\97v\91f\82ª\82P\82Â\81A\82Ü\82½\82Í\81A\96³\82¢\82Æ\82«\82Í\81A\82·\82®\82É exit}
+ end;
+
+ {ACell \82ª\82R\94Ô\96Ú\82Ì\83Z\83\8b\82ð\8ew\82·\82æ\82¤\82É\82·\82é\81B\96³\82¯\82ê\82Î\81Anil \82ð\8e\9d\82½\82¹\82é}
+ {\83\8a\83X\83g\82ª\82Q\81`\82R\8cÂ\82Ì\83Z\83\8b\82ð\8e\9d\82Â\82Æ\82«\82É\82à\81A\95ª\8a\84\82ð\8ds\82¤\82æ\82¤\82É\82·\82é\81B}
+ pACell := pCell^.Next^.Next;
+ pMidCell := pCell;
+ {MidCell \82ª\81A\83\8a\83X\83g\82Ì\90^\82ñ\92\86\82 \82½\82è\82Ì\83Z\83\8b\82ð\8ew\82·\82æ\82¤\82É\82·\82é\81B}
+ while pACell <> nil do begin
+ pMidCell := pMidCell^.Next;
+ pACell := pACell^.Next;
+ if pACell <> nil then
+ pACell := pACell^.Next;
+ end;
+
+ {MidCell \82Ì\8cã\82ë\82Å\83\8a\83X\83g\82ð\82Q\95ª\8a\84\82·\82é}
+ pACell := pMidCell^.Next;
+ pMidCell^.Next := nil;
+
+ result := MergeList(DoSort(pCell), DoSort(pACell));
+ end;
+begin {Sort \96{\91Ì}
+ for i := 0 to FStateList.Count-1 do begin
+ RE_pDFAState_t(FStateList[i])^.next :=
+ DoSort(RE_pDFAState_t(FStateList[i])^.next);
+ end;
+end;
+
+{\8b@\94\\81F \8c»\8dÝ\82Ì\90³\8bK\95\\8c»\82ª\81A\95\81\92Ê\82Ì\95¶\8e\9a\97ñ\82©\81H
+ \95\81\92Ê\82Ì\95¶\8e\9a\97ñ\82¾\82Á\82½\82ç\81AFRegExpIsSimple = True; FSimpleRegExpStr\82É\95¶\8e\9a\97ñ\82É\90Ý\92è
+ \82»\82ê\88È\8aO\82Ì\8fê\8d\87\82Í\81A FRegExpIsSimple = False;FSimpleRegExpStr = ''}
+procedure TRE_DFA.CheckIfRegExpIsSimple;
+var
+ pDFAState: RE_pDFAState_t;
+ pSub: RE_pDFAStateSub_t;
+ WChar: WChar_t;
+begin
+ FRegExpIsSimple := False;
+ FSimpleRegExpStr := '';
+
+ pDFAState := FpInitialState;
+
+ while pDFAState <> nil do begin
+ pSub := pDFAState^.next;
+ if pSub = nil then
+ break;
+ if (pSub^.next <> nil) or
+ {\95¡\90\94\82Ì\83L\83\83\83\89\83N\83^\82ð\8eó\82¯\93ü\82ê\82é}
+ (pSub^.CharClass.StartChar <> pSub^.CharClass.EndChar) or
+ {\83L\83\83\83\89\83N\83^\94Í\88Í\82ð\8e\9d\82Â}
+ (pDFAState^.Accepted and (pSub^.TransitTo <> nil))
+ {\8eó\97\9d\8cã\82à\83L\83\83\83\89\83N\83^\82ð\8eó\82¯\93ü\82ê\82é}then begin
+
+ FSimpleRegExpStr := '';
+ exit;
+ end else begin
+ WChar := pSub^.CharClass.StartChar;
+ FSimpleRegExpStr := FSimpleRegExpStr + WCharToStr(WChar);
+ end;
+ pDFAState := pSub^.TransitTo;
+ end;
+ FRegExpIsSimple := True;
+end;
+
+
+{$IFDEF DEBUG}
+{TStrings\83I\83u\83W\83F\83N\83g\82É\81ADFA \82Ì\93à\97e\82ð\8f\91\82«\8d\9e\82Þ}
+procedure TRE_DFA.WriteDFAtoStrings(Strings: TStrings);
+var
+ i: Integer;
+ pDFA_State: RE_pDFAState_t;
+ pDFA_StateSub: RE_pDFAStateSub_t;
+ Str: String;
+begin
+ Strings.clear;
+ Strings.BeginUpDate;
+ for i := 0 to FStateList.Count-1 do begin
+ pDFA_State := FStateList.items[i];
+ if pDFA_State = FpInitialState then
+ Str := Format('\8aJ\8en %2d : ', [i])
+ else if pDFA_State^.Accepted then
+ Str := Format('\8fI\97¹ %2d : ', [i])
+ else
+ Str := Format('\8fó\91Ô %2d : ', [i]);
+ pDFA_StateSub := pDFA_State^.next;
+ while pDFA_StateSub <> nil do begin
+ if pDFA_StateSub^.CharClass.StartChar <> pDFA_StateSub^.CharClass.EndChar then
+ Str := Str + Format('\95¶\8e\9a %s \82©\82ç \95¶\8e\9a%s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pDFA_StateSub^.CharClass.StartChar),
+ DebugWCharToStr(pDFA_StateSub^.CharClass.EndChar),
+ FStateList.IndexOf(pDFA_StateSub^.TransitTo)])
+
+ else if pDFA_StateSub^.CharClass.StartChar = FNFA.LHeadWChar then begin
+ Str := Str + Format('\95¶\93ª\83R\81[\83h %s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pDFA_StateSub^.CharClass.StartChar),
+ FStateList.IndexOf(pDFA_StateSub^.TransitTo)]);
+ end else if pDFA_StateSub^.CharClass.StartChar = FNFA.LTailWChar then begin
+ Str := Str + Format('\95¶\94ö\83R\81[\83h %s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pDFA_StateSub^.CharClass.StartChar),
+ FStateList.IndexOf(pDFA_StateSub^.TransitTo)]);
+ end else
+ Str := Str + Format('\95¶\8e\9a %s \82Å \8fó\91Ô %2d \82Ö :',
+ [DebugWCharToStr(pDFA_StateSub^.CharClass.StartChar),
+ FStateList.IndexOf(pDFA_StateSub^.TransitTo)]);
+
+ pDFA_StateSub := pDFA_StateSub^.Next;
+ end;
+ Strings.Add(Str);
+ end;
+ Strings.EndUpDate;
+end;
+{$ENDIF}
+
+{ -=================== TRegularExpression Class ==============================-}
+constructor TRegularExpression.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FRegExpList := TStringList.Create;
+ FRegExpListMax := 30; {RegExpList\82Ì\8d\80\96Ú\90\94\90Ý\92è 30}
+ {FCurrentIndex = 0 \82Í\83k\83\8b\82Ì\90³\8bK\95\\8c»\82Å\8fí\82É\8eg\82¦\82é\82æ\82¤\82É\82·\82é\81B}
+ FCurrentIndex := FRegExpList.Add('');
+ FPreProcessor := TREPreProcessor.Create('');
+ Translate(FRegExpList[FCurrentIndex]);
+end;
+
+destructor TRegularExpression.Destroy;
+begin
+ FPreProcessor.Free;
+ DisposeRegExpList;
+ inherited Destroy;
+end;
+
+{\90³\8bK\95\\8c»\83\8a\83X\83g(FRegExpList: TStringList)\82ÆObjects\83v\83\8d\83p\83e\83B\82É\8c\8b\82Ñ\95t\82¯\82ç\82ê\82½
+ TRE_DFA\83I\83u\83W\83F\83N\83g\82ð\94j\8aü}
+procedure TRegularExpression.DisposeRegExpList;
+var
+ i: Integer;
+begin
+ if FRegExpList <> nil then begin
+ with FRegExpList do begin
+ for i := 0 to Count-1 do begin
+ TRE_DFA(Objects[i]).Free;
+ end;
+ end;
+ FRegExpList.Free;
+ FRegExpList := nil;
+ end;
+end;
+
+{ ---------------------- \83v\83\8d\83p\83e\83B \83A\83N\83Z\83X \83\81\83\\83b\83h -----------------}
+{RegExp\83v\83\8d\83p\83e\83B\82Ìwrite\83\81\83\\83b\83h}
+procedure TRegularExpression.SetRegExp(Str: String);
+var
+ OrigRegExp: String;
+ function FindRegExpInList(RegExpStr: String): Integer;
+ var
+ i: Integer;
+ begin
+ result := -1;
+ i := 0;
+ while i < FRegExpList.Count do begin
+ if RegExpStr = FRegExpList[i] then begin
+ result := i;
+ exit;
+ end;
+ Inc(i);
+ end;
+ end;
+begin
+ OrigRegExp := Str;{\83v\83\8a\83v\83\8d\83Z\83b\83T\82ð\92Ê\82é\91O\82Ì\90³\8bK\95\\8c»\82ð\91Þ\94ð}
+ with FPreProcessor do begin
+ TargetRegExpStr := Str;
+ Run;
+ Str := ProcessedRegExpStr;
+ end;
+
+ try
+ FCurrentIndex := FindRegExpInList(Str);
+ {FRegExpList\93à\82É\83L\83\83\83b\83V\83\85\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Í\81A\83R\83\93\83p\83C\83\8b}
+ if FCurrentIndex = -1 then begin
+ if FRegExpList.Count = FRegExpListMax then begin
+ TRE_DFA(FRegExpList.Objects[FRegExpList.Count-1]).Free;
+ FRegExpList.Delete(FRegExpList.Count-1);
+ end;
+ FRegExpList.Insert(1, Str);
+ FCurrentIndex := 1;
+ Translate(FRegExpList[1]);
+ end;
+ FRegExp := OrigRegExp;
+ except
+ {\97á\8aO\82ª\94\90¶\82µ\82½\82Æ\82«\82Í\81A\8fí\82É\83k\83\8b\90³\8bK\95\\8c»\82ð\90Ý\92è\82·\82é\81B}
+ on Exception do begin
+ FCurrentIndex := 0;
+ FRegExp := '';
+ raise;
+ end;
+ end;
+end;
+
+{RegExp\83v\83\8d\83p\83e\83B\82Ìread\83\81\83\\83b\83h}
+function TRegularExpression.GetProcessedRegExp: String;
+begin
+ result := FRegExpList[FCurrentIndex];
+end;
+
+{ListOfFuzzyCharDic\83v\83\8d\83p\83e\83B read\83\81\83\\83b\83h}
+function TRegularExpression.GetListOfFuzzyCharDic: TList;
+begin
+ result := FPreProcessor.ListOfFuzzyCharDic;
+end;
+
+{GetListOfSynonymDic\83v\83\8d\83p\83e\83B read\83\81\83\\83b\83h}
+function TRegularExpression.GetListOfSynonymDic: TList;
+begin
+ result := FPreProcessor.ListOfSynonymDic;
+end;
+
+{RegExpIsSimple\83v\83\8d\83p\83e\83B read\83\81\83\\83b\83h}
+function TRegularExpression.GetRegExpIsSimple: Boolean;
+begin
+ result := GetCurrentDFA.RegExpIsSimple;
+end;
+
+{SimpleRegExp\83v\83\8d\83p\83e\83B read\83\81\83\\83b\83h}
+function TRegularExpression.GetSimpleRegExp: String;
+begin
+ result := GetCurrentDFA.SimpleRegExpStr;
+end;
+
+{HasLHead\83v\83\8d\83p\83e\83B read\83\81\83\\83b\83h}
+function TRegularExpression.GetHasLHead: Boolean;
+begin
+ result := GetCurrentDFA.RegExpHasLHead;
+end;
+
+{HasLTail\83v\83\8d\83p\83e\83B write\83\81\83\\83b\83h}
+function TRegularExpression.GetHasLTail: Boolean;
+begin
+ result := GetCurrentDFA.RegExpHasLTail;
+end;
+
+{\8c»\8dÝ\82Ì\90³\8bK\95\\8c»\82É\91Î\89\9e\82·\82éTRE_DFA\8c^\83I\83u\83W\83F\83N\83g\82ð\93¾\82é}
+function TRegularExpression.GetCurrentDFA: TRE_DFA;
+begin
+ result := TRE_DFA(FRegExpList.Objects[FCurrentIndex]);
+end;
+
+{DFA\8fó\91Ô\95\\82Ì\8f\89\8aú\8fó\91Ô\82ð\95\\82·\83m\81[\83h\82Ö\82Ì\83|\83C\83\93\83^\82ð\93¾\82é\82±\82Æ\82ª\82Å\82«\82é\81B}
+function TRegularExpression.GetpInitialDFAState: RE_pDFAState_t;
+begin
+ result := TRE_DFA(FRegExpList.Objects[FCurrentIndex]).pInitialState;
+end;
+
+function TRegularExpression.GetUseFuzzyCharDic: Boolean;
+begin
+ result := FPreProcessor.UseFuzzyCharDic;
+end;
+
+procedure TRegularExpression.SetUseFuzzyCharDic(Val: Boolean);
+begin
+ FPreProcessor.UseFuzzyCharDic := Val;
+ Self.RegExp := FRegExp; {\90V\82µ\82¢\90Ý\92è\82Å\8dÄ\83R\83\93\83p\83C\83\8b}
+end;
+
+function TRegularExpression.GetUseSynonymDic: Boolean;
+begin
+ result := FPreProcessor.UseSynonymDic;
+end;
+
+procedure TRegularExpression.SetUseSynonymDic(Val: Boolean);
+begin
+ FPreProcessor.UseSynonymDic := Val;
+ Self.RegExp := FRegExp; {\90V\82µ\82¢\90Ý\92è\82Å\8dÄ\83R\83\93\83p\83C\83\8b}
+end;
+
+function TRegularExpression.GetLineHeadWChar: WChar_t;
+begin
+ result := CONST_LINEHEAD;
+end;
+
+function TRegularExpression.GetLineTailWChar: WChar_t;
+begin
+ result := CONST_LINETAIL;
+end;
+
+{***** \90³\8bK\95\\8c»\95¶\8e\9a\97ñ\81¨\8d\\95¶\96Ø\8d\\91¢\81¨NFA\81¨DFA \82Ì\95Ï\8a·\82ð\8ds\82¤ *****}
+procedure TRegularExpression.Translate(RegExpStr: String);
+var
+ DFA: TRE_DFA;
+ Parser: TREParser;
+ NFA: TRE_NFA;
+begin
+ DFA := nil;
+ try
+ Parser := TREParser.Create(RegExpStr);
+ try
+ Parser.Run;
+ NFA := TRE_NFA.Create(Parser, GetLineHeadWChar, GetLineTailWChar);
+ try
+ Self.FLineHeadWChar := NFA.LHeadWChar;
+ Self.FLineTailWChar := NFA.LTailWChar;
+ NFA.Run;
+ DFA := TRE_DFA.Create(NFA);
+ FRegExpList.Objects[FCurrentIndex] := DFA;
+ TRE_DFA(FRegExpList.Objects[FCurrentIndex]).Run;
+ finally
+ NFA.Free;
+ end;
+ finally
+ Parser.Free;
+ end;
+ except
+ On Exception do begin
+ DFA.Free;
+ FRegExpList.Delete(FCurrentIndex);
+ FCurrentIndex := 0;
+ raise;
+ end;
+ end;
+end;
+
+{\8fó\91Ô DFAstate\82©\82ç\95¶\8e\9a\82\83\82É\82æ\82Á\82Ä\91J\88Ú\82µ\82Ä\81A\91J\88Ú\8cã\82Ì\8fó\91Ô\82ð\95Ô\82·\81B
+ \95¶\8e\9a\82\83\82É\82æ\82Á\82Ä\91J\88Ú\8fo\97\88\82È\82¯\82ê\82Înil\82ð\95Ô\82·}
+function TRegularExpression.NextDFAState(DFAState: RE_pDFAState_t; c: WChar_t): RE_pDFAState_t;
+var
+ pSub: RE_pDFAStateSub_t;
+begin
+ {\82P\82Â\82ÌDFAState\82ª\8e\9d\82Â pSub\82Ì\83\8a\83\93\83N\82Å\82Í\83L\83\83\83\89\83N\83^\83N\83\89\83X\82ª\8f¸\8f\87\82É\82È\82ç\82ñ\82Å\82¢\82é\82±\82Æ
+ \82ð\91O\92ñ\82Æ\82µ\82Ä\82¢\82é\81B}
+ result := nil;
+ pSub := DFAState^.next;
+ while pSub <> nil do begin
+ if c < pSub^.CharClass.StartChar then
+ exit
+ else if c <= pSub^.CharClass.EndChar then begin
+ result := pSub^.TransitTo;
+ exit;
+ end;
+ pSub := pSub^.next;
+ end;
+end;
+
+constructor TMatchCORE.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FLineSeparator := mcls_CRLF;
+end;
+
+procedure TMatchCORE.MatchStd(pText: PChar; var pStart, pEnd: PChar);
+var
+ pDFAState: RE_pDFAState_t;
+ pp: PChar;
+begin
+ pStart := nil;
+ pEnd := nil;
+
+ {pText\82ª\83k\83\8b\95¶\8e\9a\97ñ\82Å\81A\90³\8bK\95\\8c»\82ª\83k\83\8b\95¶\8e\9a\97ñ\82É\88ê\92v\82·\82é\82Æ\82«}
+ if (Byte(pText^) = CONST_NULL) and GetCurrentDFA.pInitialState.Accepted then begin
+ pStart := pText;
+ pEnd := pText;
+ exit;
+ end;
+
+ {\92\8d\96Ú\93_\82ð\82P\95¶\8e\9a\82Ã\82Â\82¸\82ç\82µ\82È\82ª\82ç\83}\83b\83`\82·\82é\8dÅ\8d¶\95\94\95ª\82ð\8c©\82Â\82¯\82é}
+ while Byte(pText^) <> CONST_NULL do begin
+ {DFA\82Ì\8f\89\8aú\8fó\91Ô\82ð\90Ý\92è}
+ pDFAState := Self.GetCurrentDFA.pInitialState;
+ pp := pText;
+ {DFA\8fó\91Ô\95\\82É\95¶\8e\9a\82ð\93ü\97Í\82µ\82Ä\82¢\82Á\82Ä\83}\83b\83`\82·\82é\8dÅ\92·\95\94\95ª\82ð\8c©\82Â\82¯\82é}
+ repeat
+ if pDFAState^.accepted then begin
+ {\8fI\97¹\8fó\91Ô\82Å\82 \82ê\82Î\8fê\8f\8a\82ð\8bL\98^\82µ\82Ä\82¨\82\81B
+ \8c\8b\89Ê\82Æ\82µ\82Ä\83}\83b\83`\82µ\82½\8dÅ\8d¶\8dÅ\92·\95\94\95ª\82ª\8bL\98^\82³\82ê\82é}
+ pStart := pText;
+ pEnd := pp;
+ end;
+ {\8e\9f\82Ì\8fó\91Ô\82É\91J\88Ú}
+ pDFAState := NextDFAState(pDFAState, PCharGetWChar(pp));
+ until pDFAState = nil;
+
+ {\83}\83b\83`\82µ\82½\82Æ\82«\82ÍExit}
+ if pStart <> nil then
+ exit;
+
+ {\92\8d\96Ú\88Ê\92u\82ð\82P\95¶\8e\9a\95ª\90i\82ß\82é\81B}
+ if IsDBCSLeadByte(Byte(pText^)) then
+ Inc(pText, 2)
+ else
+ Inc(pText);
+ end;
+ {\83}\83b\83`\82µ\82È\82¢\81B}
+end;
+
+procedure TMatchCORE.MatchEX(pText: PChar; var pStart, pEnd: PChar);
+begin
+ pStart := pText;
+ pEnd := MatchHead(pText, GetCurrentDFA.pInitialState);
+ if pEnd = nil then
+ MatchEX_Inside(pText, pStart, pEnd);
+end;
+
+procedure TMatchCORE.MatchEX_Inside(pText: PChar; var pStart, pEnd: PChar);
+var
+ DFA: TRE_DFA;
+ pInitialDFAState: RE_pDFAState_t;
+begin
+ pStart := nil;
+ pEnd := nil;
+
+ DFA := GetCurrentDFA;
+ pInitialDFAState := DFA.pInitialState;
+ while Byte(pText^) <> CONST_NULL do begin
+ pEnd := MatchInSide(pText, pInitialDFAState);
+ if pEnd <> nil then begin
+ pStart := pText;
+ exit;
+ end else if (Byte(pText^) = CONST_LF) and
+ DFA.RegExpHasLHead then begin
+ pEnd := MatchHead(pText+1, pInitialDFAState);
+ if pEnd <> nil then begin
+ pStart := pText+1;
+ exit;
+ end;
+ end;
+ {\92\8d\96Ú\88Ê\92u\82ð\82P\95¶\8e\9a\95ª\90i\82ß\82é\81B}
+ if IsDBCSLeadByte(Byte(pText^)) then
+ Inc(pText, 2)
+ else
+ Inc(pText);
+ end;
+
+ if DFA.RegExpHasLTail and (NextDFAState(pInitialDFAState, LineTailWChar) <> nil) then begin
+ {\90³\8bK\95\\8c»\82ª\95¶\94ö\83\81\83^\83L\83\83\83\89\83N\83^\82Ì\82Ý\82Ì\82Æ\82«(RegExp = '$')\82Ì\93Á\8eê\8f\88\97\9d}
+ pStart := pText;
+ pEnd := pText;
+ end;
+ end;
+
+function TMatchCORE.MatchHead(pText: PChar; pDFAState: RE_pDFAState_t): PChar;
+var
+ pEnd: PChar;
+begin
+{\90³\8bK\95\\8c»\82ª\8ds\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82ñ\82Å\82¢\82é}
+ if GetCurrentDFA.RegExpHasLHead then begin
+ result := MatchInSide(pText, NextDFAState(pDFAState, LineHeadWChar));
+ if result <> nil then begin
+ {\83}\83b\83`\82µ\82½\81B\82±\82Ì\8e\9e\93_\82Å\81Aresult <> nil \8am\92è}
+ pEnd := result;
+ {\82³\82ç\82É\81ARegExp = '(^Love|Love me tender)'\82Å\81AText = 'Love me tender. Love me sweet'
+ \82Ì\8fê\8d\87\82É\8dÅ\8d¶\8dÅ\92·\82Å\83}\83b\83`\82·\82é\82Ì\82Í\81A'Love me tender'\82Å\82È\82¯\82ê\82Î\82È\82ç\82È\82¢\82Ì\82Å\81A\82»\82Ì\88×\82Ì
+ \83}\83b\83`\8c\9f\8d¸\82ð\8ds\82¤\81B}
+ result := MatchInside(pText, pDFAState);
+ if (result = nil) or (pEnd > result) then
+ result := pEnd;
+ end;
+ end else begin
+{\90³\8bK\95\\8c»\82ª\8ds\93ª\83\81\83^\83L\83\83\83\89\83N\83^\82ð\8aÜ\82ñ\82Å\82¢\82È\82¢}
+ result := MatchInside(pText, pDFAState);
+ end;
+end;
+
+function TMatchCORE.MatchInside(pText: PChar; pDFAState: RE_pDFAState_t): PChar;
+var
+ pEnd: PChar;
+ WChar: WChar_t;
+ pPrevDFAState: RE_pDFAState_t;
+begin
+ result := nil;
+ pEnd := pText;
+
+ if pDFAState = nil then
+ exit;
+ repeat
+ if pDFAState^.accepted then begin
+ {\8fI\97¹\8fó\91Ô\82Å\82 \82ê\82Î\8fê\8f\8a\82ð\8bL\98^\82µ\82Ä\82¨\82\81B
+ \8c\8b\89Ê\82Æ\82µ\82Ä\83}\83b\83`\82µ\82½\8dÅ\8d¶\8dÅ\92·\95\94\95ª\82ª\8bL\98^\82³\82ê\82é}
+ result := pEnd;
+ end;
+ pPrevDFAState := pDFAState;
+ {DFA\82ð\8fó\91Ô\91J\88Ú\82³\82¹\82é}
+ WChar := PCharGetWChar(pEnd);
+ pDFAState := NextDFAState(pDFAState, WChar);
+ until pDFAState = nil;
+
+ if (IsLineEnd(WChar) or (WChar = CONST_NULL)) and
+ (NextDFAState(pPrevDFAState, LineTailWChar) <> nil) then begin
+ {\8ds\96\96\83\81\83^\83L\83\83\83\89\83N\83^\82ð\93ü\97Í\82µ\82Ä\81Anil\88È\8aO\82ª\8bA\82Á\82Ä\82\82é\82Æ\82«\82Í\95K\82¸\81A\83}\83b\83`\82·\82é}
+ result := pEnd;
+ if WChar <> CONST_NULL then
+ Dec(result); {CR($0d)\82Ì\95ª Decrement}
+ end;
+end;
+
+function TMatchCORE.IsLineEnd(WChar: WChar_t): Boolean;
+begin
+ result := False;
+ case FLineSeparator of
+ mcls_CRLF: result := (WChar = CONST_CR);
+ mcls_LF: result := (WChar = CONST_LF);
+ end;
+end;
+
+{ -========================== TAWKStr Class ==================================- }
+constructor TAWKStr.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ ListOfFuzzyCharDic.Add(RE_FuzzyCharDic); {\83L\83\83\83\89\83N\83^\93¯\88ê\8e\8b\8e«\8f\91\82ð\92Ç\89Á}
+end;
+
+procedure TAWKStr.SetRegExp(Str: String);
+begin
+ inherited SetRegExp(Str);
+ if not (HasLHead or HasLTail) then begin
+ FMatchProc := MatchStd;
+ end else begin
+ FMatchProc := MatchEx;
+ end;
+end;
+
+{\95¶\8e\9a\97ñ\92\86\82Ì'\' \82Å \88ø\97p\82³\82ê\82½\83L\83\83\83\89\83N\83^\82ð\8f\88\97\9d\82·\82é\81B \n, \t \\ ...}
+function TAWKStr.ProcessEscSeq(Text: String): String;
+var
+ WChar: WChar_t;
+ Index: Integer;
+begin
+ result := '';
+ Index := 1;
+ while Index <= Length(Text) do begin
+ WChar := GetWChar(Text, Index);
+ if WChar = Ord('\') then
+ result := result + WCharToStr(GetQuotedWChar(Text, Index))
+ else
+ result := result + WCharToStr(WChar);
+ end;
+end;
+
+{Sub, GSub\83\81\83\\83b\83h\82Å\8eg\97p\81B '&'\82ð\83}\83b\83`\82µ\82½\95¶\8e\9a\97ñ\82É\92u\8a·\82¦\82é}
+function TAWKStr.Substitute_MatchStr_For_ANDChar(Text: String; MatchStr: String): String;
+var
+ i: Integer;
+ aStr: String;
+ WCh, WCh2: WChar_t;
+begin
+ i := 1;
+ aStr := '';
+{'\&'\82ð'\\&'\82É\82µ\82Ä\82©\82ç}
+ while i <= Length(Text) do begin
+ WCh := GetWChar(Text, i);
+ if WCh = CONST_YEN then begin
+ aStr := aStr + WCharToStr(WCh);
+
+ WCh := GetWChar(Text, i);
+ if WCh = CONST_ANP then begin
+ aStr := Concat(aStr, WCharToStr(CONST_YEN));
+ end;
+ end;
+ aStr := aStr + WCharToStr(WCh);
+ end;
+
+{\83G\83X\83P\81[\83v\81E\83V\81[\83P\83\93\83X\82ð\8f\88\97\9d}
+ Text := ProcessEscSeq(aStr);
+
+{'&' \82ð MatchStr\82Å\92u\8a·\82¦\81A'\&'\82ð'&'\82É\92u\8a·\82¦}
+ result := '';
+ i := 1;
+ while i <= Length(Text) do begin
+ WCh := GetWChar(Text, i);
+ if WCh = CONST_ANP then
+ result := Concat(result, MatchStr)
+ else if WCh = CONST_YEN then begin
+ WCh2 := GetWChar(Text, i);
+ if WCh2 = CONST_ANP then begin
+ result := result + WCharToStr(WCh2);
+ end else begin
+ if WCh2 <> CONST_NULL then
+ UnGetWChar(Text, i);
+ result := result + WCharToStr(WCh);
+ end;
+ end else begin
+ result := result + WCharToStr(WCh);
+ end;
+ end;
+end;
+
+function TAWKStr.Match(Text: String; var RStart, RLength: Integer): Integer;
+var
+ pStart, pEnd: PChar;
+begin
+ FMatchProc(PChar(Text), pStart, pEnd);
+ if pStart = nil then begin
+ RStart := 0;
+ RLength := 0;
+ result := 0;
+ end else begin
+ RStart := pStart - PChar(Text)+1; {RStart\82Í\82P\83x\81[\83X}
+ RLength := pEnd - pStart;
+ result := RStart;
+ end;
+end;
+
+{AWK Like function Sub_Raw}
+function TAWKStr.Sub(SubText: String; var Text: String): Boolean;
+var
+ pStart, pEnd: PChar;
+ MatchStr: String;
+begin
+ FMatchProc(PChar(Text), pStart, pEnd);
+ if pStart <> nil then begin
+{\83}\83b\83`\82µ\82½}
+ MatchStr := Copy(Text, pStart-PChar(Text)+1, pEnd-pStart); {\83}\83b\83`\82µ\82½\95\94\95ª}
+ Delete(Text, pStart-PChar(Text)+1, pEnd-pStart);
+ {SubText\82Ì\82È\82©\82Ì&\83L\83\83\83\89\83N\83^\82ð\83}\83b\83`\82µ\82½\95\94\95ª(MatchStr)\82Å\92u\8a·\82¦\82é\81B}
+ SubText := Substitute_MatchStr_For_ANDChar(SubText, MatchStr);
+ Insert(SubText, Text, pStart-PChar(Text)+1);
+ result := True;
+ end else begin
+{\83}\83b\83`\82µ\82È\82¢}
+ result := False;
+ end;
+end;
+
+{AWK Like GSubRaw }
+function TAWKStr.GSub(SubText: String; var Text: String): Integer;
+var
+ pStart, pEnd: PChar;
+ ResultText, aText: String;
+ MatchStr: String;
+ WChar: WChar_t;
+begin
+ ResultText := ''; {\8c\8b\89Ê\82Ì\95¶\8e\9a\97ñ\82ð\93ü\82ê\82é\95Ï\90\94}
+ aText := Text; {\8c\9f\8dõ\91Î\8fÛ\82Æ\82µ\82Ä\8eg\82¤}
+ result := 0;
+ FMatchProc(PChar(aText), pStart, pEnd);
+ if pStart = nil then
+ exit {\89½\82à\83}\83b\83`\82µ\82È\82¢}
+ else if aText = '' then begin
+ result := 1; {\83}\83b\83`\82µ\82½\82ª Text=''}
+ Text := Substitute_MatchStr_For_ANDChar(SubText, '');
+ exit;
+ end;
+
+ {\83}\83b\83`\82µ\82Ä Text <> ''}
+ while True do begin
+ ResultText := Concat(ResultText, Copy(aText, 1, pStart-PChar(aText)));{\91O\94¼\95\94\95ª}
+ MatchStr := Copy(aText, pStart-PChar(aText)+1, pEnd-pStart); {\83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ}
+ MatchStr := Substitute_MatchStr_For_ANDChar(SubText, MatchStr);
+ ResultText := Concat(ResultText, MatchStr);{+ \92u\8a·\95¶\8e\9a\97ñ}
+
+ if pStart = pEnd then begin {\8bó\95¶\8e\9a\97ñ\82É\83}\83b\83`\82µ\82½\82Æ\82«\82Ì\93Á\8eê\8f\88\97\9d}
+ if isDBCSLeadByte(Byte(pStart^)) or
+ ((LineSeparator = mcls_CRLF) and (Byte(pStart^) = CONST_CR)) then begin
+ ResultText := Concat(ResultText, Copy(aText, pStart-PChar(aText)+1, 2));
+ Inc(pEnd, 2);
+ end else begin
+ ResultText := Concat(ResultText, Copy(aText, pStart-PChar(aText)+1, 1));
+ if Byte(pEnd^) <> CONST_NULL then
+ Inc(pEnd, 1);
+ end;
+ end;
+ Inc(result);
+
+ WChar := Byte((pEnd-1)^);
+ {Chr($0a)\82ð\92²\82×\82é\88×\82¾\82¯\82È\82Ì\82Å\81A\82Q\83o\83C\83g\95¶\8e\9a\82Ì\8dl\97¶\95s\97v\81B aText = ''\82Í\82 \82è\82¦\82È\82¢}
+ aText := String(pEnd);
+ {\83}\83b\83`\82µ\82½\95\94\95ª\95¶\8e\9a\97ñ\82Ì\8cã\82Ì\95\94\95ª\82ðaText\82É\90Ý\92è}
+ if aText = '' then
+ break;
+ if WChar = CONST_LF then begin
+ FMatchProc(PChar(aText), pStart, pEnd);
+ if pStart = nil then
+ break;
+ end else begin
+ MatchEX_Inside(PChar(aText), pStart, pEnd);
+ if pStart = nil then
+ break;
+ end;
+ end;
+ Text := Concat(ResultText, aText);
+end;
+
+function TAWKStr.Split(Text: String; StrList: TStrings): Integer;
+var
+ pStart, pEnd: PChar;
+ Str: String;
+begin
+ StrList.Clear;{\8c\8b\89Ê\95¶\8e\9a\97ñ\83\8a\83X\83g\82Ì\93à\97e\83N\83\8a\83A}
+ Str := '';
+ while Text <> '' do begin
+ FMatchProc(PChar(Text), pStart, pEnd);
+ if pStart = nil then begin
+ {\83}\83b\83`\82µ\82È\82©\82Á\82½\82Æ\82«}
+ StrList.Add(Concat(Str, Text));
+ Str := '';
+ break;
+ end else if (pStart = PChar(Text)) and (pStart = pEnd) then begin
+ {\90æ\93ª\82Ì\83k\83\8b\95¶\8e\9a\97ñ\82É\83}\83b\83`\82µ\82½\82Æ\82«\82Ì\93Á\8eê\8f\88\97\9d}
+ if IsDBCSLeadByte(Byte(Text[1])) then begin
+ Str := Concat(Str, Copy(Text, 1, 2));
+ Text := Copy(Text, 3, Length(Text));
+ end else begin
+ Str := Concat(Str, Text[1]);
+ Text := Copy(Text, 2, Length(Text));
+ end;
+ end else begin;
+ {\83}\83b\83`\82µ\82½}
+ StrList.Add(Concat(Str, Copy(Text, 1, pStart-PChar(Text))));
+ Str := '';
+ Text := String(pEnd);
+ if Text = '' then begin
+ {\8dÅ\8cã\94ö\82É\83}\83b\83`\82µ\82½\82Æ\82«\82Ì\93Á\8eê\8f\88\97\9d}
+ StrList.Add('');
+ break;
+ end;
+ end;
+ end;
+ if Str <> '' then
+ StrList.Add(Str);
+ result := StrList.Count;
+end;
+
+{ -=========================== TTxtFile Class ================================-}
+constructor TTxtFile.Create(aFileName: String; var CancelRequest: Boolean);
+begin
+ inherited Create;
+ FpCancelRequest := @CancelRequest; {CancelRequest\82ªTrue\82Å\93r\92\86\8fI\97¹\82·\82é}
+
+ FBuffSize := 1024*100; {\83o\83b\83t\83@\82Ì\83T\83C\83Y}
+ FTailMargin := 100;
+
+ FFileName := aFileName;
+ System.FileMode := 0; {\83t\83@\83C\83\8b\83A\83N\83Z\83X\83\82\81[\83h \82ð\93Ç\82Ý\8fo\82µ\90ê\97p\82É\90Ý\92è}
+ AssignFile(FF, FFileName);
+ try
+ Reset(FF, 1);
+ except
+ on E: EInOutError do begin
+ raise EFileNotFound.Create(E.Message);
+ end;
+ end;
+ FFileOpened := True; { \83t\83@\83C\83\8b\83I\81[\83v\83\93\82Ì\83t\83\89\83O\81BDestroy\82Å\8eg\97p\82·\82é}
+ FpBuff := AllocMem(FBuffSize+FTailMargin);
+ FpBuff^ := Chr($0a); { \83t\83@\83C\83\8b\90æ\93ª\8ds\82Ì\8ds\93ª\82É\82k\82e Chr($0a)\82ð\95t\89Á}
+ BuffRead(FpBuff+1);
+ Inc(FReadCount); { \90æ\93ª\82Ì\82k\82e($0a)\82Ì\82Ô\82ñ\82ð\89Á\8eZ}
+ FpBase := FpBuff;
+ FpLineBegin := FpBuff;
+ FpForward := FpBuff;
+ FLineNo := 0;
+end;
+
+destructor TTxtFile.Destroy;
+begin
+ if FFileOpened then
+ CloseFile(FF);
+
+ if FpBuff <> nil then begin
+ FreeMem(FpBuff, FBuffSize+FTailMargin);
+ end;
+
+ inherited Destroy;
+end;
+
+procedure TTxtFile.BuffRead(pBuff: PChar);
+begin
+ BlockRead(FF, pBuff^, FBuffSize, FReadCount);
+ if FReadCount = 0 then begin
+ {FpLineBegin := FpBase;}
+ raise EEndOfFile.Create('End Of File');
+ end;
+
+ {\93Ç\82Ý\8d\9e\82ñ\82¾\83f\81[\83^\82Ì\8dÅ\8cã\82É\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82ð\8f\91\82«\8d\9e\82Þ}
+ if not Eof(FF) then begin
+ (pBuff+FReadCount)^ := Chr(0);
+ end else begin
+ if (pBuff+FReadCount-1)^ <> Chr($0a) then begin
+ (pBuff+FReadCount)^ := Chr($0a);
+ (pBuff+FREadCount+1)^ := Chr(0);
+ (pBuff+FReadCount+2)^ := Chr(0);
+ Inc(FReadCount);
+ end else begin
+ (pBuff+FReadCount)^ := Chr(0);
+ (pBuff+FreadCount+1)^ := Char(0);
+ end;
+ end;
+
+ Application.ProcessMessages;
+ if FpCancelRequest^ then
+ raise EGrepCancel.Create('CancelRequest');
+end;
+
+procedure TTxtFile.IncPBaseNullChar(Ch: Char);
+var
+ Distance: Integer;
+begin
+ if FpBase = (PChar(FBrokenLine)+Length(FBrokenLine)) then begin
+ {FBrokenLine(String\8c^) \82Ì\92\86\82ÅChr(0)\82É\92B\82µ\82½\82Æ\82«\81B}
+ FpBase := FpBuff;
+ end else begin
+ {FpBuff(PChar) \83o\83b\83t\83@\82Ì\92\86\82ÅChr(0)\82É\92B\82µ\82½\82Æ\82«\81B}
+ if FpBase < FpBuff+FReadCount then begin
+ {\83t\83@\83C\83\8b\92\86\82Ì\95s\90³\82È\83k\83\8b\83L\83\83\83\89\83N\83^ Chr(0)\82Í\81ASpace($20)\82É\95â\90³}
+ FpBase^ := Chr($20);
+ end else begin
+ {\83o\83b\83t\83@\82Ì\8fI\82í\82è\82É\97\88\82½}
+ if Eof(FF) then begin
+ {\83t\83@\83C\83\8b\82Ì\8fI\82í\82è\82É\97\88\82½}
+ if Ch = Chr(0) then
+ Dec(FpBase);
+ raise EEndOfFile.Create('End Of File');
+ end else begin
+ {\83t\83@\83C\83\8b\82ð\82Ü\82¾\93Ç\82ß\82é}
+ if (FpLineBegin >= PChar(FBrokenLine)) and
+ (FpLineBegin < (PChar(FBrokenLine)+Length(FBrokenLine))) then begin
+ {FpLineBegin\82ªFBrokenLine\82Ì\92\86\82ð\8ew\82µ\82Ä\82¢\82é\81B}
+ Distance := FpLineBegin-PChar(FBrokenLine);
+ FBrokenLine := Concat(FBrokenLine, String(FpBuff));
+ FpLineBegin := PChar(FBrokenLine)+Distance;
+ BuffRead(FpBuff);
+ FpBase := FpBuff;
+ end else begin
+ {FpLineBegin\82ª\83o\83b\83t\83@\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Ì\82Å\82»\82±\82©\82çFBrokenLine\82ð\8eæ\82é}
+ FBrokenLine := String(FpLineBegin);
+ BuffRead(FpBuff);
+ FpBase := FpBuff;
+ FpLineBegin := PChar(FBrokenLine);
+ end;
+ end;
+ end;
+ end;
+end;
+
+{\8b@\94\\81F FpBase\82ð\83C\83\93\83N\83\8a\83\81\83\93\83g\82µ\82Ä\81A\8e\9f\82Ì\82P\83o\83C\83g\82ð\8ew\82·\82æ\82¤\82É\82·\82é\81B}
+function TTxtFile.IncPBase: Char;
+var
+ ApBase: PChar;
+begin
+ result := FpBase^;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(result);
+ if result = Chr($0a) then begin
+ {\89ü\8ds\8f\88\97\9d}
+ if (FpBase < PChar(FBrokenLine)) or (FpBase > (PChar(FBrokenLine) +
+ Length(FBrokenLine))) then begin
+ {FpBase\82ª\83o\83b\83t\83@\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FBrokenLine := '';
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end else begin
+ {FpBase\82ªFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end;
+ end;
+ if FpBase^ = Chr($0d) then begin
+ ApBase := FpBase;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(result);
+ if FpBase^ <> Chr($0a) then begin
+ { CR($0d)\82Ì\8e\9f\82ªLF($0a)\82Å\82È\82¢\82Æ\82«\82Í\81A$0d\82ð$0a\82É\92u\8a·\82·\82é\81B}
+ if FpBase = FpBuff then
+ FpBase := PChar(FBrokenLine)+Length(FBrokenLine)-1
+ else
+ FpBase := ApBase;
+ FpBase^ := Chr($0a);
+ end
+ end;
+ FpForward := FpBase;
+end;
+
+function TTxtFile.AdvanceBase: WChar_t;
+var
+ ApBase: PChar;
+ Ch: Char;
+begin
+ {\81«\8d\82\91¬\89»\82Ì\82½\82ßIncPBase\96\84\82ß\8d\9e\82Ý}
+ Ch := FpBase^;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(Ch);
+ if Ch = Chr($0a) then begin
+ {\89ü\8ds\8f\88\97\9d}
+ if (FpBase < PChar(FBrokenLine)) or (FpBase > (PChar(FBrokenLine) +
+ Length(FBrokenLine))) then begin
+ {FpBase\82ª\83o\83b\83t\83@\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FBrokenLine := '';
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end else begin
+ {FpBase\82ªFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end;
+ end;
+ if FpBase^ = Chr($0d) then begin
+ ApBase := FpBase;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(ApBase^);
+ if FpBase^ <> Chr($0a) then begin
+ { CR($0d)\82Ì\8e\9f\82ªLF($0a)\82Å\82È\82¢\82Æ\82«\82Í\81A$0d\82ð$0a\82É\92u\8a·\82·\82é\81B}
+ if FpBase = FpBuff then
+ FpBase := PChar(FBrokenLine)+Length(FBrokenLine)-1
+ else
+ FpBase := ApBase;
+ FpBase^ := Chr($0a);
+ end
+ end;
+ {\81ª\8d\82\91¬\89»\82Ì\82½\82ßIncPBase\96\84\82ß\8d\9e\82Ý}
+ result := Byte(Ch);
+ case result of
+ $81..$9F, $E0..$FC: begin
+ {\81«\8d\82\91¬\89»\82Ì\82½\82ßIncPBase\96\84\82ß\8d\9e\82Ý}
+ Ch := FpBase^;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(Ch);
+ if Ch = Chr($0a) then begin
+ {\89ü\8ds\8f\88\97\9d}
+ if (FpBase < PChar(FBrokenLine)) or (FpBase > (PChar(FBrokenLine) +
+ Length(FBrokenLine))) then begin
+ {FpBase\82ª\83o\83b\83t\83@\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FBrokenLine := '';
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end else begin
+ {FpBase\82ªFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FpLineBegin := FpBase;
+ Inc(FLineNo);
+ end;
+ end;
+ if FpBase^ = Chr($0d) then begin
+ ApBase := FpBase;
+ Inc(FpBase);
+ if FpBase^ = Chr(0) then
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ IncPBaseNullChar(ApBase^);
+ if FpBase^ <> Chr($0a) then begin
+ { CR($0d)\82Ì\8e\9f\82ªLF($0a)\82Å\82È\82¢\82Æ\82«\82Í\81A$0d\82ð$0a\82É\92u\8a·\82·\82é\81B}
+ if FpBase = FpBuff then
+ FpBase := PChar(FBrokenLine)+Length(FBrokenLine)-1
+ else
+ FpBase := ApBase;
+ FpBase^ := Chr($0a);
+ end
+ end;
+ {\81ª\8d\82\91¬\89»\82Ì\82½\82ßIncPBase\96\84\82ß\8d\9e\82Ý}
+ result := (result shl 8) or Byte(Ch);
+ end;
+ end;
+ FpForward := FpBase;
+end;
+
+procedure TTxtFile.GetCharNullChar(Ch: Char);
+var
+ Distance, Distance2: Integer;
+begin
+ if FpForward = (PChar(FBrokenLine)+Length(FBrokenLine)) then begin
+ {FBrokenLine(String\8c^) \82Ì\92\86\82ÅChr(0)\82É\92B\82µ\82½\82Æ\82«\81B}
+ FpForward := FpBuff;
+ end else begin
+ {FpBuff \83o\83b\83t\83@\82Ì\92\86\82ÅChr(0)\82É\92B\82µ\82½\82Æ\82«\81B}
+ if FpForward < FpBuff+FReadCount then begin
+ {\83t\83@\83C\83\8b\92\86\82Ì\95s\90³\82È\83k\83\8b\83L\83\83\83\89\83N\83^ Chr(0) \82Í Space($20)\82É\82·\82é\81B}
+ FpForward^ := Chr($20);
+ end else begin
+ {\83o\83b\83t\83@\82Ì\8fI\82í\82è\82É\97\88\82½}
+ if Eof(FF) then begin
+ {\82·\82Å\82É\83t\83@\83C\83\8b\82Ì\8fI\82í\82è\82É\92B\82µ\82Ä\82¢\82é\82Æ\82«}
+ if Ch = Chr(0) then
+ Dec(FpForward); {\82¸n\82Á\82Æresut = Chr(0)\82ð\95Ô\82·\82æ\82¤\82É\82·\82é}
+ exit;
+ end else begin
+ {\82Ü\82¾\83t\83@\83C\83\8b\82ð\93Ç\82ß\82é\82Æ\82«}
+ if (FpLineBegin >= PChar(FBrokenLine)) and
+ (FpLineBegin < PChar(FBrokenLine)+Length(FBrokenLine)) then begin
+ {FpLineBegin\82ªFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ Distance := FpLineBegin-PChar(FBrokenLine);
+ if (FpBase >= PChar(FBrokenLine)) and
+ (FpBase < PChar(FBrokenLine)+Length(FBrokenLine)) then
+ {FpBase\82àFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ Distance2 := FpBase-PChar(FBrokenLine)
+ else
+ {FpBase\82Í\83o\83b\83t\83@\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ Distance2 := Length(FBrokenLine)+FpBase-FpBuff;
+ FBrokenLine := Concat(FBrokenLine, String(FpBuff));
+ FpLineBegin := PChar(FBrokenLine)+Distance;
+ FpBase := PChar(FBrokenLine)+Distance2;
+ BuffRead(FpBuff);
+ FpForward := FpBuff;
+ end else begin
+ {FpLineBegin\82ª\83o\83b\83t\83@\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ FBrokenLine := String(FpLineBegin);
+ FpBase := PChar(FBrokenLine)+(FpBase-FpLineBegin);
+ FpLineBegin := PChar(FBrokenLine);
+ BuffRead(FpBuff);
+ FpForward := FpBuff;
+ end;
+ end;
+ end;
+ end;
+end;
+
+function TTxtFile.GetChar: Char;
+var
+ ApForward: PChar;
+begin
+ ApForward := FpForward;
+ result := FpForward^;
+ Inc(FpForward);
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ if FpForward^ = Chr(0) then
+ GetCharNullChar(result);
+
+ if result = Chr($0d) then begin
+ if FpForward^ <> Chr($0a) then begin
+ {CR($0d)\82Ì\8e\9f\82ªLF($0a)\82Å\82È\82¢\82Æ\82«\82Í\81A$0d\82ð$0a\82É\92u\8a·\82·\82é\81B}
+ if FpForward = FpBuff then
+ FpForward := PChar(FBrokenLine)+Length(FBrokenLine)-1
+ else
+ FpForward := ApForward;
+ FpForward^ := Chr($0a);
+ result := Chr($0a);
+ end else begin
+ result := FpForward^;
+ Inc(FpForward);
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ if FpForward^ = Chr(0) then
+ GetCharNullChar(result);
+ end;
+ end;
+end;
+
+function TTxtFile.GetWChar: WChar_t;
+var
+ ApForward: PChar;
+ Ch: Char;
+begin
+ ApForward := FpForward;
+ Ch := FpForward^;
+ Inc(FpForward);
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ if FpForward^ = Chr(0) then
+ GetCharNullChar(Ch);
+
+ if Ch = Chr($0d) then begin
+ if FpForward^ <> Chr($0a) then begin
+ {CR($0d)\82Ì\8e\9f\82ªLF($0a)\82Å\82È\82¢\82Æ\82«\82Í\81A$0d\82ð$0a\82É\92u\8a·\82·\82é\81B}
+ if FpForward = FpBuff then
+ FpForward := PChar(FBrokenLine)+Length(FBrokenLine)-1
+ else
+ FpForward := ApForward;
+ FpForward^ := Chr($0a);
+ Ch := Chr($0a);
+ end else begin
+ Ch := FpForward^;
+ Inc(FpForward);
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ if FpForward^ = Chr(0) then
+ GetCharNullChar(Ch);
+ end;
+ end;
+ result := Byte(Ch);
+ case result of
+ $81..$9F, $E0..$FC: begin
+ Ch := FpForward^;
+ Inc(FpForward);
+ {\83k\83\8b\81E\83L\83\83\83\89\83N\83^\82Ì\8f\88\97\9d}
+ if FpForward^ = Chr(0) then
+ GetCharNullChar(Ch);
+ result := (result shl 8) or Byte(Ch);
+ end;
+ end;
+end;
+
+function TTxtFile.GetThisLine: RE_LineInfo_t;
+var
+ i: Integer;
+begin
+ Application.ProcessMessages;
+ if FpCancelRequest^ then
+ raise EGrepCancel.Create('CancelRequest');
+
+ {\8ds\96\96\82ð\8c©\82Â\82¯\82é\81B}
+ while FpBase^ <> Chr($0a) do begin
+ IncPBase;
+ end;
+
+ if (FpLineBegin >= PChar(FBrokenLine)) and
+ (FpLineBegin < PChar(FBrokenLine)+Length(FBrokenLine)) then begin
+ {FpLineBegin\82ªFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ if (FpBase >= PChar(FBrokenLine)) and
+ (FpBase < PChar(FBrokenLine)+Length(FBrokenLine)) then begin
+ {FpBase\82àFBrokenLine\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ result.Line := Copy(FBrokenLine, FpLineBegin-PChar(FBrokenLine)+1,
+ FpBase-FpLineBegin);
+ end else begin
+ {FpBase\82Í\83o\83b\83t\83@\92\86\82ð\8ew\82µ\82Ä\82¢\82é\82Æ\82«}
+ SetString(result.Line, FpBuff, FpBase-FpBuff);
+ result.Line := Concat(Copy(FBrokenLine, FpLineBegin-PChar(FBrokenLine)+1,
+ Length(FBrokenLine)), result.Line);
+ end;
+ end else begin
+ SetString(result.Line, FpLineBegin, FpBase-FpLineBegin);
+ end;
+
+ {TrimRight}
+ i := Length(result.Line);
+ while (i > 0) and (result.Line[i] in [Chr($0d), Chr($0a)]) do Dec(I);
+ result.Line := Copy(result.Line, 1, i);
+
+ result.LineNo := FLineNo;
+end;
+
+function StringToWordArray(Str: String; pWCharArray: PWordArray): Integer;
+var
+ i, j: Integer;
+ WChar: WChar_t;
+begin
+ i := 1;
+ j := 0;
+ WChar := GetWChar(Str, i);
+ while WChar <> 0 do begin
+ pWCharArray^[j] := WChar;
+ Inc(j);
+ WChar := GetWChar(Str, i);
+ end;
+ pWCharArray^[j] := 0;
+ result := j;
+end;
+
+constructor TGrep.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ ListOfFuzzyCharDic.Add(RE_FuzzyCharDic); {\83L\83\83\83\89\83N\83^\93¯\88ê\8e\8b\8e«\8f\91\82ð\92Ç\89Á}
+end;
+
+procedure TGrep.SetRegExp(Str: String);
+begin
+ inherited SetRegExp(Str);
+ if Self.RegExpIsSimple then
+ FGrepProc := GrepByStr
+ else
+ FGrepProc := GrepByRegExp;
+end;
+
+function TGrep.GetLineHeadWChar: WChar_t;
+begin
+ result := CONST_LF;
+end;
+
+function TGrep.GetLineTailWChar: WChar_t;
+begin
+ result := CONST_LF;
+end;
+
+procedure TGrep.GrepByRegExp(FileName: String);
+var
+ TxtFile: TTxtFile;
+ pDFAState,pInitialDFAState: RE_pDFAState_t;
+ LineInfo: RE_LineInfo_t;
+ DFA: TRE_DFA;
+ WChar: WChar_t;
+ pSub: RE_pDFAStateSub_t;
+begin
+ {OnMatch\83C\83x\83\93\83g\83n\83\93\83h\83\89\82ª\90Ý\92è\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Í\81A\89½\82à\82µ\82È\82¢}
+ if not Assigned(FOnMatch) then
+ exit;
+
+ FCancel := False;
+ DFA := GetCurrentDFA;
+ pInitialDFAState := DFA.pInitialState;
+ try
+ TxtFile := TTxtFile.Create(FileName, Self.FCancel);
+ except on EEndOfFile do exit; {\83t\83@\83C\83\8b\83T\83C\83Y\82O\82Ì\82Æ\82«\82Íexit} end;
+
+ try
+ try
+ {\8c\9f\8dõ}
+ while True do begin
+ repeat
+ WChar := TxtFile.AdvanceBase;
+ {\81«NextDFAState\83\81\83\\83b\83h\96\84\82ß\8d\9e\82Ý}
+ pDFAState := nil;
+ pSub := pInitialDFAState^.next;
+ while pSub <> nil do begin
+ if WChar < pSub^.CharClass.StartChar then
+ break
+ else if WChar <= pSub^.CharClass.EndChar then begin
+ pDFAState := pSub^.TransitTo;
+ break;
+ end;
+ pSub := pSub^.next;
+ end;
+ {\81ªNextDFAState\83\81\83\\83b\83h\96\84\82ß\8d\9e\82Ý}
+ until pDFAState <> nil;
+
+ while True do begin
+ if pDFAState^.accepted then begin
+ {\83}\83b\83`\82µ\82½}
+ LineInfo := TxtFile.GetThisLine;
+ FOnMatch(Self, LineInfo);
+ break;
+ end;
+
+ {DFA\82ð\8fó\91Ô\91J\88Ú\82³\82¹\82é}
+ pDFAState := NextDFAState(pDFAState, TxtFile.GetWChar);
+ if pDFAState = nil then begin
+ break;
+ end;
+ end;
+ end;
+ finally TxtFile.Free; end;
+ except on EEndOfFile do ; end; {Catch EEndOfFile}
+end;
+
+procedure TGrep.GrepByStr(FileName: String);
+var
+ TxtFile: TTxtFile;
+ Pattern: String;
+ pPat: PWordArray;
+ PatLen: Integer;
+ i: Integer;
+ LineInfo: RE_LineInfo_t;
+begin
+ FCancel := False;
+ Pattern := Self.SimpleRegExp;
+ {OnMatch\83C\83x\83\93\83g\83n\83\93\83h\83\89\82ª\90Ý\92è\82³\82ê\82Ä\82¢\82È\82¢\82Æ\82«\82Í\81A\89½\82à\82µ\82È\82¢}
+ if not Assigned(FOnMatch) then
+ exit;
+
+ try
+ TxtFile := TTxtFile.Create(FileName, Self.FCancel);
+ except on EEndOfFile do exit; {\83t\83@\83C\83\8b\83T\83C\83Y\82O\82Ì\82Æ\82«\82Íexit} end;
+
+ try
+ pPat := AllocMem(Length(Pattern)*2+2);
+ try
+ PatLen := StringToWordArray(Pattern, pPat);
+ try
+ while True do begin
+ while (TxtFile.AdvanceBase <> Word(pPat^[0])) do
+ ;
+ i := 1;
+ while True do begin
+ if i = PatLen then begin
+ LineInfo := TxtFile.GetThisLine;
+ FOnMatch(Self, LineInfo);
+ break;
+ end;
+ if TxtFile.GetWChar = Word(pPat^[i]) then
+ Inc(i)
+ else
+ break;
+ end;
+ end;
+ except on EEndOfFile do ;{Catch EEndOfFile} end;
+ finally FreeMem(pPat, Length(Pattern)*2+2); end;
+ finally TxtFile.Free; end;
+end;
+
+procedure MakeFuzzyCharDic;
+var
+ StrList: TStrings;
+ i: Integer;
+begin
+ RE_FuzzyCharDic := nil;
+ RE_FuzzyCharDic := TList.Create;
+
+ i := 0;
+ repeat
+ StrList := TStringList.Create;
+ try
+ RE_FuzzyCharDic.Add(StrList);
+ except
+ on Exception do begin
+ StrList.Free;
+ raise;
+ end;
+ end;
+
+ StrList.CommaText := REFuzzyWChars[i];
+ Inc(i);
+ until i > High(REFuzzyWChars);
+end;
+
+procedure DestroyFuzzyCharDic;
+var
+ i: Integer;
+begin
+ for i := 0 to RE_FuzzyCharDic.Count-1 do
+ TStringList(RE_FuzzyCharDic[i]).Free;
+ RE_FuzzyCharDic.Free;
+end;
+
+procedure Register;
+begin
+ RegisterComponents('RegExp', [TGrep, TAWKStr]);
+end;
+
+initialization
+ MakeFuzzyCharDic;
+
+finalization
+ DestroyFuzzyCharDic;
+
+end.