0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

静态分析工具

汽车电子技术 来源:程序猿搬砖 作者: 程序猿搬砖 2023-03-02 17:53 次阅读

前言

在开发项目的过程当中或多或少的会利用静态分析工具来辅助完成一些类似语法检查、类型分析这样的工作。掌握必要的静态分析能力可以提升项目开发的效率,减少不必要的低级错误。

常用静态分析工具

iOS的开发过程中通常有以下的静态分析工具可以使用:

Analyzer:Clang Static Analyzer是一款静态代码扫描工具,专门用于针对C,C++和Objective-C的程序进行分析。已经被Xcode集成,可以直接使用Xcode进行静态代码扫描分析,也可以单独在命令行下使用并提供html格式的输出报吿和xml格式的结果文件方便集成到Jenkins上进行展示

Infer:是Facebook开发的静态分析工具。Infer 可以分析 Objective-C, Java 或者 C 代码,报告潜在的问题。

OCLint:是一个强大的静态代码分析工具,它基于clang,可以用来提高代码质量,查找潜在的bug,主要针对c,c++和Objective-c的静态分析,功能非常强大。

以上常用的三款静态分析工具都有比较完整的功能实现,内部实现相对复杂,灵活性与自定义可扩展能力都没有自己实现一个方便,可以基于clang利用C或者C++接口完成静态分析,这样实现的学习与开发成本也比较大。好有没有轻量一点的解决方案呢,答案是肯定的: 基于antlr的超轻量分析工具。接下来,本节将通过完成一个对Objective-C的类进行分析并打印出相关信息来说明怎么快速搭建一个超轻量、可控、高集成的静态分析工具。

搭建轻量静态分析工具

利用antlr4可以快速搭建一个轻量的静态分析工具,选择自己合适的语言快速开发分析业务。

一、安装antlr4

进入到antlr官网: https://www.antlr.org/,以macOS系统为例,输入以下命令:

$ cd /usr/local/lib
$ sudo curl -O https://www.antlr.org/download/antlr-4.9.2-complete.jar
$ export CLASSPATH=".:/usr/local/lib/antlr-4.9.2-complete.jar:$CLASSPATH"
$ alias antlr4='java -jar /usr/local/lib/antlr-4.9.2-complete.jar'
$ alias grun='java org.antlr.v4.gui.TestRig'

安装完成后,在终端输入

antlr4

查看是否有以下内容输入,检查是否安装成功图片目前antlrruntime已经支持以下语言

  • Java
  • C# (and an alternate C# target)
  • Python (2 and 3)
  • JavaScript
  • Go
  • C++
  • Swift
  • PHP
  • DART

你可以选择一种你最熟悉或者说当前最适合你的语言来开发静态分析工具,本节实例将采集JavaScript语言基于Node.js开发一个用于分析当前Objective-CiOS项目的中所有类实现的协议。

二、安装Node.js开发环境

进入到Node.js官网: https://nodejs.org/zh-cn/,下载一个长期支持版本或者当前最新的版本都可以,安装完成Node.js后在终端输入:

node --version

查看是否正确输出Node.js的版本。

三、搭建静态分析工具

创建Node.js分析工具项目

在终端输入

npm init

初始化一个Node.js项目,生成index.js入口文件,添加一个启动脚本命令,使用Visual Code打开看上去是这样的,最后它看上去是这样的:图片

npm run start

查看是否能正常运行。

安装JavaScriptantlr4运行时

npm install antlr4 --save

生成支持JavsScript解析规则

antlr这个地址提供了几乎所有的语言规则文件g4: https://github.com/antlr/grammars-v4/tree/master/。这里下载objc需要的规则文件,如下图:图片图片

ObjectiveCLexer:词法(Token)解析规则文件ObjectiveCParser:语法(AST)解析规则文件

首先利用antlr编译词法规则文件

antlr4 -Dlanguage=JavaScript -no-listener ObjectiveCLexer.g4

然后再编译语法规则文件

antlr4 -Dlanguage=JavaScript -no-listener ObjectiveCParser.g4

-no-listener:表示不生成listener模式的相关代码支持。

antlr有两种遍历模式: visitorlistener。从字面的意思就可以看出visitor是访问模式,即开发者主动从AST顶层开始一层一层的访问遍历AST。而listener则为监听模式,即由运行时从顶层AST开始层层遍历访问,当访问到一个节点时回调开发者。visitor模式自动生成的xxxxVisitor.js需要完善一些方法节点的方法,以检查语法中的规则。而本节实例是访问AST并获取节点上某些关键的信息,使用Parser提供的方法即可满足。

