4 * License : The MIT License
5 * Copyright(c) 2009 olyutorskii
8 package jp.sourceforge.jindolf.parser;
10 import java.util.regex.Pattern;
11 import jp.sourceforge.jindolf.corelib.EventFamily;
12 import jp.sourceforge.jindolf.corelib.GameRole;
13 import jp.sourceforge.jindolf.corelib.SysEventType;
14 import jp.sourceforge.jindolf.corelib.Team;
17 * 人狼BBSシステムが出力する各種イベント表記のパースを行うパーサ。
18 * パース進行に従い{@link SysEventHandler}の各種メソッドが呼び出される。
20 public class SysEventParser extends AbstractParser{
22 private static final String AVATAR_REGEX =
23 "[^<、" + SPCHAR + "]+\u0020[^<、。" + SPCHAR + "]+";
25 private static final Pattern C_DIV_PATTERN =
26 compile(SP_I+ "</div>" +SP_I);
27 private static final Pattern AVATAR_PATTERN =
28 compile(AVATAR_REGEX);
31 private SysEventHandler sysEventHandler;
33 private int pushedRegionStart = -1;
34 private int pushedRegionEnd = -1;
36 private final SeqRange rangepool_1 = new SeqRange();
37 private final SeqRange rangepool_2 = new SeqRange();
38 private final SeqRange rangepool_3 = new SeqRange();
44 public SysEventParser(ChainedParser parent){
50 * {@link SysEventHandler}ハンドラを登録する。
51 * @param sysEventHandler ハンドラ
53 public void setSysEventHandler(SysEventHandler sysEventHandler){
54 this.sysEventHandler = sysEventHandler;
59 * Announceメッセージをパースする。
60 * @throws HtmlParseException パースエラー
62 public void parseAnnounce() throws HtmlParseException{
63 setContextErrorMessage("Unknown Announce message");
65 this.sysEventHandler.startSysEvent(EventFamily.ANNOUNCE);
67 int regionStart = regionStart();
68 int regionEnd = regionEnd();
84 throw buildParseException();
87 getMatcher().region(regionStart, regionEnd);
90 lookingAtAffirm(C_DIV_PATTERN);
93 this.sysEventHandler.endSysEvent();
98 private static final Pattern STARTENTRY_PATTERN =
100 "昼間は人間のふりをして、夜に正体を現すという人狼。<br />"
102 +"この村に紛れ込んでいるという噂が広がった。<br /><br />"
104 +"村はずれの宿に集められることになった。"
106 private static final Pattern STARTMIRROR_PATTERN =
108 "さあ、自らの姿を鏡に映してみよう。<br />"
110 +"それとも血に飢えた人狼か。<br /><br />"
111 +"例え人狼でも、多人数で立ち向かえば怖くはない。<br />"
112 +"問題は、だれが人狼なのかという事だ。<br />"
113 +"占い師の能力を持つ人間ならば、それを見破れるだろう。"
115 private static final Pattern STARTASSAULT_PATTERN =
117 "ついに犠牲者が出た。人狼はこの村人達のなかにいる。<br />"
118 +"しかし、それを見分ける手段はない。<br /><br />"
119 +"村人達は、疑わしい者を排除するため、"
121 +"無実の犠牲者が出るのもやむをえない。"
122 +"村が全滅するよりは……。<br /><br />"
123 +"最後まで残るのは村人か、それとも人狼か。"
125 private static final Pattern NOMURDER_PATTERN =
127 "今日は犠牲者がいないようだ。人狼は襲撃に失敗したのだろうか。");
128 private static final Pattern WINVILLAGE_PATTERN =
130 "全ての人狼を退治した……。人狼に怯える日々は去ったのだ!"
132 private static final Pattern WINWOLF_PATTERN =
134 "もう人狼に抵抗できるほど村人は残っていない……。<br />"
136 +"別の獲物を求めてこの村を去っていった。"
138 private static final Pattern WINHAMSTER_PATTERN =
140 "全ては終わったかのように見えた。<br />"
142 private static final Pattern PANIC_PATTERN =
144 private static final Pattern SHORTMEMBER_PATTERN =
149 private static final Object[][] SIMPLE_REGEX_TO_TYPE = {
150 { STARTENTRY_PATTERN, SysEventType.STARTENTRY },
151 { STARTMIRROR_PATTERN, SysEventType.STARTMIRROR },
152 { STARTASSAULT_PATTERN, SysEventType.STARTASSAULT },
153 { NOMURDER_PATTERN, SysEventType.NOMURDER },
154 { WINVILLAGE_PATTERN, SysEventType.WINVILLAGE },
155 { WINWOLF_PATTERN, SysEventType.WINWOLF },
156 { WINHAMSTER_PATTERN, SysEventType.WINHAMSTER },
157 { PANIC_PATTERN, SysEventType.PANIC },
158 { SHORTMEMBER_PATTERN, SysEventType.SHORTMEMBER },
162 * 文字列が固定されたシンプルなAnnounceメッセージのパースを試みる。
164 * @throws HtmlParseException パースエラー
166 private boolean probeSimpleAnnounce() throws HtmlParseException{
171 SysEventType matchedType = null;
173 for(Object[] pair : SIMPLE_REGEX_TO_TYPE){
174 Pattern pattern = (Pattern) pair[0];
176 if(lookingAtProbe(pattern)){
178 matchedType = (SysEventType) pair[1];
183 if(matchedType == null){
188 this.sysEventHandler.sysEventType(matchedType);
195 private static final Pattern OPENROLE_HEAD_PATTERN =
196 compile("どうやらこの中には、");
197 private static final Pattern OPENROLE_NUM_PATTERN =
198 compile("が([0-9]+)名(?:、)?");
199 private static final Pattern OPENROLE_TAIL_PATTERN =
203 * OPENROLEメッセージのパースを試みる。
205 * @throws HtmlParseException パースエラー
207 private boolean probeOpenRole() throws HtmlParseException{
212 if( ! lookingAtProbe(OPENROLE_HEAD_PATTERN) ){
218 this.sysEventHandler.sysEventType(SysEventType.OPENROLE);
221 GameRole role = lookingAtRole();
223 if( lookingAtProbe(OPENROLE_TAIL_PATTERN) ){
232 if( ! lookingAtProbe(OPENROLE_NUM_PATTERN) ){
236 int num = parseGroupedInt(1);
239 this.sysEventHandler.sysEventOpenRole(role, num);
247 private static final Pattern SURVIVOR_HEAD_PATTERN =
249 private static final Pattern SURVIVOR_PATTERN =
251 "(" + AVATAR_REGEX + ")"
256 +"\u0020の\u0020([0-9]+)\u0020名。"
261 * SURVIVORメッセージのパースを試みる。
263 * @throws HtmlParseException パースエラー
265 private boolean probeSurvivor() throws HtmlParseException{
266 SeqRange avatarRange = this.rangepool_1;
272 if( ! lookingAtProbe(SURVIVOR_HEAD_PATTERN) ){
278 this.sysEventHandler.sysEventType(SysEventType.SURVIVOR);
282 if( ! lookingAtProbe(SURVIVOR_PATTERN) ){
286 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
288 .sysEventSurvivor(getContent(), avatarRange);
290 if(isGroupMatched(2)){
291 int num = parseGroupedInt(2);
293 if(num != avatarNum){
294 throw new HtmlParseException(regionStart());
306 private static final Pattern MURDERED_HEAD_PATTERN =
308 private static final Pattern MURDERED_SW_PATTERN =
313 +"\u0020が無残な姿で発見された。"
314 +"(?:<br />)?" // E国対策
319 * MURDEREDメッセージのパースを試みる。
321 * @throws HtmlParseException パースエラー
323 private boolean probeMurdered() throws HtmlParseException{
324 SeqRange avatarRange = this.rangepool_1;
325 SeqRange avatarRange2 = this.rangepool_2;
326 avatarRange .setInvalid();
327 avatarRange2.setInvalid();
333 if( ! lookingAtProbe(MURDERED_HEAD_PATTERN)){
339 this.sysEventHandler.sysEventType(SysEventType.MURDERED);
342 if( ! lookingAtProbe(AVATAR_PATTERN)){
346 if( ! avatarRange.isValid() ){
347 avatarRange.setLastMatchedRange(getMatcher());
348 }else if( ! avatarRange2.isValid() ){
349 avatarRange2.setLastMatchedRange(getMatcher());
352 throw buildParseException();
356 if( ! lookingAtProbe(MURDERED_SW_PATTERN)){
360 if(isGroupMatched(1)){
363 }else if(isGroupMatched(2)){
368 throw buildParseException();
373 .sysEventMurdered(getContent(), avatarRange);
374 if(avatarRange2.isValid()){
376 .sysEventMurdered(getContent(), avatarRange2);
384 private static final Pattern ONSTAGE_NO_PATTERN =
385 compile("([0-9]+)人目、");
386 private static final Pattern ONSTAGE_DOT_PATTERN =
389 +"(?:" + AVATAR_REGEX + ")"
390 +"|)" // F1556プロローグ対策
394 * ONSTAGEメッセージのパースを試みる。
396 * @throws HtmlParseException パースエラー
398 private boolean probeOnStage() throws HtmlParseException{
399 SeqRange avatarRange = this.rangepool_1;
405 if( ! lookingAtProbe(ONSTAGE_NO_PATTERN) ){
409 int entryNo = parseGroupedInt(1);
412 this.sysEventHandler.sysEventType(SysEventType.ONSTAGE);
414 if( ! lookingAtProbe(ONSTAGE_DOT_PATTERN) ){
418 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
422 .sysEventOnStage(getContent(), entryNo, avatarRange);
429 private static final Pattern SUDDENDEATH_PATTERN =
432 +"(?:" + AVATAR_REGEX + ")"
438 * SUDDENDEATHメッセージのパースを試みる。
440 * @throws HtmlParseException パースエラー
442 private boolean probeSuddenDeath() throws HtmlParseException{
443 SeqRange avatarRange = this.rangepool_1;
449 if( ! lookingAtProbe(SUDDENDEATH_PATTERN)){
453 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
456 this.sysEventHandler.sysEventType(SysEventType.SUDDENDEATH);
458 .sysEventSuddenDeath(getContent(), avatarRange);
465 private static final Pattern COUNTING_PATTERN =
469 +"(" + AVATAR_REGEX + ")"
470 +"\u0020は村人達の手により処刑された。"
472 +"(" + AVATAR_REGEX + ")"
474 +"(" + AVATAR_REGEX + ")"
481 * COUNTINGメッセージのパースを試みる。
483 * @throws HtmlParseException パースエラー
485 private boolean probeCounting() throws HtmlParseException{
486 SeqRange voteByRange = this.rangepool_1;
487 SeqRange voteToRange = this.rangepool_2;
493 boolean hasVote = false;
495 if( ! lookingAtProbe(COUNTING_PATTERN) ){
498 if(isGroupMatched(1)){
499 voteByRange.setInvalid();
500 voteToRange.setLastMatchedGroupRange(getMatcher(), 1);
503 .sysEventCounting(getContent(),
507 }else if(isGroupMatched(2)){
510 this.sysEventHandler.sysEventType(SysEventType.COUNTING);
512 voteByRange.setLastMatchedGroupRange(getMatcher(), 2);
513 voteToRange.setLastMatchedGroupRange(getMatcher(), 3);
516 .sysEventCounting(getContent(),
521 throw buildParseException();
535 private static final Pattern COUNTING2_PATTERN =
537 "(" + AVATAR_REGEX + ")"
539 +"(" + AVATAR_REGEX + ")"
545 * COUNTING2メッセージのパースを試みる。
547 * @throws HtmlParseException パースエラー
549 private boolean probeCounting2() throws HtmlParseException{
550 SeqRange voteByRange = this.rangepool_1;
551 SeqRange voteToRange = this.rangepool_2;
557 boolean hasVote = false;
559 if( ! lookingAtProbe(COUNTING2_PATTERN) ){
564 this.sysEventHandler.sysEventType(SysEventType.COUNTING2);
566 voteByRange.setLastMatchedGroupRange(getMatcher(), 1);
567 voteToRange.setLastMatchedGroupRange(getMatcher(), 2);
570 .sysEventCounting2(getContent(),
585 private static final Pattern PLAYERID_PATTERN =
587 "\u0020\uff08" // 全角開き括弧
588 +"(?:<a\u0020href=\"([^\"]*)\">)?"
593 private static final Pattern LIVEORDIE_PATTERN =
597 private static final Pattern PLAYER_DELIM_PATTERN =
604 * PLAYERLISTメッセージのパースを試みる。
606 * @throws HtmlParseException パースエラー
608 private boolean probePlayerList() throws HtmlParseException{
609 SeqRange avatarRange = this.rangepool_1;
610 SeqRange anchorRange = this.rangepool_2;
611 SeqRange accountRange = this.rangepool_3;
617 boolean hasPlayerList = false;
620 if( ! lookingAtProbe(AVATAR_PATTERN)){
623 avatarRange.setLastMatchedRange(getMatcher());
626 if( ! lookingAtProbe(PLAYERID_PATTERN)){
630 if(isGroupMatched(1)){
631 anchorRange.setLastMatchedGroupRange(getMatcher(), 1);
633 anchorRange.setInvalid();
635 accountRange.setLastMatchedGroupRange(getMatcher(), 2);
638 boolean isLiving = false;
639 if( ! lookingAtProbe(LIVEORDIE_PATTERN)){
643 if(isGroupMatched(1)){
645 }else if(isGroupMatched(2)){
650 GameRole role = lookingAtRole();
657 if( ! lookingAtProbe(PLAYER_DELIM_PATTERN)){
663 if( ! hasPlayerList ){
664 hasPlayerList = true;
665 this.sysEventHandler.sysEventType(SysEventType.PLAYERLIST);
669 .sysEventPlayerList(getContent(),
677 if( ! hasPlayerList ){
687 private static final Pattern EXECUTION_PATTERN =
690 + "(" + AVATAR_REGEX + ")、([0-9]+)票。(?:<br />)?"
692 +"<br />(" + AVATAR_REGEX + ")\u0020は"
698 * EXECUTIONメッセージのパースを試みる。
700 * @throws HtmlParseException パースエラー
702 private boolean probeExecution() throws HtmlParseException{
703 SeqRange avatarRange = this.rangepool_1;
709 boolean hasExecution = false;
712 if( ! lookingAtProbe(EXECUTION_PATTERN)){
716 if( ! hasExecution ){
718 this.sysEventHandler.sysEventType(SysEventType.EXECUTION);
721 if(isGroupMatched(1)){
722 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
723 int votes = parseGroupedInt(2);
726 .sysEventExecution(getContent(),
729 }else if(isGroupMatched(3)){
730 avatarRange.setLastMatchedGroupRange(getMatcher(), 3);
733 .sysEventExecution(getContent(),
739 if( ! hasExecution ){
749 private static final Pattern VANISH_PATTERN =
752 +"(" + AVATAR_REGEX + ")"
758 * VANISHメッセージのパースを試みる。
760 * @throws HtmlParseException パースエラー
762 private boolean probeVanish() throws HtmlParseException{
763 SeqRange avatarRange = this.rangepool_1;
769 boolean hasVanish = false;
772 if( ! lookingAtProbe(VANISH_PATTERN)){
778 this.sysEventHandler.sysEventType(SysEventType.VANISH);
780 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
785 .sysEventVanish(getContent(), avatarRange);
798 private static final Pattern CHECKOUT_PATTERN =
801 +"(" + AVATAR_REGEX + ")"
807 * CHECKOUTメッセージのパースを試みる。
809 * @throws HtmlParseException パースエラー
811 private boolean probeCheckout() throws HtmlParseException{
812 SeqRange avatarRange = this.rangepool_1;
818 boolean hasCheckout = false;
821 if( ! lookingAtProbe(CHECKOUT_PATTERN)){
827 this.sysEventHandler.sysEventType(SysEventType.CHECKOUT);
829 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
834 .sysEventCheckout(getContent(), avatarRange);
849 * @throws HtmlParseException パースエラー
851 public void parseOrder() throws HtmlParseException{
852 setContextErrorMessage("Unknown Order message");
854 this.sysEventHandler.startSysEvent(EventFamily.ORDER);
856 int regionStart = regionStart();
857 int regionEnd = regionEnd();
863 || probeStayEpilogue()
867 throw buildParseException();
870 getMatcher().region(regionStart, regionEnd);
873 lookingAtAffirm(C_DIV_PATTERN);
876 this.sysEventHandler.endSysEvent();
881 private static final Pattern ASKENTRY_PATTERN =
883 "演じたいキャラクターを選び、発言してください。<br />"
884 +"([0-2][0-9]):([0-5][0-9])\u0020に"
885 +"([0-9]+)名以上がエントリーしていれば進行します。<br />"
886 +"最大([0-9]+)名まで参加可能です。<br /><br />"
887 +"※[\u0020]?エントリーは取り消せません。"
888 +"ルールをよく理解した上でご参加下さい。<br />"
889 +"(?:※始めての方は、村人希望での参加となります。<br />)?"
890 +"(?:※希望能力についての発言は控えてください。<br />)?"
894 * ASKENTRYメッセージのパースを試みる。
896 * @throws HtmlParseException パースエラー
898 private boolean probeAskEntry() throws HtmlParseException{
903 if( ! lookingAtProbe(ASKENTRY_PATTERN)){
908 int hour = parseGroupedInt(1);
909 int minute = parseGroupedInt(2);
910 int minLimit = parseGroupedInt(3);
911 int maxLimit = parseGroupedInt(4);
915 this.sysEventHandler.sysEventType(SysEventType.ASKENTRY);
917 .sysEventAskEntry(hour, minute, minLimit, maxLimit);
924 private static final Pattern ASKCOMMIT_PATTERN =
927 +"([0-2][0-9]):([0-5][0-9])\u0020までに、"
928 +"誰を処刑するべきかの投票先を決定して下さい。<br />"
930 +"同数だった場合はランダムで決定されます。<br /><br />"
933 +"([0-2][0-9]):([0-5][0-9])\u0020までに"
938 * ASKCOMMITメッセージのパースを試みる。
940 * @throws HtmlParseException パースエラー
942 private boolean probeAskCommit() throws HtmlParseException{
947 if( ! lookingAtProbe(ASKCOMMIT_PATTERN)){
953 if(isGroupMatched(1)){
959 int hh1 = parseGroupedInt(1);
960 int mm1 = parseGroupedInt(2);
961 int hh2 = parseGroupedInt(3);
962 int mm2 = parseGroupedInt(4);
966 if( ! is1stDay && (hh1 != hh2 || mm1 != mm2) ){
967 throw new HtmlParseException(regionStart());
970 this.sysEventHandler.sysEventType(SysEventType.ASKCOMMIT);
971 this.sysEventHandler.sysEventAskCommit(hh2, mm2);
978 private static final Pattern NOCOMMENT_HEAD_PATTERN =
979 compile("本日まだ発言していない者は、");
980 private static final Pattern NOCOMMENT_AVATAR_PATTERN =
983 +"(" + AVATAR_REGEX + ")、"
985 +"以上\u0020([0-9]+)\u0020名。"
990 * NOCOMMENTメッセージのパースを試みる。
992 * @throws HtmlParseException パースエラー
994 private boolean probeNoComment() throws HtmlParseException{
995 SeqRange avatarRange = this.rangepool_1;
1001 if( ! lookingAtProbe(NOCOMMENT_HEAD_PATTERN)){
1007 this.sysEventHandler.sysEventType(SysEventType.NOCOMMENT);
1011 if( ! lookingAtProbe(NOCOMMENT_AVATAR_PATTERN)){
1016 if(isGroupMatched(1)){
1017 avatarRange.setLastMatchedGroupRange(getMatcher(), 1);
1018 this.sysEventHandler
1019 .sysEventNoComment(getContent(), avatarRange);
1022 }else if(isGroupMatched(2)){
1023 int num = parseGroupedInt(2);
1025 if(num != avatarNum){
1026 throw new HtmlParseException(regionStart());
1037 private static final Pattern STAYEPILOGUE_PATTERN =
1039 "(?:(村人)|(人狼)|(ハムスター))側の勝利です!<br />"
1040 +"全てのログとユーザー名を公開します。"
1041 +"([0-2][0-9]):([0-5][0-9])\u0020まで"
1043 +"今回の感想などをどうぞ。<br />"
1047 * STAYEPILOGUEメッセージのパースを試みる。
1048 * @return マッチしたらtrue
1049 * @throws HtmlParseException パースエラー
1051 private boolean probeStayEpilogue() throws HtmlParseException{
1056 if( ! lookingAtProbe(STAYEPILOGUE_PATTERN)){
1062 if(isGroupMatched(1)){
1063 winner = Team.VILLAGE;
1064 }else if(isGroupMatched(2)){
1066 }else if(isGroupMatched(3)){
1067 winner = Team.HAMSTER;
1070 int hour = parseGroupedInt(4);
1071 int minute = parseGroupedInt(5);
1075 this.sysEventHandler.sysEventType(SysEventType.STAYEPILOGUE);
1076 this.sysEventHandler.sysEventStayEpilogue(winner, hour, minute);
1083 private static final Pattern GAMEOVER_PATTERN =
1084 compile("終了しました。" + "<br />");
1087 * GAMEOVERメッセージのパースを試みる。
1088 * @return マッチしたらtrue
1089 * @throws HtmlParseException パースエラー
1091 private boolean probeGameOver() throws HtmlParseException{
1096 if( ! lookingAtProbe(GAMEOVER_PATTERN)){
1103 this.sysEventHandler.sysEventType(SysEventType.GAMEOVER);
1112 * @throws HtmlParseException パースエラー
1114 public void parseExtra() throws HtmlParseException{
1115 setContextErrorMessage("Unknown Extra message");
1117 this.sysEventHandler.startSysEvent(EventFamily.EXTRA);
1119 int regionStart = regionStart();
1120 int regionEnd = regionEnd();
1125 || probeCounting2();
1127 throw buildParseException();
1130 getMatcher().region(regionStart, regionEnd);
1133 lookingAtAffirm(C_DIV_PATTERN);
1136 this.sysEventHandler.endSysEvent();
1141 private static final Pattern JUDGE_DELIM_PATTERN =
1142 compile("\u0020は、");
1143 private static final Pattern JUDGE_TAIL_PATTERN =
1144 compile("\u0020を占った。");
1147 * JUDGEメッセージのパースを試みる。
1148 * @return マッチしたらtrue
1149 * @throws HtmlParseException パースエラー
1151 private boolean probeJudge() throws HtmlParseException{
1152 SeqRange judgeByRange = this.rangepool_1;
1153 SeqRange judgeToRange = this.rangepool_2;
1159 if( ! lookingAtProbe(AVATAR_PATTERN)){
1163 judgeByRange.setLastMatchedRange(getMatcher());
1166 if( ! lookingAtProbe(JUDGE_DELIM_PATTERN)){
1172 if( ! lookingAtProbe(AVATAR_PATTERN)){
1176 judgeToRange.setLastMatchedRange(getMatcher());
1179 if( ! lookingAtProbe(JUDGE_TAIL_PATTERN)){
1185 this.sysEventHandler.sysEventType(SysEventType.JUDGE);
1186 this.sysEventHandler
1187 .sysEventJudge(getContent(),
1195 private static final Pattern GUARD_DELIM_PATTERN =
1196 compile("\u0020は、");
1197 private static final Pattern GUARD_TAIL_PATTERN =
1198 compile("\u0020を守っている。");
1201 * GUARDメッセージのパースを試みる。
1202 * @return マッチしたらtrue
1203 * @throws HtmlParseException パースエラー
1205 private boolean probeGuard() throws HtmlParseException{
1206 SeqRange guardByRange = this.rangepool_1;
1207 SeqRange guardToRange = this.rangepool_2;
1213 if( ! lookingAtProbe(AVATAR_PATTERN)){
1217 guardByRange.setLastMatchedRange(getMatcher());
1220 if( ! lookingAtProbe(GUARD_DELIM_PATTERN)){
1226 if( ! lookingAtProbe(AVATAR_PATTERN)){
1230 guardToRange.setLastMatchedRange(getMatcher());
1233 if( ! lookingAtProbe(GUARD_TAIL_PATTERN)){
1239 this.sysEventHandler.sysEventType(SysEventType.GUARD);
1240 this.sysEventHandler.sysEventGuard(getContent(),
1248 private static final Pattern CONTENT_PATTERN =
1255 +"<a\u0020href=\"([^\"]*)\">([^<>]*)</a>"
1260 * システムイベントの内容文字列をパースする。
1261 * @throws HtmlParseException パースエラー
1263 private void parseContent() throws HtmlParseException{
1264 SeqRange anchorRange = this.rangepool_1;
1265 SeqRange contentRange = this.rangepool_2;
1270 if( ! lookingAtProbe(CONTENT_PATTERN) ){
1274 if(isGroupMatched(1)){
1275 contentRange.setLastMatchedGroupRange(getMatcher(), 1);
1276 this.sysEventHandler
1277 .sysEventContent(getContent(), contentRange);
1278 }else if(isGroupMatched(2)){
1279 this.sysEventHandler.sysEventContentBreak();
1280 }else if(isGroupMatched(3)){
1281 anchorRange.setLastMatchedGroupRange(getMatcher(), 3);
1282 contentRange.setLastMatchedGroupRange(getMatcher(), 4);
1283 this.sysEventHandler
1284 .sysEventContentAnchor(getContent(),
1299 * 待避できるのは1回のみ。複数回スタックはできない。
1302 private void pushRegion(){
1303 this.pushedRegionStart = regionStart();
1304 this.pushedRegionEnd = regionEnd();
1309 * 一時的に待避した検索領域を復活させる。
1310 * @throws IllegalStateException まだ何も待避していない。
1311 * @see #pushRegion()
1313 private void popRegion() throws IllegalStateException{
1314 if(this.pushedRegionStart < 0 || this.pushedRegionEnd < 0){
1315 throw new IllegalStateException();
1318 if( this.pushedRegionStart != regionStart()
1319 || this.pushedRegionEnd != regionEnd() ){
1320 getMatcher().region(this.pushedRegionStart, this.pushedRegionEnd);
1323 this.pushedRegionStart = -1;
1324 this.pushedRegionEnd = -1;