@@ -26,121 +26,84 @@ private protected Expression()
2626 /// <exception cref="NotSupportedException">A condition was encountered that may be valid but can't currently be parsed.</exception>
2727 public static Expression Parse ( ParserContext context )
2828 {
29- Expression ? expression = null ;
30- bool tokenWasRead ;
29+ Expression expression ;
3130
32- do
31+ switch ( context . Token )
3332 {
34- tokenWasRead = false ;
33+ case Numeric number :
34+ expression = new Value ( number ) ;
35+ break ;
36+ case AtPrefixedString atPrefixed :
37+ expression = new Value ( atPrefixed , context ) ;
38+ break ;
39+ case DoubleAtPrefixedString doubleAtPrefixedString :
40+ expression = new Value ( doubleAtPrefixedString ) ;
41+ break ;
42+ case ReservedKeyword { Keyword : Keyword . Null } :
43+ expression = new Value ( ) ;
44+ break ;
45+ case Name name :
46+ expression = new Reference ( name ) ;
47+ break ;
48+ case Operator { Character : '+' } :
49+ context . MoveNextRequired ( ) ;
50+ expression = Expression . Parse ( context ) ;
51+ break ;
52+ case Operator { Character : '-' } :
53+ context . MoveNextRequired ( ) ;
54+ expression = Parse ( context ) ;
55+ expression = new Subtract ( new Value ( 0 ) , expression ) ;
56+ break ;
57+ default :
58+ throw SimulatedSqlException . SyntaxErrorNear ( context . Token ) ;
59+ }
3560
36- switch ( context . Token )
61+ while ( true )
62+ {
63+ switch ( context . GetNextOptional ( ) )
3764 {
38- case Numeric number :
39- expression = new Value ( number ) ;
40- break ;
41- case AtPrefixedString atPrefixed :
42- expression = new Value ( atPrefixed , context ) ;
43- break ;
44- case DoubleAtPrefixedString doubleAtPrefixedString :
45- expression = new Value ( doubleAtPrefixedString ) ;
46- break ;
47- case ReservedKeyword reservedKeyword :
48- switch ( reservedKeyword . Keyword )
49- {
50- case Keyword . As :
51- if ( expression is null || context . GetNextOptional ( ) is not Name alias )
52- throw SimulatedSqlException . SyntaxErrorNearKeyword ( reservedKeyword ) ;
53-
54- expression = new NamedExpression ( expression , alias . Value ) ;
55- context . MoveNextOptional ( ) ;
56- return expression ;
57- case Keyword . From :
58- if ( expression is null )
59- throw SimulatedSqlException . SyntaxErrorNearKeyword ( reservedKeyword ) ;
60-
61- return expression ;
62- case Keyword . Null :
63- expression = new Value ( ) ;
64- continue ;
65- }
66-
67- throw SimulatedSqlException . SyntaxErrorNearKeyword ( reservedKeyword ) ;
68- case Name name :
69- expression = new Reference ( name ) ;
70- break ;
7165 case Operator { Character : '+' } :
72- if ( expression is null )
73- {
74- context . MoveNextRequired ( ) ;
75- expression = Expression . Parse ( context ) ;
76- break ;
77- }
78-
7966 context . MoveNextRequired ( ) ;
80-
81- {
82- var parsed = Parse ( context ) ;
83- expression = new Add ( expression , parsed ) ;
84- if ( parsed is NamedExpression named )
85- expression = named . TransferName ( expression ) ;
86- }
87-
88- tokenWasRead = true ;
67+ expression = new Add ( expression , Parse ( context ) ) ;
8968 break ;
9069 case Operator { Character : '-' } :
91- if ( expression is null )
92- {
93- context . MoveNextRequired ( ) ;
94- expression = Parse ( context ) ;
95- expression = new Subtract ( new Value ( 0 ) , expression ) ;
96- break ;
97- }
98-
9970 context . MoveNextRequired ( ) ;
100-
101- {
102- var parsed = Parse ( context ) ;
103- expression = new Subtract ( expression , parsed ) ;
104- if ( parsed is NamedExpression named )
105- expression = named . TransferName ( expression ) ;
106- }
107-
108- tokenWasRead = true ;
71+ expression = new Subtract ( expression , Parse ( context ) ) ;
10972 break ;
11073
11174 case Operator { Character : '.' } :
112- if ( expression is null )
113- throw new NotSupportedException ( "Simulated expression parser doesn't know how to handle '.' at the start of an expression." ) ;
114-
11575 {
11676 if ( expression is not Reference reference )
117- throw new NotSupportedException ( "Simulated expression parser doesn't know how to handle '.' here." ) ;
77+ throw SimulatedSqlException . SyntaxErrorNear ( context . Token ) ;
11878
11979 reference . AddMultiPartComponent ( context . GetNextRequired < Name > ( ) ) ;
12080 }
121- break ;
122- case Operator { Character : ',' } :
81+ continue ;
12382 case Operator { Character : ')' } :
124- if ( expression is null )
125- throw SimulatedSqlException . SyntaxErrorNear ( context . Token ) ;
126- return expression ;
83+ break ;
12784 case Operator { Character : '(' } :
12885 {
12986 if ( expression is not Reference reference )
13087 throw SimulatedSqlException . SyntaxErrorNear ( context . Token ) ;
13188 context . MoveNextRequired ( ) ; // Move past (
13289 expression = ResolveBuiltIn ( reference . Name , context ) ;
13390 context . MoveNextOptional ( ) ; // Move past )
134- return expression ;
91+ continue ;
13592 }
136- default :
137- throw new NotSupportedException ( $ "Simulated expression parser doesn't know how to handle '{ context . Token } '.") ;
13893 }
139- } while ( ( tokenWasRead && context . Token is not null ) || context . GetNextOptional ( ) is not null ) ;
14094
141- return expression ;
95+ return expression ;
96+ }
14297 }
14398
99+ /// <summary>
100+ /// Wraps the provided <see cref="Expression"/> in a <see cref="NamedExpression"/> with the provided <paramref name="name"/>.
101+ /// </summary>
102+ /// <param name="expression">The expression to wrap.</param>
103+ /// <param name="name">The name to assign.</param>
104+ /// <returns>The named expression.</returns>
105+ public static Expression AssignName ( Expression expression , string name ) => new NamedExpression ( expression , name ) ;
106+
144107 /// <summary>
145108 /// Runs the expression, returning its result.
146109 /// </summary>
@@ -180,30 +143,13 @@ private sealed class NamedExpression(Expression expression, string name) : Expre
180143 {
181144 private readonly Expression expression = expression ;
182145 private readonly string name = name ;
183- #if DEBUG
184- private bool transferred ;
185- #endif
186146
187147 public override string Name => this . name ;
188148
189149 public override object ? Run ( Func < List < string > , object ? > getColumnValue ) => this . expression . Run ( getColumnValue ) ;
190150
191- /// <summary>
192- /// Transfers the name to an outer expression.
193- /// </summary>
194- /// <param name="destination">The expression wrapping this<see cref="NamedExpression"/>.</param>
195- /// <returns>A new <see cref="NamedExpression"/> wrapping <paramref name="destination"/> using <see cref="Name"/>.</returns>
196- public NamedExpression TransferName ( Expression destination )
197- {
198- #if DEBUG
199- transferred = true ;
200- #endif
201-
202- return new ( destination , this . name ) ;
203- }
204-
205151#if DEBUG
206- public override string ToString ( ) => transferred ? expression . ToString ( ) : $ "{ expression } { name } ";
152+ public override string ToString ( ) => $ "{ expression } { name } ";
207153#endif
208154 }
209155
0 commit comments