Beispiel #1
0
        public override void VisitIfNode(IfNode bl)
        {
            Console.WriteLine(Tag + " VisitIfNode");

            bl.Cond.Visit(this);
            var ifThenLine = new ThreeAddrLine();

            ifThenLine.Label  = GenNewLabel();
            ifThenLine.LeftOp = GetLastLine().Accum;
            ifThenLine.OpType = ThreeAddrOpType.IfGoto;
            Data.Add(ifThenLine);
            if (bl.ElseB != null)
            {
                bl.ElseB.Visit(this);
            }
            var outsideIfLine = new ThreeAddrLine();

            outsideIfLine.Label  = GenNewLabel();
            outsideIfLine.OpType = ThreeAddrOpType.Goto;
            Data.Add(outsideIfLine);
            ifThenLine.RightOp = GenNewLabel();
            bl.ThenB.Visit(this);
            InsertNop();
            outsideIfLine.RightOp = GetLastLine().Label;
        }
Beispiel #2
0
        public override void VisitCycleNode(CycleNode c)
        {
            Console.WriteLine(Tag + " VisitCycleNode");

            var startLoopLabel = GenNewLabel();

            c.Expr.Visit(this);

            var whileLine = new ThreeAddrLine();

            whileLine.Label  = GenNewLabel();
            whileLine.LeftOp = GetLastLine().Accum;
            whileLine.OpType = ThreeAddrOpType.IfGoto;
            Data.Add(whileLine);

            var outsideWhileLine = new ThreeAddrLine();

            outsideWhileLine.Label  = GenNewLabel();
            outsideWhileLine.OpType = ThreeAddrOpType.Goto;
            Data.Add(outsideWhileLine);
            whileLine.RightOp = GenNewLabel();
            c.Stat.Visit(this);

            var gotoStartLine = new ThreeAddrLine();

            gotoStartLine.Label   = GenNewLabel();
            gotoStartLine.OpType  = ThreeAddrOpType.Goto;
            gotoStartLine.RightOp = startLoopLabel;
            Data.Add(gotoStartLine);

            InsertNop();
            outsideWhileLine.RightOp = GetLastLine().Label;
        }
Beispiel #3
0
        public override void VisitReadNode(ReadNode rd)
        {
            var readLine = new ThreeAddrLine();

            readLine.Label  = GenNewLabel();
            readLine.Accum  = rd.Id.Name;
            readLine.OpType = ThreeAddrOpType.Read;
            Data.Add(readLine);
        }
Beispiel #4
0
        public override void VisitIntNumNode(IntNumNode num)
        {
            var line = new ThreeAddrLine();

            line.Accum  = num.Num.ToString();
            line.Label  = GenNewLabel();
            line.OpType = ThreeAddrOpType.Nop;
            Data.Add(line);
        }
Beispiel #5
0
        public override void VisitWriteNode(WriteNode w)
        {
            Console.WriteLine(Tag + " VisitWriteNode");
            w.Expr.Visit(this);
            var printLine = new ThreeAddrLine();

            printLine.Label   = GenNewLabel();
            printLine.RightOp = GetLastLine().Accum;
            printLine.OpType  = ThreeAddrOpType.Write;
            Data.Add(printLine);
        }
Beispiel #6
0
        public override void VisitIdNode(IdNode id)
        {
            Console.WriteLine(Tag + " VisitIdNode");
            var line = new ThreeAddrLine();

            line.Accum   = GenNewTemporaryVariable();
            line.Label   = GenNewLabel();
            line.OpType  = ThreeAddrOpType.Assign;
            line.RightOp = id.Name;
            Data.Add(line);
        }
Beispiel #7
0
        public override void VisitAssignNode(AssignNode a)
        {
            Console.WriteLine(Tag + " VisitAssingNode");
            if (a == null)
            {
                return;
            }
            a.Expr.Visit(this);
            var line = new ThreeAddrLine();

            line.Accum   = a.Id.Name;
            line.RightOp = GetLastLine().Accum;
            line.Label   = GenNewLabel();
            line.OpType  = ThreeAddrOpType.Assign;
            Data.Add(line);
        }
Beispiel #8
0
        private bool Recognize(ThreeAddrLine line)         // метод получает строку трехадресного кода, конвертирует операнты и записывает результат.
        {
            int  a = 0, b = 0;
            bool isaconst = int.TryParse(line.LeftOp, out a);             // Получаем левый оперант.
            bool isbconst = int.TryParse(line.RightOp, out b);

            if (line.LeftOp == null)
            {
                isaconst = true;
                a        = 0;
            }
            string res = null;

            if (!isaconst && !isbconst && (line.LeftOp != line.RightOp))
            {
                return(false);                                                                     // обе переменны, которые не равны друг другу, то не наш случай
            }
            // Конвертируем операнды и считаем результат
            if (!isaconst && !isbconst)
            {
                res = ComputeBothVar(line.OpType);
            }
            if (isaconst && (a == 1 || a == 0))
            {
                res = ComputeVarRigth(a, line.RightOp, line.OpType);
            }
            if (isbconst && (b == 1 || b == 0))
            {
                res = ComputeVarLeft(line.LeftOp, b, line.OpType);
            }

            if (res != null)
            {
                line.LeftOp  = null;                   // Просто зануляем.
                line.OpType  = ThreeAddrOpType.Assign; // записываем в тип операции assign.
                line.RightOp = res;
                return(true);
            }
            return(false);
        }
Beispiel #9
0
        public List <ThreeAddrLine> ReadTextFile(string FilePath) // Метод читает трёхадерсную программу из текстового файла.
        {
            BinaryFormatter      Formater = new BinaryFormatter();
            List <ThreeAddrLine> Code     = new List <ThreeAddrLine>();

            using (StreamReader FS = new StreamReader(FilePath))
            {
                string line;
                while ((line = FS.ReadLine()) != null)
                {
                    line = line.Replace("=", " ");
                    line = line.Replace(":", " ");
                    line = Regex.Replace(line, @"\s+", " ");

                    string[] tokens      = line.Split(' ');
                    int      size_tokens = tokens.Count();

                    ThreeAddrLine threeAddrLine = new ThreeAddrLine();

                    threeAddrLine.Label = tokens[0];

                    // 1
                    if (tokens[1] == "nop") // 35:  =  nop
                    {
                        threeAddrLine.OpType = "nop";
                        Code.Add(threeAddrLine);
                        continue;
                    }

                    if (tokens[1] == "write" ||
                        tokens[1] == "goto"
                        ) // 39:  =  write p11
                    {
                        threeAddrLine.OpType  = tokens[1];
                        threeAddrLine.RightOp = tokens[2];
                        Code.Add(threeAddrLine);
                        continue;
                    }

                    // 2
                    if (tokens[2] == "nop" ||
                        tokens[2] == "read"
                        ) // 40: 5 =  nop
                    {
                        threeAddrLine.OpType = tokens[2];
                        threeAddrLine.Accum  = tokens[1];
                        Code.Add(threeAddrLine);
                        continue;
                    }

                    if (tokens[2] == "ifgoto") // 78:  = p29 ifgoto 80
                    {
                        threeAddrLine.OpType  = "ifgoto";
                        threeAddrLine.LeftOp  = tokens[1];
                        threeAddrLine.RightOp = tokens[3];
                        Code.Add(threeAddrLine);
                        continue;
                    }

                    if (tokens[2] == "assign" ||
                        tokens[2] == "not"
                        ) // 36: p10 =  assign v2
                    {
                        threeAddrLine.OpType  = tokens[2];
                        threeAddrLine.Accum   = tokens[1];
                        threeAddrLine.RightOp = tokens[3];
                        Code.Add(threeAddrLine);
                        continue;
                    }


                    // 3
                    if (tokens[3] == "or" ||
                        tokens[3] == "and" ||
                        tokens[3] == "+" ||
                        tokens[3] == "-" ||
                        tokens[3] == "/" ||
                        tokens[3] == "*" ||
                        tokens[3] == "<" ||
                        tokens[3] == ">" ||
                        tokens[3] == "<=" ||
                        tokens[3] == ">=" ||
                        tokens[3] == "==" ||
                        tokens[3] == "!=" ||
                        tokens[3] == "assign"
                        ) // 45: p12 = p13 or 0
                    {
                        threeAddrLine.OpType  = tokens[3];
                        threeAddrLine.Accum   = tokens[1];
                        threeAddrLine.LeftOp  = tokens[2];
                        threeAddrLine.RightOp = tokens[4];

                        Code.Add(threeAddrLine);
                        continue;
                    }
                }
            }
            return(Code);
        }