Пример #1
0
        static void _VisitUnreferenced(XbnfDocument doc, XbnfExpression expr, HashSet <string> result)
        {
            var r = expr as XbnfRefExpression;

            if (null != r)
            {
                if (!doc.Productions.Contains(r.Symbol))
                {
                    result.Add(r.Symbol);
                }
                return;
            }
            var u = expr as XbnfUnaryExpression;

            if (null != u)
            {
                _VisitUnreferenced(doc, u.Expression, result);
                return;
            }
            var b = expr as XbnfBinaryExpression;

            if (null != b)
            {
                _VisitUnreferenced(doc, b.Left, result);
                _VisitUnreferenced(doc, b.Right, result);
                return;
            }
        }
Пример #2
0
        static XbnfExpression _FindNonTerminal(XbnfExpression expr)
        {
            var re = expr as XbnfRefExpression;

            if (null != re)
            {
                return(re);
            }
            var bo = expr as XbnfBinaryExpression;

            if (bo != null)
            {
                var res = _FindNonTerminal(bo.Left);
                if (null != res)
                {
                    return(res);
                }
                res = _FindNonTerminal(bo.Right);
                if (null != res)
                {
                    return(res);
                }
            }
            var ue = expr as XbnfUnaryExpression;

            if (null != ue)
            {
                return(_FindNonTerminal(ue.Expression));
            }
            return(null);
        }
Пример #3
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();
         }
     }
 }
Пример #4
0
        static XbnfImport _ParseIncludePart(XbnfDocument doc, LexContext pc)
        {
            pc.TrySkipCCommentsAndWhiteSpace();
            var l = pc.Line;
            var c = pc.Column;
            var p = pc.Position;

            pc.Expecting('\"');
            // borrow the parsing from XbnfExpression for this.
            var le = XbnfExpression.Parse(pc) as XbnfLiteralExpression;

            if (null == le)
            {
                throw new ExpectingException("Expecting string literal include argument", l, c, p, pc.FileOrUrl, "string literal");
            }
            var res = le.Value;

            pc.TrySkipCCommentsAndWhiteSpace();
            pc.Expecting(';');
            pc.Advance();
            var cmp    = res.ToLowerInvariant();
            var result = new XbnfImport();

            if (-1 < cmp.IndexOf("://"))
            {
                result.Document = XbnfDocument.ReadFromUrl(cmp);
            }
            else
            {
                string mdir = null;
                if (null != doc && !string.IsNullOrEmpty(doc.FileOrUrl))
                {
                    mdir = doc.FileOrUrl;
                    if (!Path.IsPathRooted(mdir))
                    {
                        mdir = Path.GetFullPath(mdir);
                    }
                    mdir = Path.GetDirectoryName(mdir);
                }
                var path = res;
                if (!Path.IsPathRooted(path))
                {
                    if (null != mdir)
                    {
                        path = Path.Combine(mdir, path);
                    }
                    else
                    {
                        path = Path.GetFullPath(path);
                    }
                }
                result.Document = XbnfDocument.ReadFrom(path);
            }
            result.SetLocation(l, c, p);
            return(result);
        }
Пример #5
0
 public XbnfProduction GetProductionForExpression(XbnfExpression expr)
 {
     for (int ic = Productions.Count, i = 0; i < ic; ++i)
     {
         var prod = Productions[i];
         if (Equals(expr, prod.Expression))
         {
             return(prod);
         }
     }
     return(null);
 }
        public XbnfConcatExpression(XbnfExpression left, params XbnfExpression[] right)
        {
            Left = left;
            for (int i = 0; i < right.Length; i++)
            {
                var r = right[i];
                if (null == Right)
                {
                    Right = r;
                }

                var c = new XbnfConcatExpression();
                c.Left  = Left;
                c.Right = Right;
                Right   = null;
                Left    = c;
            }
        }
 public XbnfOrExpression(XbnfExpression left, params XbnfExpression[] right)
 {
     Right = null;
     Left  = left;
     for (int i = 0; i < right.Length; i++)
     {
         if (null == Right)
         {
             Right = right[i];
         }
         else
         {
             var or = new XbnfOrExpression();
             or.Left  = Left;
             or.Right = Right;
             Left     = or;
             Right    = right[i];
         }
     }
 }
