Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Is there a parser for .NET expression trees?

Is there a parser for .NET expression trees?

Scheduled Pinned Locked Moved The Lounge
csharpquestionlinqcom
24 Posts 9 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H honey the codewitch

    Cool, maybe I'll write it then. I already have a C# subset parser.

    Real programmers use butterflies

    Q Offline
    Q Offline
    quantasm23
    wrote on last edited by
    #12

    Front End - jQuery QueryBuilder Backend - GitHub - castle-it/dynamic-linq-query-builder: A truly generic and dynamic linq query builder to compliment jQuery QueryBuilder and other dynamic linq query generation needs Other backend parsers - jQuery QueryBuilder

    1 Reply Last reply
    0
    • Sander RosselS Sander Rossel

      I just thought of something. If you could ever find that eval-like function, you could do something like Eval($"Expression<Func<int, int>> exp = {myCode};"); and the exp variable would be available outside the Eval function in your current scope :D I remember the context in which I saw that function. The customer wanted to do stuff like enter "amount * 10", sort of a calculator utility inside the application. My coworker was like, "I could write a parser and spend a few days, or I can do it like this and be done with it" :laugh: I should mention it was VB.NET though and I think it was somewhere inside a VB specific namespace (although I'm not sure). I think I saw it work with C# once too. The fact that I can't find this function anywhere is really pissing me off (not that I'd want to use it) :sigh: I did find some smart guy who just compiled a string using reflection (using ICodeCompiler.CompileAssemblyFromSource) and then simply invokes it :laugh:

      Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

      H Offline
      H Offline
      honey the codewitch
      wrote on last edited by
      #13

      Sander Rossel wrote:

      My coworker was like, "I could write a parser and spend a few days, or I can do it like this and be done with it

      I can write an expression parser in about a day, but it would take forever to test

      Sander Rossel wrote:

      I did find some smart guy who just compiled a string using reflection (using ICodeCompiler.CompileAssemblyFromSource) and then simply invokes it

      I actually considered that approach. Or using Roslyn. I think I'll avoid the Eval function, wherever it is. It probably compiles code anyway.

      Real programmers use butterflies

      Sander RosselS 1 Reply Last reply
      0
      • H honey the codewitch

        @SanderRossel I believe you've used them before. Do you know anything that will let me do like Expression.Parse("1 + x"); or similar? Anyone? Bueller? Basically, I already have the code to parse C# expressions and turn them into trees. I'd simply have to modify it to make expression trees instead of codedom expression trees. The question is, am I reinventing the wheel?

        Real programmers use butterflies

        Z Offline
        Z Offline
        ZevSpitz
        wrote on last edited by
        #14

        If you already have code that parses C# expressions, why not use the factory methods at [`System.Linq.Expressions.Expression`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression)?

        H 1 Reply Last reply
        0
        • Z ZevSpitz

          If you already have code that parses C# expressions, why not use the factory methods at [`System.Linq.Expressions.Expression`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression)?

          H Offline
          H Offline
          honey the codewitch
          wrote on last edited by
          #15

          That was my plan, but before I did it I wanted to see if it was done. My parser spits out CodeDOM constructs, so it needs some retooling to work with expressions.

          Real programmers use butterflies

          1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            How about the Dynamic Linq library? GitHub - zzzprojects/System.Linq.Dynamic.Core: The .NET Standard / .NET Core version from the System Linq Dynamic functionality.[^]


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            O Offline
            O Offline
            Oleg Shilo
            wrote on last edited by
            #16

            Are you looking for something like that?

            var product = CSScript.CreateFunc(@"int Product(int a, int b)
            {
            return a * b;
            }");
            int result = product(3, 4);

            The solution (cs-script) is based on Roslyn engine.

            1 Reply Last reply
            0
            • H honey the codewitch

              @SanderRossel I believe you've used them before. Do you know anything that will let me do like Expression.Parse("1 + x"); or similar? Anyone? Bueller? Basically, I already have the code to parse C# expressions and turn them into trees. I'd simply have to modify it to make expression trees instead of codedom expression trees. The question is, am I reinventing the wheel?

              Real programmers use butterflies

              B Offline
              B Offline
              buckrogerz 0
              wrote on last edited by
              #17

              So not sure if this is what your looking for but I used the System.Linq.Expressions namespace to build a dynamic link query to be executed against EF. here is an incomplete sample for syntax example:

              propertyToUse = workingProperty.Substring(0, workingProperty.IndexOf('.'));
              Type propertyToUseType = GetEntityType(propertyToUse, incomingParentType);

                          ParameterExpression propertyToUseParameterExpression = Expression.Parameter(propertyToUseType, propertyToUse.Substring(0,1));
                          Expression parentExpression = Expression.Property(workingExpression, propertyToUse);
              
                          if (parentExpression.Type.IsGenericType &&
                              typeof(IEnumerable<>)
                                  .MakeGenericType(parentExpression.Type.GetGenericArguments())
                                  .IsAssignableFrom(parentExpression.Type))
                          {
                              Expression childExpression = BuildPropertyExpression(propertyToUseParameterExpression,
                                  workingProperty, comparisonOperation, compareValue);
                              Type func = typeof(Func<,>);
                              Type genericFunc = func.MakeGenericType(propertyToUseType, typeof(bool));
                              LambdaExpression predicate =
                                  Expression.Lambda(genericFunc, childExpression, propertyToUseParameterExpression);
              
                              //we have call the AsQueryable on the collection since we don't have the compiler working for us and we need to use the any method
                              MethodInfo asQueryableMethod = typeof(Queryable).GetMethods()
                                  .Where(m => m.Name == "AsQueryable")
                                  .Single(m => m.IsGenericMethod)
                                  .MakeGenericMethod(propertyToUseType);
                              Expression asQueryableExpression = Expression.Call(null, asQueryableMethod, parentExpression);
              
                              //call the any method with the lambda expression we set up
                              MethodInfo anyMethod = typeof(Queryable).GetMethods()
                                  .Where(m => m.Name == "Any")
                                  .Single(m => m.GetParameters().Length == 2)
                                  .MakeGenericMethod(propertyToUseType);
                              returnValue = Expression.Call(
                                  null,
                                  anyMethod,
                                  asQueryableExpression, //the source
                                  predicate); // the lambda expression
                          }
              

              There are other fa

              1 Reply Last reply
              0
              • M Member 14025503

                CS0030 Cannot convert type 'string' to 'System.Linq.Expressions.Expression'

                Sander RosselS Offline
                Sander RosselS Offline
                Sander Rossel
                wrote on last edited by
                #18

                Yes. That was a joke, there's no way a string can simply be cast to an Expression ;)

                Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                1 Reply Last reply
                0
                • H honey the codewitch

                  Sander Rossel wrote:

                  My coworker was like, "I could write a parser and spend a few days, or I can do it like this and be done with it

                  I can write an expression parser in about a day, but it would take forever to test

                  Sander Rossel wrote:

                  I did find some smart guy who just compiled a string using reflection (using ICodeCompiler.CompileAssemblyFromSource) and then simply invokes it

                  I actually considered that approach. Or using Roslyn. I think I'll avoid the Eval function, wherever it is. It probably compiles code anyway.

                  Real programmers use butterflies

                  Sander RosselS Offline
                  Sander RosselS Offline
                  Sander Rossel
                  wrote on last edited by
                  #19

                  honey the codewitch wrote:

                  but it would take forever to test

                  I wrote some TagHelpers for ASP.NET Core Razor and all your writing inspired me to write an article about it. So, clean up the code a bit (which took me hours, it was a mess, you'd be proud :laugh: ) and add unit tests... Turns out it's pretty much impossible to unit test those things! Here's the unit tests for the InputTagHelper: Mvc/InputTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] That's almost 2000 lines and I inherited that thing :wtf: I'd need to test others too, like Mvc/SelectTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] and Mvc/ValidationMessageTagHelperTest.cs at master · aspnet/Mvc · GitHub[^], another 1300 something LOC just for the basic tests :( But it doesn't stop there. It makes use of a "TestableHtmlGenerator", which I'm obviously going to need. Luckily, it's not a big class, but what the hell does it all do? :) Mvc/TestableHtmlGenerator.cs at master · aspnet/Mvc · GitHub[^] A single test would need about as much LOC as my entire library :sigh: So to hell with unit tests and back to some good old manual testing and praying for the best :laugh:

                  Best, Sander sanderrossel.com M

                  H 1 Reply Last reply
                  0
                  • Sander RosselS Sander Rossel

                    honey the codewitch wrote:

                    but it would take forever to test

                    I wrote some TagHelpers for ASP.NET Core Razor and all your writing inspired me to write an article about it. So, clean up the code a bit (which took me hours, it was a mess, you'd be proud :laugh: ) and add unit tests... Turns out it's pretty much impossible to unit test those things! Here's the unit tests for the InputTagHelper: Mvc/InputTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] That's almost 2000 lines and I inherited that thing :wtf: I'd need to test others too, like Mvc/SelectTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] and Mvc/ValidationMessageTagHelperTest.cs at master · aspnet/Mvc · GitHub[^], another 1300 something LOC just for the basic tests :( But it doesn't stop there. It makes use of a "TestableHtmlGenerator", which I'm obviously going to need. Luckily, it's not a big class, but what the hell does it all do? :) Mvc/TestableHtmlGenerator.cs at master · aspnet/Mvc · GitHub[^] A single test would need about as much LOC as my entire library :sigh: So to hell with unit tests and back to some good old manual testing and praying for the best :laugh:

                    Best, Sander sanderrossel.com M

                    H Offline
                    H Offline
                    honey the codewitch
                    wrote on last edited by
                    #20

                    Sander Rossel wrote:

                    So to hell with unit tests and back to some good old manual testing and praying for the best

                    That's the spirit! Liberating isn't it? What's a good program without a few bugs anyway? :-D

                    Real programmers use butterflies

                    Sander RosselS 1 Reply Last reply
                    0
                    • H honey the codewitch

                      Sander Rossel wrote:

                      So to hell with unit tests and back to some good old manual testing and praying for the best

                      That's the spirit! Liberating isn't it? What's a good program without a few bugs anyway? :-D

                      Real programmers use butterflies

                      Sander RosselS Offline
                      Sander RosselS Offline
                      Sander Rossel
                      wrote on last edited by
                      #21

                      honey the codewitch wrote:

                      What's a good program without a few bugs anyway?

                      A very short program :laugh:

                      Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly

                      1 Reply Last reply
                      0
                      • H honey the codewitch

                        @SanderRossel I believe you've used them before. Do you know anything that will let me do like Expression.Parse("1 + x"); or similar? Anyone? Bueller? Basically, I already have the code to parse C# expressions and turn them into trees. I'd simply have to modify it to make expression trees instead of codedom expression trees. The question is, am I reinventing the wheel?

                        Real programmers use butterflies

                        N Offline
                        N Offline
                        nassimi
                        wrote on last edited by
                        #22

                        I did it this way (and I an NOT a JavaScript programmer): 1. JavaScript code:

                        class JsMath
                        {
                        static function Eval(expression: String): double
                        {
                        return eval(expression);
                        };
                        }

                        2. Compile:

                        C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\jsc.exe /t:library jsMath.js

                        3. Use in C#:

                            private static double ExpressionValue(string expr)
                            {
                                return JsMath.Eval(expr);
                            }
                        
                        H 1 Reply Last reply
                        0
                        • N nassimi

                          I did it this way (and I an NOT a JavaScript programmer): 1. JavaScript code:

                          class JsMath
                          {
                          static function Eval(expression: String): double
                          {
                          return eval(expression);
                          };
                          }

                          2. Compile:

                          C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\jsc.exe /t:library jsMath.js

                          3. Use in C#:

                              private static double ExpressionValue(string expr)
                              {
                                  return JsMath.Eval(expr);
                              }
                          
                          H Offline
                          H Offline
                          honey the codewitch
                          wrote on last edited by
                          #23

                          well I suppose that's one way to do it. :-D

                          Real programmers use butterflies

                          N 1 Reply Last reply
                          0
                          • H honey the codewitch

                            well I suppose that's one way to do it. :-D

                            Real programmers use butterflies

                            N Offline
                            N Offline
                            nassimi
                            wrote on last edited by
                            #24

                            Very lazy way :)

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups