private static ExpressionNode ParseCast(RuleContext expression)
        {
            //( LPARENTHESIS type RPARENTHESIS ) * unary_expression
            var             castExpression = (CrawlParser.Cast_expressionContext)expression;
            List <TypeNode> targetTypes    = new List <TypeNode>();

            //Parse every part of the chain of casts. The for-loop works; Trust me.
            for (int i = castExpression.ChildCount - 3; i > 2; i -= 3)
            {
                targetTypes.Add(ParseTreeParser.ParseType((CrawlParser.TypeContext)castExpression.GetChild(i)));
            }

            //Parse the rest of the expression.
            ExpressionNode result = ParseExpression((RuleContext)castExpression.LastChild());

            //Wrap the casts around the rest of the expression one at a time.
            foreach (TypeNode type in targetTypes)
            {
                result = CrawlSyntaxNode.CastExpression(
                    Interval.Invalid, ExpressionType.Cast, CrawlType.UnspecifiedType,
                    type,
                    result
                    );
            }

            return(result);
        }
        private static ExpressionNode ParseArrayInitialization(RuleContext rule)
        {
            // An array initialization is the call of a typeNode's constructor

            TypeNode             type            = ParseTreeParser.ParseType((CrawlParser.TypeContext)rule.GetChild(0));
            ArrayConstructorNode typeConstructor = CrawlSyntaxNode.ArrayConstructor(type.Interval, CrawlType.UnspecifiedType, type);
            // TypeConstructorNode is an ExpressionNode that corresponds to a TypeNode

            IEnumerable <ArgumentNode> arguments = ParseCallTail((RuleContext)rule.GetChild(1)).Select(x => CrawlSyntaxNode.Argument(x.Interval, false, x));

            return(CrawlSyntaxNode.Call(rule.SourceInterval, CrawlType.UnspecifiedType, typeConstructor, arguments));
        }
        private static ExpressionNode ParsePostfix(RuleContext rule)
        {
            ExpressionNode node = ParseExpression((RuleContext)rule.GetChild(0));

            for (int i = 1; i < rule.ChildCount; i++)
            {
                RuleContext post = (RuleContext)rule.GetChild(i);
                if (post.RuleIndex == CrawlParser.RULE_call_expression)
                {
                    node = CrawlSyntaxNode.Call(post.SourceInterval, CrawlType.UnspecifiedType, node, ParseArgumentList(post));
                }
                else if (post.RuleIndex == CrawlParser.RULE_index_expression)
                {
                    node = CrawlSyntaxNode.Index(post.SourceInterval, CrawlType.UnspecifiedType, node, ParseArgumentList(post));
                }
                else if (post.RuleIndex == CrawlParser.RULE_subfield_expression)
                {
                    IdentifierNode sub = CrawlSyntaxNode.Identifier(post.GetChild(1).SourceInterval, post.GetChild(1).GetText());
                    node = CrawlSyntaxNode.MemberAccess(post.SourceInterval, CrawlType.UnspecifiedType, node, sub);
                }
                else if (post.RuleIndex == CrawlParser.RULE_generic_unpack_expression)
                {
                    List <TypeNode> generics = new List <TypeNode>();
                    for (int j = 1; j < post.ChildCount; j += 2)
                    {
                        generics.Add(ParseTreeParser.ParseType((CrawlParser.TypeContext)post.GetChild(j)));
                    }
                    node = CrawlSyntaxNode.GenericsUnpack(post.SourceInterval, CrawlType.UnspecifiedType, node, generics);
                }
                else
                {
                    throw new NotImplementedException("Strange postfix expression");
                }
            }

            return(node);
        }