Example #1
0
 public Parser(Scanner scanner)
 {
     this.scanner = scanner;
     errors = new Errors();
 }
Example #2
0
        static void Main(string[] args)
        {
            string filename;
            if (args.Length > 0)
            {
                filename = args[0];
            }
            else
            {
                filename = "Test";
            }

            Scanner scanner = new Scanner(filename + ".LLC");
            Parser parser = new Parser(scanner);
            parser.tab = new SymbolTable(parser);
            parser.gen = new CodeGenerator();
            parser.Parse();

            if (parser.errors.count == 0)
            {
                Console.WriteLine("Проверка синтаксиса прошла успешно");
                //Состовление списка нодов
                var mNodes = parser.tab.PortObjs.Select(t => new MultiNode {BaseType = t.type+"Port",name = t.name,wide = t.wide }).ToList();
                mNodes.AddRange(parser.tab.Trigers.Select(t => new MultiNode {BaseType = "TRIGD",name = t.name,wide = t.wide }));
                mNodes.AddRange(parser.tab.WireObjs.Select(t => new MultiNode { BaseType = "DUMMY", name = t.name, wide = t.wide }));
                mNodes.AddRange(parser.tab.ConstObjs.Select(t => new MultiNode { BaseType = "CONST_" + t.val.ToString("X4") + "_" , name = t.name, wide = t.wide }));
                mNodes.AddRange(parser.tab.Bops.Select(t => new MultiNode { BaseType = t.opType, name = t.Name, wide = 0 }));
                //Состовление списка соеденений
                var mWires = parser.tab.conections.Select(t => new MultiWire { Src = t.from, Dist = t.to, DistPort = t.ToPort, SrcPort = t.FromPort }).ToList();
                //Определение размерностей
                //Установка выходов на логических опперациях
                var logicOp = mNodes.Where(t => t.BaseType == "EQ" || t.BaseType == "NOTEQ" || t.BaseType == "MORE"
                                             || t.BaseType == "LESS" || t.BaseType == "LESSEQ" || t.BaseType == "MOREEQ").ToList();
                foreach (var node in logicOp)
                {
                    node.outWide = 1;
                }

                bool NextIterration = true;

                while (NextIterration)
                {
                    NextIterration = false;
                    //установка воходов на нодах
                    var unUpdatedOp = mNodes.Where(t => t.outWide == 0);
                    foreach (var node in unUpdatedOp)
                    {
                        if (node.wide != 0)
                        {
                            node.outWide = node.wide;
                            NextIterration = true;
                        }
                    }
                    //Установка размерности соеденений
                    var unUpdatetWires = mWires.Where(t => t.Wide == 0).ToList();
                    foreach (var wire in unUpdatetWires)
                    {
                        var srcNode = mNodes.First(t => t.name == wire.Src);
                        if (srcNode.outWide > 0)
                        {
                            wire.Wide = srcNode.outWide;
                            NextIterration = true;
                        }
                    }
                    var unWidetOp = mNodes.Where(t => t.wide == 0);
                    foreach (var node in unWidetOp)
                    {
                        var fromWire = mWires.First(t => t.Dist == node.name);
                        if (fromWire.Wide > 0)
                        {
                            node.wide = fromWire.Wide;
                        }
                    }
                }
                //Проверка размерностей

                //Определение финалного типа
                foreach (var node in mNodes)
                {
                    node.Type = node.BaseType + node.wide;
                }
                //Удаление Dummy обьектов
                var dummy = mNodes.Where(t => t.BaseType == "DUMMY").ToList();
                foreach (var node in dummy)
                {
                    var toWires = mWires.Where(t => t.Dist == node.name).ToList();
                    var fromWires = mWires.Where(t => t.Src == node.name).ToList();
                    if (toWires.Count > 1)
                    {
                        Console.WriteLine("ERROR: Есть неоднозначные соеденения");
                    }
                    foreach (var wire in fromWires)
                    {
                        wire.Src = toWires.First().Src;
                        wire.Src = toWires.First().Src;
                    }
                    foreach (var wire in toWires) mWires.Remove(wire);
                }
                foreach (var node in dummy) mNodes.Remove(node);

                NetUtils.Mnet mainNetwork = new NetUtils.Mnet();
                mainNetwork.Nodes = new List<NetUtils.Node>();
                mainNetwork.Wires = new List<NetUtils.Wire>();

                /*
                //Автодекомпозиция и выгрузка возможных нодов

                //Порты
                var inPorts = mNodes.Where(t => t.BaseType.Contains("INPort")).ToList();
                foreach (var node in inPorts)
                {
                    var wires = mWires.Where(t => t.Src == node.name).ToList();
                    for (int i = 0; i < node.wide; i++)
                    {
                        mainNetwork.Nodes.Add(new NetUtils.Node { NodeName = node.name + "[" + i + "]", NodeType = node.BaseType });
                        foreach (var wire in wires)
                        {
                            mainNetwork.Wires.Add(new NetUtils.Wire { SrcName = node.name + "[" + i + "]",SrcPort = "O0"
                                                                     ,DistName = wire.Dist , DistPort = wire.DistPort + i});
                        }
                    }
                    foreach (var wire in wires) mWires.Remove(wire);
                }
                foreach (var node in inPorts) mNodes.Remove(node);

                var outPorts = mNodes.Where(t => t.BaseType.Contains("OUTPort")).ToList();
                foreach (var node in outPorts)
                {
                    var wires = mWires.Where(t => t.Dist == node.name).ToList();
                    for (int i = 0; i < node.wide; i++)
                    {
                        mainNetwork.Nodes.Add(new NetUtils.Node { NodeName = node.name + "[" + i + "]", NodeType = node.BaseType });
                        foreach (var wire in wires)
                        {
                            mainNetwork.Wires.Add(new NetUtils.Wire
                            {
                                DistName = node.name + "[" + i + "]",
                                DistPort = "O0"
                             ,
                                SrcName = wire.Src,
                                SrcPort = wire.DistPort + i
                            });
                        }
                    }
                    foreach (var wire in wires) mWires.Remove(wire);
                }
                foreach (var node in inPorts) mNodes.Remove(node);
                //Константы
                //Регистры
                */
                //Выгрузка обьектов
                foreach (var node in mNodes)
                {
                    mainNetwork.Nodes.Add(new NetUtils.Node { NodeName = node.name, NodeType = node.Type });
                }
                //Выгрузка соеденений
                foreach (var wire in mWires)
                {
                    for (int i = 0; i < wire.Wide; i++)
                    {
                        mainNetwork.Wires.Add(new NetUtils.Wire { DistName = wire.Dist, DistPort = wire.DistPort + i, SrcName = wire.Src, SrcPort = wire.SrcPort + i });
                    }
                }
                //Автогенерация clk, reset
                var regs = mainNetwork.Nodes.Where(t => t.NodeType.Contains("TRIGD")).ToList();
                if (regs.Count > 0)
                {
                    mainNetwork.Nodes.Add(new NetUtils.Node { NodeName = "clk", NodeType = "INPort" });
                    mainNetwork.Nodes.Add(new NetUtils.Node { NodeName = "reset", NodeType = "INPort" });
                    foreach (var node in regs)
                    {
                        mainNetwork.Wires.Add(new NetUtils.Wire { DistName = node.NodeName, DistPort = "clk", SrcName = "clk", SrcPort = "O0" });
                        mainNetwork.Wires.Add(new NetUtils.Wire { DistName = node.NodeName, DistPort = "reset", SrcName = "reset", SrcPort = "O0" });
                    }
                }
                //Декомпозиция обьектов
                int throughId = 0;
                //Базовая декомпозиция регистров
                var registers = mainNetwork.Nodes.Where(t => t.NodeType.Contains("TRIGD")).ToList();
                foreach (var node in registers)
                {
                    int regnums = Convert.ToInt32(node.NodeType.Replace("TRIGD", ""));
                    var wclk = mainNetwork.Wires.First(t => t.DistName == node.NodeName && t.DistPort == "clk");
                    var wreset = mainNetwork.Wires.First(t => t.DistName == node.NodeName && t.DistPort == "reset");
                    mainNetwork.Wires.Remove(wclk);
                    mainNetwork.Wires.Remove(wreset);
                    var inwares = mainNetwork.Wires.Where(t => t.DistName == node.NodeName).ToList();
                    var outwares = mainNetwork.Wires.Where(t => t.SrcName == node.NodeName).ToList();
                    mainNetwork.Nodes.Remove(node);
                    List<NetUtils.Node> newnodes = new List<NetUtils.Node>();
                    //Новые ноды
                    for (int i = 0; i < regnums; i++)
                    {
                        var newNode = new NetUtils.Node { NodeName = node.NodeName + "_" + throughId, NodeType = "TRIG_D" };
                        newnodes.Add(newNode);
                        mainNetwork.Nodes.Add(newNode);
                        mainNetwork.Wires.Add(new NetUtils.Wire { SrcName = wclk.SrcName, SrcPort = wclk.SrcPort, DistName = newNode.NodeName, DistPort = "clk" });
                        mainNetwork.Wires.Add(new NetUtils.Wire { SrcName = wreset.SrcName, SrcPort = wreset.SrcPort, DistName = newNode.NodeName, DistPort = "sclr" });
                        throughId++;
                    }
                    //Ремапинг соеденений
                    foreach (var wire in inwares)
                    {
                        wire.DistName = newnodes[Convert.ToInt32(wire.DistPort.Replace("I", ""))].NodeName;
                        wire.DistPort = "datain";
                    }
                    foreach (var wire in outwares)
                    {
                        wire.SrcName = newnodes[Convert.ToInt32(wire.SrcPort.Replace("O", ""))].NodeName;
                        wire.SrcPort = "regout";
                    }

                }
                //Базовая декомпозиция констант
                var consts = mainNetwork.Nodes.Where(t => t.NodeType.Contains("CONST")).ToList();
                foreach (var node in consts)
                {
                    int len = Convert.ToInt32(node.NodeType.Split('_')[2]);
                    int[] value = hexConv(node.NodeType.Split('_')[1], len);
                    bool have1 = value.Contains(1);
                    bool have0 = value.Contains(0);
                    var vcc = new NetUtils.Node { NodeName = "VCC_" + throughId, NodeType = "VCC" };
                    var gnd = new NetUtils.Node { NodeName = "GND_" + throughId, NodeType = "GND" };
                    throughId++;
                    var wares = mainNetwork.Wires.Where(t => t.SrcName == node.NodeName).ToList();
                    foreach (var wire in wares)
                    {
                        if (value[Convert.ToInt32(wire.SrcPort.Replace("O", ""))] == 1)
                        {
                            wire.SrcPort = "O0";
                            wire.SrcName = vcc.NodeName;
                        }
                        else
                        {
                            wire.SrcPort = "O0";
                            wire.SrcName = gnd.NodeName;
                        }
                    }
                    if (have0) mainNetwork.Nodes.Add(gnd);
                    if (have1) mainNetwork.Nodes.Add(vcc);
                    mainNetwork.Nodes.Remove(node);
                }
                //Базовая декомпозиция Портов
                var inports = mainNetwork.Nodes.Where(t => t.NodeType.Contains("INPort") && t.NodeType.Length > ("INPort").Length).ToList();
                foreach (var node in inports)
                {
                    int len = Convert.ToInt32(node.NodeType.Replace("INPort", ""));
                    var outwares = mainNetwork.Wires.Where(t => t.SrcName == node.NodeName).ToList();
                    var newNodes = new List<NetUtils.Node>();
                    for (int i = 0; i < len; i++)
                    {
                        var newNode = new NetUtils.Node { NodeName = node.NodeName + "_" + i, NodeType = "INPort" };
                        newNodes.Add(newNode);
                        mainNetwork.Nodes.Add(newNode);

                    }
                    //Ремапинг соеденений
                    foreach (var wire in outwares)
                    {
                        wire.SrcName = newNodes[Convert.ToInt32(wire.SrcPort.Replace("O", ""))].NodeName;
                        wire.SrcPort = "O0";
                    }
                    mainNetwork.Nodes.Remove(node);
                }
                var outports = mainNetwork.Nodes.Where(t => t.NodeType.Contains("OUTPort") && t.NodeType.Length > ("OUTPort").Length).ToList();
                foreach (var node in outports)
                {
                    int len = Convert.ToInt32(node.NodeType.Replace("OUTPort", ""));
                    var outwares = mainNetwork.Wires.Where(t => t.DistName == node.NodeName).ToList();
                    var newNodes = new List<NetUtils.Node>();
                    for (int i = 0; i < len; i++)
                    {
                        var newNode = new NetUtils.Node { NodeName = node.NodeName + "_" + i, NodeType = "OUTPort" };
                        newNodes.Add(newNode);
                        mainNetwork.Nodes.Add(newNode);
                    }
                    //Ремапинг соеденений
                    foreach (var wire in outwares)
                    {
                        wire.DistName = newNodes[Convert.ToInt32(wire.DistPort.Replace("I", ""))].NodeName;
                        wire.DistPort = "I0";
                    }
                    mainNetwork.Nodes.Remove(node);
                }
                //Декомпозиция из файлов MNET
                //Получение списка доступных темплейтов
                int nodeindex = 0;
                var tpnames = System.IO.Directory.GetFiles(@".\comp\");
                var templatesNames = new List<string>();
                var nodeToAdd = new List<NetUtils.Node>();
                var nodeToRemove = new List<NetUtils.Node>();
                var wireToAdd = new List<NetUtils.Wire>();
                foreach (var tp in tpnames) templatesNames.Add(tp.Replace(@".\comp\","").Replace(".MNET",""));
                foreach (var node in mainNetwork.Nodes)
                {
                    if (templatesNames.Contains(node.NodeType))
                    {
                        //замена нода на темплейт
                        //Загрузка темплаейта
                        var template = new NetUtils.Mnet();
                        template.ReadMnetFile(@".\comp\" + node.NodeType + ".MNET");
                        //Переименование нодов
                        var nodeToRename = template.Nodes.Where(t => !t.NodeType.Contains("Port"));

                        foreach (var tnode in nodeToRename)
                        {
                            string newNodeName = "Node_" + nodeindex;
                            nodeindex++;
                            var wireto = template.Wires.Where(t => t.DistName == tnode.NodeName).ToList();
                            var wirefrom = template.Wires.Where(t => t.SrcName == tnode.NodeName).ToList();
                            foreach (var wire in wireto) wire.DistName = newNodeName;
                            foreach (var wire in wirefrom) wire.SrcName = newNodeName;
                            tnode.NodeName = newNodeName;
                        }
                        //Перенос соеденение
                        var wireToTemplate = mainNetwork.Wires.Where(t => t.DistName == node.NodeName).ToList();
                        var wireFromTemplate = mainNetwork.Wires.Where(t => t.SrcName == node.NodeName).ToList();
                        foreach (var wire in wireToTemplate)
                        {
                            var port = template.Nodes.First(t => t.NodeName == wire.DistPort);
                            var rmwire = template.Wires.First(t => t.SrcName == port.NodeName);

                            wire.DistPort = rmwire.DistPort;
                            wire.DistName = rmwire.DistName;

                            template.Wires.Remove(rmwire);
                            template.Nodes.Remove(port);
                        }

                        foreach (var wire in wireFromTemplate)
                        {
                            var port = template.Nodes.First(t => t.NodeName == wire.SrcPort);
                            var rmwire = template.Wires.First(t => t.DistName == port.NodeName);

                            wire.SrcPort = rmwire.SrcPort;
                            wire.SrcName = rmwire.SrcName;

                            template.Wires.Remove(rmwire);
                            template.Nodes.Remove(port);
                        }
                        //Перенос нодов и соеденений
                        nodeToAdd.AddRange(template.Nodes);
                        wireToAdd.AddRange(template.Wires);
                        nodeToRemove.Add(node);
                    }

                }
                foreach (var node in nodeToRemove) mainNetwork.Nodes.Remove(node);
                mainNetwork.Nodes.AddRange(nodeToAdd);
                mainNetwork.Wires.AddRange(wireToAdd);
                //Пересоздание DUP
                bool work = true;
                while (work)
                {
                    work = false;
                    List<NetUtils.Wire> wg = null;
                    foreach (var wire in mainNetwork.Wires)
                    {
                        wg = mainNetwork.Wires.Where(t => t.SrcName == wire.SrcName && t.SrcPort == wire.SrcPort).ToList();
                        if (wg.Count > 1)
                        {
                            break;
                        }
                    }
                    if (wg != null)
                    {
                        if (wg.Count > 1)
                        {
                            work = true;
                            //Добовляем DUP
                            var dup = new NetUtils.Node { NodeName = "DUP" + nodeindex, NodeType = "DUP" + wg.Count };
                            nodeindex++;
                            var wireToDup = new NetUtils.Wire { SrcPort = wg.First().SrcPort, SrcName = wg.First().SrcName, DistName = dup.NodeName, DistPort = "I0" };
                            int port = 0;
                            foreach (var wire in wg)
                            {
                                wire.SrcName = dup.NodeName;
                                wire.SrcPort = "O" + port;
                                port++;
                            }
                            mainNetwork.Wires.Add(wireToDup);
                            mainNetwork.Nodes.Add(dup);
                        }
                    }
                }

                //Выгрузка
                string s = mainNetwork.GetSting();
                System.IO.File.WriteAllText(filename + ".MNET", s);
            }
        }