I want to use the parser to give me details of where C/C++
statements are, however I have so far failed to penetrate the AST with an
instance of the ISourceElementRequestor (See code at the end). Here is an
example of what I’d like as information, take the following C code:
1: int main(int argc, char argv[])
2: {
3: if (argc == 0) {
4: printf("You didn't pass in any
arguments");
5: return -1;
6: }
7: else {
8: printf("You passed in %d
args\n",argc);
9: return 1;
10: }
11:}
I am particularly interested in understanding that the ‘If’
keyword is on line 3, the condition statement is also on line 3, the ‘else’
keyword is on line 7. Then I need to know the details of the ‘then’
code block and the ‘else’ code block.
I traced through the parser code and it seems that it should
be possible to get this information, but it seems that the line number is not
stored, or it maybe stored if a new scope is generated for the ‘if’.
For those not familiar with the code this token reading etc. is all
happening in the package cdt.internal.core.parser. and
cdt.internal.core.parser.ast.
So right now my ISourceElementRequestor gets the codeBody
call back for the ‘then’ block and the ‘else’ block,
but I don’t seem to be able to determine the details of the
statements within the code bodies, nor the location of syntactic keywords.
Could someone please shed some light on this for me? I
am assuming that this kind of thing is already done for the editor that
highlights keywords in the source files, but I am not sure.
Any insights will be very much appreciated.
Jason
PS: Below is the code I’m using.
class CMySourceElementRequestor extends
StructuralParseCallback
{
private ParserMode mode =
ParserMode.COMPLETE_PARSE;
private
void addElement (IASTDeclaration element){
if(inclusionLevel
== 0){
if(
currentScope instanceof ASTScope )
((ASTScope)currentScope).addDeclaration(element);
else
if( currentScope instanceof ASTLinkageSpecification )
((ASTLinkageSpecification)currentScope).addDeclaration(
element );
}
}
private
void enterScope(IASTNode node){
if(node
instanceof IASTScope){
if(node
instanceof ASTScope){
((ASTScope)node).initDeclarations();
}
pushScope((IASTScope)node);
}
}
private
void exitScope(IASTNode node){
if(node
instanceof IASTScope){
popScope();
}
}
private
void pushScope( IASTScope scope ){
scopeStack.addFirst(
currentScope );
currentScope
= scope;
}
private
IASTScope popScope(){
IASTScope
oldScope = currentScope;
currentScope
= (scopeStack.size() > 0 ) ? (IASTScope) scopeStack.removeFirst() : null;
return
oldScope;
}
public
void enterFunctionBody( IASTFunction function )
{
System.out.println("Enter
function");
if(function.getOwnerTemplateDeclaration()
== null)
addElement(function);
else
if(function.getOwnerTemplateDeclaration() instanceof IASTTemplateDeclaration)
addElement((IASTTemplateDeclaration)function.getOwnerTemplateDeclaration());
}
public
void exitFunctionBody( IASTFunction function )
{
System.out.println("Exit
function");
function.setHasFunctionBody(
true );
}
public
void enterCodeBlock( IASTCodeScope scope )
{
System.out.println("Enter
Code Block");
enterScope(scope);
}
public
void exitCodeBlock( IASTCodeScope scope )
{
System.out.println("Exit
Code Block");
exitScope(scope);
}
public
void enterCompilationUnit( IASTCompilationUnit compilationUnit )
{
System.out.println("Enter
Compilation Unit");
enterScope(compilationUnit);
}
public
void exitCompilationUnit( IASTCompilationUnit compilationUnit )
{
System.out.println("Exit
Compilation");
exitScope(compilationUnit);
this.compUnit
= compilationUnit;
}
/**
*
@param finalPath
*
@return
*/
public
CodeReader createReader(String finalPath, Iterator workingCopies )
{
return
InternalParserUtil.createFileReader( finalPath );
}
/**
*
The parser asks the client if it wishes to time out
*
in case it is taking more than the expected time.
*
@return
*/
public
boolean parserTimeout()
{
return
false;
}
}
/**
* @author jason
*
* TODO To change the template for this generated type
comment go to
* Window - Preferences - Java - Code Style - Code
Templates
*/
public class Test {
public
static void main(String[] args) {
IScanner
myIScanner;
IParser
myIParser;
CMySourceElementRequestor
mySourceElementRequestor;
try
{
mySourceElementRequestor
= new CMySourceElementRequestor();
myIScanner
= ParserFactory.createScanner("c:\\temp\\test.c",new
ScannerInfo(),ParserMode.COMPLETE_PARSE,ParserLanguage.C, mySourceElementRequestor,
null,null);
myIParser
= ParserFactory.createParser(myIScanner, mySourceElementRequestor,
ParserMode.COMPLETE_PARSE, ParserLanguage.C,null);
if
(myIParser.parse() == true)
{
System.out.print("Parse
successful");
}
else
{
System.out.print("Parse
unsuccessful");
}
}
catch
(IOException e)
{
return;
}
}
}