Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >分析方法中的变量。JavaParser/ANTLR或其他什么?

分析方法中的变量。JavaParser/ANTLR或其他什么?
EN

Stack Overflow用户
提问于 2012-11-26 03:40:15
回答 3查看 2.4K关注 0票数 4

我正在写一个java代码分析片段,它将找出一个方法中变量的使用。(具体地说,一个全局类变量在一个方法中被读取和写入的次数)。使用JavaParser可以做到这一点吗?还有没有人有其他建议?有人知道类指标是如何计算的吗?他们可能会处理类似的事情。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-28 06:42:20

谢谢你们。您的两个答案都将我引向了使用JAVAPARSER中的AST实现来解决这个问题的方向。下面是帮助其他人的代码片段

代码语言:javascript
运行
AI代码解释
复制
class CatchNameExpr extends VoidVisitorAdapter {
    HashMap<String, ArrayList<Integer>> variableLineNumMap;``
    ArrayList<String> variableList;
    boolean functionParsing = false;
    public CatchNameExpr(ArrayList<String> classVariables) {
        variableList=classVariables;
    }
    public void visit(MethodDeclaration method, Object arg) {
        System.out.println("---------------");
        System.out.println(method.getName());
        System.out.println("---------------");
        variableLineNumMap = new HashMap<String, ArrayList<Integer>>();
        System.out.println();
        functionParsing = true;
        visit(method.getBody(),arg);
        // Analyze lines for variable usage. Add to list of vars after checking if its read or written or unknown.

        functionParsing = false;
    }

    public void visit(NameExpr n, Object arg) {

        if(!functionParsing)
            return;
        //TODO: check if this var was declared above it, as a local var to the func. if yes, return
        ArrayList<Integer> setOfLineNum;

        System.out.println(n.getBeginLine()+" NameExpr " + n.getName());

        if(!variableList.contains(n.getName()) || n.getName().length()==0)
            return;
        if (!variableLineNumMap.containsKey(n.getName()))
        {
            setOfLineNum =   new ArrayList<Integer>();
            setOfLineNum.add(n.getBeginLine());
            variableLineNumMap.put(n.getName(), setOfLineNum);
        }
        else
        {
            setOfLineNum = variableLineNumMap.get(n.getName());
            setOfLineNum.add(n.getBeginLine());
            variableLineNumMap.put(n.getName(), setOfLineNum);

        }
    }
}

实例化类->

代码语言:javascript
运行
AI代码解释
复制
CatchNameExpr nameExp = new CatchNameExpr(classVariables);
        nameExp.visit(classCompilationUnit, null);

以类似的方式,您可以访问AST以获取以下表达式、语句、条件等

http://www.jarvana.com/jarvana/view/com/google/code/javaparser/javaparser/1.0.8/javaparser-1.0.8-javadoc.jar!/japa/parser/ast/visitor/VoidVisitorAdapter.html

我很清楚字节码处理器将会更有效率,并且会比我期望的做得更好。但考虑到时间限制,这个选项最适合我。

谢谢你们,贾斯米特

票数 3
EN

Stack Overflow用户

发布于 2012-11-26 05:12:15

为了完成查找变量用法的任务,带有ANTLR的解析器单元也应该生成AST。我几乎可以肯定你可以找到准备好的AST构建器,但不知道在哪里。

另一种方法是使用ASMBCEL或其他类文件分析器分析类文件。我认为这更容易,而且会更快地工作。此外,它还适用于其他jvm语言(例如Scala)。

票数 2
EN

Stack Overflow用户

发布于 2012-11-26 05:52:26

要询问变量读取是否是“全局的”,您需要一个完整的Java编译器前端,它解析代码、构建符号表和相关的类型信息。

只要编译器在你的类文件中实际记录了这个信息,你就可以执行“反射”操作来获得它。只要这样的信息存在于.class文件中,您就可以使用类文件字节码处理器来访问它,比如Kaigorodov的答案中提到的那些。

ANTLR有用于Java的语法,但我不相信有任何对符号表构造的支持。您无法自己伪造这一点;Java的规则太复杂了。您也许能够扩展ANTLR解析器来完成此任务,但这将是一项大量的工作;“Java的规则太复杂了”。

我知道Java编译器提供了对其内部结构的某种名称/类型的准确访问;您也许能够使用它。

我们的DMS软件再工程工具包具有完整的Java解析器,具有名称和类型解析功能,可用于此目的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13558373

