private void TreatWhileStatement(CSharpParser.WhileStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a do statement:
            IToken whileToken = statement.WHILE().Symbol;
            Node   whileNode  = new Node(whileToken, Node.Kind.DoStatement, null);

            ast.AddNode(whileNode);
            int whileIndex = ast.NodeIndex(whileNode);

            parentNode.AddChildIndex(whileIndex);

            symbolTable.EnterScope(whileIndex);

            // Creating sub tree for the condition expression:
            beginTreatExpression(statement.expression(), whileNode);

            // Craeting sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, whileNode);
            }
            else
            {
                TreatBlock(embedded.block(), whileNode);
            }

            symbolTable.ExitScope();
        }
        private void TreatForeachStatement(CSharpParser.ForeachStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a foreach statement:
            IToken foreachToken = statement.FOREACH().Symbol;
            Node   foreachNode  = new Node(foreachToken, Node.Kind.ForeachStatement, null);

            ast.AddNode(foreachNode);
            int foreachIndex = ast.NodeIndex(foreachNode);

            parentNode.AddChildIndex(foreachIndex);

            symbolTable.EnterScope(foreachIndex);

            // Creating sub tree for the variable creation in the iterator:
            Type   t              = symbolTable.FindType(statement.local_variable_type().type_().Stop);
            IToken idToken        = statement.identifier().Start;
            Symbol iteratorSymbol = new Symbol(Symbol.ModifierFlag.None);

            symbolTable.AddSymbol(idToken, iteratorSymbol);
            Node iteratorNode = new Node(idToken, Node.Kind.IteratorDeclaration, t, iteratorSymbol);

            ast.AddNode(iteratorNode);
            int iteratorIndex = ast.NodeIndex(iteratorNode);

            foreachNode.AddChildIndex(iteratorIndex);

            // Treat the expression that returns the iterable
            beginTreatExpression(statement.expression(), foreachNode);

            // Creating sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, foreachNode);
            }
            else
            {
                TreatBlock(embedded.block(), foreachNode);
            }

            symbolTable.ExitScope();
        }
        private void TreatForStatement(CSharpParser.ForStatementContext statement, Node parentNode)
        {
            // Creating node indicating it's a for statement:
            IToken forToken = statement.FOR().Symbol;
            Node   forNode  = new Node(forToken, Node.Kind.ForStatement, null);

            ast.AddNode(forNode);
            int forIndex = ast.NodeIndex(forNode);

            parentNode.AddChildIndex(forIndex);

            symbolTable.EnterScope(forIndex);

            // Craeting sub tree for the initializer expression:
            CSharpParser.For_initializerContext initContext = statement.for_initializer();
            if (initContext != null)
            {
                CSharpParser.Local_variable_declarationContext declContext = initContext.local_variable_declaration();
                if (declContext != null)
                {
                    // Getting the local variables modifiers:
                    Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None;
                    if (declContext.REF() != null)
                    {
                        modFlags |= Symbol.ModifierFlag.Ref;
                    }
                    if (declContext.READONLY() != null)
                    {
                        modFlags |= Symbol.ModifierFlag.ReadOnly;
                    }

                    // Creating the local variables symbols:
                    IToken typeToken = declContext.local_variable_type().Start;
                    Type   t         = symbolTable.FindType(typeToken);
                    if (t == null)
                    {
                        Console.WriteLine("FATAL ERROR: Unidentified type found.");
                        Environment.Exit(1);
                    }
                    MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast);
                    CSharpParser.Local_variable_declaratorContext[] declarators =
                        declContext.local_variable_declarator();
                    foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators)
                    {
                        // Creating the variable symbol:
                        CSharpParser.IdentifierContext identifier = declarator.identifier();
                        IToken         variableID     = identifier.Start;
                        VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod);
                        symbolTable.AddSymbol(variableID, variableSymbol);

                        // Creating the variable node and adding it to the AST:
                        Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t);
                        ast.AddNode(variableNode);
                        int varDeclIndex = ast.NodeIndex(variableNode);
                        parentNode.AddChildIndex(varDeclIndex);

                        // Treating the variable initialization:
                        TreatVariableInitializer(declarator.local_variable_initializer(), variableNode);
                    }
                }
                else
                {
                    CSharpParser.ExpressionContext[] initExpressions = initContext.expression();
                    foreach (CSharpParser.ExpressionContext expression in initExpressions)
                    {
                        beginTreatExpression(expression, forNode);
                    }
                }
            }

            // Creating sub tree for the condition expression:
            beginTreatExpression(statement.expression(), forNode);

            // Creating sub tree for the iterator:
            CSharpParser.For_iteratorContext iteratorContext = statement.for_iterator();
            if (iteratorContext != null)
            {
                CSharpParser.ExpressionContext[] expressions = iteratorContext.expression();
                foreach (CSharpParser.ExpressionContext expression in expressions)
                {
                    beginTreatExpression(expression, forNode);
                }
            }

            // Craeting sub tree and scope for the list of statements:
            CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
            CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
            if (simpleStatement != null)
            {
                TreatSimpleEmbeddedStatement(simpleStatement, forNode);
            }
            else
            {
                TreatBlock(embedded.block(), forNode);
            }

            symbolTable.ExitScope();
        }
        private void TreatStatement(CSharpParser.StatementContext statement, Node parentNode)
        {
            CSharpParser.Labeled_StatementContext labeledStatement = statement.labeled_Statement();
            if (labeledStatement != null)
            {
                // Getting the label token:
                CSharpParser.IdentifierContext label = labeledStatement.identifier();
                IToken labelToken = label.Start;

                // Adding the label to the symbol table:
                Symbol labelSymbol = new Symbol(Symbol.ModifierFlag.None);
                symbolTable.AddSymbol(labelToken, labelSymbol);

                // Creating the label node and adding it to the AST:
                Node labelNode = new Node(labelToken, Node.Kind.Label, null);
                ast.AddNode(labelNode);
                int labelNodeIndex = ast.NodeIndex(labelNode);

                parentNode.AddChildIndex(labelNodeIndex);

                CSharpParser.StatementContext innerStatement = labeledStatement.statement();

                // Treating the labeled statement:
                TreatStatement(innerStatement, labelNode);
            }
            else
            {
                CSharpParser.DeclarationStatementContext declaration = statement.declarationStatement();
                if (declaration != null)
                {
                    CSharpParser.Local_variable_declarationContext localVariable = declaration.local_variable_declaration();
                    if (localVariable != null)
                    {
                        // Getting the local variables modifiers:
                        Symbol.ModifierFlag modFlags = Symbol.ModifierFlag.None;
                        if (localVariable.REF() != null)
                        {
                            modFlags |= Symbol.ModifierFlag.Ref;
                        }
                        if (localVariable.READONLY() != null)
                        {
                            modFlags |= Symbol.ModifierFlag.ReadOnly;
                        }

                        // Creating the local variables symbols:
                        IToken typeToken = localVariable.local_variable_type().Start;
                        Type   t         = symbolTable.FindType(typeToken);
                        if (t == null)
                        {
                            Console.WriteLine("FATAL ERROR: Unidentified type found.");
                            Environment.Exit(1);
                        }
                        MethodSymbol ownerMethod = (MethodSymbol)symbolTable.FindSymbol(parentNode.Token, ast);
                        CSharpParser.Local_variable_declaratorContext[] declarators =
                            localVariable.local_variable_declarator();
                        foreach (CSharpParser.Local_variable_declaratorContext declarator in declarators)
                        {
                            // Creating the variable symbol:
                            CSharpParser.IdentifierContext identifier = declarator.identifier();
                            IToken         variableID     = identifier.Start;
                            VariableSymbol variableSymbol = new VariableSymbol(modFlags, ownerMethod);
                            symbolTable.AddSymbol(variableID, variableSymbol);

                            // Creating the variable node and adding it to the AST:
                            Node variableNode = new Node(variableID, Node.Kind.MethodVariableDeclaration, t);
                            ast.AddNode(variableNode);
                            int varDeclIndex = ast.NodeIndex(variableNode);
                            parentNode.AddChildIndex(varDeclIndex);

                            // Treating the variable initialization:
                            TreatVariableInitializer(declarator.local_variable_initializer(), variableNode);
                        }
                    }
                }
                else
                {
                    CSharpParser.Embedded_statementContext        embedded        = statement.embedded_statement();
                    CSharpParser.Simple_embedded_statementContext simpleStatement = embedded.simple_embedded_statement();
                    if (simpleStatement != null)
                    {
                        TreatSimpleEmbeddedStatement(simpleStatement, parentNode);
                    }
                    else
                    {
                        TreatBlock(embedded.block(), parentNode);
                    }
                }
            }
        }