11using System . Globalization ;
22using System . Text . RegularExpressions ;
3- using HydraScript . Domain . FrontEnd . Lexer ;
43using HydraScript . Domain . FrontEnd . Parser . Impl . Ast . Nodes . Expressions ;
54using HydraScript . Domain . FrontEnd . Parser . Impl . Ast . Nodes . Expressions . AccessExpressions ;
65using HydraScript . Domain . FrontEnd . Parser . Impl . Ast . Nodes . Expressions . ComplexLiterals ;
@@ -12,7 +11,7 @@ public partial class TopDownParser
1211{
1312 /// <summary>
1413 /// Expression -> CastExpression | AssignmentExpression
15- /// AssignmentExpression -> MemberExpression "Operator"? '=' Expression
14+ /// AssignmentExpression -> MemberExpression '=' Expression
1615 /// </summary>
1716 private Expression Expression ( )
1817 {
@@ -28,7 +27,8 @@ private Expression Expression()
2827 }
2928
3029 /// <summary>
31- /// CallExpression -> MemberExpression Arguments (Arguments | '[' Expression ']' | '.' 'Ident')*
30+ /// CallExpression -> MemberExpression Arguments
31+ /// Arguments -> '(' (Expression ',')* ')'
3232 /// </summary>
3333 private Expression CallExpression ( )
3434 {
@@ -46,55 +46,49 @@ private Expression CallExpression()
4646 }
4747
4848 var rp = Expect ( "RightParen" ) ;
49- return new CallExpression ( ( member as MemberExpression ) ! , expressions )
49+ return new CallExpression ( member , expressions )
5050 { Segment = member . Segment + rp . Segment } ;
5151 }
5252
53- return member ;
53+ return member . Empty ( ) && ! CurrentIs ( "Assign" ) ? member . Id : member ;
5454 }
5555
5656 /// <summary>
57- /// MemberExpression -> "Ident" ('[' Expression ']' | '.' 'Ident')*
57+ /// MemberExpression -> Var ('[' Expression ']' | '.' 'Ident')*
5858 /// </summary>
59- private Expression MemberExpression ( )
59+ private MemberExpression MemberExpression ( )
6060 {
61- var primary = PrimaryExpression ( ) ;
62-
63- if ( ! CurrentIs ( "LeftBracket" ) && ! CurrentIs ( "Dot" ) &&
64- ! CurrentIs ( "Assign" ) && ! CurrentIs ( "LeftParen" ) )
65- return primary ;
66-
67- var identRef = ( primary as IdentifierReference ) ! ;
68- var accessChain = new List < AccessExpression > ( ) ;
61+ var memberRoot = Var ( ) ;
62+ var accessChain = new LinkedList < AccessExpression > ( ) ;
6963 while ( CurrentIs ( "LeftBracket" ) || CurrentIs ( "Dot" ) )
7064 {
71- Token access ;
7265 if ( CurrentIs ( "LeftBracket" ) )
7366 {
74- access = Expect ( "LeftBracket" ) ;
75- var lb = access . Segment ;
67+ var lb = Expect ( "LeftBracket" ) . Segment ;
7668 var expr = Expression ( ) ;
7769 var rb = Expect ( "RightBracket" ) . Segment ;
78- accessChain . Add (
79- new IndexAccess ( expr , accessChain . LastOrDefault ( ) ) { Segment = lb + rb } ) ;
70+ accessChain . AddLast (
71+ new IndexAccess ( expr , accessChain . Last ? . Value )
72+ { Segment = lb + rb } ) ;
8073 }
8174 else if ( CurrentIs ( "Dot" ) )
8275 {
83- access = Expect ( "Dot" ) ;
84- var identToken = Expect ( "Ident" ) ;
85- var idRef = new IdentifierReference ( identToken . Value )
86- { Segment = identToken . Segment } ;
87- accessChain . Add (
88- new DotAccess ( idRef , accessChain . LastOrDefault ( ) ) { Segment = access . Segment } ) ;
76+ var access = Expect ( "Dot" ) ;
77+ var propToken = Expect ( "Ident" ) ;
78+ var propIdent = new IdentifierReference ( propToken . Value )
79+ { Segment = propToken . Segment } ;
80+ accessChain . AddLast (
81+ new DotAccess ( propIdent , accessChain . Last ? . Value )
82+ { Segment = access . Segment } ) ;
8983 }
9084 }
9185
9286 return new MemberExpression (
93- identRef ,
94- accessChain . FirstOrDefault ( ) ,
95- tail : accessChain . LastOrDefault ( ) )
87+ memberRoot ,
88+ accessChain . First ? . Value ,
89+ tail : accessChain . Last ? . Value )
9690 {
97- Segment = identRef . Segment
91+ Segment = memberRoot . Segment
9892 } ;
9993 }
10094
@@ -285,18 +279,14 @@ private Expression UnaryExpression()
285279 }
286280
287281 /// <summary>
288- /// LeftHandSideExpression -> MemberExpression | CallExpression
282+ /// LeftHandSideExpression -> PrimaryExpression
283+ /// ParenthesizedExpression
284+ /// ComplexLiteral
285+ /// MemberExpression
286+ /// CallExpression
287+ /// ParenthesizedExpression -> '(' Expression ')'
289288 /// </summary>
290289 private Expression LeftHandSideExpression ( )
291- {
292- return CallExpression ( ) ;
293- }
294-
295- /// <summary>
296- /// PrimaryExpression -> "Ident" | EnvVar | Literal | '(' Expression ')' | ObjectLiteral | ArrayLiteral
297- /// EnvVar -> '$' "Ident"
298- /// </summary>
299- private Expression PrimaryExpression ( )
300290 {
301291 if ( CurrentIs ( "LeftParen" ) )
302292 {
@@ -306,41 +296,48 @@ private Expression PrimaryExpression()
306296 return expr ;
307297 }
308298
309- if ( CurrentIs ( "Ident " ) )
299+ if ( CurrentIs ( "LeftCurl" ) || CurrentIs ( "LeftBracket ") )
310300 {
311- var ident = Expect ( "Ident" ) ;
312- return new IdentifierReference ( ident . Value )
313- {
314- Segment = ident . Segment
315- } ;
301+ return ComplexLiteral ( ) ;
316302 }
317303
318- if ( CurrentIsOperator ( "$" ) )
304+ if ( CurrentIs ( "Ident" ) || CurrentIsOperator ( "$" ) )
319305 {
320- var dollar = Expect ( "Operator" ) ;
321- var ident = Expect ( "Ident" ) ;
322- return new EnvVarReference ( ident . Value )
323- {
324- Segment = dollar . Segment + ident . Segment
325- } ;
306+ return CallExpression ( ) ;
326307 }
327308
328- if ( CurrentIsLiteral ( ) )
329- {
330- return LiteralNode ( ) ;
331- }
309+ return PrimaryExpression ( ) ;
310+ }
332311
333- if ( CurrentIs ( "LeftCurl" ) )
334- {
335- return ObjectLiteral ( ) ;
336- }
312+ /// <summary>
313+ /// PrimaryExpression -> Var | Literal
314+ /// </summary>
315+ private PrimaryExpression PrimaryExpression ( )
316+ {
317+ return LiteralNode ( ) ;
318+ }
337319
338- if ( CurrentIs ( "LeftBracket" ) )
320+ /// <summary>
321+ /// Var -> "Ident" | EnvVar
322+ /// EnvVar -> '$' "Ident"
323+ /// </summary>
324+ private IdentifierReference Var ( )
325+ {
326+ if ( CurrentIs ( "Ident" ) )
339327 {
340- return ArrayLiteral ( ) ;
328+ var ident = Expect ( "Ident" ) ;
329+ return new IdentifierReference ( ident . Value )
330+ {
331+ Segment = ident . Segment
332+ } ;
341333 }
342334
343- return null ! ;
335+ var dollar = Expect ( "Operator" ) ;
336+ var envIdent = Expect ( "Ident" ) ;
337+ return new EnvVarReference ( envIdent . Value )
338+ {
339+ Segment = dollar . Segment + envIdent . Segment
340+ } ;
344341 }
345342
346343 /// <summary>
@@ -379,12 +376,27 @@ private Literal LiteralNode()
379376 CultureInfo . InvariantCulture ) ,
380377 segment ) ,
381378 "BooleanLiteral" => Literal . Boolean ( value : bool . Parse ( Expect ( "BooleanLiteral" ) . Value ) , segment ) ,
382- _ => throw new ParserException ( "There are no more supported literals" )
379+ _ => throw new ParserException ( "Literal" , _tokens . Current )
383380 } ;
384381 }
385382
383+ /// <summary>
384+ /// ComplexLiteral -> ObjectLiteral | ArrayLiteral
385+ /// </summary>
386+ private ComplexLiteral ComplexLiteral ( )
387+ {
388+ if ( CurrentIs ( "LeftCurl" ) )
389+ {
390+ return ObjectLiteral ( ) ;
391+ }
392+
393+ return ArrayLiteral ( ) ;
394+ }
395+
386396 /// <summary>
387397 /// ObjectLiteral -> '{' PropertyDefinitionList '}'
398+ /// PropertyDefinitionList -> (FieldProperty ';')*
399+ /// FieldProperty -> "Ident" ':' Expression
388400 /// </summary>
389401 private ObjectLiteral ObjectLiteral ( )
390402 {
@@ -409,6 +421,7 @@ private ObjectLiteral ObjectLiteral()
409421
410422 /// <summary>
411423 /// ArrayLiteral -> '[' ElementList ']'
424+ /// ElementList -> (Expression ',')*
412425 /// </summary>
413426 private ArrayLiteral ArrayLiteral ( )
414427 {
0 commit comments