Beispiel #1
0
        public Module CreateSyntaxTree(string module_name="MainProgram")
        {
            // Are we currently in a comment block.
            bool inCommentBlock = false;

            // Parser stack.
            Stack stack = new Stack();

            // Syntax stack.
            SyntaxStack syntaxStack = new SyntaxStack();

            m_Scanner.Reset();
            ParserState currentState = m_Language.ParserStartState;

            // Push start state.
            stack.Push(currentState);

            while (true)
            {
                // Get next token.
                Token nextToken = m_Scanner.PeekNextToken();
                Symbol nextSymbol = nextToken.Symbol;

                // Ignore whitespace.
                if (nextSymbol.Type == SymbolType.Whitespace)
                {
                    m_Scanner.GetNextToken();
                    continue;
                }

                // Ignore comment blocks
                if (nextSymbol.Type == SymbolType.CommentStart)
                {
                    m_Scanner.GetNextToken();
                    inCommentBlock = true;
                    continue;
                }

                // Ignore comment blocks
                if (nextSymbol.Type == SymbolType.CommentEnd)
                {
                    m_Scanner.GetNextToken();
                    inCommentBlock = false;
                    continue;
                }

                // Ignore stuff inside comments
                if (inCommentBlock)
                {
                    m_Scanner.GetNextToken();
                    continue;
                }

                Print(stack);
                PrintSyntax(syntaxStack.Stack);

                // Lookup action out of current state.
                Action action = currentState.Find(nextSymbol);

                // Do we have a parser error ? (Entered an invalid state.)
                if (action == null)
                {
                    StringBuilder message = new StringBuilder("Token Unexpected, expecting [ ");

                    for (int x = 0; x < currentState.Actions.Length; x++)
                    {
                        if (currentState.Actions[x].Symbol.Type == SymbolType.Terminal)
                            message.Append(currentState.Actions[x].Symbol.Name + " ");
                    }
                    message.Append("]");

                    if (Error != null)
                        Error(nextToken, message.ToString());

                    return null;
                }

                // Should we shift token and the next state on the stack.
                else if (action.Type == ActionType.Shift)
                {
                    Token token = m_Scanner.GetNextToken();
                    stack.Push(token.Symbol);
                    syntaxStack.Push(token.Text);
                    stack.Push(action.ParserState);
                }
                // Should we reduce ?
                else if (action.Type == ActionType.Reduce)
                {
                    // Pop off the stack however many state-symbol pairs as the Production
                    // has Right Terminals,Nonterminals.

                    int rightItems = action.Production.Right.Length;
                    for (int i = 0; i < rightItems; i++)
                    {
                        stack.Pop();
                        stack.Pop();
                    }

                    // Find the top of the stack.
                    ParserState topState = (ParserState)stack.Peek();
                    // Push left hand side of the production.
                    stack.Push(action.Production.Left);
                    // Find next state by looking up the action for the top of the stack
                    // on the Left hand side symbol of the production.
                    stack.Push(topState.Find(action.Production.Left).ParserState);

                    // Apply semantic rule.
                    Semantics.Apply(action.Production, syntaxStack);

                }
                else if (action.Type == ActionType.Accept)
                {
                    Debug.WriteLine("Accept");
                    return new Module((Body)syntaxStack.Pop(), module_name);
                }
                currentState = (ParserState)stack.Peek();
            }

            return null;
        }
