I am trying to analyse Java code sturcture.
So, I generated a Java parser and lexer by using ANTLRv3 and java grammar code...
but I don\'t know how could I g
These days, I found an Eclipse plug-in generating Java Control Flow Graph:Control Flow Graph Factory. This plug-in generates CFG perfectly and store it by XML file.
AFAIK, ANTLR provides no specific help in building a control flow graph.
You can build one yourself by walking the AST, and collecting knowledge of actions (unconditional statements) and conditions (expression nodes control conditionals), and assembling the graph from that information. Note that switch statements are a kind of compound conditional and need to be handled as a set of decisions, or a special N-way conditional.
Exception handling may change what you think of as "unconditional actions"; every method call has the potential to redirect control flow to the exception handler (or to the exit of the function) and you need to decide if you are going to include these in your control flow graph. If you want to reason about what the program does (especially dataflow) you will need to model these.
You will need to create control flow nodes (just a kind of class) that can refer to pieces of the AST ("this is the action") and to two other control flow nodes (to handle if-then-else); this of these exits as "true exit" and "false exit" or alternatively "continue to" and "trap to" exits. Subclasses of this will represent pure computation, IF statements, TRY blocks, etc.
The fact that Java is a pure "structured" langauge means you can build the control flow graph "bottom up"; you can build bits of the control flow graph as you traverse leaf-upwards, and combine control flow graphs from children as you climb the tree. What you need to do is pass a so-far-assembled control flow graph (initially empty at the leaves) up the tree with a reference to a list of control flow nodes in that graph that want to pass control to an exception handler. Then as you climb the tree, extend the control flow graph.
Most of the work happens at a conditional, such as an IF-THEN-ELSE node; in this case, two control flow subgraphs with two sets of exceptions are passed to that node. You then create a control flow node to represent the conditional, set its action to point to the conditional expression, set its two children to point to the two subgraphs passed in, and set its exception set to the union of the exception set.
Subroutine calls get flow nodes whose action is the method call, with an exit to the following statement/subexpression, and another exit (unfilled) that will eventually point to the catch clause. Add the subroutine call node to the list of exceptions passed up.
Treat THROW statment similarly, although they have have no "next" action.
When you encounter a TRY construct, generate a conditional node with the action pointing to the try body, one exit pointing to the end of try or to a finally subroutine call. Finally, patch all the control flow nodes in the exception list to point to the catch clause.
You'll need to chain the catch clauses together as a sequence of if statements.
You have to treat "finally" as a subroutine call, invoked from the try clause, and the various catch clauses.