1 module zua.pattern.parser;
2 import zua.pattern;
3 import std.bitmanip;
4 
5 /** A pattern parser */
6 final class Parser {
7 	private string pattern;
8 	private size_t index;
9 
10 	/** Create a new Parser */
11 	this(string pattern) {
12 		this.pattern = pattern;
13 	}
14 
15 private:
16 
17 	bool eof() {
18 		return index >= pattern.length;
19 	}
20 
21 	char nextChar() {
22 		return pattern[index++];
23 	}
24 
25 	char peekChar() {
26 		return pattern[index];
27 	}
28 
29 	CharClass nextCharClass(bool sqBracket = true) {
30 		char c = nextChar();
31 		if (c == '%') {
32 			if (eof) {
33 				throw new PatternError("malformed pattern (ends with '%')");
34 			}
35 			char nc = nextChar();
36 			BitArray set;
37 			set.length = 256;
38 			switch (nc) {
39 			case 'a':
40 				set['a' .. 'z' + 1] = true;
41 				set['A' .. 'Z' + 1] = true;
42 				break;
43 			case 'c':
44 				set[0 .. 0x1f + 1] = true;
45 				set[0x7f] = true;
46 				break;
47 			case 'd':
48 				set['0' .. '9' + 1] = true;
49 				break;
50 			default:
51 				LiteralChar res = new LiteralChar;
52 				res.value = nc;
53 				return res;
54 			}
55 			SetClass res = new SetClass;
56 			res.set = set;
57 			return res;
58 		}
59 		else if (c == '.') {
60 			BitArray set;
61 			set.length = 256;
62 			set[] = true;
63 			SetClass res = new SetClass;
64 			res.set = set;
65 			return res;
66 		}
67 		else if (c == '[' && sqBracket) {
68 			if (eof) {
69 				throw new PatternError("malformed pattern (missing ']')");
70 			}
71 			char fc = peekChar();
72 			bool complement = false;
73 			if (fc == '^') {
74 				nextChar();
75 				complement = true;
76 			}
77 			BitArray set;
78 			size_t save = index;
79 			CharClass first = nextCharClass(false);
80 			if (save + 1 == index) {
81 				
82 			}
83 			if (complement) set.flip();
84 			SetClass res = new SetClass;
85 			res.set = set;
86 			return res;
87 		}
88 		else {
89 			LiteralChar res = new LiteralChar;
90 			res.value = c;
91 			return res;
92 		}
93 	}
94 
95 }