How To Get name of CSharp classes and methods..etc

Jan 13, 2011 at 7:28 PM

Hi I am trying to basically use this CSharp grammer with Antlr to parse csharp source file and get some information like:

name of namespaces, classes, methods ..etc.

this might sound simple but I couldnt figoure out how to get these information ..I looked at CSParser here (http://csparser.codeplex.com/) and it was very easy to use..but I like to use ANTLR to support parsing different languages in the future.

 

any help will be really appreciated.

Thanks.

Jan 13, 2011 at 8:58 PM
Edited Jan 13, 2011 at 9:00 PM

To get names of methods, go to method_declaration parser rule, add an action statement at the end of the rule:

{string methodName = $method_header.text;} 

Namespaces are similar. Classes are, however, a bit tricky. The rule is:

class_declaration:
 'class' type_or_generic   class_base?   type_parameter_constraints_clauses?   class_body   ';'?

and type_or_generic contains the class name you want. And rule type_or_generic is:

type_or_generic:
 (identifier
   generic_argument_list) => identifier   generic_argument_list
 | identifier
;

so if you're only interested in the class name but not the generic argument, you can't simply use $type_or_generic.text to get what you want. Instead, you may have to play a small trick here. First, define a protected variable in the @members section at the begining of the grammar file:

protected bool _isClass = false;

then add 2 statements in the class_declaration rule:

 'class' {_isClass = true;} type_or_generic {_isClass = false;}  class_base?   type_parameter_constraints_clauses?   class_body   ';'?

in type_or_generic rule, add a few statements so that it looks like this:

type_or_generic:
 (t=identifier { if (_isClass) { string className = $t.text; } }
   generic_argument_list) => identifier   generic_argument_list
 | p=identifier  {  if (_isClass) { string className = $t.text; }  }
;

You may also do this through dynamic scope which, however, seems less reliable to me than protected variables.

Hope this helps.

Jan 13, 2011 at 9:52 PM

Thanks a lot bradleyasdf,
I apologize I am new to ANTLR and need more clarification please.
let us just talk about the method names only .

so basically, the first step is to open the cs.g file and append this action
{string methodName = $method_header.text;}

at the end of the method_declaration rule, so now it is like this:

///////////////////////////////////////////////////////
method_declaration:
    method_header   method_body ;
method_header:
    member_name  '('   formal_parameter_list?   ')'   type_parameter_constraints_clauses? ;
method_body:
    block ;
member_name:
    qid ;        // IInterface.Method logic added.
{string methodName = $method_header.text;}

///////////////////////////////////////////////////////


so now in my program, how can I access the methodName ?

CommonTokenStream tokens = CreateLexer<PreProcessor>(file_name);
csParser p = new csParser(tokens);

then what ?

I found that csParser object contain a lot of methods that are void.. like there is one called : method_declaration and from the first look I thought this is what I need but not sure now how can I use such method?
I thought csParser object will contain some sort of a table structure that contains all matches for all rules defined in the grammar file cs.g ?


Thanks Again for your help .






Jan 14, 2011 at 2:03 PM

The easiest way is to define a public variable in the parser class (I'm using .net port of Antlr, so I use C# code below. The java code should be quite similar, though.

public List<string> MethodNames = new List<string>();

method_declaration:
    t=method_header  { this.MethodNames.Add($t.text); }  method_body ;

So you can simply access to this variable from your class:

csParser p = new csParser(tokens);

csParser.compilation_unit();

List<string> whatIWant = csParser.MethodNames;

Of course you may also do it through class properties/get and set methods as well.

 

Jan 14, 2011 at 5:44 PM
Edited Jan 14, 2011 at 6:18 PM

Thanks again bradleyasdf :)

I have rally better understanding now .. I made a reply but now I am editing .

I maanged to modify the cs.g to contain :

///////////////////////////////////////////////////////
method_declaration:
      t=method_header  { this.MethodNames.Add($t.text); }  method_body ;
method_header:
    member_name  '('   formal_parameter_list?   ')'   type_parameter_constraints_clauses? ;
method_body:
    block ;
member_name:
    qid ;        // IInterface<int>.Method logic added.

///////////////////////////////////////////////////////

 

I rebuild the solution and ran it ..but unfortuantly  p.MethodNames is empty :(

ofcourse I tested the program with cs files that contains methods.

 

 

 

Jan 14, 2011 at 10:11 PM

I applogoize , I did some silly mitake and now the it works fine

Thanks a lot for the help bradleyasdf :)

Mar 24, 2011 at 2:19 PM
bradleyasdf wrote:

The easiest way is to define a public variable in the parser class (I'm using .net port of Antlr, so I use C# code below. The java code should be quite similar, though.

 


Hi bradleyasdf,

I have downloaded the source code of this project, and looks to me like it's firing the java version of antlr. Is the .NET port stable and reliable in your opinion? Where can I get the latest version? Also, are you using any type of IDE for ANTLR? ("ANTLR IDE 2.1 looks promising, but I don't want to have tu use eclipse if I can avoid it).

Thanks in advance.

Gustavo