public static SelectIntruction PrepareInstructions(SelectClauseNode parseRoot) { var res = new SelectIntruction {ArrayLength = parseRoot.GetList().Select(z => z.Letter).Max() + 1}; foreach (var e in parseRoot.GetList()) { var ins = new LetterInstruction {LetterIndex = e.Letter, IsRoot = e.Parent == null}; if (!ins.IsRoot) { ins.ParentIndex = e.Parent.Letter; ins.ChildNumberInArray = e.Parent.Children.IndexOf(e); ins.LeftBrotherIndexes = e.Parent.Children.Take(ins.ChildNumberInArray).Select(z => z.Letter).ToArray(); } else { ins.LeftBrotherIndexes = new int[] { }; } if (e.Children.Count != 0) { if (e.Children.Count != 0) { var sub = Math.Sign(e.Children.Where(z => z.Recursive == LetterRecursionType.Subtree).Count()); var child = Math.Sign(e.Children.Where(z => z.Recursive == LetterRecursionType.Children).Count()); var clear = Math.Sign(e.Children.Where(z => z.Recursive == LetterRecursionType.No).Count()); if (sub + child + clear > 1) throw new Exception("Error in rule: letter " + (char)('A' + e.Letter) + " must have only one type of childs (for example A(?B,.C) is not acceptable)"); if (clear != 0) ins.Arity = e.Children.Count; } } ins.Recursive = e.Recursive; res.Letters.Add(ins); } return res; }