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();
         }
     }
 }
Esempio n. 2
0
 public override string ToString()
 {
     if (null == Document)
     {
         return("");
     }
     if (string.IsNullOrEmpty(Document.FileOrUrl))
     {
         return("@import <<in-memory>>;");
     }
     return("@import \"" + XbnfNode.Escape(Document.FileOrUrl) + "\";");
 }
        public string ToString(string fmt)
        {
            var sb = new StringBuilder();

            for (int ic = Includes.Count, i = 0; i < ic; ++i)
            {
                sb.Append("@include ");
                sb.Append("\"" + XbnfNode.Escape(Includes[i].Document.FileOrUrl) + "\"");
                sb.AppendLine(";");
            }
            var oc = Options.Count;

            if (0 < oc)
            {
                sb.Append("@options ");
                for (var i = 0; i < oc; ++i)
                {
                    if (0 != i)
                    {
                        sb.Append(", ");
                    }
                    sb.Append(Options[i]);
                }
                sb.AppendLine(";");
            }
            if ("gnc" == fmt)
            {
                for (int ic = Productions.Count, i = 0; i < ic; ++i)
                {
                    sb.AppendLine(Productions[i].ToString("pnc"));
                }
            }
            else if ("xc" == fmt)
            {
                for (int ic = Productions.Count, i = 0; i < ic; ++i)
                {
                    sb.AppendLine(Productions[i].ToString("xc"));
                }
            }
            else
            {
                for (int ic = Productions.Count, i = 0; i < ic; ++i)
                {
                    sb.AppendLine(Productions[i].ToString());
                }
            }
            return(sb.ToString());
        }
        static string _ToRegex(XbnfDocument d, XbnfExpression e, bool first, bool gplex = false)
        {
            var le = e as XbnfLiteralExpression;

            if (null != le)
            {
                var s = _EscapeLiteral(XbnfNode.Escape(le.Value), !gplex);
                if (gplex)
                {
                    s = string.Concat("\"", s, "\"");
                }
                return(s);
            }
            var rxe = e as XbnfRegexExpression;

            if (null != rxe)
            {
                var r = rxe.Value;
                if (gplex)
                {
                    r = r.Replace("\"", "\\\"");
                }
                return(first ? r : string.Concat("(", r, ")"));
            }
            var rfe = e as XbnfRefExpression;

            if (null != rfe)
            {
                _ToRegex(d, d.Productions[rfe.Symbol].Expression, first, gplex);
            }
            var re = e as XbnfRepeatExpression;

            if (null != re)
            {
                if (re.IsOptional)
                {
                    return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")*"));
                }
                else
                {
                    return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")+"));
                }
            }
            var oe = e as XbnfOrExpression;

            if (null != oe)
            {
                if (!first)
                {
                    return(string.Concat("(", _ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex), ")"));
                }
                else
                {
                    return(string.Concat(_ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex)));
                }
            }
            var oc = e as XbnfConcatExpression;

            if (null != oc)
            {
                return(string.Concat(_ToRegex(d, oc.Left, false, gplex), _ToRegex(d, oc.Right, false, gplex)));
            }
            var ope = e as XbnfOptionalExpression;

            if (null != ope)
            {
                return(string.Concat("(", _ToRegex(d, ope.Expression, true, gplex), ")?"));
            }
            return("");
        }
        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);
        }