示例#1
0
        public static void Reduce(ref Stack <Term> SS, ref Stack <Term> ST)
        {
            var  rightOperand = ST.Pop();
            var  operatorTerm = SS.Pop();
            Term leftOperand  = null;

            if (ST.Count > 0 && (operatorTerm.Type != TermType.dec && operatorTerm.Type != TermType.inc &&
                                 operatorTerm.Type != TermType.compl && operatorTerm.Type != TermType.reference &&
                                 operatorTerm.Type != TermType.dereference && operatorTerm.Type != TermType.not))
            {
                leftOperand = ST.Pop();
            }

            ADExpression expression = new ADExpression();

            if (rightOperand.Expression != null)
            {
                expression.Right = rightOperand.Expression;
            }
            else
            {
                expression.Right = GetExpression(rightOperand.STRecord);
            }

            expression.Operator = operatorTerm.Type;


            if (leftOperand != null)
            {
                if (leftOperand.Expression != null)
                {
                    expression.Left = leftOperand.Expression;
                }
                else
                {
                    expression.Left = GetExpression(leftOperand.STRecord);
                }
            }

            if (expression.Operator == TermType.asgn)
            {
                if (leftOperand.STRecord.Type != STType.variable && leftOperand.STRecord.Type != STType.array)
                {
                    ParserFunctions.SyntaxError("Na leve strane operace prirazeni musi byt promenna.");
                }
            }

            ST.Push(new Term()
            {
                Type = TermType.id, Expression = expression
            });
        }
