用反讽分析C#源
这就是我和我的团队为我们的学校项目所选择的。实际上,我们还没有决定如何解析C#源文件 我们的目标是对C#源文件进行全面分析,并生成报告。 其中报告将包含代码中发生的内容 报告只需包含:用反讽分析C#源,c#,parsing,irony,C#,Parsing,Irony,这就是我和我的团队为我们的学校项目所选择的。实际上,我们还没有决定如何解析C#源文件 我们的目标是对C#源文件进行全面分析,并生成报告。 其中报告将包含代码中发生的内容 报告只需包含: 字符串文字 方法名 变量名 字段名 等 我负责调查这个讽刺图书馆。老实说,我不知道将数据整理成清晰可读的报告的最佳方法。我正在使用压缩包中的C#语法类 是否有任何步骤可以正确识别每个节点子节点?(例如:使用指令、名称空间声明、类声明等、方法体) 任何帮助或建议都将不胜感激。谢谢 编辑:很抱歉,我忘了说我们也需
- 字符串文字
- 方法名
- 变量名
- 字段名
- 等
编辑:很抱歉,我忘了说我们也需要分析方法调用。我不确定这是您需要的,但您可以使用CodeDom和CodeDom.Compiler命名空间来编译C代码,然后使用反射分析结果,例如:
// Create assamblly in Memory
CodeSnippetCompileUnit code = new CodeSnippetCompileUnit(classCode);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerResults results = provider.CompileAssemblyFromDom(compileParams, code);
foreach(var type in results.CompiledAssembly)
{
// Your analysis go here
}
更新:在VS2015中,您可以使用新的C#编译器(又名Roslyn)来执行同样的操作,例如
你的主要目标是掌握正式语言的基础知识。可能会找到一个好的启动。本文描述了在一个简单的数字计算器的语法示例上使用反讽的方法 假设您要解析某个文件,该文件包含您知道的路径的C#代码:
private void ParseForLongMethods(string path)
{
_parser = new Parser(new CSharpGrammar());
if (_parser == null || !_parser.Language.CanParse()) return;
_parseTree = null;
GC.Collect(); //to avoid disruption of perf times with occasional collections
_parser.Context.SetOption(ParseOptions.TraceParser, true);
try
{
string contents = File.ReadAllText(path);
_parser.Parse(contents);//, "<source>");
}
catch (Exception ex)
{
}
finally
{
_parseTree = _parser.Context.CurrentParseTree;
TraverseParseTree();
}
}
讽刺给你一个AST,然后你可以翻译。然而,AST是代码的一部分,因此如果不知道实际的AST,就很难告诉您如何获取信息,实际上不仅仅是AST。他们现有的C#语法为您提供了一个简单的树。我将试着在晚上之前发布一些示例。
private void ParseForLongMethods(string path)
{
_parser = new Parser(new CSharpGrammar());
if (_parser == null || !_parser.Language.CanParse()) return;
_parseTree = null;
GC.Collect(); //to avoid disruption of perf times with occasional collections
_parser.Context.SetOption(ParseOptions.TraceParser, true);
try
{
string contents = File.ReadAllText(path);
_parser.Parse(contents);//, "<source>");
}
catch (Exception ex)
{
}
finally
{
_parseTree = _parser.Context.CurrentParseTree;
TraverseParseTree();
}
}
private void TraverseParseTree()
{
if (_parseTree == null) return;
ParseNodeRec(_parseTree.Root);
}
private void ParseNodeRec(ParseTreeNode node)
{
if (node == null) return;
string functionName = "";
if (node.ToString().CompareTo("class_declaration") == 0)
{
ParseTreeNode tmpNode = node.ChildNodes[2];
currentClass = tmpNode.AstNode.ToString();
}
if (node.ToString().CompareTo("method_declaration") == 0)
{
foreach (var child in node.ChildNodes)
{
if (child.ToString().CompareTo("qual_name_with_targs") == 0)
{
ParseTreeNode tmpNode = child.ChildNodes[0];
while (tmpNode.ChildNodes.Count != 0)
{ tmpNode = tmpNode.ChildNodes[0]; }
functionName = tmpNode.AstNode.ToString();
}
if (child.ToString().CompareTo("method_body") == 0) //method_declaration
{
int statementsCount = FindStatements(child);
//Register bad smell
if (statementsCount>(((LongMethodsOptions)this.Options).MaxMethodLength))
{
//function.StartPoint.Line
int functionLine = GetLine(functionName);
foundSmells.Add(new BadSmellRegistry(name, functionLine,currentFile,currentProject,currentSolution,false));
}
}
}
}
foreach (var child in node.ChildNodes)
{ ParseNodeRec(child); }
}