public Parser(Scanner scanner) { this.scanner = scanner; errors = new Errors(); }
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); } }