通过以上的antlr命令编译生成如下的规则解析文件:

图片

编码

index.js中导入相关的JavsScript文件与库:

import antlr4 from "antlr4";
import ObjectiveCLexer from "./ObjectiveCLexer.js";
import ObjectiveCParser from "./ObjectiveCParser.js";
import fs from "fs";

由于这里支持ES6import语法,所以package.json中需要申明一下:图片

准备好一个测试使用的Objective-C的文件,本节使用的是一个非常简单的头文件,仅用于说明实例的使用:图片

读取Objective-C文件:

const input = fs.readFileSync("./FSBaseViewController.h", {
  encoding: "utf-8",
});

利用antlr生成的运行时语法解析文件,将读取到的Objective-C解析成AST

const chars = new antlr4.InputStream(input);
const lexer = new ObjectiveCLexer(chars);
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new ObjectiveCParser(tokens);
parser.buildParseTrees = true;
const tree = parser.translationUnit();

这里的ObjectiveCParser是根据ObjectiveCParser.g4生成的规则解析文件,从ObjectiveCParser.g4中可以到

图片

ObjectiveCParser.g4申明的顶层节点是translationUint。

ObjectiveCParser.g4中的申明可以看出, translationUnit中只申明了两个子节点topLevelDeclaration*表示顶层节点是一个或者多个,与EOF结束节点。这是因为在同一个源文件中可以申明多个Objective-C的Class。,通过如下代码即可取到对应的顶层节点,由于本节明确只有一个顶层顶点,所以代码如下:

const topLevelDeclarationNodes = tree.topLevelDeclaration();
if (topLevelDeclarationNodes.length == 0) return;
const topLevelDeclarationNode = topLevelDeclarationNodes[0];
if (!topLevelDeclarationNode) return;

或者

const topLevelDeclarationNode = tree.topLevelDeclaration(0);
if(!topLevelDeclarationNode) return;

获取到topLevelDeclarationNode之后,再查看ObjectiveCParser.g4中的申明如下:

图片

这个节点申明了很多种节点类型,在本节中关心的是classInterface节点。如果你还想进一步要判断协议中的方法是否实现,可以进一步探查clasImplementation节点。

const classInterfaceNode = topLevelDeclarationNode.classInterface();
if (!classInterfaceNode) return;

ObjectiveCParser.g4classInterface节点的解析规则定义如下:

图片

其中classInterface包含了className,可能包含一个protocolList它是一个数组,即这个类申明实现了的Protocol

获取class name,ObjectiveCParser.g4中可将节点推导成一个TerminalNode节点,节点包含一个symbol即节点的字符串字面量。

/// GenericTypeSpecifierContext
const classNameNode = classInterfaceNode.className;
if (!classNameNode) return;
const classNameIdentifierNode = classNameNode.identifier();
console.log(`class interface name: ${_getSymbolText(classNameIdentifierNode)}`);

其中_getSynbolText函数定义如下:

function _getSymbolText(identifierNode) {
  if (!identifierNode) return null;
  if (!(identifierNode instanceof ObjectiveCParser.IdentifierContext)) return null;
  if (identifierNode && identifierNode.children && identifierNode.children instanceof Array && identifierNode.children.length > 0) {
    const terminalNodeImpl = identifierNode.children[0];
    if (terminalNodeImpl) {
      const symbol = terminalNodeImpl.symbol;
      if (symbol) {
        return symbol.text;
      }
    }
  }
  return null;
}

获取实现的协议列表:

const protocolList = classInterfaceNode.protocolList();
if (protocolList && protocolList instanceof ObjectiveCParser.ProtocolListContext) {
  const protocolListNames = protocolList.children.map((protocol) => {
    const identifier = protocol.identifier();
    const protocolName = _getSymbolText(identifier);
    return {
      protocolName,
    };
  });
  console.log(protocolListNames);
}

最终运行结果如下:图片

到这里一个基于antlr4的快速轻量静态分析工具雏形就完成了,多尝试练习一下即可在10分鈡搭建一个能快速集成到你的工程中的静态分析工具,这个集成是轻量的、可控的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66776
  • objective-c
    +关注

    关注

    0

    文章

    2

    浏览量

    58
