Ejemplo n.º 1
0
        bool _HasExpression(EbnfExpression search, EbnfExpression match)
        {
            if (Equals(search, match))
            {
                return(true);
            }
            var b = search as EbnfBinaryExpression;

            if (null != b)
            {
                if (_HasExpression(b.Left, match) || _HasExpression(b.Right, match))
                {
                    return(true);
                }
            }
            var u = search as EbnfUnaryExpression;

            if (null != u)
            {
                if (_HasExpression(u.Expression, match))
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 2
0
        void _VisitFetchTerminals(EbnfExpression expr, HashSet <EbnfExpression> terms)
        {
            var l = expr as EbnfLiteralExpression;

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

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

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

            if (null != b)
            {
                _VisitFetchTerminals(b.Left, terms);
                _VisitFetchTerminals(b.Right, terms);
                return;
            }
        }
Ejemplo n.º 3
0
 public string GetIdForExpression(EbnfExpression expression)
 {
     foreach (var prod in Productions)
     {
         if (Equals(prod.Value.Expression, expression))
         {
             return(prod.Key);
         }
     }
     return("");
 }
Ejemplo n.º 4
0
        public string GetContainingIdForExpression(EbnfExpression expression)
        {
            foreach (var prod in Productions)
            {
                if (_HasExpression(prod.Value.Expression, expression))
                {
                    return(prod.Key);
                }
            }

            return("");
        }
Ejemplo n.º 5
0
 public EbnfOrExpression(EbnfExpression left, params EbnfExpression[] right)
 {
     if (null == right)
     {
         right = new EbnfExpression[] { null }
     }
     ;
     Left = left;
     for (var i = 0; i < right.Length; ++i)
     {
         if (Right == null)
         {
             Right = right[i];
         }
         else
         {
             Right = new EbnfOrExpression(Right, right[i]);
         }
     }
 }
Ejemplo n.º 6
0
 public EbnfOptionalExpression(EbnfExpression expression)
 {
     Expression = expression;
 }
Ejemplo n.º 7
0
 public EbnfProduction(EbnfExpression expression)
 {
     Expression = expression;
 }
Ejemplo n.º 8
0
        static EbnfExpression _ParseExpression(EbnfDocument doc, ParseContext pc)
        {
            EbnfExpression current = null;
            EbnfExpression 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.TrySkipCCommentsAndWhiteSpace();
                position = pc.Position; line = pc.Line; column = pc.Column;
                switch (pc.Current)
                {
                case '|':
                    pc.Advance();
                    current = new EbnfOrExpression(current, _ParseExpression(doc, pc));
                    current.SetLocationInfo(line, column, position);
                    break;

                case '(':
                    pc.Advance();
                    e = _ParseExpression(doc, pc);
                    current.SetLocationInfo(line, column, position);
                    pc.Expecting(')');
                    pc.Advance();
                    e.SetLocationInfo(line, column, position);
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new EbnfConcatExpression(current, e);
                    }

                    break;

                case '[':
                    pc.Advance();
                    e = new EbnfOptionalExpression(_ParseExpression(doc, pc));
                    e.SetLocationInfo(line, column, position);
                    pc.TrySkipCCommentsAndWhiteSpace();
                    pc.Expecting(']');
                    pc.Advance();
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new EbnfConcatExpression(current, e);
                    }

                    break;

                case '{':
                    pc.Advance();
                    e = new EbnfRepeatExpression(_ParseExpression(doc, pc));
                    e.SetLocationInfo(line, column, position);
                    pc.TrySkipCCommentsAndWhiteSpace();
                    pc.Expecting('}');
                    pc.Advance();
                    if ('+' == pc.Current)
                    {
                        pc.Advance();
                        ((EbnfRepeatExpression)e).IsOptional = false;
                    }
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new EbnfConcatExpression(current, e);
                    }

                    break;

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

                case '\'':
                    pc.Advance();
                    pc.ClearCapture();
                    pc.TryReadUntil('\'', '\\', false);
                    pc.Expecting('\'');
                    pc.Advance();
                    e = new EbnfRegexExpression(pc.Capture);
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new EbnfConcatExpression(current, e);
                    }
                    e.SetLocationInfo(line, column, position);
                    break;

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

                default:
                    e = new EbnfRefExpression(_ParseIdentifier(pc));
                    if (null == current)
                    {
                        current = e;
                    }
                    else
                    {
                        current = new EbnfConcatExpression(current, e);
                    }
                    e.SetLocationInfo(line, column, position);
                    break;
                }
            }
            pc.TrySkipCCommentsAndWhiteSpace();
            return(current);
        }
