I finally have an end to end example of code generation with MGrammar I’m happy with. It’s pretty simple too I think. What I have working right now is the scenario where you author a grammar for use as an external DSL and would like to use it in existing applications. You are able to add templates to any .NET project and generate code in the native language. Which means the same template will work for C#, VB, F#, Boo or whatever projects since it compiles down to the CodeDom.
In addition to your MGrammar language definition you can now create a template in MetaSharp, there is a MSBuild task that compiles that template file into a Template class in the native language of your project. That template class knows how to generate code that binds to a model (MGraph objects or CLR objects). Here is a visual example.
Here is an example of a template in MetaSharp.
namespace Samples.Song.Templates: import System; import System.Collections.Generic; import System.Threading; import System.Text; public class {Song.Name} as Song: public constructor: @for(b in {Song.Bars as enumerable}): super.Bars.Add(new Bar( "{b.Note1}", "{b.Note2}", "{b.Note3}", "{b.Note4}")); @end end end end
Its a very simple language, the interesting parts are the ‘@’ characters and the {…} groups. The @ symbol puts that line into template mode. Meaning that will be a literal line in the template. The curly bracket groups are Binding statements, similar to what you see in Xaml only much less expressive at this point. So far you just specify a path and an optional type to cast it to. “enumerable” is just a helper to cast it to IEnumerable, or in the case if MGraph to get the sequence for the node.
So if you take the song DSL file from the Song Sample included in the Oslo SDK.
Song Fun - - - D C C# F G E E - D A E - E G F - E D C D E A E D D D E A C
And apply that to the template above you end up with this code (in C# in this case):
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:2.0.50727.3521 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace Samples.Song.Templates { using System; using System.Collections.Generic; using System.Threading; using System.Text; public class Fun : Song { public Fun() { base.Bars.Add(new Bar("-", "-", "-", "D")); base.Bars.Add(new Bar("C", "C#", "F", "G")); base.Bars.Add(new Bar("E", "E", "-", "D")); base.Bars.Add(new Bar("A", "E", "-", "E")); base.Bars.Add(new Bar("G", "F", "-", "E")); base.Bars.Add(new Bar("D", "C", "D", "E")); base.Bars.Add(new Bar("A", "E", "D", "D")); base.Bars.Add(new Bar("D", "E", "A", "C")); } } }
So this is really cool! This will allow you to create MGrammar DSLs without having to write complicated code to consume the object graph. And it all happens at build time! I’m planning on doing a little more cleanup then probably creating a CodePlex project for this. This is exactly what I wanted for NBusiness… hopefully I can get back to that soon, haha!
You must log in to post a comment.