复制
相关文章
浅尝antlr4
这次使用antlr的诱因是whosbug中使用的ctags(另一个语法分析器)只对c系语言支持较好,对java等语言的支持欠佳(甚至可以说很差了),为了whosbug的鲁棒性我认为还是有必要换一个语法分析器的
Kevinello
2022/08/19
1.8K0
浅尝antlr4
能“理解代码”的缺陷分配服务之技术内核
如果缺陷没有分配给正确的人,会导致重要缺陷不断流转,很慢才能解决;而在流转的过程中会增加大量的交接成本——我们观察到一个简单的缺陷在流转中会浪费超过5天(见下图)。而且把缺陷分配给错误的人还可能导致被分配人不知道此缺陷的前因后果,修改缺陷时容易犯错,引发新的问题。
010101011001
2021/02/10
1.2K0
R变量索引 - 什么时候使用 @或$
单细胞分析经常用到Seurat包,整个分析过程中的中间结果都在一个Seurat对象中存储。常需要从里面提取对应数据进行后续分析,有时会用$,有时会用@,怎么选择呢?
生信宝典
2019/12/11
1.5K0
js全局变量在其他方法中赋值后无法影响到该方法外的全局变量的值(奇葩问题)
做个笔记,以防忘记 遇到一个奇葩问题(书写规范不会遇到此问题 ) 问题描述:
全栈程序员站长
2022/08/22
1.8K0
VUE中隐藏和限制DIV或其他HTML元素
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
程序新视界
2019/09/25
4.5K0
机器学习:单或双变量常用分析技巧
在机器学习EDA阶段,变量分析及可视化是常做的事情,这篇文章总结变量分析中,最常使用的单变量,双变量分析以及可视化。
double
2023/03/21
1K0
机器学习:单或双变量常用分析技巧
教你如何用AST语法树对代码“动手脚”
作为程序猿,每天都在写代码,但是有没有想过通过代码对写好的代码”动点手脚”呢?今天就与大家分享——如何通过用AST语法树改写Java代码。 先抛一个问题:如何将图一代码改写为图二? void someMethod(){     String rst=callAnotherMethod();     LogUtil.log(TAG,”这里是一条非常非常长,比唐僧还啰嗦的日志信息描述,但是我短一点还不方便进行错误日志分析,调用callSomeMethod返回的结果是:”+rst); …… } 图一 void s
个推君
2018/03/21
2.8K0
教你如何用AST语法树对代码“动手脚”
产品迭代过程中的问题或事故复盘分析方法
在产品的迭代和更新中,会遇到各种各样的问题或事故,为了避免同样的问题和事故再次发生,对相关的问题或事故进行及时复盘分析,总结经验,防止再次发生。
产品言语
2022/06/02
7910
smarty 模板中定义变量的方法
{assign var="i" value=0} {foreach name=simple_tab from=$zhinan_cate key=key item=item} {if $i} <small>|</small> {/if} {if $item['count']} {math assign="i" equation="x + y" x=$i y=1} <span><a title="{$segment_parent}期{$it
零式的天空
2022/03/02
1.7K0
WPF如何在子线程或其他类中操控控件
一开始使用WPF界面的时候,会有这样的需求就是在后台更新控件,以完成列表更新,计时器,进度条等功能,但WPF这边架构限制,决定子线程是不安全的,如果创建子线程直接操作控件就会出错。
zls365
2021/03/16
2K0
java中跳出或终止if语句的方法
break:跳出当前循环;但是如果是嵌套循环,则只能跳出当前的这一层循环,只有逐层break才能跳出所有循环。
Java架构师必看
2021/12/21
5.5K1
sql中declare声明变量_什么是变量说明
前言:最近在修改Android项目的后台业务实现,发现很多地方都需要跟数据库的表连接,视图,存储过程打交道,接触一段时间,感觉不会编写sql脚本真是硬伤,在此小结一下。
全栈程序员站长
2022/09/24
9810
php中各种定义变量的方法小结
1.定义常量define("CONSTANT", "Hello world."); 常量只能包含标量数据(boolean,integer,float 和 string)。 调用常量时,只需要简单的用名称取得常量的值,而不能加“$”符号,如:echo CONSTANT; 注: 常量和(全局)变量在不同的名字空间中。这意味着例如 TRUE 和 $TRUE 是不同的。 2.普通变量$a = "hello"; 3.可变变量(使用两个美元符号($)) $$a = "world"; 两个变量都被定义了: $a 的内容是“hello”并且 $hello 的内容是“world”。 因此,可以表述为: echo "$a ${$a}";或者 echo "$a $hello";它们都会输出:hello world 要将可变变量用于数组,必须解决一个模棱两可的问题。这就是当写下 $$a[1] 时,解析器需要知道是想要 $a[1] 作为一个变量呢,还是想要 $$a 作为一个变量并取出该变量中索引为 [1] 的值。解决此问题的语法是,对第一种情况用 ${$a[1]},对第二种情况用 ${$a}[1]。 4.静态变量 在函数内部static $a = 0; 注意:声明中用表达式的结果对其赋值会导致解析错误如static $a =3+3;(error) 静态变量仅在局部函数域中存在(函数内部),函数执行完之后,变量值不会丢失,可用于递归调用 5.全局变量 在函数体内定义的global变量,函数体外可以使用,在函数体外定义的global变量不能在函数体内使用,在全局范围内访问变量可以用特殊的 PHP 自定义 $GLOBALS 数组: 如:$GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"]; 在一个函数域内用 global 语句导入的一个真正的全局变量实际上是建立了一个到全局变量的引用 global $obj; 注:对于变量的 static 和 global 定义是以 应用 的方式实现的 6.给变量赋值:传地址赋值(简单引用): $bar = &amp;$foo; //加&符号到将要赋值的变量前 改动新的变量将影响到原始变量,这种赋值操作更加快速 注意:只有命名变量才可以传地址赋值 注意:如果 $bar = &amp;$a; $bar = &amp;$foo; 改变$bar的值只能改变变量foo的值,而不改变a的值(引用/【技术点,其实还需要更多地实践】/改变了) 7.PHP 超全局变量$GLOBALS : 包含一个引用指向每个当前脚本的全局范围内有效的变量。该数组的键标为全局变量的 名称。从 PHP 3 开始存在 $GLOBALS 数组。 $_SERVER : 变量由 Web 服务器设定或者直接与当前脚本的执行环境相关联。类似于旧数组 $HTTP_SERVER_VARS 数组(依然有效,但反对使用)。
用户2323866
2021/07/12
3.6K0
Python中如何定义变量?定义变量的规则是什么?
上一篇文章讲述了变量的概念和作用,下面讲解的是变量的第二个知识点 - 定义变量和定义变量名的规则,下一篇在讲解变量的使用。
python自学网
2022/02/24
3.4K0
IDEA插件:快速删除Java代码中的注释
本文针对Java语言,介绍一种利用第三方库的方式,可以方便快速地移除代码中的注释。
xiaoxi666
2021/02/17
2.9K0
Antlr4的相关用法
ANTLR (ANother Tool for Language Recognition) 是一个强大的解析器的生成器,可以用来读取、处理、执行或翻译结构化文本或二进制文件。他被广泛用来构建语言,工具和框架。ANTLR可以从语法上来生成一个可以构建和遍历解析树的解析器。
东风压倒西风
2022/11/23
7040
javascript ||或运算符的其他用法
关于或运算符的基本用法可以参阅javascript 逻辑||运算符一章节。 其实运算符也可以起到类似于if语句的功能,下面看一段代码实例: function func(arg) { var arg = arg || 5; console.log(arg); } func();
IT工作者
2021/12/29
3410
Linux的环境变量配置在/etc/profile或/etc/profile.d/*.sh文件中的区别是什么?
Linux的环境变量可在多个文件中配置,如/etc/profile,/etc/profile.d/*.sh,~/.bashrc等,下面说明上述几个文件之间的关系和区别。
孙晨c
2021/01/29
2.5K0
Linux的环境变量配置在/etc/profile或/etc/profile.d/*.sh文件中的区别是什么?
java中的成员变量和全局变量有什么区别?
作者:Winston 链接:https://www.zhihu.com/question/294221894/answer/493705474 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用户8639654
2021/07/26
1.3K0
点击加载更多

相似问题

ANTLR新手:ANTLR和JavaParser之间的区别是什么

20

ANTLR v4、JavaLexer和JavaParser返回null作为分析树

213

使用JavaParser解析变量的正确方法是什么?

30

Javaparser变量声明

12

如何使用JavaParser解析方法或任何其他有效表达式

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文