For now not very powerful, but already capable of more than existing builder. OK, it is not really generator, it just rewrites the rules into builder method calls but since I focus solely on grammar syntax it is fine with me.
Let’s take a look at the core — production rules:
data_type -> STRUCT { DataTypeEnum.ValueType } | CLASS { DataTypeEnum.ReferenceType } ;
The syntax is way more compact than written in pure C#, on the other hand the file format is not supported by any IDE so you cannot refactor the grammar or the code (enclosed in braces).
Of course this “generator” is used to build parser for Skila — and now I can write productions with optional symbols:
deco_identifier -> sink:SINK? name:IDENTIFIER { new IdentifierDecorated((IdentifierSymbol)name) { WithSink = (sink!=null) } };
Probably not the best example (I am writing this entry right after testing and uploading NLT), but it shows you can squeeze two productions into one — it is up to user which form is more readable.
This ability is the main reason why I created parser generator for NLT — one option in production is no brainer, but take two and you will have four productions. The number of rules quickly explodes as you have more and more options inside production.
Behind the scene single rule as shown above is rewritten into two regular rules — the difference is it is done by computer, not human. And with generator it is easy to implement because all it does is writing text — there are no boundaries for it. Handling such case with builder (just C#) is doable but leads to huge amounts of code — each permutation of optional symbols has to be created in advance by hand and put inside builder.
Since further enhancement of the builder would be a really fruitless effort I decided to go with “generator”. Next I will try to add value constraints, groups, then integrate lexer patterns and as last step I will make it true generator.