Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
0
        public override IList <IList <string> > ToDisjunctions(EbnfDocument parent, Cfg cfg)
        {
            string sid = null;
            var    sr  = Expression as EbnfRefExpression;

            if (null != parent && null != sr)
            {
                sid = string.Concat(sr.Symbol, "list");
            }
            if (string.IsNullOrEmpty(sid))
            {
                var cc = Expression as EbnfConcatExpression;
                if (null != cc)
                {
                    sr = cc.Right as EbnfRefExpression;
                    if (null != sr)
                    {
                        sid = string.Concat(sr.Symbol, "listtail");
                    }
                }
            }
            if (string.IsNullOrEmpty(sid))
            {
                sid = "implicitlist";
            }
            var _listId = cfg.GetUniqueId(sid);
            var attrs   = new AttributeSet();

            attrs.Add("collapsed", true);
            cfg.AttributeSets.Add(_listId, attrs);
            var expr =
                new EbnfOrExpression(
                    new EbnfConcatExpression(
                        new EbnfRefExpression(_listId), Expression), Expression);

            //if (IsOptional)
            //	expr = new EbnfOrExpression(expr, null);
            foreach (var nt in expr.ToDisjunctions(parent, cfg))
            {
                CfgRule r = new CfgRule();
                r.Left = _listId;
                foreach (var s in nt)
                {
                    if (1 < r.Right.Count && null == s)
                    {
                        continue;
                    }
                    r.Right.Add(s);
                }
                if (!cfg.Rules.Contains(r))
                {
                    cfg.Rules.Add(r);
                }
            }
            if (!IsOptional)
            {
                return(new List <IList <string> >(new IList <string>[] { new List <string>(new string[] { _listId }) }));
            }
            else
            {
                var result = new List <IList <string> >();
                result.Add(new List <string>(new string[] { _listId }));
                result.Add(new List <string>());
                return(result);
            }
        }