Пример #8
0
        static void _VisitFetchTerminals(XbnfExpression expr, HashSet <XbnfExpression> terms)
        {
            var l = expr as XbnfLiteralExpression;

            if (null != l)
            {
                if (!terms.Contains(l))
                {
                    terms.Add(l);
                }
                return;
            }
            var r = expr as XbnfRegexExpression;

            if (null != r)
            {
                if (!terms.Contains(r))
                {
                    terms.Add(r);
                }
                return;
            }
            var u = expr as XbnfUnaryExpression;

            if (null != u)
            {
                _VisitFetchTerminals(u.Expression, terms);
                return;
            }
            var b = expr as XbnfBinaryExpression;

            if (null != b)
            {
                _VisitFetchTerminals(b.Left, terms);
                _VisitFetchTerminals(b.Right, terms);
                return;
            }
        }
Пример #9
0
 public XbnfOptionalExpression(XbnfExpression expression)
 {
     Expression = expression;
 }
Пример #10
0
        static IList <IList <string> > _GetDysjunctions(
            XbnfDocument d,
            ICollection <string> syms,
            IDictionary <XbnfExpression, string> tmap,
            IDictionary <string, XbnfAttributeList> attrs,
            IList <KeyValuePair <string, IList <string> > > rules,
            XbnfProduction p,
            XbnfExpression e
            )
        {
            var le = e as XbnfLiteralExpression;

            if (null != le)
            {
                var res = new List <IList <string> >();
                var l   = new List <string>();
                l.Add(tmap[le]);
                res.Add(l);
                return(res);
            }
            var rxe = e as XbnfRegexExpression;

            if (null != rxe)
            {
                var res = new List <IList <string> >();
                var l   = new List <string>();
                l.Add(tmap[rxe]);
                res.Add(l);
                return(res);
            }
            var rfe = e as XbnfRefExpression;

            if (null != rfe)
            {
                var res = new List <IList <string> >();
                var l   = new List <string>();
                l.Add(rfe.Symbol);
                res.Add(l);
                return(res);
            }
            var ce = e as XbnfConcatExpression;

            if (null != ce)
            {
                return(_GetDysConcat(d, syms, tmap, attrs, rules, p, ce));
            }

            var oe = e as XbnfOrExpression;

            if (null != oe)
            {
                return(_GetDysOr(d, syms, tmap, attrs, rules, p, oe));
            }
            var ope = e as XbnfOptionalExpression;

            if (null != ope)
            {
                return(_GetDysOptional(d, syms, tmap, attrs, rules, p, ope));
            }
            var re = e as XbnfRepeatExpression;

            if (null != re)
            {
                return(_GetDysRepeat(d, syms, tmap, attrs, rules, p, re));
            }
            throw new NotSupportedException("The specified expression type is not supported.");
        }
Пример #11
0
        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("");
        }
Пример #12
0
        public static string ToRolexSpec(XbnfGenerationInfo genInfo)
        {
            var termStart = 0;
            var stbl      = GetSymbolTable(genInfo, out termStart);
            var stbli     = new List <KeyValuePair <string, int> >();
            var id        = 0;

            // assign temp ids
            foreach (var se in stbl)
            {
                if (id >= termStart)
                {
                    stbli.Add(new KeyValuePair <string, int>(se, id));
                }
                ++id;
            }
            stbli.Sort(new _TermPriorityComparer(genInfo.Cfg));

            var sb = new StringBuilder();

            for (int ic = stbli.Count, i = 0; i < ic; ++i)
            {
                var sym = stbli[i].Key;
                if ("#EOS" == sym || "#ERROR" == sym)
                {
                    continue;
                }
                XbnfExpression e = null;
                foreach (var k in genInfo.TerminalMap)
                {
                    if (k.Value == sym)
                    {
                        e = k.Key;
                        break;
                    }
                }
                //var te = genInfo.TerminalMap[i];
                //var sym = te.Value;
                //var id = stbli.IndexOf(new KeyValuePair<string, XbnfDocument>(sym, d));
                id = stbli[i].Value;
                if (-1 < id)                 // some terminals might never be used.
                {
                    // implicit terminals do not have productions and therefore attributes
                    var pi = genInfo.Xbnf.Productions.IndexOf(sym);
                    if (-1 < pi)
                    {
                        // explicit
                        var prod = genInfo.Xbnf.Productions[pi];
                        sb.Append(sym);
                        sb.Append("<id=");
                        sb.Append(id);
                        foreach (var attr in prod.Attributes)
                        {
                            sb.Append(", ");
                            sb.Append(attr.ToString());
                        }
                        sb.Append(">");
                    }
                    else
                    {
                        // implicit
                        sb.Append(sym);
                        sb.Append(string.Concat("<id=", id, ">"));
                    }
                    sb.AppendLine(string.Concat("= \'", _ToRegex(genInfo.Xbnf, e, true), "\'"));
                }
            }
            return(sb.ToString());
        }
Пример #13
0
 public XbnfProduction(string name, XbnfExpression expression = null)
 {
     Name       = name;
     Expression = expression;
 }
Пример #14
0
        void _ValidateExpression(XbnfExpression expr, IDictionary <string, int> refCounts, IList <XbnfMessage> messages)
        {
            var l = expr as XbnfLiteralExpression;

            if (null != l)
            {
                string id = null;
                for (int ic = Productions.Count, i = 0; i < ic; ++i)
                {
                    var ll = Productions[i].Expression as XbnfLiteralExpression;
                    if (ll == l)
                    {
                        id = Productions[i].Name;
                        break;
                    }
                }
                // don't count itself. only things just like itself
                if (!string.IsNullOrEmpty(id) && !ReferenceEquals(Productions[id].Expression, l))
                {
                    refCounts[id] += 1;
                }
            }

            var r = expr as XbnfRefExpression;

            if (null != r)
            {
                int rc;
                if (null == r.Symbol)
                {
                    messages.Add(
                        new XbnfMessage(
                            ErrorLevel.Error, -1,
                            "Null reference expression",
                            expr.Line, expr.Column, expr.Position, FileOrUrl));
                    return;
                }
                if (!refCounts.TryGetValue(r.Symbol, out rc))
                {
                    messages.Add(
                        new XbnfMessage(
                            ErrorLevel.Error, -1,
                            string.Concat(
                                "Reference to undefined symbol \"",
                                r.Symbol,
                                "\""),
                            expr.Line, expr.Column, expr.Position, FileOrUrl));
                    return;
                }
                refCounts[r.Symbol] = rc + 1;
                return;
            }
            var b = expr as XbnfBinaryExpression;

            if (null != b)
            {
                if (null == b.Left && null == b.Right)
                {
                    messages.Add(
                        new XbnfMessage(
                            ErrorLevel.Warning, -1,
                            "Nil expression",
                            expr.Line, expr.Column, expr.Position, FileOrUrl));
                    return;
                }
                _ValidateExpression(b.Left, refCounts, messages);
                _ValidateExpression(b.Right, refCounts, messages);
                return;
            }
            var u = expr as XbnfUnaryExpression;

            if (null != u)
            {
                if (null == u.Expression)
                {
                    messages.Add(
                        new XbnfMessage(
                            ErrorLevel.Warning, -1,
                            "Nil expression",
                            expr.Line, expr.Column, expr.Position, FileOrUrl));
                    return;
                }
                _ValidateExpression(u.Expression, refCounts, messages);
            }
        }
 public XbnfRepeatExpression(XbnfExpression expression, bool isOptional = true)
 {
     Expression = expression;
     IsOptional = isOptional;
 }
