Ejemplo n.º 1
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.º 2
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);
        }