module dlex.Rule.BetweenRule; import dlex.Rule; class BetweenRule : Rule { public: Rule beginRule; Rule endRule; Rule innerRule; this (Rule beginRule, Rule endRule, Rule innerRule) { this.beginRule = beginRule; this.endRule = endRule; this.innerRule = innerRule; } override MatchResult match(dstring source, ref Position pos) { auto prevPos = pos; // begin がマッチ auto beginR = beginRule.matched(source, pos); if (!beginR) { pos = prevPos; return null; } auto str = beginR.str; while (true) { auto save = pos; // end がマッチしたら返る auto endR = endRule.matched(source, pos); if (endR) { str ~= endR.str; break; } pos = save; // innerがマッチしなかったらそもそもダメ auto innerR = innerRule.matched(source, pos); if (! innerR) { pos = prevPos; return null; } str ~= innerR.str; } return new MatchResult(str, prevPos); } }