Vera ++ TCL规则:列出所有本地变量 [英] Vera ++ TCL rule : list all local variables

查看:291
本文介绍了Vera ++ TCL规则:列出所有本地变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为vera ++静态分析器写一个规则。由于我没有找到一个vera ++这里的组,并且vera ++使用TCL来实现其分析规则我发布到TCL论坛。我已经在vera ++ inspirel.com/vera/ce/doc/tclapi.html工作,但由于我不知道TCL很多,我想要进一步的建议。



我是TCL编程的初学者,但想知道一个TCL程序列出C ++源代码文件中的所有局部变量的方法?我的意思是什么方法和如何可以实现?



我面对的问题是解析C ++源代码文件以检测本地变量声明。

解决方案

使用vera ++规则解析本地(或任何其他)变量定义相当复杂,但当然可以。基本的方法是使用vera ++的 getTokens 函数结合使用vera ++。



<有一个小状态机检查完成的C ++语句。你需要收集令牌(并且可能是它们的值,因为你以后需要变量名来设置列表),并且连接它们,直到你有一个完整的语句。如果你有一个完整的语句,你可以使用正则表达式来检查它是否是一个变量定义,并从子匹配中提取变量名。还需要记住,如果你在一个 {} 块,以知道它是一个局部变量定义。



您可以找到一个样例,用于构建一个简单的状态机,以将标记收集到vera ++规则T019中的语句中,该规则检查完整的卷曲代码块,以此作为起点。



我已经使用vera ++解析变量定义(检查各种命名约定),但很遗憾,无法发布完整的代码,因为它是我的雇主的专有工作。但是我可以给你一个代码片断,显示我用来检查变量声明的正则表达式:

  set isVar false 
if [regexp {\s +((extern \s +)?(static \s + | mutable \s + | register\s + | volatile \s +)?(const \s +)?)?标识符#[^#] +#\s + colon_colon\s +)*标识符#[^#] +#)\s +(star \s + | const \s + |和\s + | less。* greater \s + | greater \s +)*(identifier#[^#] +#\s + colon_colon\s +)* identifier#([^#] +)#(\s + leftbracket。* rightbracket)? (\s + assign)?。* semicolon $} $ statement m s1 s2 s3 s4 s5 s6 s7 s8 s9 s10] {
set locVarname $ s9
set isVar true
set currentMatch $ m
} elseif [regexp {\s +((extern\s +)?(static \s + | mutable \s + | register\s + | volatile \s +)? )?(char \s + | int \s + | short \s + | long \s + | void \s + | bool\s + | double \s + | float\s + | unsigned \s + | and\\ \\ s + | star \s + | unsigned \s +)+(identifier#[^#] +#\s + colon_colon)* \s + identifier#([^#] +)# 。* rightbracket)?(\s + assign)?。* semicolon $} $ statement m s1 s2 s3 s4 s5 s6 s7 s8] {
set locVarname $ s7
set isVar true
set currentMatch $ m
}

$语句包含前面提到的完整语句。请注意,我使用 identifier#< value>#将令牌值连接到标识符正则表达式组提取它。


I am trying to write a rule for vera++ static analyzer. Since I did not found a group for vera++ here and that vera++ uses TCL to implement its rule for analysis I posted to TCL forum. I have worked on vera++ inspirel.com/vera/ce/doc/tclapi.html but since I do not know TCL much I wanted advices to approach further on.

Since I am a beginner in TCL programming but would like to know approach for a TCL program to list all local variables within a C++ source code file? I mean what approach and how it can achieved?

The issue I am facing is while parsing C++ source code files to detect local variable declaration?

解决方案

It's pretty complicated to parse for local (or any other) variable definitions using vera++ rules, but doable of course. The basic C++ parsing and tokenizing is done by vera++.

The basic approach is to use vera++'s getTokens function in conjunction with a little state machine that checks for completed C++ statements. You need to gather tokens (and may be their values additionally, since you'll need the variable names later to setup the list) and concatenate them until you have a complete statement. If you have a complete statement you can use a regular expression to check if it's a variable defintion and extract the variable name from a submatch. Also you need to remember if you're inside a {} block to know if it's a local variable definition.

You can find a sample for building a simple statemachine to gather the tokens to statements in vera++'s rule T019 that checks for complete curly braced blocks of code, to take as a starting point.

I've done parsing for variable defintions with vera++ (to check for various naming conventions), but unfortunately can't post the complete code since it's proprietary work for my employer. But I can give you a snippet showing the regular expression I'm using to check for variable declarations:

set isVar false
if [regexp {\s+((extern\s+)?(static\s+|mutable\s+|register\s+|volatile\s+)?(const\s+)?)?((identifier#[^#]+#\s+colon_colon\s+)*identifier#[^#]+#)\s+(star\s+|const\s+|and\s+|less.*greater\s+|greater\s+)*(identifier#[^#]+#\s+colon_colon\s+)*identifier#([^#]+)#(\s+leftbracket.*rightbracket)?(\s+assign)?.*semicolon$} $statement m s1 s2 s3 s4 s5 s6 s7 s8 s9 s10] {
    set locVarname $s9
    set isVar true
    set currentMatch $m
} elseif [regexp {\s+((extern\s+)?(static\s+|mutable\s+|register\s+|volatile\s+)?(const\s+)?)?(char\s+|int\s+|short\s+|long\s+|void\s+|bool\s+|double\s+|float\s+|unsigned\s+|and\s+|star\s+|unsigned\s+)+(identifier#[^#]+#\s+colon_colon)*\s+identifier#([^#]+)#(\s+leftbracket.*rightbracket)?(\s+assign)?.*semicolon$} $statement m s1 s2 s3 s4 s5 s6 s7 s8] {
    set locVarname $s7
    set isVar true
    set currentMatch $m
}

$statement contains the complete statement as mentioned before. Note that I'm concatenating the token value to the identifier token using identifier#<value># and use a regex group to extract it.

这篇关于Vera ++ TCL规则:列出所有本地变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