Ejemplo n.º 1
0
 static void _ParseIncludes(LexContext pc, IList <string> result)
 {
     pc.TrySkipCCommentsAndWhiteSpace();
     while ('@' == pc.Current)
     {
         pc.Advance();
         var s = XbnfNode.ParseIdentifier(pc);
         if ("include" == s)
         {
             pc.TrySkipCCommentsAndWhiteSpace();
             var lit = XbnfExpression.Parse(pc) as XbnfLiteralExpression;
             if (!result.Contains(lit.Value))
             {
                 result.Add(lit.Value);
             }
             pc.TryReadCCommentsAndWhitespace();
             pc.Advance();
             pc.TryReadCCommentsAndWhitespace();
         }
         else
         {
             while (-1 != pc.Current && ';' != pc.Current)
             {
                 pc.Advance();
             }
             if (';' == pc.Current)
             {
                 pc.Advance();
             }
             pc.TrySkipCCommentsAndWhiteSpace();
         }
     }
 }
Ejemplo n.º 2
0
        internal static XbnfDocument Parse(LexContext pc)
        {
            var result = new XbnfDocument();

            if (!string.IsNullOrEmpty(pc.FileOrUrl))
            {
                result.SetFilename(pc.FileOrUrl);
            }
            while (-1 != pc.Current && '}' != pc.Current)
            {
                pc.TrySkipCCommentsAndWhiteSpace();
                while ('@' == pc.Current)                 // directives
                {
                    pc.Advance();
                    var l   = pc.Line;
                    var c   = pc.Column;
                    var p   = pc.Position;
                    var str = XbnfNode.ParseIdentifier(pc);
                    if (0 == string.Compare("include", str, StringComparison.InvariantCulture))
                    {
                        result.Includes.Add(_ParseIncludePart(result, pc));
                    }
                    else if (0 == string.Compare("options", str, StringComparison.InvariantCulture))
                    {
                        if (0 < result.Options.Count)
                        {
                            throw new ExpectingException("Duplicate directive \"options\" specified", l, c, p, pc.FileOrUrl);
                        }
                        while (-1 != pc.Current && ';' != pc.Current)
                        {
                            l = pc.Line;
                            c = pc.Column;
                            p = pc.Position;
                            var opt = XbnfOption.Parse(pc);
                            opt.SetLocation(l, c, p);
                            result.Options.Add(opt);
                            pc.TrySkipCCommentsAndWhiteSpace();
                            pc.Expecting(';', ',');
                            if (',' == pc.Current)
                            {
                                pc.Advance();
                            }
                        }
                        pc.Expecting(';');
                        pc.Advance();
                        if (0 == result.Options.Count)
                        {
                            throw new ExpectingException("Expection options but \"options\" directive was empty", l, c, p, pc.FileOrUrl);
                        }
                    }
                    else
                    {
                        throw new ExpectingException("Expecting \"include\" or \"options\"", l, c, p, pc.FileOrUrl, "include", "options");
                    }


                    pc.TrySkipCCommentsAndWhiteSpace();
                }
                if (pc.Current == '{')
                {
                    pc.Advance();
                    var l = pc.Line;
                    var c = pc.Column;
                    var p = pc.Position;
                    var s = ReadCode(pc);
                    pc.Expecting('}');
                    pc.Advance();
                    var code = new XbnfCode(s);
                    code.SetLocation(l, c, p);
                    result.Code.Add(code);
                }
                else if (-1 != pc.Current)
                {
                    if ('@' == pc.Current)
                    {
                        throw new ExpectingException("Expecting productions. Includes and options must be specified before any productions", pc.Line, pc.Column, pc.Position, pc.FileOrUrl, "Production");
                    }
                    result.Productions.Add(XbnfProduction.Parse(pc));
                }
                else                 // end of input
                {
                    return(result);
                }
                // have to do this so trailing whitespace
                // doesn't get read as a production
                pc.TryReadCCommentsAndWhitespace();
            }
            return(result);
        }