8

How to find all the variables in the source C# code?
Here's my non-working grammar, which does not work because ZeroOrMore (VarDef4)

Protected = Literal("protected")  
Private = Literal("private")  
Public = Literal("public")  
Modification = Public^Private^Protected  

Static = Literal("static")  
Auto = Literal("Auto")   
MemoryType =(Static^Auto)  
Bool = Literal("bool"); Byte = Literal("byte"); Char = Literal("char"); Decimal = Literal("decimal"); Double = Literal("double"); Enum = Literal("enum")
Float = Literal("float"); Int = Literal("int"); Long = Literal ("long"); Sbyte = Literal("sbyte"); Short = Literal("short")
Struct = Literal("struct"); String = Literal("string"); Uint = Literal("uint"); Ulong = Literal("ulong"); Ushort = Literal("ushort")  

VariableType = (Bool)^(Byte)^(Char)^(Decimal)^(Double)^(Enum)^(Float)^(Int)^(Long)^(Sbyte)^(Short)^(Struct)^(String)^(Uint)^(Ulong)^(Ushort)    

Variable = Word(alphanums + '_' + '$'+ '.' ) 
VarDef2 = '=' + OneOrMore(Word(alphanums + '_' + '$' + '"' + '-'+ "'" ) )  
VarDef3 = ZeroOrMore("," + Variable + Optional(VarDef2))  
VarDef4 = VarDef2^VarDef3 VarDef =  Optional(Modification) + Optional(MemoryType) + (VariableType) + Variable  + ZeroOrMore(VarDef4) + ";"

For example my string input given:

int k1 = 89, k2 = 6;  
public static int alpha = 54 ;  

In the output file:

{'Row': 1, 'Construct': "['int', 'k1', '89]", "['int', 'k2', '6']", 'Variable' : k1, k2, 'VariableType': int, 'Modification': not defined, 'MemoryType': not defined, 'Line': 'int k1 = 89, k2 = 6'}  
{'Row': 2, 'Construct': "['public', 'static', 'int', 'alpha']", 'Variable': alpha, 'VariableType': int,'Modification': public, 'MemoryType': static, 'Line': 'public static int alpha = 54'} 

Maybe there is another way to implement this grammar or how to make this grammar?

farabiDev
  • 81
  • 3
  • 2
    Any reason you don't want to use Roslyn instead? That's basically the *canonical* way of parsing .NET code... – Jon Skeet Nov 14 '16 at 13:59
  • 1
    @Jon Skeet Unless this can not be done with the help of pyparsing. I need to write it in python – farabiDev Nov 14 '16 at 14:14
  • Before you start writing code, write some examples of what you want to parse, and then from that map out a BNF that describes those examples. *Then* you'll be ready to start writing parser code (whether it's pyparsing, PLY, spark, or whatever). – PaulMcG Nov 14 '16 at 22:26
  • 1
    You can call into roslyn from pythonnet or ironpython, no need to re-invent the wheel! – denfromufa Nov 16 '16 at 05:07
  • There are various parser libraries available for C#, such as Roslyn, ANTLR, Irony... – ghostlegend Mar 28 '23 at 10:00

1 Answers1

0

Here it is an example of C# code on how you can use a parser to extract variables. Note that this is just a simple example and you may need to adjust the code to handle more complex scenarios:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

public class Literals
{
    public void Execute()
    {
        string code = @"int k1 = 89, k2 = 6;
                    public static int alpha = 54;
                    bool flag = true;
                    string message = ""Hello, world!"";
                    double pi = 3.14159;";
    
        SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
        IEnumerable<VariableDeclarationSyntax> variableDeclarations = tree.GetRoot()
            .DescendantNodes()
            .OfType<VariableDeclarationSyntax>();
    
         variableDeclarations.ToList().ForEach(variableDeclaration =>
         {
           variableDeclaration.Variables.ToList().ForEach(variableDeclarator =>
            {
                Console.WriteLine($"" +
                    $"{variableDeclaration.Type} " +
                    $"{variableDeclarator.Identifier.ValueText} = " +
                    $"{variableDeclarator.Initializer?.Value?.ToString() ?? "null"}");
            });
        });
    }
}
ghostlegend
  • 512
  • 10
  • 19