When I started my DSL talk for los officiea, I was looking around for neat DSL things to add when I found Irony. I found it at a Lang.NET talk. Then I wrote a small DSL to define some geometric circles. So, here’s a quick rundown of how I made it happen.
Irony is used to define a parser. Inside the parser’s constructor, we build the BNF tree that describes the grammar. When that’s done, Irony will spit out an Abstract Syntax Tree (AST) that we can use for “real work”. Let’s take a look at some of the grammar, before we see the Parser code.
program <- shape +
shape <- circle | polygon | rectangle
circle <- circle point radius number
point <- [ number , number ]
What this looks like is the program ‘circle [100, 150] radius 35’. It gives me circle with a center and a radius. What’s that look like in C#? Or at least the circle bit?
public class ShapesParser : GrammarParser { public ShapesParser() { // Terminal statements var numbers = new NumberTerminal("number"); // Non-Terminal var circle = new NonTerminal("circle", CircleBuilder); var point = new NonTerminal("point", PointBuilder); // Rules circle.Rule = "circle" + point + "radius" + number; point.Rule = "[" + number + "," + number + "]"; this.Root = Circle } }
You’ll notice the definitions for the non-Terminals contain delegates. These are methods in the ShapesGrammar that accept an NodeArgs and breaks out the interesting stuff and creates the custom node for the AST. This means we aren’t beholden to the default way ASTs fall out of the grammar, but inform it with some real smarts and make it fit our mindset.
But it seems that every time I play with Irony, I run into something. I started playing with FSharp, but the hyperstrong typing is far too picky. This wouldn’t be a problem if I was confident in FSharp and Irony, but I have to do a lot of casting involving an API I’m just learning. In addition, there’s a disjunction between functions in fsharp and delegates. I’ll have to figure that out.
Yesterday, I started working on Irony again, using VS10 because I can. Then it turns out nUnit is having problems loading .NET 4 dlls, because I didn’t build it. Enter yack shaving as I’m having issues building Nant.
None of these are Irony’s problem. It’s a great library, and as soon as I get a full demo working, I’ll be posting more.