Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ExpressionParser.cs
Go to the documentation of this file.
3
4namespace System.Data;
5
6internal sealed class ExpressionParser
7{
8 private readonly struct ReservedWords
9 {
10 internal readonly string _word;
11
12 internal readonly Tokens _token;
13
14 internal readonly int _op;
15
16 internal ReservedWords(string word, Tokens token, int op)
17 {
18 _word = word;
19 _token = token;
20 _op = op;
21 }
22 }
23
24 private static readonly ReservedWords[] s_reservedwords = new ReservedWords[12]
25 {
26 new ReservedWords("And", Tokens.BinaryOp, 26),
27 new ReservedWords("Between", Tokens.BinaryOp, 6),
28 new ReservedWords("Child", Tokens.Child, 0),
29 new ReservedWords("False", Tokens.ZeroOp, 34),
30 new ReservedWords("In", Tokens.BinaryOp, 5),
31 new ReservedWords("Is", Tokens.BinaryOp, 13),
32 new ReservedWords("Like", Tokens.BinaryOp, 14),
33 new ReservedWords("Not", Tokens.UnaryOp, 3),
34 new ReservedWords("Null", Tokens.ZeroOp, 32),
35 new ReservedWords("Or", Tokens.BinaryOp, 27),
36 new ReservedWords("Parent", Tokens.Parent, 0),
37 new ReservedWords("True", Tokens.ZeroOp, 33)
38 };
39
40 private readonly char _escape = '\\';
41
42 private readonly char _decimalSeparator = '.';
43
44 private readonly char _listSeparator = ',';
45
46 private readonly char _exponentL = 'e';
47
48 private readonly char _exponentU = 'E';
49
50 internal char[] _text;
51
52 internal int _pos;
53
54 internal int _start;
55
56 internal Tokens _token;
57
58 internal int _op;
59
60 internal OperatorInfo[] _ops = new OperatorInfo[100];
61
62 internal int _topOperator;
63
64 internal int _topNode;
65
66 private readonly DataTable _table;
67
69
70 internal int _prevOperand;
71
73
75 {
76 _table = table;
77 }
78
79 internal void LoadExpression(string data)
80 {
81 int num;
82 if (data == null)
83 {
84 num = 0;
85 _text = new char[num + 1];
86 }
87 else
88 {
89 num = data.Length;
90 _text = new char[num + 1];
91 data.CopyTo(0, _text, 0, num);
92 }
93 _text[num] = '\0';
94 if (_expression != null)
95 {
96 _expression = null;
97 }
98 }
99
100 internal void StartScan()
101 {
102 _op = 0;
103 _pos = 0;
104 _start = 0;
105 _topOperator = 0;
106 _ops[_topOperator++] = new OperatorInfo(Nodes.Noop, 0, 0);
107 }
108
110 {
111 _expression = null;
112 StartScan();
113 int num = 0;
114 while (_token != Tokens.EOS)
115 {
116 while (true)
117 {
118 Scan();
119 switch (_token)
120 {
121 case Tokens.EOS:
122 break;
123 case Tokens.Name:
124 case Tokens.Numeric:
125 case Tokens.Decimal:
126 case Tokens.Float:
127 case Tokens.StringConst:
128 case Tokens.Date:
129 case Tokens.Parent:
130 {
131 ExpressionNode node = null;
132 string text = null;
133 if (_prevOperand != 0)
134 {
135 throw ExprException.MissingOperator(new string(_text, _start, _pos - _start));
136 }
137 if (_topOperator > 0)
138 {
139 OperatorInfo operatorInfo = _ops[_topOperator - 1];
140 if (operatorInfo._type == Nodes.Binop && operatorInfo._op == 5 && _token != Tokens.Parent)
141 {
143 }
144 }
145 _prevOperand = 1;
146 switch (_token)
147 {
148 case Tokens.Parent:
149 {
150 string relationName;
151 try
152 {
153 Scan();
154 if (_token == Tokens.LeftParen)
155 {
156 ScanToken(Tokens.Name);
157 relationName = NameNode.ParseName(_text, _start, _pos);
158 ScanToken(Tokens.RightParen);
159 ScanToken(Tokens.Dot);
160 }
161 else
162 {
163 relationName = null;
164 CheckToken(Tokens.Dot);
165 }
166 }
167 catch (Exception e) when (ADP.IsCatchableExceptionType(e))
168 {
170 }
171 ScanToken(Tokens.Name);
172 string columnName = NameNode.ParseName(_text, _start, _pos);
173 OperatorInfo operatorInfo = _ops[_topOperator - 1];
174 node = new LookupNode(_table, columnName, relationName);
175 break;
176 }
177 case Tokens.Name:
178 {
179 OperatorInfo operatorInfo = _ops[_topOperator - 1];
180 node = new NameNode(_table, _text, _start, _pos);
181 break;
182 }
183 case Tokens.Numeric:
184 text = new string(_text, _start, _pos - _start);
185 node = new ConstNode(_table, ValueType.Numeric, text);
186 break;
187 case Tokens.Decimal:
188 text = new string(_text, _start, _pos - _start);
189 node = new ConstNode(_table, ValueType.Decimal, text);
190 break;
191 case Tokens.Float:
192 text = new string(_text, _start, _pos - _start);
193 node = new ConstNode(_table, ValueType.Float, text);
194 break;
195 case Tokens.StringConst:
196 text = new string(_text, _start + 1, _pos - _start - 2);
197 node = new ConstNode(_table, ValueType.Str, text);
198 break;
199 case Tokens.Date:
200 text = new string(_text, _start + 1, _pos - _start - 2);
201 node = new ConstNode(_table, ValueType.Date, text);
202 break;
203 }
204 NodePush(node);
205 continue;
206 }
207 case Tokens.LeftParen:
208 {
209 num++;
210 ExpressionNode node;
211 if (_prevOperand == 0)
212 {
213 OperatorInfo operatorInfo = _ops[_topOperator - 1];
214 if (operatorInfo._type == Nodes.Binop && operatorInfo._op == 5)
215 {
216 node = new FunctionNode(_table, "In");
217 NodePush(node);
218 _ops[_topOperator++] = new OperatorInfo(Nodes.Call, 0, 2);
219 }
220 else
221 {
222 _ops[_topOperator++] = new OperatorInfo(Nodes.Paren, 0, 2);
223 }
224 continue;
225 }
226 BuildExpression(22);
227 _prevOperand = 0;
228 ExpressionNode expressionNode2 = NodePeek();
229 if (expressionNode2 == null || expressionNode2.GetType() != typeof(NameNode))
230 {
232 }
233 NameNode nameNode2 = (NameNode)NodePop();
234 node = new FunctionNode(_table, nameNode2._name);
235 Aggregate aggregate = (Aggregate)((FunctionNode)node).Aggregate;
236 if (aggregate != Aggregate.None)
237 {
238 node = ParseAggregateArgument((FunctionId)aggregate);
239 NodePush(node);
240 _prevOperand = 2;
241 }
242 else
243 {
244 NodePush(node);
245 _ops[_topOperator++] = new OperatorInfo(Nodes.Call, 0, 2);
246 }
247 continue;
248 }
249 case Tokens.RightParen:
250 {
251 if (_prevOperand != 0)
252 {
254 }
255 if (_topOperator <= 1)
256 {
258 }
259 _topOperator--;
260 OperatorInfo operatorInfo = _ops[_topOperator];
261 if (_prevOperand == 0 && operatorInfo._type != Nodes.Call)
262 {
263 throw ExprException.MissingOperand(operatorInfo);
264 }
265 if (operatorInfo._type == Nodes.Call)
266 {
267 if (_prevOperand != 0)
268 {
269 ExpressionNode argument2 = NodePop();
270 FunctionNode functionNode2 = (FunctionNode)NodePop();
271 functionNode2.AddArgument(argument2);
272 functionNode2.Check();
273 NodePush(functionNode2);
274 }
275 }
276 else
277 {
278 ExpressionNode node = NodePop();
279 node = new UnaryNode(_table, 0, node);
280 NodePush(node);
281 }
282 _prevOperand = 2;
283 num--;
284 continue;
285 }
286 case Tokens.ListSeparator:
287 {
288 if (_prevOperand == 0)
289 {
291 }
293 OperatorInfo operatorInfo = _ops[_topOperator - 1];
294 if (operatorInfo._type != Nodes.Call)
295 {
297 }
298 ExpressionNode argument = NodePop();
299 FunctionNode functionNode = (FunctionNode)NodePop();
300 functionNode.AddArgument(argument);
301 NodePush(functionNode);
302 _prevOperand = 0;
303 continue;
304 }
305 case Tokens.BinaryOp:
306 if (_prevOperand == 0)
307 {
308 if (_op == 15)
309 {
310 _op = 2;
311 }
312 else
313 {
314 if (_op != 16)
315 {
317 }
318 _op = 1;
319 }
320 goto case Tokens.UnaryOp;
321 }
322 _prevOperand = 0;
325 continue;
326 case Tokens.UnaryOp:
328 continue;
329 case Tokens.ZeroOp:
330 if (_prevOperand != 0)
331 {
332 throw ExprException.MissingOperator(new string(_text, _start, _pos - _start));
333 }
334 _ops[_topOperator++] = new OperatorInfo(Nodes.Zop, _op, 24);
335 _prevOperand = 2;
336 continue;
337 case Tokens.Dot:
338 {
339 ExpressionNode expressionNode = NodePeek();
340 if (expressionNode != null && expressionNode.GetType() == typeof(NameNode))
341 {
342 Scan();
343 if (_token == Tokens.Name)
344 {
345 NameNode nameNode = (NameNode)NodePop();
346 string name = nameNode._name + "." + NameNode.ParseName(_text, _start, _pos);
347 NodePush(new NameNode(_table, name));
348 continue;
349 }
350 }
351 goto default;
352 }
353 default:
354 throw ExprException.UnknownToken(new string(_text, _start, _pos - _start), _start + 1);
355 }
356 break;
357 }
358 if (_prevOperand == 0)
359 {
360 if (_topNode != 0)
361 {
362 OperatorInfo operatorInfo = _ops[_topOperator - 1];
363 throw ExprException.MissingOperand(operatorInfo);
364 }
365 }
366 else
367 {
369 if (_topOperator != 1)
370 {
372 }
373 }
374 }
376 return _expression;
377 }
378
380 {
381 Scan();
382 bool flag;
383 string relationName;
384 string columnName;
385 try
386 {
387 if (_token != Tokens.Child)
388 {
389 if (_token != Tokens.Name)
390 {
392 }
393 columnName = NameNode.ParseName(_text, _start, _pos);
394 ScanToken(Tokens.RightParen);
395 return new AggregateNode(_table, aggregate, columnName);
396 }
397 flag = _token == Tokens.Child;
398 _prevOperand = 1;
399 Scan();
400 if (_token == Tokens.LeftParen)
401 {
402 ScanToken(Tokens.Name);
403 relationName = NameNode.ParseName(_text, _start, _pos);
404 ScanToken(Tokens.RightParen);
405 ScanToken(Tokens.Dot);
406 }
407 else
408 {
409 relationName = null;
410 CheckToken(Tokens.Dot);
411 }
412 ScanToken(Tokens.Name);
413 columnName = NameNode.ParseName(_text, _start, _pos);
414 ScanToken(Tokens.RightParen);
415 }
416 catch (Exception e) when (ADP.IsCatchableExceptionType(e))
417 {
419 }
420 return new AggregateNode(_table, aggregate, columnName, !flag, relationName);
421 }
422
424 {
425 return _nodeStack[--_topNode];
426 }
427
429 {
430 if (_topNode <= 0)
431 {
432 return null;
433 }
434 return _nodeStack[_topNode - 1];
435 }
436
437 private void NodePush(ExpressionNode node)
438 {
439 if (_topNode >= 98)
440 {
442 }
443 _nodeStack[_topNode++] = node;
444 }
445
446 private void BuildExpression(int pri)
447 {
448 ExpressionNode expressionNode = null;
449 while (true)
450 {
451 OperatorInfo operatorInfo = _ops[_topOperator - 1];
452 if (operatorInfo._priority < pri)
453 {
454 break;
455 }
456 _topOperator--;
457 switch (operatorInfo._type)
458 {
459 default:
460 return;
461 case Nodes.Binop:
462 {
463 ExpressionNode right = NodePop();
464 ExpressionNode expressionNode2 = NodePop();
465 switch (operatorInfo._op)
466 {
467 case 4:
468 case 6:
469 case 22:
470 case 23:
471 case 24:
472 case 25:
473 throw ExprException.UnsupportedOperator(operatorInfo._op);
474 default:
475 expressionNode = ((operatorInfo._op != 14) ? new BinaryNode(_table, operatorInfo._op, expressionNode2, right) : new LikeNode(_table, operatorInfo._op, expressionNode2, right));
476 break;
477 }
478 break;
479 }
480 case Nodes.Unop:
481 {
482 ExpressionNode expressionNode2 = null;
483 ExpressionNode right = NodePop();
484 int op = operatorInfo._op;
485 if (op != 1 && op != 3 && op == 25)
486 {
487 throw ExprException.UnsupportedOperator(operatorInfo._op);
488 }
489 expressionNode = new UnaryNode(_table, operatorInfo._op, right);
490 break;
491 }
492 case Nodes.Zop:
493 expressionNode = new ZeroOpNode(operatorInfo._op);
494 break;
495 case Nodes.UnopSpec:
496 case Nodes.BinopSpec:
497 return;
498 }
499 NodePush(expressionNode);
500 }
501 }
502
503 internal void CheckToken(Tokens token)
504 {
505 if (_token != token)
506 {
507 throw ExprException.UnknownToken(token, _token, _pos);
508 }
509 }
510
511 internal Tokens Scan()
512 {
513 char[] text = _text;
514 _token = Tokens.None;
515 while (true)
516 {
517 _start = _pos;
518 _op = 0;
519 char c = text[_pos++];
520 switch (c)
521 {
522 case '\0':
523 _token = Tokens.EOS;
524 break;
525 case '\t':
526 case '\n':
527 case '\r':
528 case ' ':
529 goto IL_0111;
530 case '(':
531 _token = Tokens.LeftParen;
532 break;
533 case ')':
534 _token = Tokens.RightParen;
535 break;
536 case '#':
537 ScanDate();
538 CheckToken(Tokens.Date);
539 break;
540 case '\'':
541 ScanString('\'');
542 CheckToken(Tokens.StringConst);
543 break;
544 case '=':
545 _token = Tokens.BinaryOp;
546 _op = 7;
547 break;
548 case '>':
549 _token = Tokens.BinaryOp;
550 ScanWhite();
551 if (text[_pos] == '=')
552 {
553 _pos++;
554 _op = 10;
555 }
556 else
557 {
558 _op = 8;
559 }
560 break;
561 case '<':
562 _token = Tokens.BinaryOp;
563 ScanWhite();
564 if (text[_pos] == '=')
565 {
566 _pos++;
567 _op = 11;
568 }
569 else if (text[_pos] == '>')
570 {
571 _pos++;
572 _op = 12;
573 }
574 else
575 {
576 _op = 9;
577 }
578 break;
579 case '+':
580 _token = Tokens.BinaryOp;
581 _op = 15;
582 break;
583 case '-':
584 _token = Tokens.BinaryOp;
585 _op = 16;
586 break;
587 case '*':
588 _token = Tokens.BinaryOp;
589 _op = 17;
590 break;
591 case '/':
592 _token = Tokens.BinaryOp;
593 _op = 18;
594 break;
595 case '%':
596 _token = Tokens.BinaryOp;
597 _op = 20;
598 break;
599 case '&':
600 _token = Tokens.BinaryOp;
601 _op = 22;
602 break;
603 case '|':
604 _token = Tokens.BinaryOp;
605 _op = 23;
606 break;
607 case '^':
608 _token = Tokens.BinaryOp;
609 _op = 24;
610 break;
611 case '~':
612 _token = Tokens.BinaryOp;
613 _op = 25;
614 break;
615 case '[':
616 ScanName(']', _escape, "]\\");
617 CheckToken(Tokens.Name);
618 break;
619 case '`':
620 ScanName('`', '`', "`");
621 CheckToken(Tokens.Name);
622 break;
623 default:
624 if (c == _listSeparator)
625 {
626 _token = Tokens.ListSeparator;
627 break;
628 }
629 if (c == '.')
630 {
631 if (_prevOperand == 0)
632 {
633 ScanNumeric();
634 }
635 else
636 {
637 _token = Tokens.Dot;
638 }
639 break;
640 }
641 if (c == '0' && (text[_pos] == 'x' || text[_pos] == 'X'))
642 {
643 _token = Tokens.BinaryConst;
644 break;
645 }
646 if (IsDigit(c))
647 {
648 ScanNumeric();
649 break;
650 }
651 ScanReserved();
652 if (_token != 0)
653 {
654 break;
655 }
656 if (IsAlphaNumeric(c))
657 {
658 ScanName();
659 if (_token != 0)
660 {
661 CheckToken(Tokens.Name);
662 break;
663 }
664 }
665 _token = Tokens.Unknown;
666 throw ExprException.UnknownToken(new string(text, _start, _pos - _start), _start + 1);
667 }
668 break;
669 IL_0111:
670 ScanWhite();
671 }
672 return _token;
673 }
674
675 private void ScanNumeric()
676 {
677 char[] text = _text;
678 bool flag = false;
679 bool flag2 = false;
680 while (IsDigit(text[_pos]))
681 {
682 _pos++;
683 }
685 {
686 flag = true;
687 _pos++;
688 }
689 while (IsDigit(text[_pos]))
690 {
691 _pos++;
692 }
693 if (text[_pos] == _exponentL || text[_pos] == _exponentU)
694 {
695 flag2 = true;
696 _pos++;
697 if (text[_pos] == '-' || text[_pos] == '+')
698 {
699 _pos++;
700 }
701 while (IsDigit(text[_pos]))
702 {
703 _pos++;
704 }
705 }
706 if (flag2)
707 {
708 _token = Tokens.Float;
709 }
710 else if (flag)
711 {
712 _token = Tokens.Decimal;
713 }
714 else
715 {
716 _token = Tokens.Numeric;
717 }
718 }
719
720 private void ScanName()
721 {
722 char[] text = _text;
723 while (IsAlphaNumeric(text[_pos]))
724 {
725 _pos++;
726 }
727 _token = Tokens.Name;
728 }
729
730 private void ScanName(char chEnd, char esc, string charsToEscape)
731 {
732 char[] text = _text;
733 do
734 {
735 if (text[_pos] == esc && _pos + 1 < text.Length && charsToEscape.Contains(text[_pos + 1]))
736 {
737 _pos++;
738 }
739 _pos++;
740 }
741 while (_pos < text.Length && text[_pos] != chEnd);
742 if (_pos >= text.Length)
743 {
744 throw ExprException.InvalidNameBracketing(new string(text, _start, _pos - 1 - _start));
745 }
746 _pos++;
747 _token = Tokens.Name;
748 }
749
750 private void ScanDate()
751 {
752 char[] text = _text;
753 do
754 {
755 _pos++;
756 }
757 while (_pos < text.Length && text[_pos] != '#');
758 if (_pos >= text.Length || text[_pos] != '#')
759 {
760 if (_pos >= text.Length)
761 {
762 throw ExprException.InvalidDate(new string(text, _start, _pos - 1 - _start));
763 }
764 throw ExprException.InvalidDate(new string(text, _start, _pos - _start));
765 }
766 _token = Tokens.Date;
767 _pos++;
768 }
769
770 private void ScanReserved()
771 {
772 char[] text = _text;
773 if (!IsAlpha(text[_pos]))
774 {
775 return;
776 }
777 ScanName();
778 string @string = new string(text, _start, _pos - _start);
779 CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
780 int num = 0;
781 int num2 = s_reservedwords.Length - 1;
782 do
783 {
784 int num3 = (num + num2) / 2;
785 int num4 = compareInfo.Compare(s_reservedwords[num3]._word, @string, CompareOptions.IgnoreCase);
786 if (num4 == 0)
787 {
788 _token = s_reservedwords[num3]._token;
789 _op = s_reservedwords[num3]._op;
790 break;
791 }
792 if (num4 < 0)
793 {
794 num = num3 + 1;
795 }
796 else
797 {
798 num2 = num3 - 1;
799 }
800 }
801 while (num <= num2);
802 }
803
804 private void ScanString(char escape)
805 {
806 char[] text = _text;
807 while (_pos < text.Length)
808 {
809 char c = text[_pos++];
810 if (c == escape && _pos < text.Length && text[_pos] == escape)
811 {
812 _pos++;
813 }
814 else if (c == escape)
815 {
816 break;
817 }
818 }
819 if (_pos >= text.Length)
820 {
821 throw ExprException.InvalidString(new string(text, _start, _pos - 1 - _start));
822 }
823 _token = Tokens.StringConst;
824 }
825
826 internal void ScanToken(Tokens token)
827 {
828 Scan();
829 CheckToken(token);
830 }
831
832 private void ScanWhite()
833 {
834 char[] text = _text;
835 while (_pos < text.Length && IsWhiteSpace(text[_pos]))
836 {
837 _pos++;
838 }
839 }
840
841 private bool IsWhiteSpace(char ch)
842 {
843 if (ch <= ' ')
844 {
845 return ch != '\0';
846 }
847 return false;
848 }
849
850 private bool IsAlphaNumeric(char ch)
851 {
852 switch (ch)
853 {
854 case '$':
855 case '0':
856 case '1':
857 case '2':
858 case '3':
859 case '4':
860 case '5':
861 case '6':
862 case '7':
863 case '8':
864 case '9':
865 case 'A':
866 case 'B':
867 case 'C':
868 case 'D':
869 case 'E':
870 case 'F':
871 case 'G':
872 case 'H':
873 case 'I':
874 case 'J':
875 case 'K':
876 case 'L':
877 case 'M':
878 case 'N':
879 case 'O':
880 case 'P':
881 case 'Q':
882 case 'R':
883 case 'S':
884 case 'T':
885 case 'U':
886 case 'V':
887 case 'W':
888 case 'X':
889 case 'Y':
890 case 'Z':
891 case '_':
892 case 'a':
893 case 'b':
894 case 'c':
895 case 'd':
896 case 'e':
897 case 'f':
898 case 'g':
899 case 'h':
900 case 'i':
901 case 'j':
902 case 'k':
903 case 'l':
904 case 'm':
905 case 'n':
906 case 'o':
907 case 'p':
908 case 'q':
909 case 'r':
910 case 's':
911 case 't':
912 case 'u':
913 case 'v':
914 case 'w':
915 case 'x':
916 case 'y':
917 case 'z':
918 return true;
919 default:
920 if (ch > '\u007f')
921 {
922 return true;
923 }
924 return false;
925 }
926 }
927
928 private bool IsDigit(char ch)
929 {
930 switch (ch)
931 {
932 case '0':
933 case '1':
934 case '2':
935 case '3':
936 case '4':
937 case '5':
938 case '6':
939 case '7':
940 case '8':
941 case '9':
942 return true;
943 default:
944 return false;
945 }
946 }
947
948 private bool IsAlpha(char ch)
949 {
950 switch (ch)
951 {
952 case 'A':
953 case 'B':
954 case 'C':
955 case 'D':
956 case 'E':
957 case 'F':
958 case 'G':
959 case 'H':
960 case 'I':
961 case 'J':
962 case 'K':
963 case 'L':
964 case 'M':
965 case 'N':
966 case 'O':
967 case 'P':
968 case 'Q':
969 case 'R':
970 case 'S':
971 case 'T':
972 case 'U':
973 case 'V':
974 case 'W':
975 case 'X':
976 case 'Y':
977 case 'Z':
978 case '_':
979 case 'a':
980 case 'b':
981 case 'c':
982 case 'd':
983 case 'e':
984 case 'f':
985 case 'g':
986 case 'h':
987 case 'i':
988 case 'j':
989 case 'k':
990 case 'l':
991 case 'm':
992 case 'n':
993 case 'o':
994 case 'p':
995 case 'q':
996 case 'r':
997 case 's':
998 case 't':
999 case 'u':
1000 case 'v':
1001 case 'w':
1002 case 'x':
1003 case 'y':
1004 case 'z':
1005 return true;
1006 default:
1007 return false;
1008 }
1009 }
1010}
static bool IsCatchableExceptionType(Exception e)
Definition ADP.cs:790
static Exception LookupArgument()
static Exception InvalidDate(string date)
static Exception InvalidString(string str)
static Exception ExpressionTooComplex()
static Exception InvalidNameBracketing(string name)
static Exception UnknownToken(string token, int position)
static Exception UnsupportedOperator(int op)
static Exception MissingOperator(string token)
static Exception InWithoutParentheses()
static Exception MissingRightParen()
static Exception MissingOperand(OperatorInfo before)
static Exception MissingOperandBefore(string op)
static Exception AggregateArgument()
static Exception SyntaxError()
static Exception TooManyRightParentheses()
static readonly ReservedWords[] s_reservedwords
void ScanName(char chEnd, char esc, string charsToEscape)
void NodePush(ExpressionNode node)
ExpressionNode ParseAggregateArgument(FunctionId aggregate)
void AddArgument(ExpressionNode argument)
static string ParseName(char[] text, int start, int pos)
Definition NameNode.cs:150
static int Priority(int op)
Definition Operators.cs:49
static string ToString(int op)
Definition Operators.cs:58
int Compare(string? string1, string? string2)
static CultureInfo InvariantCulture
ReservedWords(string word, Tokens token, int op)