public static HashSet <string> GetSurroundingKeys( this CstNode node, int length, bool inner = true, bool outer = true) { //inner = outer = true; // TODO: for debug var ret = new HashSet <string>(); var childElements = new List <Tuple <CstNode, string> >(); if (inner) { childElements.Add(Tuple.Create(node, node.Name)); var ancestorStr = ""; foreach (var e in node.AncestorsWithSingleChildAndSelf()) { ancestorStr = ancestorStr + "<" + e.NameWithId(); ret.Add(ancestorStr); } } var i = 1; if (outer) { var parentElement = Tuple.Create(node, node.Name); var descendantStr = ""; foreach (var e in node.DescendantsOfSingleAndSelf()) { descendantStr = descendantStr + "<" + e.NameWithId(); ret.Add(descendantStr); } // 自分自身の位置による区別も考慮する ret.Add(node.NameAndTokenWithId()); for (; i <= length; i++) { var newChildElements = new List <Tuple <CstNode, string> >(); foreach (var t in childElements) { foreach (var e in t.Item1.Children()) { var key = t.Item2 + ">" + e.NameAndTokenWithId(); newChildElements.Add(Tuple.Create(e, key)); // トークンが存在するかチェックする弱い条件 // for Preconditions.checkArguments() ret.Add(t.Item2 + ">'" + e.TokenText + "'"); } foreach (var e in t.Item1.Descendants()) { // トークンが存在するかチェックする弱い条件 //ret.Add(t.Item2 + ">>'" + e.TokenText() + "'"); } } foreach (var e in parentElement.Item1.Siblings(10)) { var key = parentElement.Item2 + "-" + e.NameAndTokenWithId(); newChildElements.Add(Tuple.Create(e, key)); // トークンが存在するかチェックする弱い条件 // for Preconditions.checkArguments() ret.Add(parentElement.Item2 + "-'" + e.TokenText + "'"); //// 先祖に存在するかチェックする弱い条件 //var iLastName = parentElement.Item2.LastIndexOf("<"); //var weakKey = "<<" + parentElement.Item2.Substring(iLastName + 1) + "-" + e.NameAndTokenWithId(); //newChildElements.Add(Tuple.Create(e, weakKey)); } ret.UnionWith(newChildElements.Select(t => t.Item2)); childElements = newChildElements; var newParentElement = parentElement.Item1.Parent; if (newParentElement == null) { break; } parentElement = Tuple.Create( newParentElement, parentElement.Item2 + "<" + newParentElement.NameAndTokenWithId()); ret.Add(parentElement.Item2); } } for (; i <= length; i++) { var newChildElements = new List <Tuple <CstNode, string> >(); foreach (var t in childElements) { foreach (var e in t.Item1.Children()) { var key = t.Item2 + ">" + e.NameAndTokenWithId(); newChildElements.Add(Tuple.Create(e, key)); // トークンが存在するかチェックする弱い条件 // for Preconditions.checkArguments() ret.Add(t.Item2 + ">'" + e.TokenText + "'"); } } ret.UnionWith(newChildElements.Select(t => t.Item2)); childElements = newChildElements; } return(ret); }