快速构建静态分析工具的C语言编译前端——Psyche-C

快速构建静态分析工具的C语言编译前端——Psyche-C

build status test-suite status

Psyche-C Logo

Psyche-C 是一个独特的C语言编译器前端,特别为实现静态分析工具而设计。它的创新之处在于:

  • 清晰地分隔了语法和语义编译阶段。
  • 利用算法和启发式方法进行语法歧义消除。
  • 缺失structunionenum,和typedef类型推断,即使在#include失败时也能“恢复”和宽容处理。
  • API灵感来源于 Roslyn .NET compiler
  • AST(抽象语法树)类似于 LLVM's Clang frontend

库与API

Psyche-C 实现为一个库,其原生API是C++(其他语言的API正在开发中,Issue #112)。以下是简单的API示例:

void analyse(const SourceText& srcText, const FileInfo& fi)
{
    // 设置解析选项
    ParseOptions parseOpts;
    parseOpts.setTreatmentOfAmbiguities(ParseOptions::TreatmentOfAmbiguities::DisambiguateAlgorithmically);
    
    // 解析源代码
    auto tree = SyntaxTree::parseText(srcText,
                                      TextPreprocessingState::Preprocessed,
                                      TextCompleteness::Fragment,
                                      parseOpts,
                                      fi.fileName());

    // 创建编译上下文
    auto compilation = Compilation::create("code-analysis");
    compilation->addSyntaxTree(tree.get());

    // 运行分析
    AnalysisVisitor analysis(tree.get(), compilation->semanticModel(tree.get()));
    analysis.run(tree->translationUnitRoot());
}

你可以在函数定义等节点上编写自定义的访问器,以执行特定的分析任务。

SyntaxVisitor::Action AnalysisVisitor::visitFunctionDefinition(const FunctionDefinitionSyntax* node) override
{
    const sym = semaModel->declaredSymbol(node);
    if (sym->kind() == SymbolKind::Function) {
        const FunctionSymbol* funSym = sym->asFunction();
        // ...
    }
    return Action::Skip;
}

cnippet 驱动程序

Psyche-C 提供了一个名为cnippet的驱动程序,使其可以作为一个普通的C语言解析器使用。例如:

void f()
{
    int ;
}

使用cnippet运行上述代码将得到与GCC或Clang类似的错误诊断。

~ cnip test.c
test.c:4:4 error: declaration does not declare anything
int ;
    ^

请注意,目前的语义分析功能还不完全。

类型推断

Psyche-C 能够对代码片段(不完整程序)中的缺失类型进行推断,这在很多场景下非常有用:

  • 允许在不完整的源码上实现那些依赖完全类型信息的静态分析技术。
  • 可以编译部分代码(如从bug跟踪器获取的代码片段),用于对象代码检查。
  • 对于孤立的函数,生成测试输入数据,无需考虑其依赖关系。
  • 在快速原型设计算法时,无须显式声明类型。

类型推断功能当前仅在原始分支中可用。

文档和资源

构建与测试

除类型推断部分使用Haskell外,Psyche-C 使用C++17编写,而cnippet使用Python 3编写。构建和测试过程如下:

cmake CMakeLists.txt && make -j 4
./test-suite

相关出版物

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Medusa是一个基于深度学习的图像生成模型,它可以生成逼真的人脸图像。下面是一个简单的Medusa使用教程: 1. 安装依赖:首先,你需要安装Python和一些依赖库,比如TensorFlow和NumPy。你可以使用pip命令来安装它们: ``` pip install tensorflow numpy ``` 2. 下载预训练模型:Medusa的开发者已经在GitHub上提供了预训练模型,你可以从以下链接下载: ``` https://github.com/Psyche-mia/Medusa ``` 3. 导入模型和相关库:将下载的预训练模型文件导入到你的项目中,并导入相关的库: ```python import tensorflow as tf import numpy as np # 导入预训练模型 model_path = 'path_to_model/medusa.pb' with tf.gfile.GFile(model_path, 'rb') as f: graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) tf.import_graph_def(graph_def, name='') ``` 4. 生成图像:使用Medusa生成图像的过程涉及到向模型输入噪声并获取输出图像。以下是一个简单的函数来执行这个过程: ```python def generate_image(): with tf.Session() as sess: input_tensor = sess.graph.get_tensor_by_name('input:0') output_tensor = sess.graph.get_tensor_by_name('output:0') # 生成噪声 noise = np.random.randn(1, 512) # 输入噪声并获取输出图像 generated_image = sess.run(output_tensor, feed_dict={input_tensor: noise}) # 将图像从[-1, 1]范围转换为[0, 255]范围 generated_image = (generated_image + 1) * 127.5 # 显示生成的图像 plt.imshow(generated_image[0].astype(np.uint8)) plt.show() ``` 5. 调用生成函数:调用上述生成函数来生成图像: ```python generate_image() ``` 这只是一个简单的Medusa使用教程。你可以根据自己的需要对其进行更多的定制和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邬筱杉Lewis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值