Repository navigation
Expand file tree
/
Copy pathAbstractPatternParser.cs
More file actions
105 lines (93 loc) · 3.55 KB
/
Copy pathAbstractPatternParser.cs
File metadata and controls
105 lines (93 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
namespace Cecil.AspectN
{
public abstract class AbstractPatternParser<TMatcher>
{
protected abstract TMatcher NewNotMatcher(TMatcher matcher);
protected abstract TMatcher NewAndMatcher(TMatcher matcher1, TMatcher matcher2);
protected abstract TMatcher NewOrMatcher(TMatcher matcher1, TMatcher matcher2);
protected abstract TMatcher ParseSingle(string pattern, ref int index);
public TMatcher ParsePattern(string pattern)
{
var index = 0;
return ParsePattern(pattern, ref index);
}
protected virtual TMatcher ParsePattern(string pattern, ref int index)
{
var not = ParseNot(pattern, ref index);
var matcher = ParseSingle(pattern, ref index);
if (not) matcher = NewNotMatcher(matcher);
var connector = ParseConnector(pattern, ref index);
if (connector == Connector.And)
{
matcher = NewAndMatcher(matcher, ParseNotOr(pattern, ref index, out connector));
}
if (connector == Connector.Or)
{
matcher = NewOrMatcher(matcher, ParsePattern(pattern, ref index));
}
return matcher;
}
protected virtual TMatcher ParseNotOr(string pattern, ref int index, out Connector connector)
{
var not = ParseNot(pattern, ref index);
var matcher = ParseSingle(pattern, ref index);
if (not) matcher = NewNotMatcher(matcher);
connector = ParseConnector(pattern, ref index);
if (connector == Connector.And)
{
matcher = NewAndMatcher(matcher, ParseNotOr(pattern, ref index, out connector));
}
return matcher;
}
protected virtual bool ParseNot(string pattern, ref int index)
{
var stash = index;
while (index < pattern.Length)
{
var ch = pattern[index++];
if (ch.IsWhiteSpace()) continue;
if (ch == '!') return true;
break;
}
index = stash;
return false;
}
protected virtual Connector ParseConnector(string pattern, ref int index)
{
while (index < pattern.Length)
{
var ch = pattern[index++];
if (ch.IsWhiteSpace()) continue;
if (ch == '&')
{
if (index < pattern.Length)
{
var next = pattern[index++];
if (next == '&') return Connector.And;
throw new ArgumentException($"Unexpected AND connector symbol '{next}' at index {index} of {pattern}");
}
return Connector.Eof;
}
if (ch == '|')
{
if (index < pattern.Length)
{
var next = pattern[index++];
if (next == '|') return Connector.Or;
throw new ArgumentException($"Unexpected OR connector symbol '{next}' at index {index} of {pattern}");
}
return Connector.Eof;
}
throw new ArgumentException($"Unexpected connector symbol '{ch}' at index {index} of {pattern}");
}
return Connector.Eof;
}
protected enum Connector
{
Eof,
And,
Or,
}
}
}