/// <summary> /// 크리티컬 변수 목록 추출 /// </summary> /// <param name="line">현재 코드줄</param> /// <returns></returns> public IEnumerable <string> ExtractCriticalVariant(string line, bool skipDefine = true) { line = line.Trim(); if (string.IsNullOrWhiteSpace(line)) { yield break; } if (line.StartsWith("//")) { yield break; } string declarePattern = @"(?<Declare>[a-zA-Z0-9_\.]+) [a-zA-Z0-9_\.]+ ="; // 메서드 정규식 패턴 string methodPattern = @"([a-zA-Z0-9_\.]+)\s*\("; // 변수 정규식 패턴 string fieldPattern = @"\*?(?<Field>([a-zA-Z0-9_\.]|\-\>)+)"; string invalidPattern = @"^[\d\.]+"; string commentPattern = @"[""].*[""]"; string commentPattern2 = @"\/\/.*"; string commentPattern3 = @"\/\*.+\*\/"; line = Regex.Replace(line, commentPattern, ""); line = Regex.Replace(line, commentPattern2, ""); line = Regex.Replace(line, commentPattern3, ""); // 메서드 목록 var methodSets = new HashSet <string>(); // 선언 타입명 추출 var declareMatch = Regex.Match(line, declarePattern); string declareName = string.Empty; if (declareMatch.Success) { declareName = declareMatch.Groups["Declare"]?.Value ?? string.Empty; } //Console.WriteLine($"선언 : {declareName}"); var methods = Regex.Matches(line, methodPattern); // 현재 코드 라인에서 메서드 목록 추가 foreach (var met in methods) { var method = met as Match; if (method.Success) { // Console.WriteLine(method.Groups[1].Value); methodSets.Add(method.Groups[1].Value); // aaaa } } // Console.WriteLine("----"); var vars = Regex.Matches(line, fieldPattern) .Cast <Match>() .Where(m => { if (m.Value.Equals(declareName)) { return(false); } /* 제일 앞자리가 숫자로 시작하면 넘어감 */ if (Regex.IsMatch(m.Value, invalidPattern)) { return(false); } /* 전 단계에서 구한 메서드 목록에 있으면 넘어감 */ if (methodSets.Contains(m.Value)) { return(false); } /* 예약어 목록에 있으면 넘어감 */ if (ReservedList.Contains(m.Value)) { return(false); } /* 알파벳이 하나도 없으면 넘어감 */ if (!m.Value.Any(c => char.IsLetter(c))) { return(false); } /* 대문자로 구성된 변수면 넘어감 */ if (skipDefine && m.Value.All(c => char.IsUpper(c) || !char.IsLetter(c))) { return(false); } return(true); }) .Distinct(new MatchComparer()); foreach (var x in vars) { var field = x as Match; if (field.Success) { yield return(field.Value); } } }
public MethodVarList ExtractMethodVariantList(string line, bool skipDefine = true) { line = line.Trim(); if (string.IsNullOrWhiteSpace(line)) { return(null); } if (line.StartsWith("//")) { return(null); } var methodVarList = new MethodVarList() { Methods = new List <string>(), Vars = new List <string>() }; string declarePattern = @"(?<Declare>[a-zA-Z0-9_\.]+)\s+[a-zA-Z0-9_\.]+\s*(=|;|,)"; // 메서드 정규식 패턴 string methodPattern = @"([a-zA-Z0-9_\.]+)\s*\("; // 변수 정규식 패턴 string fieldPattern = @"\*?(?<Field>([a-zA-Z0-9_\.]|\-\>)+)"; string fieldArrayPattern = @"(?<ArrayName>[a-zA-Z0-9_\.]+)\[.+\]"; string invalidPattern = @"^[\d\.]+"; string commentPattern = @"[""].*[""]"; string commentPattern2 = @"\/\/.*"; string commentPattern3 = @"\/\*.+\*\/"; line = Regex.Replace(line, commentPattern, ""); line = Regex.Replace(line, commentPattern2, ""); line = Regex.Replace(line, commentPattern3, ""); // 메서드 목록 var methodSets = new HashSet <string>(); // 선언 타입명 추출 var declareMatch = Regex.Match(line, Regex.Escape(declarePattern)); string declareName = string.Empty; if (declareMatch.Success) { declareName = declareMatch.Groups["Declare"]?.Value ?? string.Empty; } var methods = Regex.Matches(line, methodPattern); // 현재 코드 라인에서 메서드 목록 추가 foreach (var met in methods) { var method = met as Match; if (method.Success) { if (ReservedList.Contains(method.Groups[1].Value)) { continue; } methodSets.Add(method.Groups[1].Value); } } // Console.WriteLine("----"); var arrayNames = Regex.Matches(line, fieldArrayPattern) .Cast <Match>() .Where(m => { if (m.Value.Equals(declareName)) { return(false); } /* 제일 앞자리가 숫자로 시작하면 넘어감 */ if (Regex.IsMatch(m.Value, invalidPattern)) { return(false); } /* 전 단계에서 구한 메서드 목록에 있으면 넘어감 */ if (methodSets.Contains(m.Value)) { return(false); } /* 예약어 목록에 있으면 넘어감 */ if (ReservedList.Contains(m.Value)) { return(false); } /* 알파벳이 하나도 없으면 넘어감 */ if (!m.Value.Any(c => char.IsLetter(c))) { return(false); } ///* 대문자로 구성된 변수면 넘어감 */ //if (skipDefine && m.Value.All(c => char.IsUpper(c) || !char.IsLetter(c))) //{ // return false; //} return(true); }) .Distinct(new MatchComparer()); var arrays = arrayNames.Select(m => m.Groups["ArrayName"].Value); var vars = Regex.Matches(line, fieldPattern) .Cast <Match>() .Where(m => { if (m.Value.Equals(declareName)) { return(false); } /* 제일 앞자리가 숫자로 시작하면 넘어감 */ if (Regex.IsMatch(m.Value, invalidPattern)) { return(false); } /* 전 단계에서 구한 메서드 목록에 있으면 넘어감 */ if (methodSets.Contains(m.Value)) { return(false); } /* 예약어 목록에 있으면 넘어감 */ if (ReservedList.Contains(m.Value)) { return(false); } if (m.Value.StartsWith("-")) { return(false); } /* 알파벳이 하나도 없으면 넘어감 */ if (!m.Value.Any(c => char.IsLetter(c))) { return(false); } ///* 대문자로 구성된 변수면 넘어감 */ //if (skipDefine && m.Value.All(c => char.IsUpper(c) || !char.IsLetter(c))) //{ // return false; //} return(true); }) .Distinct(new MatchComparer()); foreach (var x in vars) { if (x.Success) { var field = x.Groups["Field"].Value; /* a->b 포인터 변수 나눠서 추가 */ if (field.Contains("->")) { var connects = Regex.Split(field, "->"); var connectList = new List <string>(); string s = string.Empty; foreach (var c in connects) { if (s == string.Empty) { s = c; } else { s = string.Join("->", s, c); } connectList.Add(s); } foreach (var c in connectList) { if (c == connects[connects.Length - 1]) { continue; } if (methodVarList.Vars.Contains(c)) { continue; } methodVarList.Vars.Add(c); } continue; } methodVarList.Vars.Add(field); } } foreach (var x in arrays) { methodVarList.Vars.Add(x); } foreach (var m in methodSets) { methodVarList.Methods.Add(m); } return(methodVarList); }