static void _ReadProduction(EbnfDocument doc, EbnfParser parser)
        {
            parser.Read();
            var id   = parser.Value;
            var prod = new EbnfProduction();

            parser.Read();
            if (EbnfParser.lt == parser.SymbolId)
            {
                parser.Read();
                _ReadAttributes(prod.Attributes, parser);
                parser.Read();
            }
            parser.Read();
            prod.Expression = _ReadExpressions(parser);
        }
        public static EbnfDocument Parse2(ParseContext pc)
        {
            var doc    = new EbnfDocument();
            var parser = new EbnfParser(pc);

            while (parser.Read())
            {
                if (EbnfParser.production == parser.SymbolId)
                {
                    _ReadProduction(doc, parser);
                }
            }
            return(doc);
        }
        static void _ReadAttributes(IDictionary <string, object> attrs, EbnfParser parser)
        {
            parser.Read();
            while (EbnfParser.attribute == parser.SymbolId)
            {
                parser.Read();
                var id = parser.Value;
                parser.Read();
                object val = true;
                if (EbnfParser.eq == parser.SymbolId)
                {
                    parser.Read();
                    parser.Read();
                    switch (parser.SymbolId)
                    {
                    case EbnfParser.identifier:

                        if ("null" == parser.Value)
                        {
                            val = null;
                        }
                        else if ("true" == parser.Value)
                        {
                            val = true;
                        }
                        else if ("false" == parser.Value)
                        {
                            val = false;
                        }
                        else
                        {
                            throw new ExpectingException("Expecting true, false, or null.");
                        }
                        break;

                    case EbnfParser.integer:
                        val = int.Parse(parser.Value);
                        break;

                    case EbnfParser.literal:
                        val = ParseContext.Create(parser.Value).ParseJsonString();
                        break;
                    }
                    parser.Read();
                }
                attrs.Add(id, val);
                if (EbnfParser.comma == parser.SymbolId)
                {
                    parser.Read();
                }
            }
        }