-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathQueryParser.cs
146 lines (123 loc) · 4.14 KB
/
QueryParser.cs
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.Collections.Generic;
namespace Unitinium
{
public class QueryParser : IQueryParser
{
public QueryAstBase[] Parse(object[] tokens)
{
var tokenQueue = new Queue<object>(tokens);
var nodeList = new List<QueryAstBase>();
while (tokenQueue.Count > 0)
{
var token = tokenQueue.Dequeue();
if (token is QuerySpecialToken specialToken)
{
var node = ProcessOperator(specialToken, tokenQueue);
nodeList.Add(node);
continue;
}
string name = null;
if (token is string idValue)
{
name = idValue;
}
else if (token is int idIntValue)
{
name = idIntValue.ToString();
}
if (name != null)
{
nodeList.Add(new QueryNameAst
{
Value = name
});
continue;
}
throw new QueryGrammarException($"Not expected {token}");
}
return nodeList.ToArray();
}
private QueryAstBase ProcessOperator(QuerySpecialToken token, Queue<object> tokenQueue)
{
if (token.Value == "$")
{
return ProcessGlobaFilter(tokenQueue);
}
if (token.Value == "#")
{
return ProcessComponentFilter(tokenQueue);
}
if (token.Value == ".")
{
return new QueryFirstExpandAst();
}
if (token.Value == "[")
{
return ProcessIndex(tokenQueue);
}
if (token.Value == "@")
{
return ProcessName(tokenQueue);
}
throw new QueryGrammarException($"Not expected operator {token.Value}");
}
private QueryAstBase ProcessName(Queue<object> tokenQueue)
{
var name = tokenQueue.Dequeue();
if (name is string | name is int)
{
return new QueryNameAst
{
Value = name
};
}
throw new QueryGrammarException($"Expected identifier after @ operator");
}
private QueryAstBase ProcessIndex(Queue<object> tokenQueue)
{
var intValue = Dequeue(tokenQueue, "number");
var end = Dequeue(tokenQueue, "]");
if (intValue is int && end is QuerySpecialToken endValue && endValue.Value == "]")
{
return new QueryIndexAst
{
Value = intValue
};
}
throw new QueryGrammarException($"Expected number in [] operator");
}
private QueryAstBase ProcessComponentFilter(Queue<object> tokenQueue)
{
var name = Dequeue(tokenQueue, "identifier");
if (name is string value)
{
return new QueryComponentAst()
{
Value = value
};
}
throw new QueryGrammarException($"Expected identifier after # operator");
}
private QueryAstBase ProcessGlobaFilter(Queue<object> tokenQueue)
{
var name = tokenQueue.Dequeue();
if (name is string | name is int)
{
return new QueryGlobalAst
{
Value = name
};
}
throw new QueryGrammarException($"Expected identifier after $ operator");
}
private object Dequeue(Queue<object> tokenQueue, string expected)
{
if (tokenQueue.Count <= 0)
{
throw new QueryGrammarException($"Ecpected {expected}, but fount end of query");
}
return tokenQueue.Dequeue();
}
}
}