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