1 module dlex.Rule; 2 3 public import dlex.MatchResult, 4 dlex.Position; 5 6 abstract class Rule { 7 public: 8 alias ProcessFunc = dstring delegate(dstring); 9 10 bool skip = false; 11 ProcessFunc processFunc; 12 this() { 13 processFunc = null; 14 } 15 16 MatchResult match(dstring source, ref Position pos); 17 MatchResult matched(dstring source, ref Position pos) { 18 auto r = match(source, pos); 19 if (!r) { 20 return null; 21 } 22 if (processFunc) { 23 auto r2 = processFunc(r.str); 24 if (r2) { 25 return new MatchResult(r2, r.pos); 26 } 27 } 28 return r; 29 } 30 31 Rule opBinary(string op)(Rule rhs) { 32 static if (op == "+") { 33 return new SeqRule(this, rhs); 34 } 35 else static if (op == "|") { 36 return new SelectRule([this, rhs]); 37 } 38 else { 39 static assert(0, "operator " ~ op ~ " not implemented"); 40 } 41 } 42 43 Rule Repeat() { 44 return new RepeatRule(this); 45 } 46 47 Rule Skip() { 48 this.skip = true; 49 return this; 50 } 51 52 Rule As(ProcessFunc f) { 53 this.processFunc = f; 54 return this; 55 } 56 } 57 58 auto Any() { 59 return new AnyRule; 60 } 61 auto Char(dchar c) { 62 return new CharRule(c); 63 } 64 auto String(dstring str) { 65 return new StringRule(str); 66 } 67 auto Pred(bool function(dchar) pred) { 68 return new PredicateRule(pred); 69 } 70 auto Select(Rule[] rules ...) { 71 return new SelectRule(rules); 72 } 73 auto Between(Rule beginRule, Rule endRule, Rule innerRule) { 74 return new BetweenRule(beginRule, endRule, innerRule); 75 } 76 77 public import dlex.Rule.AnyRule, 78 dlex.Rule.CharRule, 79 dlex.Rule.StringRule, 80 dlex.Rule.PredicateRule, 81 dlex.Rule.SeqRule, 82 dlex.Rule.SelectRule, 83 dlex.Rule.RepeatRule, 84 dlex.Rule.BetweenRule; 85