The following is a list of resources provided by Simon for anyone interested in learning more:
Videos
- http://microsoftpdc.com/Sessions/FT34
- http://www.informit.com/podcasts/episode.aspx?e=FCD86576-CB86-406D-8B59-DC3714F33B7E
- http://channel9.msdn.com/posts/Charles/Don-Box-Paul-Vick-and-Chris-Anderson-Introducing-M/
- http://www.microsoft.com/showcase/en/us/details/f6aa43f6-4d63-46c8-ac79-2c6c76c099f2
- http://channel9.msdn.com/pdc2008/TL31/ (the best one to start)
Pages
- http://msdn.microsoft.com/en-us/library/dd129519%28VS.85%29.aspx
- http://msdn.microsoft.com/en-us/library/dd285282.aspx
- http://blogs.msdn.com/mlanguage/
- http://community.bartdesmet.net/blogs/bart/archive/2009/02/14/the-m-programming-language-part-0-intellipad-mrepl-vs2008-project-support-and-excel-integration.aspx
- https://community.dynamics.com/blogs/crmcesardalatorre/comments/23686.aspx
Sample Code
- http://code.msdn.microsoft.com/SQLServerModelingCTP
- http://code.msdn.microsoft.com/SQLModCTPMLangWix
More Links
- http://dougfinke.com/blog/?p=499
- http://msdn.microsoft.com/en-us/library/dd129870.aspx (good introduction)
- http://blog.codeslower.com/2008/11/Syntax-Coloring-for-Your-Custom-Mg-Language-with-Intellipad (syntax highlighting)
Also as promised the code from Simon's presentation:
MGrammar Sample Code
- module ConsoleApplication2
- {
- language Language1
- {
- syntax Main= a:List(DomainName) b:List(EmailDetails) => {Domains [valuesof(a)], valuesof(b)};
- syntax EmailDetails =(a:EmailAddress b:EmailFullname => {Address {a}, Fullname {b}})
- | (a:EmailAddress c:EmailAlias b:EmailFullname => {Address {a}, Fullname {b}, Alias {c}});
- syntax EmailAddress = Email a:NameWithDot => a;
- syntax EmailFullname = Fullname b:QuotedName => b;
- syntax EmailAlias = Alias c:NameWithDot => c;
- syntax DomainName = Domain a:NameWithDot =>a;
- syntax List(element) = e:element | es:List(element) e:element => [valuesof(es),e];
- interleave whitespace = '\t' | ' ' | '\r' | '\n';
- @{Classification["Keyword"]} token Begin = "Begin";
- @{Classification["Keyword"]} token End = "End";
- @{Classification["Keyword"]} token Domain = "Domain";
- @{Classification["Keyword"]} token Email = "Email";
- @{Classification["Keyword"]} token Fullname = "Fullname";
- @{Classification["Keyword"]} token Alias = "Alias";
- token TextEscape = '\\"';
- token TextCharacter = !( '"' ) | TextEscape | '_';
- token TextCharacters = TextCharacter*;
- @{Classification["String"]} token QuotedName = '"' TextCharacters '"';
- token Name = ('A'..'Z'| 'a'..'z')+;
- token NameWithDot = (Name | "." | DecimalDigit)+;
- token DecimalDigit ='0'..'9';
- }
- }
Compiler Code in C#
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Microsoft.M;
- using System.Reflection;
- using System.Dataflow;
- namespace ConsoleApplication2
- {
- class Program
- {
- static void Main(string[] args)
- {
- using (var image = MImage.LoadFromAssembly(Assembly.GetExecutingAssembly()))
- {
- var language = image.ParserFactories["ConsoleApplication2.Language1"].Create();
- language.GraphBuilder = new NodeGraphBuilder();
- Node root = (Node)language.Parse(@"..\..\TextFile1.txt", ErrorReporter.Standard);
- foreach (var item in root.ViewAllNodes())
- {
- if (item.Brand.Text == "Domains")
- {
- Console.WriteLine("Domains");
- foreach (var i in item.Edges)
- {
- Console.WriteLine(i.Node.AtomicValue);
- }
- }
- else if (item.Brand.Text == "EmailDetails")
- {
- Console.WriteLine("Emails");
- foreach (var i in item.Edges)
- {
- foreach (var j in i.Node.Edges)
- {
- if (j.Node.Brand.Text == "Address")
- { Console.WriteLine("Address " + j.Node.Edges.First().Node.AtomicValue); }
- else if (j.Node.Brand.Text == "Fullname")
- { Console.WriteLine("Fullname " + j.Node.Edges.First().Node.AtomicValue); }
- else if (j.Node.Brand.Text == "Alias")
- { Console.WriteLine("Alias " + j.Node.Edges.First().Node.AtomicValue); }
- }
- }
- }
- }
- Console.WriteLine("Code Compiled");
- }
- Environment.Exit(0);
- }
- }
- }
Update (29/06/10):
David Burela who filmed Simon's presentation has uploaded the video to his blog.Nice one, thanks for that David.