Beispiel #2
0
        // !TODO: ОБРАБОТКА КЛАССОВ CLASS_MEMBER (тут access level)
        public static void Apply(Production production, SyntaxStack stack)
        {
            switch (production.m_ID)
            {
                case (short)ProductionIndex.Program:
                    // <PROGRAM> ::= <CLASS>
                    break;

                case (short)ProductionIndex.Program2:
                    // <PROGRAM> ::= <METHOD>
                    StatementCollection statements = new StatementCollection();
                    statements.Add(stack.PopStatement());
                    Body program_body = new Body(statements, null);
                    stack.Push(program_body);
                    break;

                case (short)ProductionIndex.Program3:
                    // <PROGRAM> ::= <PROGRAM> <CLASS>
                    break;

                case (short)ProductionIndex.Program4:
                    // <PROGRAM> ::= <PROGRAM> <METHOD>
                    {
                        Function topFunction = (Function)stack.Pop();
                        ((Body)stack.Peek()).AddStatements(new StatementCollection(topFunction));
                    }
                    break;

                case (short)ProductionIndex.Body:
                    // <BODY> ::= <SUPER_INIT> <THIS_INIT> <BLOCK>
                    break;

                case (short)ProductionIndex.Body2:
                    // <BODY> ::= <THIS_INIT> <BLOCK>
                    break;

                case (short)ProductionIndex.Body3:
                    // <BODY> ::= <SUPER_INIT> <BLOCK>
                    break;

                case (short)ProductionIndex.Body4:
                    // <BODY> ::= <BLOCK>
                    // ничего
                    break;

                case (short)ProductionIndex.This_init_This_Lparan_Rparan:
                    // <THIS_INIT> ::= this '(' <ARGLIST> ')'
                    break;

                case (short)ProductionIndex.Super_init_Super_Lparan_Rparan:
                    // <SUPER_INIT> ::= super '(' <ARGLIST> ')'
                    break;

                case (short)ProductionIndex.Block_Begin_End:
                    // <BLOCK> ::= <VARDECS> begin <STATEMENTS> end
                    stack.Remove(0);
                    stack.Remove(1);
                    Body body = new Body((StatementCollection)stack.Pop(), (VariableCollection)stack.Pop());
                    stack.Push(body);
                    break;

                case (short)ProductionIndex.Block_Begin_End2:
                    // <BLOCK> ::= begin <STATEMENTS> end
                    break;

                case (short)ProductionIndex.Vardeclist_Id_Semi:
                    // <VARDECLIST> ::= <TYPE> Id ';'
                    {
                        stack.Pop();
                        stack.Push(new Variable(null, stack.PopString(), stack.PopType()));
                        stack.Remove(1);
                    }
                    break;

                case (short)ProductionIndex.Vardeclist_Id_Semi2:
                    // <VARDECLIST> ::= <TYPE> Id <VAR_TYPELIST> ';'
                    // удалим из стека ";"
                    {
                        stack.Pop();
                        List<string> variables = new List<string>();
                        while (stack.Peek() is string)
                        {
                            if ((string)stack.Peek() == ",")
                            {
                                stack.Pop();
                            }
                            else
                            {
                                variables.Add(stack.PopString());
                            }
                        }

                        Type var_type = stack.PopType();
                        stack.Pop(); // pop "declare"

                        foreach (string var_name in variables)
                        {
                            stack.Push(new Variable(null, var_name, var_type));
                        }
                    }
                    break;

                case (short)ProductionIndex.Var_typelist_Comma_Id:
                    // <VAR_TYPELIST> ::= ',' Id
                    // ничего не делаем, пусть накапливаются

                    break;

                case (short)ProductionIndex.Var_typelist_Comma_Id2:
                    // <VAR_TYPELIST> ::= <VAR_TYPELIST> ',' Id
                    // последняя переменная типа
                    break;

                case (short)ProductionIndex.Vardecs_Declare:
                    // <VARDECS> ::= declare <VARDECLIST>
                    {
                        VariableCollection var_collection = new VariableCollection();
                        while (stack.Peek() is Variable)
                        {
                            var_collection.Add((Variable)stack.Pop());
                        }
                        stack.Push(var_collection);
                    }
                    break;

                case (short)ProductionIndex.Vardecs_Declare2:
                    // <VARDECS> ::= declare <VARDECLIST> <VARDECS>
                    break;

                case (short)ProductionIndex.Name_Id:
                    // <NAME> ::= Id
                    // ничего не делаем, идентификатор в стеке
                    break;

                case (short)ProductionIndex.Name_Dot_Id:
                    // <NAME> ::= <NAME> '.' Id
                    break;

                case (short)ProductionIndex.Assignment_Eq:
                    // <ASSIGNMENT> ::= <NAME> '=' <EXPRESSION>
                    {
                        if (stack.Peek() is Type)
                        {
                            stack.Remove(2);
                            Type temp_type = stack.PopType();
                            Expression temp_expr = stack.PopExpression();

                            stack.Push(new Variable(temp_expr, stack.PopString(), temp_type));
                        }
                        else
                        {

                            stack.Remove(1);
                            stack.Push(new Assignment(stack.PopExpression(), null, stack.PopString()));
                        }
                    }
                    break;

                case (short)ProductionIndex.Assignment_Lbracket_Rbracket_Eq:
                    // <ASSIGNMENT> ::= <NAME> '[' <EXPRESSION> ']' '=' <EXPRESSION>
                    stack.Remove(1); // =
                    stack.Remove(1); // ]
                    stack.Remove(2); // [
                    stack.Push(new Assignment(stack.PopExpression(), stack.PopExpression(), stack.PopString()));
                    break;

                case (short)ProductionIndex.Factor_This:
                    // <FACTOR> ::= this
                    break;

                case (short)ProductionIndex.Factor_Super:
                    // <FACTOR> ::= super
                    break;

                case (short)ProductionIndex.Factor_Number:
                    // <FACTOR> ::= Number
                    stack.Push(new Literal(stack.PopString(), LiteralType.Integer));
                    break;

                case (short)ProductionIndex.Factor_False:
                    // <FACTOR> ::= false
                    break;

                case (short)ProductionIndex.Factor_True:
                    // <FACTOR> ::= true
                    break;

                case (short)ProductionIndex.Factor_Null:
                    // <FACTOR> ::= null
                    break;

                case (short)ProductionIndex.Factor:
                    // <FACTOR> ::= <ALLOCATOR>
                    {
                        Expression temp_expr = stack.PopExpression();
                        Type temp_type = stack.PopType();
                        stack.Push(temp_expr);
                        stack.Push(temp_type);
                        //stack.Push(new Variable(temp_expr, stack.PopString(), temp_type));
                    }
                    break;

                case (short)ProductionIndex.Factor2:
                    // <FACTOR> ::= <CAST_EXPR>
                    break;

                case (short)ProductionIndex.Allocator_New_Lparan_Rparan:
                    // <ALLOCATOR> ::= new <TYPE> '(' <ARGLIST> ')'
                    break;

                case (short)ProductionIndex.Allocator_New_Lparan_Rparan2:
                    // <ALLOCATOR> ::= new <TYPE> '(' ')'
                    break;

                case (short)ProductionIndex.Allocator_New_Lbracket_Rbracket:
                    // <ALLOCATOR> ::= new <TYPE> '[' <EXPRESSION> ']'
                    {
                        stack.Pop();
                        stack.Remove(1);
                        stack.Remove(2);

                        Expression temp = (Expression)stack.Pop();
                        stack.Push(Type.CreateArrayFromType(stack.PopType()));
                        stack.Push(temp);
                    }
                    break;

                case (short)ProductionIndex.Arglist:
                    // <ARGLIST> ::= <ARGUMENT>
                    stack.Push(new ArgumentCollection((Argument)stack.Pop()));
                    break;

                case (short)ProductionIndex.Arglist_Comma:
                    // <ARGLIST> ::= <ARGLIST> ',' <ARGUMENT>
                    {
                        Argument argument = (Argument)stack.Pop();
                        stack.Pop(1);
                        ((ArgumentCollection)stack.Peek()).Add(argument);
                    }
                    break;

                case (short)ProductionIndex.Argument:
                    // <ARGUMENT> ::= <EXPRESSION>
                    stack.Push(new Argument(stack.PopExpression(), PassMethod.ByValue));
                    break;

                case (short)ProductionIndex.Argument_Ref:
                    // <ARGUMENT> ::= ref <EXPRESSION>
                    stack.Remove(1);
                    stack.Push(new Argument(stack.PopExpression(), PassMethod.ByReference));
                    break;
                case (short)ProductionIndex.Cast_expr_Cast_Lparan_Comma_Rparan:
                    // <CAST_EXPR> ::= cast '(' <TYPE> ',' <EXPRESSION> ')'
                    break;

                case (short)ProductionIndex.Expression:
                    // <EXPRESSION> ::= <EXPRESSION_TERM>
                    // ничего
                    break;

                case (short)ProductionIndex.Expression_Plus:
                    // <EXPRESSION> ::= <EXPRESSION> '+' <EXPRESSION_TERM>
                    {
                        stack.Remove(1);
                        stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Add));
                    }
                    break;

                case (short)ProductionIndex.Expression_Minus:
                    // <EXPRESSION> ::= <EXPRESSION> '-' <EXPRESSION_TERM>
                    {
                        stack.Remove(1);
                        stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Subtract));
                    }
                    break;

                case (short)ProductionIndex.Expression_term:
                    // <EXPRESSION_TERM> ::= <EXPRESSION_FACTOR>
                    // ничего
                    break;

                case (short)ProductionIndex.Expression_term_Times:
                    // <EXPRESSION_TERM> ::= <EXPRESSION_TERM> '*' <EXPRESSION_FACTOR>
                    {
                        stack.Remove(1);
                        stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Multiply));
                    }
                    break;

                case (short)ProductionIndex.Expression_term_Div:
                    // <EXPRESSION_TERM> ::= <EXPRESSION_TERM> '/' <EXPRESSION_FACTOR>
                    {
                        stack.Remove(1);
                        stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Divide));
                    }
                    break;

                case (short)ProductionIndex.Expression_factor:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_BINARY>
                    // ничего
                    break;

                case (short)ProductionIndex.Expression_factor_Percent:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '%' <EXPRESSION_BINARY>
                    break;

                case (short)ProductionIndex.Expression_factor_Gt:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '>' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.GreaterThen));
                    break;

                case (short)ProductionIndex.Expression_factor_Lt:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '<' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.LessThen));
                    break;

                case (short)ProductionIndex.Expression_factor_Gteq:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '>=' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.GraterOrEqualTo));
                    break;

                case (short)ProductionIndex.Expression_factor_Lteq:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '<=' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.LessOrEqualTo));
                    break;

                case (short)ProductionIndex.Expression_factor_Eqeq:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '==' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Equal));
                    break;

                case (short)ProductionIndex.Expression_factor_Num:
                    // <EXPRESSION_FACTOR> ::= <EXPRESSION_FACTOR> '#' <EXPRESSION_BINARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.NotEqual));
                    break;

                case (short)ProductionIndex.Expression_binary:
                    // <EXPRESSION_BINARY> ::= <EXPRESSION_UNARY>
                    // ничего
                    break;

                case (short)ProductionIndex.Expression_binary_Ampamp:
                    // <EXPRESSION_BINARY> ::= <EXPRESSION_BINARY> '&&' <EXPRESSION_UNARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.And));
                    break;

                case (short)ProductionIndex.Expression_binary_Pipepipe:
                    // <EXPRESSION_BINARY> ::= <EXPRESSION_BINARY> '||' <EXPRESSION_UNARY>
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Or));
                    break;

                case (short)ProductionIndex.Expression_unary_Plus:
                    // <EXPRESSION_UNARY> ::= '+' <EXPRESSION_PRIMARY>
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Positive));
                    break;

                case (short)ProductionIndex.Expression_unary_Minus:
                    // <EXPRESSION_UNARY> ::= '-' <EXPRESSION_PRIMARY>
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Negative));
                    break;

                case (short)ProductionIndex.Expression_unary_Exclam:
                    // <EXPRESSION_UNARY> ::= '!' <EXPRESSION_PRIMARY>
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Not));
                    break;

                case (short)ProductionIndex.Expression_unary:
                    // <EXPRESSION_UNARY> ::= <EXPRESSION_PRIMARY>
                    // ничего не делаем
                    break;

                case (short)ProductionIndex.Expression_unary_Lbracket_Rbracket:
                    // <EXPRESSION_UNARY> ::= <EXPRESSION_PRIMARY> '[' <EXPRESSION> ']'
                    stack.Pop(1);
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(stack.PopExpression(), stack.PopExpression(), UnaryOperatorType.Indexer));
                    break;

                case (short)ProductionIndex.Expression_unary_Lparan_Rparan:
                    // <EXPRESSION_UNARY> ::= <EXPRESSION_PRIMARY> '(' <ARGLIST> ')'
                    break;

                case (short)ProductionIndex.Expression_primary:
                    // <EXPRESSION_PRIMARY> ::= <NAME>
                    stack.Push(new Name(stack.PopString()));
                    break;

                case (short)ProductionIndex.Expression_primary2:
                    // <EXPRESSION_PRIMARY> ::= <FUNCTION_CALL>
                    // ничего не делаем
                    break;

                case (short)ProductionIndex.Expression_primary3:
                    // <EXPRESSION_PRIMARY> ::= <FACTOR>
                    // ничего не делаем
                    break;

                case (short)ProductionIndex.Expression_primary_Lparan_Rparan:
                    // <EXPRESSION_PRIMARY> ::= '(' <EXPRESSION> ')'
                    stack.Pop(1);
                    stack.Remove(1);
                    break;

                case (short)ProductionIndex.Statements:
                    // <STATEMENTS> ::= <STATEMENT>
                    stack.Push(new StatementCollection(stack.PopStatement()));
                    break;

                case (short)ProductionIndex.Statements2:
                    // <STATEMENTS> ::= <STATEMENTS> <STATEMENT>
                    Statement statement = stack.PopStatement();
                    ((StatementCollection)stack.Peek()).Add(statement);
                    break;

                case (short)ProductionIndex.Statement:
                    // <STATEMENT> ::= <BLOCK>
                    break;

                case (short)ProductionIndex.Statement2:
                    // <STATEMENT> ::= <METHOD>
                    break;

                case (short)ProductionIndex.Statement3:
                    // <STATEMENT> ::= <CLASS>
                    break;

                case (short)ProductionIndex.Statement_Semi:
                    // <STATEMENT> ::= <FUNCTION_CALL> ';'
                    {
                        stack.Pop(); // ;
                        Call call = stack.Pop() as Call;
                        stack.Push(new CallStatement(call.Arguments, call.Name));
                    }
                    break;

                case (short)ProductionIndex.Statement_Semi2:
                    // <STATEMENT> ::= <ASSIGNMENT> ';'
                    // удаляем ";"
                    stack.Pop(1);
                    break;

                case (short)ProductionIndex.Statement_Semi3:
                    // <STATEMENT> ::= <INPUTSTMT> ';'
                    stack.Pop(1);
                    break;

                case (short)ProductionIndex.Statement_Semi4:
                    // <STATEMENT> ::= <OUTPUTSTMT> ';'
                    stack.Pop(1);
                    break;

                case (short)ProductionIndex.Statement_Return_Semi:
                    // <STATEMENT> ::= return <EXPRESSION> ';'
                    stack.Pop(1);
                    stack.Remove(1);
                    stack.Push(new Return(stack.PopExpression()));
                    break;

                case (short)ProductionIndex.Statement_Return_Semi2:
                    // <STATEMENT> ::= return ';'
                    stack.Pop(2);
                    stack.Push(new Return(null));
                    break;

                case (short)ProductionIndex.Statement_Continue_Semi:
                    // <STATEMENT> ::= continue ';'
                    stack.Pop(2);
                    stack.Push(new Continue(null));
                    break;

                case (short)ProductionIndex.Statement_Break_Semi:
                    // <STATEMENT> ::= break ';'
                    stack.Pop(2);
                    stack.Push(new Break(null));
                    break;

                case (short)ProductionIndex.Statement4:
                    // <STATEMENT> ::= <IFSTMT>
                    break;

                case (short)ProductionIndex.Statement5:
                    // <STATEMENT> ::= <TRYSTMT>
                    break;

                case (short)ProductionIndex.Statement_Loop_End_Loop:
                    // <STATEMENT> ::= loop <STATEMENTS> end loop
                    {
                        stack.Pop(2); // end, loop
                        // создадим бесконечный цикл
                        BinaryExpression be = new BinaryExpression(new Literal("1", LiteralType.String), new Literal("1", LiteralType.String), BinaryOperatorType.Equal);
                        stack.Remove(1); // loop
                        stack.Push(new While(new Body((StatementCollection)stack.Pop(), null), be));
                    }
                    break;

                case (short)ProductionIndex.Statement_Exit_Semi:
                    // <STATEMENT> ::= exit ';'
                    break;

                case (short)ProductionIndex.Statement_Throw_Semi:
                    // <STATEMENT> ::= throw <EXPRESSION> ';'
                    break;

                #region ==> If statements
                case (short)ProductionIndex.Ifstmt_If_Then_End_If:
                    // <IFSTMT> ::= if <EXPRESSION> then <STATEMENTS> end if
                    stack.Pop(2);
                    stack.Remove(1);
                    stack.Remove(2);
                    stack.Push(new If(null, new Body((StatementCollection)stack.Pop(), null), stack.PopExpression()));
                    break;

                case (short)ProductionIndex.Ifstmt_If_Then_End_If2:
                    // <IFSTMT> ::= if <EXPRESSION> then <STATEMENTS> <ELSEPART> end if
                    {
                        stack.Pop(2);
                        stack.Remove(1);

                        Body elseBody = stack.PopBody();

                        Body ifBody = new Body((StatementCollection)stack.Pop(), null);
                        stack.Pop();
                        stack.Remove(1);

                        stack.Push(new If(elseBody, ifBody, stack.PopExpression()));
                    }
                    break;

                case (short)ProductionIndex.Ifstmt_If_Then_End_If3:
                    // <IFSTMT> ::= if <EXPRESSION> then <STATEMENTS> <ELSEIF_PART> <ELSEPART> end if
                    {
                        stack.Pop(2);
                        stack.Remove(1);
                        Body elseBody = stack.PopBody();

                        while (stack.Peek() is If)
                        {
                            (stack.Peek() as If).ElseBody = elseBody;
                            elseBody = new Body(new StatementCollection((If)stack.Pop()), null);
                        }

                        stack.Remove(1); // then
                        stack.Remove(2); // if

                        stack.Push(new If(elseBody, new Body((StatementCollection)stack.Pop(), null), stack.PopExpression()));

                    }
                    break;

                case (short)ProductionIndex.Elsepart_Else:
                    // <ELSEPART> ::= else <STATEMENTS>
                    stack.Push(new Body((StatementCollection)stack.Pop(), null));
                    break;

                case (short)ProductionIndex.Elseif_part_Elsif_Then:
                    // <ELSEIF_PART> ::= elsif <EXPRESSION> then <STATEMENTS>
                    stack.Remove(1);
                    stack.Remove(2);
                    stack.Push(new If(null, new Body((StatementCollection)stack.Pop(), null), stack.PopExpression()));
                    break;

                case (short)ProductionIndex.Elseif_part_Elsif_Then2:
                    // <ELSEIF_PART> ::= elsif <EXPRESSION> then <STATEMENTS> <ELSEIF_PART>
                    {
                        stack.Remove(1);
                        stack.Remove(2);
                        stack.Push(new If(null, new Body((StatementCollection)stack.Pop(), null), stack.PopExpression()));
                    }
                    break;
                #endregion

                #region ==> Try Catch statements
                case (short)ProductionIndex.Trystmt_Try_End_Try:
                    // <TRYSTMT> ::= try <STATEMENTS> <CATCH_CLAUSE> end try
                    break;

                case (short)ProductionIndex.Catch_clause_Catch_Lparan_Id_Rparan:
                    // <CATCH_CLAUSE> ::= catch '(' <TYPE> Id ')' <STATEMENTS>
                    break;

                case (short)ProductionIndex.Catch_clause_Catch_Lparan_Id_Rparan2:
                    // <CATCH_CLAUSE> ::= catch '(' <TYPE> Id ')' <STATEMENTS> <CATCH_CLAUSE>
                    break;
                #endregion

                case (short)ProductionIndex.Outputstmt_Output_Ltlt:
                    {
                        // <OUTPUTSTMT> ::= output '<<' <EXPRESSION>
                        stack.Remove(1);
                        stack.Remove(1);
                        ArgumentCollection args = new ArgumentCollection();
                        args.Add(new Argument((Expression)stack.Pop(), PassMethod.ByValue));
                        Call call = new Call(args, "Write");
                        stack.Push(new CallStatement(call.Arguments, call.Name));
                    }
                    break;

                case (short)ProductionIndex.Outputstmt_Output_Ltlt_Stringliteral:
                    // <OUTPUTSTMT> ::= output '<<' StringLiteral
                    {
                        stack.Remove(1);
                        stack.Remove(1);
                        ArgumentCollection args = new ArgumentCollection();
                        args.Add(new Argument(new Literal(stack.PopString(), LiteralType.String), PassMethod.ByValue));
                        Call call = new Call(args, "Write");
                        stack.Push(new CallStatement(call.Arguments, call.Name));
                    }
                    break;

                case (short)ProductionIndex.Outputstmt_Output_Ltlt_Charliteral:
                    // <OUTPUTSTMT> ::= output '<<' CharLiteral
                    break;

                case (short)ProductionIndex.Inputstmt_Input_Gtgt:
                    {
                        // <INPUTSTMT> ::= input '>>' <NAME>
                        stack.Remove(1);
                        stack.Remove(1);

                        stack.Push(new Assignment(new Call(null, "Read"), null, stack.PopString()));
                    }
                    break;

                case (short)ProductionIndex.Type:
                    // <TYPE> ::= <STRUCTURE_TYPE>

                    break;

                case (short)ProductionIndex.Type2:
                    // <TYPE> ::= <PRIMITIVE_TYPE>
                    // ничего не делаем, тип стеке
                    break;

                case (short)ProductionIndex.Type3:
                    // <TYPE> ::= <ARRAY_TYPE>
                    // ничего не делаем
                    break;

                case (short)ProductionIndex.Primitive_type_Integer:
                    // <PRIMITIVE_TYPE> ::= integer
                    // Создаем тип объекта integer
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Integer));
                    break;

                case (short)ProductionIndex.Primitive_type_Boolean:
                    // <PRIMITIVE_TYPE> ::= boolean
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Boolean));
                    break;

                case (short)ProductionIndex.Structure_type_Id:
                    // <STRUCTURE_TYPE> ::= Id
                    break;

                case (short)ProductionIndex.Array_type_Lbracketrbracket:
                    // <ARRAY_TYPE> ::= <STRUCTURE_TYPE> '[]'
                    break;

                case (short)ProductionIndex.Array_type_Lbracketrbracket2:
                    // <ARRAY_TYPE> ::= <PRIMITIVE_TYPE> '[]'
                    stack.Pop(1);
                    stack.Push(Type.CreateArrayFromType(stack.PopType()));
                    break;

                case (short)ProductionIndex.Access_spec_Private:
                    // <ACCESS_SPEC> ::= private
                    stack.Pop();
                    stack.Push(AccessLevel.al_private);
                    break;

                case (short)ProductionIndex.Access_spec_Protected:
                    // <ACCESS_SPEC> ::= protected
                    stack.Pop();
                    stack.Push(AccessLevel.al_protected);
                    break;

                case (short)ProductionIndex.Access_spec_Public:
                    // <ACCESS_SPEC> ::= public
                    stack.Pop();
                    stack.Push(AccessLevel.al_public);
                    break;

                case (short)ProductionIndex.Field_decl_Semi:
                    {
                        // <FIELD_DECL> ::= <ACCESS_SPEC> <TYPE> <FIELD_DECLLIST> ';'
                        stack.Pop(1);

                        VariableCollection variables = new VariableCollection();
                        while (stack.Peek() is Variable)
                        {
                            variables.Add((Variable)stack.Pop());
                        }

                        AccessLevel acl = AccessLevel.al_public;
                        if (stack.Peek() is AccessLevel)
                        {
                            acl = (AccessLevel)stack.Pop();
                        }

                        foreach (Variable v in variables)
                        {
                            stack.Push(new Field(v.Value, v.Name, v.Type, acl));
                        }

                    }
                    break;

                case (short)ProductionIndex.Field_decllist_Id:
                    // <FIELD_DECLLIST> ::= Id
                    break;

                case (short)ProductionIndex.Field_decllist_Comma_Id:
                    // <FIELD_DECLLIST> ::= <FIELD_DECLLIST> ',' Id
                    // последняя переменная типа
                    {
                        List<object> variables = new List<object>();
                        Type var_type = null;
                        object topStack = null;

                        while (! (stack.Peek() is Type ))
                        {
                            topStack = stack.Pop();
                            if ((string)topStack != ",")
                            {
                                variables.Add(topStack);
                            }
                        }

                        var_type = stack.PopType();

                        foreach (string var_name in variables)
                        {
                            stack.Push(new Variable(null, var_name, var_type));
                        }
                        variables.Clear();
                    }
                    break;

                case (short)ProductionIndex.Method_Method_Lparan_Rparan_Is_Id:
                    // <METHOD> ::= method <M_TYPE> <METHOD_ID> '(' <PARAMETERS> ')' is <BODY> Id
                    {
                        stack.Pop(2);       // id, end
                        stack.Remove(1);    // begin
                        stack.Remove(1);    // is
                        stack.Remove(1);    // )
                        stack.Remove(2);    // (

                        stack.Push(new Function(new Body((StatementCollection)stack.Pop(), null), (ParameterCollection)stack.Pop(), stack.PopString(),
                            stack.PopType()));
                        stack.Remove(1);
                    }
                    break;

                case (short)ProductionIndex.Method_Method_Lparan_Rparan_Is_Id2:
                    // <METHOD> ::= method <M_TYPE> <METHOD_ID> '(' ')' is <BODY> Id
                    stack.Remove(2);
                    stack.Remove(0);
                    stack.Remove(1);
                    stack.Remove(1);

                    stack.Push(new Function(stack.PopBody(), null, stack.PopString(), stack.PopType()));
                    stack.Remove(1);
                    break;

                case (short)ProductionIndex.Method_decl_Method_Id_Lparan_Rparan_Semi:
                    // <METHOD_DECL> ::= <ACCESS_SPEC> method <M_TYPE> Id '(' <PARAMETER_DECL> ')' ';'
                    break;

                case (short)ProductionIndex.Method_decl_Method_Id_Lparan_Rparan_Semi2:
                    // <METHOD_DECL> ::= <ACCESS_SPEC> method <M_TYPE> Id '(' ')' ';'
                    break;

                case (short)ProductionIndex.Method_id_Id_Coloncolon_Id:
                    // <METHOD_ID> ::= Id '::' Id
                    break;

                case (short)ProductionIndex.Method_id_Id:
                    // <METHOD_ID> ::= Id
                    // ничего не делаем, идентификатор стеке
                    break;

                case (short)ProductionIndex.M_type:
                    // <M_TYPE> ::= <TYPE>
                    // ничего не делаем
                    break;

                case (short)ProductionIndex.M_type_Void:
                    // <M_TYPE> ::= void
                    // создаем тип объекта void
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Void));
                    break;

                case (short)ProductionIndex.Parameters:
                    // <PARAMETERS> ::= <PARAMETER>
                    stack.Push(new ParameterCollection((Parameter)stack.Pop()));
                    break;

                case (short)ProductionIndex.Parameters_Comma:
                    // <PARAMETERS> ::= <PARAMETERS> ',' <PARAMETER>
                    {
                        Parameter parameter = (Parameter)stack.Pop();
                        stack.Pop(1);
                        ((ParameterCollection)stack.Peek()).Add(parameter);
                    }
                    break;

                case (short)ProductionIndex.Parameter_Id:
                    // <PARAMETER> ::= <TYPE> Id
                    stack.Push(new Parameter(stack.PopString(), stack.PopType(), PassMethod.ByValue));
                    break;

                case (short)ProductionIndex.Parameter_Ref_Id:
                    // <PARAMETER> ::= ref <TYPE> Id
                    stack.Remove(2);
                    stack.Push(new Parameter(stack.PopString(), stack.PopType(), PassMethod.ByReference));
                    ((Parameter)stack.Peek()).Type.IsRef = true;
                    break;

                case (short)ProductionIndex.Parameters_decl:
                    // <PARAMETERS_DECL> ::= <PARAMETER_DECL>
                    break;

                case (short)ProductionIndex.Parameters_decl_Comma:
                    // <PARAMETERS_DECL> ::= <PARAMETERS_DECL> ',' <PARAMETER_DECL>
                    break;

                case (short)ProductionIndex.Parameter_decl_Id:
                    // <PARAMETER_DECL> ::= <TYPE> Id
                    break;

                case (short)ProductionIndex.Parameter_decl:
                    // <PARAMETER_DECL> ::= <TYPE>
                    break;

                case (short)ProductionIndex.Function_call_Call_Lparan_Rparan:
                    // <FUNCTION_CALL> ::= call <NAME> '(' ')'
                    stack.Pop(2); // (,)
                    stack.Remove(1);
                    stack.Push(new Call(null, stack.PopString()));
                    break;

                case (short)ProductionIndex.Function_call_Call_Lparan_Rparan2:
                    // <FUNCTION_CALL> ::= call <NAME> '(' <ARGLIST> ')'
                    stack.Pop(1);
                    stack.Remove(1);
                    stack.Remove(2);
                    stack.Push(new Call((ArgumentCollection)stack.Pop(), stack.PopString()));
                    break;

                case (short)ProductionIndex.Class_Class_Id_Is_End_Id:
                    // <CLASS> ::= class Id <SUPER_CLASS> is <CLASS_MEMBERLIST> end Id
                    break;

                case (short)ProductionIndex.Class_Class_Id_Is_End_Id2:
                    // <CLASS> ::= class Id is <CLASS_MEMBERLIST> end Id
                    break;

                case (short)ProductionIndex.Class_memberlist:
                    // <CLASS_MEMBERLIST> ::= <CLASS_MEMBER>
                    break;

                case (short)ProductionIndex.Class_memberlist2:
                    // <CLASS_MEMBERLIST> ::= <CLASS_MEMBERLIST> <CLASS_MEMBER>
                    break;

                case (short)ProductionIndex.Class_member:
                    // <CLASS_MEMBER> ::= <FIELD_DECL>
                    break;

                case (short)ProductionIndex.Class_member2:
                    // <CLASS_MEMBER> ::= <METHOD_DECL>
                    break;

                case (short)ProductionIndex.Super_class_Extends_Id:
                    // <SUPER_CLASS> ::= extends Id
                    break;

            }  //switch

            #region Старый вариант
            #region example
            /*switch (production.m_ID)
            {

                case 0: // <Literal> ::= boolean_literal
                    // Create boolean literal object.
                    stack.Push(new Literal(stack.PopString(), LiteralType.Boolean));
                    break;
                case 1: // <Literal> ::= integer_literal
                    // Create integer literal object.
                    stack.Push(new Literal(stack.PopString(), LiteralType.Integer));
                    break;
                case 2: // <Literal> ::= real_literal
                    // Create real literal object.
                    stack.Push(new Literal(stack.PopString(), LiteralType.Real));
                    break;
                case 3: // <Literal> ::= character_literal
                    // Create character literal object.
                    stack.Push(new Literal(stack.PopString(), LiteralType.Character));
                    break;
                case 4: // <Literal> ::= string_literal
                    // Create string literal object.
                    stack.Push(new Literal(stack.PopString(), LiteralType.String));
                    break;
                case 5: // <Type> ::= <Structure_Type>
                    // !!! DO NOTHING !!!
                    break;
                case 6: // <Type> ::= <Primitive_Type>
                    // !!! DO NOTHING !!!
                    break;
                case 7: // <Type> ::= <Array_Type>
                    // !!! DO NOTHING !!!
                    break;
                case 8: // <Structure_Type> ::= identifier
                    // Create structure type object.
                    stack.Push(new Type(stack.PopString()));
                    break;
                case 9: // <Primitive_Type> ::= bool
                    // Create a boolean type object.
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Boolean));
                    break;
                case 10: // <Primitive_Type> ::= int
                    // Create an integer type object.
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Integer));
                    break;
                case 11: // <Primitive_Type> ::= real
                    // Create an real type object.
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Real));
                    break;
                case 12: // <Primitive_Type> ::= char
                    // Create an character type object.
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Character));
                    break;
                case 13: // <Primitive_Type> ::= void
                    // Create an void type object.
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Void));
                    break;
                case 14: // <Array_Type> ::= <Structure_Type> '[' ']'
                    // Create a structure array type.
                    stack.Pop(2);
                    stack.Push(Type.CreateArrayFromType(stack.PopType()));
                    break;
                case 15: // <Array_Type> ::= <Primitive_Type> '[' ']'
                    // Create a primitive array type.
                    stack.Pop(2);
                    stack.Push(Type.CreateArrayFromType(stack.PopType()));
                    break;
                case 16: // <Module> ::= module identifier <Body>
                    // Create a module object.
                    stack.Remove(2);
                    stack.Push(new Module(stack.PopBody(), stack.PopString()));
                    break;
                case 17: // <Body> ::= '{' <Statements> '}'
                    // Create a body object.
                    stack.Pop(1);
                    Body body = new Body((StatementCollection)stack.Pop());
                    stack.Pop(1);
                    stack.Push(body);
                    break;
                case 18: // <Body> ::= '{' '}'
                    // Create a null body object.
                    stack.Pop(2);
                    stack.Push(new Body(null));
                    break;
                case 19: // <Name> ::= identifier
                    // !!! DO NOTHING !!!
                    break;
                case 20: // <Name> ::= <Name> . identifier
                    // Append name section to top of stack.
                    string identifer = stack.PopString();
                    stack.Pop(1);
                    string name = stack.PopString();
                    stack.Push(name + "." + identifer);
                    break;
                case 21: // <Variable_Declarations> ::= <Variable_Declaration>
                    // Create a variable collection containing the variable on top of the stack.
                    stack.Push(new VariableCollection((Variable)stack.Pop()));
                    break;
                case 22: // <Variable_Declarations> ::= <Variable_Declarations> <Variable_Declaration>
                    // Add the variable on top of the stack to the variable collection.
                    Variable variable = (Variable)stack.Pop();
                    ((VariableCollection)stack.Peek()).Add(variable);
                    break;
                case 23: // <Variable_Declaration> ::= <Type> identifier ;
                    // Create a variable object with a null value.
                    stack.Pop(1);
                    stack.Push(new Variable(null, stack.PopString(), stack.PopType()));
                    break;
                case 24: // <Variable_Declaration> ::= <Type> identifier = <Expression> ;
                    // Create a variable object with an expression value.
                    stack.Pop(1);
                    stack.Remove(1);
                    stack.Push(new Variable(stack.PopExpression(), stack.PopString(), stack.PopType()));
                    break;
                case 25: // <Variable_Declaration> ::= <Type> identifier = new '[' <Expression> ']' ;
                    // Create a variable object with an expression value.
                    stack.Pop(2); stack.Remove(1); stack.Remove(1); stack.Remove(1);
                    stack.Push(new Variable(stack.PopExpression(), stack.PopString(), stack.PopType()));
                    break;
                case 26: // <Variable_Declaration> ::= <Type> identifier = '{' <Elements> '}' ;
                    // Create a variable object with an element collection value.
                    stack.Pop(2); stack.Remove(1); stack.Remove(1);
                    stack.Push(new Variable(stack.Pop(), stack.PopString(), stack.PopType()));
                    break;
                case 27: // <Elements> ::= <Element>
                    // Create an element collection containing the element on top of the stack.
                    stack.Push(new ElementCollection((Element)stack.Pop()));
                    break;
                case 28: // <Elements> ::= <Elements> , <Element>
                    // Add the element on top of the stack to the current element collection.
                    Element element = (Element)stack.Pop();
                    stack.Pop(1);
                    ((ElementCollection)stack.Peek()).Add(element);
                    break;
                case 29: // <Element> ::= <Expression>
                    // Create a new element object.
                    stack.Push(new Element(stack.PopExpression()));
                    break;
                case 30: // <Element> ::= '{' <Elements> '}'
                    // Create a new element object with elements inside of it.
                    stack.Pop(1); stack.Remove(1);
                    stack.Push(new Element((ElementCollection)stack.Pop()));
                    break;
                case 31: // <Function_Declaration> ::= <Type> identifier '(' ')' <Body>
                    // Create a function object.
                    stack.Remove(1); stack.Remove(1);
                    stack.Push(new Function(stack.PopBody(), null, stack.PopString(), stack.PopType()));
                    break;
                case 32: // <Function_Declaration> ::= <Type> identifier '(' <Parameters> ')' <Body>
                    // Create a function object.
                    stack.Remove(1); stack.Remove(2);
                    stack.Push(new Function(stack.PopBody(), (ParameterCollection)stack.Pop(), stack.PopString(), stack.PopType()));
                    break;
                case 33: // <Parameters> ::= <Parameter>
                    // Create a parameter collection containing the parameter on top of the stack.
                    stack.Push(new ParameterCollection((Parameter)stack.Pop()));
                    break;
                case 34: // <Parameters> ::= <Parameters> , <Parameter>
                    // Add parameter to parameter collection.
                    Parameter parameter = (Parameter)stack.Pop();
                    stack.Pop(1);
                    ((ParameterCollection)stack.Peek()).Add(parameter);
                    break;
                case 35: // <Parameter> ::= <Type> identifier
                    // Create a parameter object.
                    stack.Push(new Parameter(stack.PopString(), stack.PopType(), PassMethod.ByValue));
                    break;
                case 36: // <Parameter> ::= ref <Type> identifier
                    // Create a parameter object.
                    stack.Remove(2);
                    stack.Push(new Parameter(stack.PopString(), stack.PopType(), PassMethod.ByReference));
                    ((Parameter)stack.Peek()).Type.IsRef = true;
                    break;
                case 37: // <Function_Call> ::= <Name> '(' ')'
                    // Create a function call object.
                    stack.Pop(2);
                    stack.Push(new Call(null, stack.PopString()));
                    break;
                case 38: // <Function_Call> ::= <Name> '(' <Arguments> ')'
                    // Create a function call object.
                    stack.Pop(1); stack.Remove(1);
                    stack.Push(new Call((ArgumentCollection)stack.Pop(), stack.PopString()));
                    break;
                case 39: // <Arguments> ::= <Argument>
                    // Create an argument collection containing the argument on top of stack.
                    stack.Push(new ArgumentCollection((Argument)stack.Pop()));
                    break;
                case 40: // <Arguments> ::= <Arguments> , <Argument>
                    // Add argument to argument collection.
                    Argument argument = (Argument)stack.Pop();
                    stack.Pop(1);
                    ((ArgumentCollection)stack.Peek()).Add(argument);
                    break;
                case 41: // <Argument> ::= <Expression>
                    // Create argument object.
                    stack.Push(new Argument(stack.PopExpression(), PassMethod.ByValue));
                    break;
                case 42: // <Argument> ::= ref <Expression>
                    // Create argument object.
                    stack.Remove(1);
                    stack.Push(new Argument(stack.PopExpression(), PassMethod.ByReference));
                    break;
                case 43: // <Structure_Declaration> ::= struct identifier '{' <Variable_Declarations> '}'
                    // Create structure object.
                    stack.Pop(1); stack.Remove(1); stack.Remove(2);
                    stack.Push(new Structure((VariableCollection)stack.Pop(), stack.PopString()));
                    break;
                case 44: // <Structure_Declaration> ::= struct identifier '{' '}'
                    // Create structure object.
                    stack.Pop(2); stack.Remove(1);
                    stack.Push(new Structure(null, stack.PopString()));
                    break;
                case 45: // <Statements> ::= <Statement>
                    // Create statement collection containing statement on stack.
                    stack.Push(new StatementCollection(stack.PopStatement()));
                    break;
                case 46: // <Statements> ::= <Statements> <Statement>
                    // Add current statement to collection.
                    Statement statement = stack.PopStatement();
                    ((StatementCollection)stack.Peek()).Add(statement);
                    break;
                case 47: // <Statement> ::= <Variable_Declaration>
                    // !!! DO NOTHING !!!
                    break;
                case 48: // <Statement> ::= <Function_Declaration>
                    // !!! DO NOTHING !!!
                    break;
                case 49: // <Statement> ::= <Structure_Declaration>
                    // !!! DO NOTHING !!!
                    break;
                case 50: // <Statement> ::= <Function_Call> ;
                    // Remove ';'
                    stack.Pop(1);
                    Call call = (Call)stack.Pop();
                    stack.Push(new CallStatement(call.Arguments, call.Name));
                    break;
                case 51: // <Statement> ::= <Assignment> ;
                    // Remove ';'
                    stack.Pop(1);
                    break;
                case 52: // <Statement> ::= return <Expression> ;
                    // Create return object.
                    stack.Pop(1); stack.Remove(1);
                    stack.Push(new Return(stack.PopExpression()));
                    break;
                case 53: // <Statement> ::= return ;
                    // Create return object.
                    stack.Pop(2);
                    stack.Push(new Return(null));
                    break;
                case 54: // <Statement> ::= if '(' <Expression> ')' <Body>
                    // Create if statement.
                    stack.Remove(1); stack.Remove(2); stack.Remove(2);
                    stack.Push(new If(null, stack.PopBody(), stack.PopExpression()));
                    break;
                case 55: // <Statement> ::= if '(' <Expression> ')' <Body> else <Body>
                    // Create if statement.
                    stack.Remove(1); stack.Remove(2); stack.Remove(3); stack.Remove(3);
                    stack.Push(new If(stack.PopBody(), stack.PopBody(), stack.PopExpression()));
                    break;
                case 56: // <Statement> ::= while '(' <Expression> ')' <Body>
                    // Create while statement.
                    stack.Remove(1); stack.Remove(2); stack.Remove(2);
                    stack.Push(new While(stack.PopBody(), stack.PopExpression()));
                    break;
                case 57: // <Statement> ::= do <Body> while '(' <Expression> ')'
                    /// Create do statement.
                    stack.Pop(1); stack.Remove(1); stack.Remove(1); stack.Remove(2);
                    stack.Push(new Do(stack.PopExpression(), stack.PopBody()));
                    break;
                case 58: // <Statement> ::= for '(' <Assignment> ; <Expression> ; <Assignment> ')' <Body>
                    // Create for statement.
                    stack.Remove(1); stack.Remove(2); stack.Remove(3); stack.Remove(4); stack.Remove(4);
                    stack.Push(new For(stack.PopBody(), stack.PopAssignment(), stack.PopExpression(), stack.PopAssignment()));
                    break;
                case 59: // <Assignment> ::= set <Name> = <Expression>
                    // Create assignment statement.
                    stack.Remove(1);
                    stack.Remove(2);
                    stack.Push(new Assignment(stack.PopExpression(), null, stack.PopString()));
                    break;
                case 60: // <Assignment> ::= set <Name> [ <Expression> ] = <Expression>
                    // Create assignment statement.
                    stack.Remove(1);
                    stack.Remove(1);
                    stack.Remove(2);
                    stack.Remove(3);
                    stack.Push(new Assignment(stack.PopExpression(), stack.PopExpression(), stack.PopString()));
                    break;
                case 61: // <Assignment> ::= set <Name> '++'
                    // TO DO:
                    break;
                case 62: // <Assignment> ::= set <Name> '--'
                    // TO DO:
                    break;
                case 63: // <Expression> ::= <Expression_Term>
                    // !!! DO NOTHING !!!
                    break;
                case 64: // <Expression> ::= <Expression> '+' <Expression_Term>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Add));
                    break;
                case 65: // <Expression> ::= <Expression> '-' <Expression_Term>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Subtract));
                    break;
                case 66: // <Expression_Term> ::= <Expression_Factor>
                    // !!! DO NOTHING !!!
                    break;
                case 67: // <Expression_Term> ::= <Expression_Term> '*' <Expression_Factor>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Multiply));
                    break;
                case 68: // <Expression_Term> ::= <Expression_Term> / <Expression_Factor>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Divide));
                    break;
                case 69: // <Expression_Factor> ::= <Expression_Binary>
                    // !!! DO NOTHING !!!
                    break;
                case 70: // <Expression_Factor> ::= <Expression_Factor> % <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Modulo));
                    break;
                case 71: // <Expression_Factor> ::= <Expression_Factor> '>' <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.GreaterThen));
                    break;
                case 72: // <Expression_Factor> ::= <Expression_Factor> '<' <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.LessThen));
                    break;
                case 73: // <Expression_Factor> ::= <Expression_Factor> '>=' <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.GraterOrEqualTo));
                    break;
                case 74: // <Expression_Factor> ::= <Expression_Factor> '<=' <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.LessOrEqualTo));
                    break;
                case 75: // <Expression_Factor> ::= <Expression_Factor> == <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Equal));
                    break;
                case 76: // <Expression_Factor> ::= <Expression_Factor> '!=' <Expression_Binary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.NotEqual));
                    break;
                case 77: // <Expression_Binary> ::= <Expression_Unary>
                    // !!! DO NOTHING !!!
                    break;
                case 78: // <Expression_Binary> ::= <Expression_Binary> && <Expression_Unary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.And));
                    break;
                case 79: // <Expression_Binary> ::= <Expression_Binary> '||' <Expression_Unary>
                    // Create binary expression.
                    stack.Remove(1);
                    stack.Push(new BinaryExpression(stack.PopExpression(), stack.PopExpression(), BinaryOperatorType.Or));
                    break;
                case 80: // <Expression_Unary> ::= '+' <Expression_Primary>
                    // Create unary expression.
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Positive));
                    break;
                case 81: // <Expression_Unary> ::= '-' <Expression_Primary>
                    // Create unary expression.
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Negative));
                    break;
                case 82: // <Expression_Unary> ::= '!' <Expression_Primary>
                    // Create unary expression.
                    stack.Remove(1);
                    stack.Push(new UnaryExpression(null, stack.PopExpression(), UnaryOperatorType.Not));
                    break;
                case 83: // <Expression_Unary> ::= <Expression_Primary>
                    // !!! DO NOTHING !!!
                    break;
                case 84: // <Expression_Unary> ::= <Expression_Primary> '[' <Expression> ']'
                    // Create unary expression.
                    stack.Pop(1); stack.Remove(1);
                    stack.Push(new UnaryExpression(stack.PopExpression(), stack.PopExpression(), UnaryOperatorType.Indexer));
                    break;
                case 85: // <Expression_Primary> ::= <Name>
                    // Create name expression.
                    stack.Push(new Name(stack.PopString()));
                    break;
                case 86: // <Expression_Primary> ::= <Function_Call>
                    // !!! DO NOTHING !!!
                    break;
                case 87: // <Expression_Primary> ::= <Literal>
                    // !!! DO NOTHING !!!
                    break;
                case 88:  // <Expression_Primary> ::= '(' <Expression> ')'
                    // Remove pharanthesis
                    stack.Pop(1); stack.Remove(1);
                    break;
                case 109: // <SUPER_CLASS> ::=
                    //
                    stack.Pop(1);
                    break;*/
                #endregion
            /*switch (production.m_ID)
            {
                case 0:     // <PROGRAM> ::= <CLASS> <PROGRAM>
                    break;
                case 1:     // <PROGRAM> ::= <METHOD> <PROGRAM>
                    break;
                case 2:     // <PROGRAM> ::=
                    break;
                case 3:     // <ACCESS_SPEC> ::= private
                    break;
                case 4:     // <ACCESS_SPEC> ::= protected
                    break;
                case 5:     // <ACCESS_SPEC> ::= public
                    break;
                case 6:     // <ADDOP> ::= '+'
                    break;
                case 7:     // <ADDOP> ::= '-'
                    break;
                case 8:     // <ALLOCATOR> ::= new <TYPE> '(' <ARGLIST> ')'
                    break;
                case 9:     // <ALLOCATOR> ::= new <TYPE> '[' <EXPR> ']'
                    break;
                case 10:    // <ARGLIST> ::= <EXPRLIST>
                    break;
                case 11:    // <ARGLIST> ::=
                    break;
                case 12:    // <EXPRLIST> ::= <EXPR>
                    break;
                case 13:    // <EXPRLIST> ::= <EXPR> ',' <EXPRLIST>
                    break;
                case 14:    // <ASSIGNSTMT> ::= <FACTOR> '=' <EXPR>
                    break;
                case 15:    // <BEXPR> ::= <SIMPLEEXPR>
                    break;
                case 16:    // <BEXPR> ::= <SIMPLEEXPR> <RELOP> <SIMPLEEXPR>
                    break;
                case 17:    // <BLOCK> ::= <VARDECS> begin <STMTLIST> end
                    break;
                case 18:    // <BODY> ::= <SUPER_INIT> <THIS_INIT> <BLOCK>
                    break;
                case 19:    // <CALLSTMT> ::= call <FACTOR>
                    break;
                case 20:    // <CAST_EXPR> ::= cast '(' <TYPE> ',' <EXPR> ')'
                    break;
                case 21:    // <CATCH_CLAUSE> ::= catch '(' <TYPE> Id ')' <STMTLIST>
                    break;
                case 22:    // <CEXPR> ::= <BEXPR>
                    break;
                case 23:    // <CEXPR> ::= <BEXPR> and <CEXPR>
                    break;
                case 24:    // <CLASS> ::= class Id <SUPER_CLASS> is <CLASS_MEMBERLIST> end Id
                    break;
                case 25:    // <CLASS_MEMBERLIST> ::= <CLASS_MEMBER> <CLASS_MEMBERLIST>
                    break;
                case 26:    // <CLASS_MEMBERLIST> ::=
                    break;
                case 27:    // <CLASS_MEMBER> ::= <FIELD_DECL>
                    break;
                case 28:    // <CLASS_MEMBER> ::= <METHOD_DECL>
                    break;
                case 29:    // <ELSEPART> ::= else <STMTLIST>
                    break;
                case 30:    // <ELSEPART> ::=
                    break;
                case 31:    // <EXPR> ::= <CEXPR>
                    break;
                case 32:    // <EXPR> ::= <CEXPR> or <EXPR>
                    break;
                case 33:    // <FACTOR> ::= '-' <FACTOR>
                    break;
                case 34:    // <FACTOR> ::= not <FACTOR>
                    break;
                case 35:    // <FACTOR> ::= Number
                    break;
                case 36:    // <FACTOR> ::= false
                    break;
                case 37:    // <FACTOR> ::= true
                    break;
                case 38:    // <FACTOR> ::= null
                    break;
                case 39:    // <FACTOR> ::= <ALLOCATOR>
                    break;
                case 40:    // <FACTOR> ::= <CAST_EXPR>
                    break;
                case 41:    // <FACTOR> ::= <VALUE_OR_REF> <MEMBER_PARTLIST>
                    break;
                case 42:    // <MEMBER_PARTLIST> ::= <MEMBER_PART> <MEMBER_PARTLIST>
                    break;
                case 43:    // <MEMBER_PARTLIST> ::=
                    // ничего не делаем
                    break;
                case 44:    // <FIELD_DECL> ::= <ACCESS_SPEC> <TYPE> Id <FIELD_DECLLIST> ';'
                    break;
                case 45:    // <FIELD_DECLLIST> ::= ',' Id <FIELD_DECLLIST>
                    break;
                case 46:    // <FIELD_DECLLIST> ::=
                    break;
                case 47:    // <IFSTMT> ::= if <EXPR> then <STMTLIST> <ELSEIF_PART> <ELSEPART> end if
                    break;
                case 48:    // <ELSEIF_PART> ::= elsif <EXPR> then <STMTLIST> <ELSEIF_PART>
                    break;
                case 49:    // <ELSEIF_PART> ::=
                    break;
                case 50:    // <INPUTSTMT> ::= input '>>' <FACTOR>
                    break;
                case 51:    // <LOOPSTMT> ::= loop <STMTLIST> end loop
                    break;
                case 52:    // <MEMBER_PART> ::= '.' Id
                    break;
                case 53:    // <MEMBER_PART> ::= '.' Id '(' <ARGLIST> ')'
                    break;
                case 54:    // <MEMBER_PART> ::= '.' Id '[' <EXPR> ']'
                    break;
                case 55:    // <METHOD> ::= method <M_TYPE> <METHOD_ID> '(' <PARAMETERS> ')' is <BODY> Id
                    break;
                case 56:    // <METHOD_DECL> ::= <ACCESS_SPEC> method <M_TYPE> Id '(' <PARAMETER_DECL> ')' ';'
                    break;
                case 57:    // <METHOD_ID> ::= Id '::' Id
                    break;
                case 58:    // <METHOD_ID> ::= Id
                    break;
                case 59:    // <M_TYPE> ::= <TYPE>
                    break;
                case 60:    // <M_TYPE> ::= void
                    // создаем тип объекта void
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Void));
                    break;
                case 61:    // <MULTOP> ::= '*'
                    break;
                case 62:    // <MULTOP> ::= '/'
                    break;
                case 63:    // <MULTOP> ::= mod
                    break;
                case 64:    // <OPTIONAL_ID> ::= Id
                    break;
                case 65:    // <OPTIONAL_ID> ::=
                    break;
                case 66:    // <OUTPUTSTMT> ::= output '<<' <EXPR>
                    break;
                case 67:    // <OUTPUTSTMT> ::= output '<<' <STRING_OR_CHAR>
                    break;
                case 68:    // <STRING_OR_CHAR> ::= StringLiteral
                    break;
                case 69:    // <STRING_OR_CHAR> ::= CharLiteral
                    break;
                case 70:    // <STRING_OR_CHAR> ::=
                    break;
                case 71:    // <PARAMETER_DECL> ::= <TYPE> <OPTIONAL_ID> <PARAMETER_DECLL>
                    break;
                case 72:    // <PARAMETER_DECL> ::=
                    break;
                case 73:    // <PARAMETER_DECLL> ::= ',' <TYPE> <OPTIONAL_ID> <PARAMETER_DECLL>
                    break;
                case 74:    // <PARAMETER_DECLL> ::=
                    break;
                case 75:    // <PARAMETERS> ::= <TYPE> Id <PARAMETER_TYPELIST>
                    break;
                case 76:    // <PARAMETERS> ::=
                    // create an empty collection of parameters
                    stack.Push(new ParameterCollection());
                    break;
                case 77:    // <PARAMETER_TYPELIST> ::= ',' <TYPE> Id <PARAMETER_TYPELIST>
                    break;
                case 78:    // <PARAMETER_TYPELIST> ::=
                    break;
                case 79:    // <RELOP> ::= '=='
                    break;
                case 80:    // <RELOP> ::= '<'
                    break;
                case 81:    // <RELOP> ::= '<='
                    break;
                case 82:    // <RELOP> ::= '>'
                    break;
                case 83:    // <RELOP> ::= '>='
                    break;
                case 84:    // <RELOP> ::= '#'
                    break;
                case 85:    // <SIMPLEEXPR> ::= <TERM> <SIMPLEEXPRR>
                    break;
                case 86:    // <SIMPLEEXPRR> ::= <ADDOP> <TERM> <SIMPLEEXPRR>
                    break;
                case 87:    // <SIMPLEEXPRR> ::=
                    break;
                case 88:    // <STMT> ::= <BLOCK>
                    break;
                case 89:    // <STMT> ::= <TRYSTMT>
                    break;
                case 90:    // <STMT> ::= <IFSTMT>
                    break;
                case 91:    // <STMT> ::= <LOOPSTMT>
                    break;
                case 92:    // <STMT> ::= <ASSIGNSTMT>
                    break;
                case 93:    // <STMT> ::= <CALLSTMT>
                    break;
                case 94:    // <STMT> ::= <OUTPUTSTMT>
                    break;
                case 95:    // <STMT> ::= <INPUTSTMT>
                    break;
                case 96:    // <STMT> ::= continue
                    break;
                case 97:    // <STMT> ::= break
                    break;
                case 98:    // <STMT> ::= return
                    break;
                case 99:    // <STMT> ::= return <EXPR>
                    break;
                case 100:   // <STMT> ::= exit
                    break;
                case 101:   // <STMT> ::= throw <EXPR>
                    break;
                case 102:   // <STMTLIST> ::= <STMT> ';' <STMTLISTT>
                    break;
                case 103:   // <STMTLIST> ::=
                    break;
                case 104:   // <STMTLISTT> ::= <STMT> ';' <STMTLISTT>
                    break;
                case 105:   // <STMTLISTT> ::=
                    break;
                case 106:   // <SUPER_INIT> ::= super '(' <ARGLIST> ')'
                    break;
                case 107:   // <SUPER_INIT> ::=
                    // ничего делать не надо
                    break;
                case 108:   // <SUPER_CLASS> ::= extends Id
                    break;
                case 109:   // <SUPER_CLASS> ::=
                    break;
                case 110:   // <TERM> ::= <FACTOR> <TERMLIST>
                    break;
                case 111:   // <TERMLIST> ::= <MULTOP> <FACTOR> <TERMLIST>
                    break;
                case 112:   // <TERMM> ::=
                    break;
                case 113:   // <THIS_INIT> ::= this '(' <ARGLIST> ')'
                    break;
                case 114:   // <THIS_INIT> ::=
                    // ничего делать не надо
                    break;
                case 115:   // <TRYSTMT> ::= try <STMTLIST> <CATCH_CLAUSE> <CATCH_CLAUSEE> end try
                    break;
                case 116:   // <CATCH_CLAUSEE> ::= <CATCH_CLAUSE> <CATCH_CLAUSEE>
                    break;
                case 117:   // <CATCH_CLAUSEE> ::=
                    break;
                case 118:   // <TYPE> ::= <Structure_Type>
                    // ничего делать не надо
                    break;
                case 119:   // <TYPE> ::= <Primitive_Type>
                    // ничего не делаем
                    break;
                case 120:   // <TYPE> ::= <Array_Type>
                    break;
                case 121:   // <Primitive_Type> ::= integer
                    // Создаем тип объекта integer
                    stack.Pop(1);
                    stack.Push(new Type(PrimitiveType.Integer));
                    break;
                case 122:   // <Primitive_Type> ::= boolean
                    break;
                case 123:   // <Structure_Type> ::= Id
                    break;
                case 124:   // <Array_Type> ::= <Structure_Type> '[]'
                    break;
                case 125:   // <Array_Type> ::= <Primitive_Type> '[]'
                    break;
                case 126:   // <VALUE_OR_REF> ::= this
                    break;
                case 127:   // <VALUE_OR_REF> ::= super
                    break;
                case 128:   // <VALUE_OR_REF> ::= Id
                    // ничего не делаем, пусть идентификатор лежит в стеке
                    break;
                case 129:   // <VALUE_OR_REF> ::= Id '[' <EXPR> ']'
                    break;
                case 130:   // <VALUE_OR_REF> ::= Id '(' <ARGLIST> ')'
                    break;
                case 131:   // <VALUE_OR_REF> ::= '(' <EXPR> ')'
                    // ничего делать не надо
                    break;
                case 132:   // <VARDECLIST> ::= <TYPE> Id <VAR_TYPELIST> ';'
                    // удалим с вершины стека ";"
                    stack.Pop();
                    break;
                case 133:   // <VAR_TYPELIST> ::= ',' Id <VAR_TYPELIST>
                    List<object> variables = new List<object>();
                    Type var_type = null;

                    object topStack = stack.Pop();

                    if (topStack is VariableCollection)
                    {
                        stack.Push(topStack);
                        break;
                    }

                    while ((string)topStack != "declare")
                    {
                        if ((string)topStack != ",")
                        {
                            variables.Add(topStack);
                        }

                        topStack = stack.Pop();

                        if (topStack is Type)
                        {
                            var_type = (Type)topStack;
                            topStack = stack.Pop();
                        }
                    }

                    VariableCollection var_collection = new VariableCollection();
                    foreach (string var_name in variables)
                    {
                        var_collection.Add(new Variable(null, var_name, var_type));
                    }
                    stack.Push(var_collection);
                    variables.Clear();
                    break;
                case 134:   // <VAR_TYPELIST> ::=
                    break;
                case 135:   // <VARDECS> ::= declare <VARDECLIST> <VARDECS>
                    // ничего не делаем VariableCollection могут быть много
                    break;
                case 136:   // <VARDECS> ::=
                    // ничего не делаем
                    break;
            }
            */
            #endregion
        }