示例#2
0
        public static string PrintOperation(ADExpression expression, bool dereference = false)
        {
            string result = string.Empty;

            if (expression.Right != null)
            {
                result += ("popq %rsi") + Environment.NewLine;
            }

            if (expression.Left != null)
            {
                result += ("popq %rdx") + Environment.NewLine;
            }

            switch (expression.Operator)
            {
            case TermType.plus:
                if (expression.Left is ADVariable &&
                    (expression.Left as ADVariable).STRecord.Type == Parser.SymbolTable.STType.array &&
                    !dereference)
                {
                    result += "#Nasobim index 8 kvuli poli" + Environment.NewLine;
                    result += "pushq %rdx" + Environment.NewLine;

                    result += "movq %rsi, %rax" + Environment.NewLine;
                    result += "movq $8, %rcx" + Environment.NewLine;
                    result += "mulq %rcx" + Environment.NewLine;
                    result += "movq %rax, %rsi" + Environment.NewLine;

                    result += "popq %rdx" + Environment.NewLine;
                }
                result += ("addq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.compl:
                result += "notq %rsi" + Environment.NewLine;
                result += "movq %rsi, %rdx" + Environment.NewLine;
                break;

            case TermType.minus:
                result += ("subq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.binAnd:
                result += ("andq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.mul:
                result += ("movq %rsi, %rax") + Environment.NewLine;
                result += ("mulq %rdx") + Environment.NewLine;
                result += ("movq %rax, %rdx") + Environment.NewLine;
                break;

            case TermType.div:
                result += "movq %rdx, %rcx" + Environment.NewLine;
                result += "xorq %rdx, %rdx" + Environment.NewLine;
                result += "movq %rcx, %rax" + Environment.NewLine;
                result += "divq %rsi" + Environment.NewLine;
                result += "movq %rax, %rdx" + Environment.NewLine;
                break;

            case TermType.left:
                result += ("mov %sil, %cl") + Environment.NewLine;
                result += ("shlq %cl, %rdx") + Environment.NewLine;
                break;

            case TermType.right:
                result += ("mov %sil, %cl") + Environment.NewLine;
                result += ("shrq %cl, %rdx") + Environment.NewLine;
                break;

            case TermType.binOr:
                result += ("orq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.rightEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.right, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.mod:
                result += "movq %rdx, %rcx" + Environment.NewLine;
                result += "xorq %rdx, %rdx" + Environment.NewLine;
                result += "movq %rcx, %rax" + Environment.NewLine;
                result += "divq %rsi" + Environment.NewLine;
                break;

            case TermType.modEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.mod, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.leftEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.left, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.reference:
                result += ($"leaq {(expression.Right as ADVariable).STRecord.Address}, %rdx") + Environment.NewLine;
                break;

            case TermType.dereference:
                result += ("popq %rdx") + Environment.NewLine;
                result += ("movq (%rdx), %rcx") + Environment.NewLine;
                result += ("movq %rcx, %rdx") + Environment.NewLine;
                break;

            case TermType.less:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("setl %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.lessEq:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("setle %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.grt:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("setg %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.grtEq:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("setge %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.eq:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("sete %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.negEq:
                result += ("cmpq %rsi, %rdx") + Environment.NewLine;
                result += ("setne %cl") + Environment.NewLine;
                result += ("xorq %rdx, %rdx") + Environment.NewLine;
                result += ("mov %cl, %dl") + Environment.NewLine;
                break;

            case TermType.logAnd:
                result += GetLogicalExpression("%rdx");
                result += GetLogicalExpression("%rsi");

                result += ("andq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.logOr:
                result += ("orq %rsi, %rdx") + Environment.NewLine;
                break;

            case TermType.xorEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.xor, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.xor:
                result += "xorq %rsi, %rdx" + Environment.NewLine;
                break;

            case TermType.mulEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.mul, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.plusEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.plus, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;

            case TermType.minusEq:
                result += PrintExpression(new ADExpression {
                    Left = expression.Left, Operator = TermType.minus, Right = expression.Right
                });
                result += PrintAssignRdx(expression.Left);
                break;
            }

            result += ("pushq %rdx") + Environment.NewLine;

            return(result);
        }
示例#3
0
        public static IADExpression Precedence(TokenType endType, bool decl = false)
        {
            Stack <Term> SS = new Stack <Term>(); // Sign stack
            Stack <Term> ST = new Stack <Term>(); // Term stack

            int numOfLeftB  = 0;
            int numOfRightB = 0;

            bool mustBeId   = true;
            Term actualTerm = null;

            SS.Push(new Term()
            {
                Type = TermType.end
            });

            while (true)
            {
                if (actualTerm == null || actualTerm.Type != TermType.end)
                {
                    actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl);
                }

                var stackSym = SS.Peek();

                if (actualTerm.Type == TermType.leftBr)
                {
                    numOfLeftB++;
                }

                if (actualTerm.Type == TermType.rightBr)
                {
                    numOfRightB++;
                }

                if ((numOfRightB > numOfLeftB) && endType == TokenType.semiType)
                {
                    ParserFunctions.SyntaxError("Neocekavany konec vyrazu.");
                }

                if (actualTerm.Type == TermType.leftABtype)
                {
                    if (ST.Count == 0)
                    {
                        ParserFunctions.SyntaxError("Vyraz nemuze zacinat znakem \'[\'");
                    }

                    var arrayTerm = ST.Pop();
                    var record    = arrayTerm.STRecord;

                    MainFSM.Index--;

                    var arrayValue = new ADArrayValue()
                    {
                        STRecord = record
                    };

                    arrayValue.ComputeIndexes();

                    if (arrayTerm.Expression != null)
                    {
                        arrayValue.ArrayExpression = arrayTerm.Expression;
                    }

                    arrayTerm.Expression = arrayValue;

                    actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl);

                    if (actualTerm.Type == TermType.leftBr)
                    {
                        MainFSM.Index--;
                        var fceCall = ParserFunctions.fce_call();
                        fceCall.Expression = arrayValue;

                        ST.Push(new Term()
                        {
                            Expression = fceCall, Type = TermType.id
                        });

                        actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl);
                    }
                    else
                    {
                        ST.Push(arrayTerm);
                    }
                }

                if (mustBeId && actualTerm.Type == TermType.binAnd)
                {
                    actualTerm.Type = TermType.reference;
                }
                else if (mustBeId && actualTerm.Type == TermType.mul)
                {
                    actualTerm.Type = TermType.dereference;
                }

                if (actualTerm.Type == TermType.inc || actualTerm.Type == TermType.dec)
                {
                    var expr = new ADExpression();
                    expr.Operator = actualTerm.Type;

                    if (mustBeId)
                    {
                        actualTerm = GetNextTerm(endType, numOfLeftB, numOfRightB, ref SS, decl);

                        if (actualTerm.Type != TermType.id)
                        {
                            ParserFunctions.SyntaxError("Byl ocekavan identifikator.");
                        }

                        expr.Right = GetExpression(actualTerm.STRecord);

                        mustBeId = false;
                    }
                    else
                    {
                        actualTerm = ST.Pop();
                        expr.Left  = GetExpression(actualTerm.STRecord);
                    }

                    var newTerm = new Term {
                        Expression = expr
                    };
                    ST.Push(newTerm);
                    continue;
                }

                switch (precTable[(int)stackSym.Type, (int)actualTerm.Type])
                {
                case L:
                    if (actualTerm.Type == TermType.id)
                    {
                        if (mustBeId)
                        {
                            ST.Push(actualTerm);
                            mustBeId = false;
                        }
                        else
                        {
                            ParserFunctions.SyntaxError("Byl ocekavan operator.");
                        }
                    }
                    else if ((actualTerm.Type != TermType.id) && (actualTerm.Type != TermType.end))
                    {
                        if (!mustBeId || actualTerm.Type == TermType.leftBr ||
                            actualTerm.Type == TermType.rightBr)
                        {
                            SS.Push(actualTerm);
                            mustBeId = true;
                        }
                        else if (mustBeId && (actualTerm.Type == TermType.not || actualTerm.Type == TermType.minus ||
                                              actualTerm.Type == TermType.plus || actualTerm.Type == TermType.compl ||
                                              actualTerm.Type == TermType.reference || actualTerm.Type == TermType.dereference))
                        {
                            SS.Push(actualTerm);
                        }
                        else
                        {
                            ParserFunctions.SyntaxError("Byla ocekavana hodnota typu long.");
                        }
                    }
                    break;

                case G:
                    if (actualTerm.Type == TermType.rightBr)
                    {
                        while (stackSym.Type != TermType.leftBr)
                        {
                            Reduce(ref SS, ref ST);
                            stackSym = SS.Peek();
                        }
                        SS.Pop();
                    }
                    else
                    {
                        Reduce(ref SS, ref ST);
                        if (actualTerm.Type != TermType.end)
                        {
                            SS.Push(actualTerm);
                            mustBeId = true;
                        }
                    }
                    break;

                case E:
                    SS.Pop();
                    break;

                case B:
                    ParserFunctions.SyntaxError("Chyba ve vyrazu.");
                    break;

                case S:
                    break;
                }

                if (actualTerm.Type == TermType.end && stackSym.Type == TermType.end)
                {
                    break;
                }
            }

            MainFSM.Index--;

            if (ST.Count > 0)
            {
                var result = ST.Pop();
                if (result.Expression == null)
                {
                    if (result.STRecord.Type == STType.constant)
                    {
                        result.Expression = new ADConstant {
                            Value = result.STRecord.Value
                        };
                    }
                    else if (result.STRecord.Type == STType.variable || result.STRecord.Type == STType.array || result.STRecord.Type == STType.str)
                    {
                        result.Expression = new ADVariable
                        {
                            Name     = result.STRecord.Name,
                            Type     = ADVariable.VarType.variable,
                            STRecord = result.STRecord
                        };
                    }
                    else if (result.STRecord.Type == STType.function)
                    {
                        result.Expression = ParserFunctions.fce_call();
                    }
                }
                return(result.Expression);
            }

            return(null);
        }