Ejemplo n.º 9
0
        void _ValidateExpression(EbnfExpression expr, IDictionary <string, int> refCounts, IList <EbnfMessage> messages)
        {
            var l = expr as EbnfLiteralExpression;

            if (null != l)
            {
                var i = GetIdForExpression(l);
                // don't count itself. only things just like itself
                if (!string.IsNullOrEmpty(i) && !ReferenceEquals(Productions[i].Expression, l))
                {
                    refCounts[i] += 1;
                }
            }
            var rx = expr as EbnfRegexExpression;

            if (null != rx)
            {
                try
                {
                    CharFA.Parse(rx.Value);
                }
                catch (ExpectingException)
                {
                    messages.Add(
                        new EbnfMessage(
                            EbnfErrorLevel.Error, 12,
                            "Invalid regular expression",
                            expr.Line, expr.Column, expr.Position));
                }
                var i = GetIdForExpression(rx);
                if (!string.IsNullOrEmpty(i) && !ReferenceEquals(Productions[i].Expression, l))
                {
                    refCounts[i] += 1;
                }
            }
            var r = expr as EbnfRefExpression;

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

            if (null != b)
            {
                if (null == b.Left && null == b.Right)
                {
                    messages.Add(
                        new EbnfMessage(
                            EbnfErrorLevel.Warning, 3,
                            "Nil expression",
                            expr.Line, expr.Column, expr.Position));
                    return;
                }
                _ValidateExpression(b.Left, refCounts, messages);
                _ValidateExpression(b.Right, refCounts, messages);
                return;
            }
            var u = expr as EbnfUnaryExpression;

            if (null != u)
            {
                if (null == u.Expression)
                {
                    messages.Add(
                        new EbnfMessage(
                            EbnfErrorLevel.Warning, 3,
                            "Nil expression",
                            expr.Line, expr.Column, expr.Position));
                    return;
                }
                _ValidateExpression(u.Expression, refCounts, messages);
            }
        }
Ejemplo n.º 10
0
        static IList <EbnfMessage> _TryParseExpressions(ParseNode parent, int firstChildIndex, out EbnfExpression result)
        {
            var msgs = new List <EbnfMessage>();

            result = null;
            var or  = new List <IList <EbnfExpression> >();
            var seq = new List <EbnfExpression>();

            for (int ic = parent.Children.Count, i = firstChildIndex; i < ic; ++i)
            {
                EbnfExpression expr;
                var            pn = parent.Children[i];
                switch (pn.SymbolId)
                {
                case EbnfParser.expression:
                    msgs.AddRange(_TryParseExpression(parent.Children[i], out expr));
                    seq.Add(expr);
                    break;

                case EbnfParser.or:
                    or.Add(seq);
                    seq = new List <EbnfExpression>();
                    break;

                default:
                    break;
                }
            }

            or.Add(seq);
            result = null;
            switch (or.Count)
            {
            case 0:
                result = null;
                break;

            case 1:
                result = _SeqToExpression(or[0]);
                break;

            default:
                var state = 0;
                var oe    = new EbnfOrExpression();
                for (int ic = or.Count, i = 0; i < ic; ++i)
                {
                    switch (state)
                    {
                    case 0:
                        oe.Left = _SeqToExpression(or[i]);
                        state   = 1;
                        break;

                    case 1:
                        oe.Right = _SeqToExpression(or[i]);
                        state    = 2;
                        break;

                    case 2:
                        oe       = new EbnfOrExpression(oe, null);
                        oe.Right = _SeqToExpression(or[i]);
                        break;
                    }
                }
                //if (0 == state || 2 == state)
                //	result = oe.Left;
                //else
                result = oe;
                break;
            }

            return(msgs);
        }
Ejemplo n.º 11
0
        static IList <EbnfMessage> _TryParseExpression(ParseNode pn, out EbnfExpression result)
        {
            result = null;
            Debug.Assert(EbnfParser.expression == pn.SymbolId, "Not positioned on expression");
            var msgs = new List <EbnfMessage>();

            if (1 == pn.Children.Count)
            {
                var c = pn.Children[0];
                if (EbnfParser.symbol == c.SymbolId)
                {
                    ParseContext pc;
                    var          cc = c.Children[0];
                    //TODO: parse the regular expressions and literals to make sure they're valid.
                    switch (cc.SymbolId)
                    {
                    case EbnfParser.identifier:
                        result = new EbnfRefExpression(cc.Value);
                        return(msgs);

                    case EbnfParser.regex:
                        pc = ParseContext.Create(cc.Value);
                        pc.EnsureStarted();
                        pc.Advance();
                        pc.TryReadUntil('\'', '\\', false);
                        result = new EbnfRegexExpression(pc.GetCapture());
                        return(msgs);

                    case EbnfParser.literal:
                        pc = ParseContext.Create(cc.Value);
                        pc.EnsureStarted();
                        pc.Advance();
                        pc.TryReadUntil('\"', '\\', false);
                        result = new EbnfLiteralExpression(pc.GetCapture());
                        return(msgs);

                    case EbnfParser.lbrace:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        result = new EbnfRepeatExpression(result);
                        if (EbnfParser.rbracePlus == c.Children[c.Children.Count - 1].SymbolId)
                        {
                            ((EbnfRepeatExpression)result).IsOptional = false;
                        }
                        return(msgs);

                    case EbnfParser.lbracket:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        result = new EbnfOptionalExpression(result);
                        return(msgs);

                    case EbnfParser.lparen:
                        msgs.AddRange(_TryParseExpressions(c, 1, out result));
                        return(msgs);

                    default:
                        break;
                    }
                }
            }
            return(msgs);
        }
Ejemplo n.º 12
0
 public EbnfRepeatExpression(EbnfExpression expression)
 {
     Expression = expression;
 }