用反讽分析C#源

用反讽分析C#源,c#,parsing,irony,C#,Parsing,Irony,这就是我和我的团队为我们的学校项目所选择的。实际上,我们还没有决定如何解析C#源文件 我们的目标是对C#源文件进行全面分析,并生成报告。 其中报告将包含代码中发生的内容 报告只需包含: 字符串文字 方法名 变量名 字段名 等 我负责调查这个讽刺图书馆。老实说,我不知道将数据整理成清晰可读的报告的最佳方法。我正在使用压缩包中的C#语法类 是否有任何步骤可以正确识别每个节点子节点?(例如:使用指令、名称空间声明、类声明等、方法体) 任何帮助或建议都将不胜感激。谢谢 编辑:很抱歉,我忘了说我们也需

这就是我和我的团队为我们的学校项目所选择的。实际上,我们还没有决定如何解析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); }
        }