public XamlMarkupExtensionGrammar() { // Non Terminals var markupExtension = new NonTerminal(MarkupExtensionTerm); var arguments = new NonTerminal("Arguments"); var namedArgs = new NonTerminal("NamedArgs"); var namedArg = new NonTerminal(NamedArgumentTerm); var positionalArgs = new NonTerminal("PositionalArgs"); var argument = new NonTerminal("Argument"); // Terminals var typeName = new TypeNameTerminal(TypeNameTerm); var memberName = new MemberNameTerminal(MemberNameTerm); var @string = new StringTerminal(StringTerm); var startExtension = this.ToTransientTerm("{"); var endExtension = this.ToTransientTerm("}"); var namedArgumentSeparator = this.ToTransientTerm("="); var argumentSeparator = this.ToTransientTerm(","); // Setup rules markupExtension.Rule = (startExtension + typeName + endExtension) | (startExtension + typeName + arguments + endExtension); arguments.Rule = namedArgs | positionalArgs | (positionalArgs + argumentSeparator + namedArgs); namedArgs.Rule = namedArg | (namedArg + argumentSeparator + namedArgs); namedArg.Rule = (memberName + namedArgumentSeparator + argument); positionalArgs.Rule = namedArgs | argument | (argument + argumentSeparator + positionalArgs); argument.Rule = markupExtension | @string; this.Root = markupExtension; this.MarkTransient(arguments, argument); }