Пример #16
0
        internal static XbnfExpression Parse(LexContext pc)
        {
            XbnfExpression current = null;
            XbnfExpression e;
            long           position;
            int            line;
            int            column;

            pc.TrySkipCCommentsAndWhiteSpace();
            position = pc.Position; line = pc.Line; column = pc.Column;
            while (-1 != pc.Current && ']' != pc.Current && ')' != pc.Current && '}' != pc.Current && ';' != pc.Current && ':' != pc.Current)
            {
                pc.TrySkipCCommentsAndWhiteSpace();
                position = pc.Position; line = pc.Line; column = pc.Column;
                switch (pc.Current)
                {
                case '|':
                    pc.Advance();
                    position = pc.Position; line = pc.Line; column = pc.Column;
                    current  = new XbnfOrExpression(current, Parse(pc));
                    current.SetLocation(line, column, position);
                    break;

                case '(':
                    pc.Advance();
                    position = pc.Position; line = pc.Line; column = pc.Column;
                    e        = Parse(pc);
                    if (null != current)
                    {
                        current.SetLocation(line, column, position);
                    }
                    pc.Expecting(')');
                    pc.Advance();
                    e.SetLocation(line, column, position);
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }

                    break;

                case '[':
                    pc.Advance();
                    e = new XbnfOptionalExpression(Parse(pc));
                    e.SetLocation(line, column, position);
                    pc.TrySkipCCommentsAndWhiteSpace();
                    pc.Expecting(']');
                    pc.Advance();
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }

                    break;

                case '{':
                    pc.Advance();
                    e = new XbnfRepeatExpression(Parse(pc));
                    e.SetLocation(line, column, position);
                    pc.TrySkipCCommentsAndWhiteSpace();
                    pc.Expecting('}');
                    pc.Advance();
                    if ('+' == pc.Current)
                    {
                        pc.Advance();
                        ((XbnfRepeatExpression)e).IsOptional = false;
                    }
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }

                    break;

                case '\"':
                    e = new XbnfLiteralExpression(pc.ParseJsonString());
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }
                    e.SetLocation(line, column, position);
                    break;

                case '\'':
                    pc.Advance();
                    pc.ClearCapture();
                    pc.TryReadUntil('\'', '\\', false);
                    pc.Expecting('\'');
                    pc.Advance();
                    e = new XbnfRegexExpression(pc.GetCapture());
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }
                    e.SetLocation(line, column, position);
                    break;

                case ';':
                case ']':
                case ')':
                case '}':
                case '=':
                case ':':
                    return(current);

                default:
                    e = new XbnfRefExpression(ParseIdentifier(pc));
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new XbnfConcatExpression(current, e);
                    }
                    e.SetLocation(line, column, position);
                    break;
                }
            }
            pc.TrySkipCCommentsAndWhiteSpace();
            return(current);
        }
Пример #17
0
        internal static XbnfProduction Parse(LexContext pc)
        {
            var result = new XbnfProduction();

            pc.TrySkipCCommentsAndWhiteSpace();
            var l = pc.Line;
            var c = pc.Column;
            var p = pc.Position;

            // read identifier
            result.Name = ParseIdentifier(pc);
            // read attributes
            if ('<' == pc.Current)
            {
                pc.Advance();
                while (-1 != pc.Current && '>' != pc.Current)
                {
                    result.Attributes.Add(XbnfAttribute.Parse(pc));
                    pc.TrySkipCCommentsAndWhiteSpace();
                    pc.Expecting('>', ',');
                    if (',' == pc.Current)
                    {
                        pc.Advance();
                    }
                }
                pc.Expecting('>');
                pc.Advance();
            }
            pc.TrySkipCCommentsAndWhiteSpace();
            pc.Expecting('=');

            pc.Advance();
            result.Expression = XbnfExpression.Parse(pc);

            pc.Expecting(';', '=');
            result.SetLocation(l, c, p);
            if (';' == pc.Current)
            {
                pc.Advance();
                return(result);
            }
            if ('=' == pc.Current)
            {
                pc.Advance();
                pc.Expecting('>');
                pc.Advance();
                pc.TrySkipCCommentsAndWhiteSpace();
                pc.Expecting('{');
                pc.Advance();
                l = pc.Line;
                c = pc.Column;
                p = pc.Position;
                var s = XbnfDocument.ReadCode(pc);
                pc.Expecting('}');
                pc.Advance();
                result.Action = new XbnfCode(s);
                result.SetLocation(l, c, p);
            }

            return(result);
        }