收藏 人收藏

    评论

    相关推荐

    IAR静态分析工具的主要特点有哪些

    IAR静态分析工具的主要特点有哪些?IAR静态分析工具有何作用?
    发表于 01-27 06:54

    基于数据融合的源代码静态分析

    采用数据融合技术对源代码进行静态分析,实现可扩展的原型系统。对现有静态分析工具分析结果进行解析
    发表于 04-13 08:57 9次下载

    汇编语言静态分析工具设计与应用

    本文针对当前汇编语言的测试工具较少这一实际情况,针对某种汇编语言语法结构特 点,确定了汇编语言静态分析工具的总体结构框架,并对工具实现过程中
    发表于 06-19 11:52 26次下载

    五个程序员必知的静态分析工具推荐

    目前,市面上有许多代码分析工具,但昂贵的费用对于初创公司和个人来说有些难以承受。但以下的免费静态分析工具可以帮助到你。
    的头像 发表于 04-05 17:22 5693次阅读

    Krane Kubernetes RBAC静态分析工具

    ./oschina_soft/krane.zip
    发表于 05-16 10:15 2次下载
    Krane Kubernetes RBAC<b class='flag-5'>静态</b><b class='flag-5'>分析</b><b class='flag-5'>工具</b>

    Klocwork静态分析工具的主要功能及应用行业

    Klocwork工具应用了静态分析技术,可实现对C、C++、Java、C#、python等代码的全面静态分析。检查问题种类既包含软件质量和安
    的头像 发表于 05-18 17:40 1992次阅读

    使用静态分析查找并发错误

      多线程为嵌入式开发人员必须考虑的潜在错误添加了全新的类别,使得查找各种错误变得更加困难。最新一代的静态分析工具可以帮助解决这两个问题。
    的头像 发表于 06-19 10:00 849次阅读
    使用<b class='flag-5'>静态</b><b class='flag-5'>分析</b>查找并发错误

    静态分析与编译器和数据库集成

    高级静态分析工具在嵌入式系统开发中变得越来越重要。远远超出实际上是编码风格检查器的旧静态分析工具
    的头像 发表于 06-28 14:09 750次阅读
    将<b class='flag-5'>静态</b><b class='flag-5'>分析</b>与编译器和数据库集成

    使用静态分析查找并发错误

      多线程为嵌入式开发人员必须考虑的潜在错误添加了全新的类别,使得查找各种错误变得更加困难。最新一代的静态分析工具可以帮助解决这两个问题。
    的头像 发表于 07-09 07:10 668次阅读
    使用<b class='flag-5'>静态</b><b class='flag-5'>分析</b>查找并发错误

    【技术分享】代码可以静态分析,PCB可以吗?

    软件代码有bug,可以通过人工查找,也可以通过编译发现,同时也可以通过代码静态分析工具找到错误或警告。人工查找代码bug,显然不合理,除非只有几十行代码的项目。通过编译器(IDE)编译查找代码bug
    的头像 发表于 03-21 09:34 270次阅读
    【技术分享】代码可以<b class='flag-5'>静态</b><b class='flag-5'>分析</b>,PCB可以吗?

    Harmony系统代码的静态测试

    本文通过使用静态分析工具QAC,来分析测试Harmony系统代码对汽车行业内常用编码规范的遵循情况。
    的头像 发表于 08-01 14:22 763次阅读
    Harmony系统代码的<b class='flag-5'>静态</b>测试

    什么是静态代码分析静态代码分析概述

    静态分析可帮助面临压力的开发团队。高质量的版本需要按时交付。需要满足编码和合规性标准。错误不是一种选择。 这就是开发团队使用静态分析工具/源
    的头像 发表于 07-19 12:09 928次阅读
    什么是<b class='flag-5'>静态</b>代码<b class='flag-5'>分析</b>?<b class='flag-5'>静态</b>代码<b class='flag-5'>分析</b>概述

    用于嵌入式的常见代码静态分析工具有哪些?

    当前标准的C语言编译器存在普遍只能找出代码中潜在的缺陷,而对程序方案设计并没有效。
    发表于 08-09 10:10 783次阅读
    用于嵌入式的常见代码<b class='flag-5'>静态</b><b class='flag-5'>分析</b><b class='flag-5'>工具</b>有哪些?

    分享一款不错的嵌入式静态代码扫描工具

    之前给大家分享过嵌入式开发常用的代码静态分析工具,比如:PC-lint、LDRA、VectorCAST等。
    的头像 发表于 10-16 15:39 1046次阅读
    分享一款不错的嵌入式<b class='flag-5'>静态</b>代码扫描<b class='flag-5'>工具</b>

    Shell脚本检查工具ShellCheck介绍

    ShellCheck是一个用于bash/sh shell脚本的静态分析工具,可以辅助检查脚本语法错误,给出建议增强脚本健壮性。
    的头像 发表于 12-27 13:43 568次阅读
    Shell脚本检查<b class='flag-5'>工具</b>ShellCheck介绍