示例#1
0
 public void Add(BnfRule rule)
 {
     if (rules.ContainsKey(rule) == false)
     {
         rules.Add(rule, rule);
     }
 }
    public void Add(BnfRule rule)
    {
        rules.Add(rule);
        var nt = rule.Nonterminal;

        if (NonTerminals.ContainsKey(nt.Name) == false)
        {
            NonTerminals.Add(nt.Name, nt);
        }
        nt.Add(rule);
    }
 BnfGrammar Convert(EbnfGrammar EG)
 {
     Bnf       = new BnfGrammar();
     Footprint = new OperationFootprintGroup <EbnfGrammar, BnfGrammar> (EG, Bnf);
     foreach (var er in EG.Rules)
     {
         BnfRule br = Convert(er);
     }
     Footprint.Parts = ops.ToArray();
     return(Bnf);
 }
 private static IParser <AstNode> CreateParser(BnfRule rule, Dictionary <string, IParser <AstNode> > parsers)
 => CreateParser(rule.Symbol.Name, rule.Expression, parsers);
示例#5
0
        public BnfRule NextRule()
        {
            var streamPosition = (long)0;
            var symbol         = "";

            EatWhitespace();
            if (EatSymbol(out symbol))
            {
                if (symbol == "EOF")
                {
                    // This is the marker for the end of the BNF data. We don't care what else there is, eat it ALL.
                    Reader.ReadToEnd();
                    return(null);
                }
                EatWhitespace();
                if (Reader.Peek() == -1)
                {
                    return(null);
                }
                if ('=' != Reader.Read())
                {
                    throw new InvalidBnfFormatException(Reader, 1, "BNF parser expected '='.");
                }
                var production = ('=' == Reader.Peek());
                if (production)
                {
                    if ('=' != Reader.Read())
                    {
                        throw new InvalidBnfFormatException(Reader, 2, "BNF parser expected '==>'.");
                    }
                    if ('>' != Reader.Read())
                    {
                        throw new InvalidBnfFormatException(Reader, 3, "BNF parser expected '==>'.");
                    }
                }

                var        stackEx        = new Stack <Operator>();
                var        stackOp        = new Stack <char>();
                Func <int> stackProcessOp = () => {
                    var op = stackOp.Pop();
                    switch (op)
                    {
                    case ']':
                        if (stackEx.Count < 1)
                        {
                            throw new InvalidBnfFormatException(Reader, 0, "BNF parser found unmatched '['.");
                        }
                        var right = stackEx.Pop();
                        stackEx.Push(new OptionalOperator(right));
                        break;

                    case '}':
                        if (stackEx.Count < 1)
                        {
                            throw new InvalidBnfFormatException(Reader, 0, "BNF parser found unmatched '{'.");
                        }
                        right = stackEx.Pop();
                        stackEx.Push(new RepeatOperator(right));
                        break;

                    case '|':
                        if (stackEx.Count < 2)
                        {
                            throw new InvalidBnfFormatException(Reader, 0, "BNF parser found unbalanced '|'.");
                        }
                        right = stackEx.Pop();
                        var left = stackEx.Pop();
                        stackEx.Push(new LogicalOrOperator(left, right));
                        break;

                    case ' ':
                        if (stackEx.Count < 2)
                        {
                            throw new InvalidBnfFormatException(Reader, 0, "BNF parser found unbalanced ' '.");
                        }
                        right = stackEx.Pop();
                        left  = stackEx.Pop();
                        stackEx.Push(new LogicalAndOperator(left, right));
                        break;
                    }
                    return(0);
                };

                while (true)
                {
                    EatWhitespace();
                    while (new char[] { '[', '{' }.Contains <char>((char)Reader.Peek()))
                    {
                        if ('[' == Reader.Peek())
                        {
                            Reader.Read();
                            stackOp.Push(']');
                        }
                        else if ('{' == Reader.Peek())
                        {
                            Reader.Read();
                            stackOp.Push('}');
                        }
                        EatWhitespace();
                    }

                    Operator ex = null;
                    EatWhitespace();
                    if ('"' == Reader.Peek())
                    {
                        var value = "";
                        streamPosition = Reader.BaseStream.Position;
                        if (!EatString(out value))
                        {
                            throw new InvalidBnfFormatException(Reader, Reader.BaseStream.Position - streamPosition, "BNF parser expected string.");
                        }
                        ex = new StringOperator(value);
                    }
                    else if ('.' == Reader.Peek())
                    {
                        Reader.Read();
                        if ((stackOp.Count > 0) && (' ' == stackOp.Peek()))
                        {
                            stackOp.Pop();
                        }
                        while (stackOp.Count > 0)
                        {
                            stackProcessOp();
                        }
                        if (stackEx.Count > 1)
                        {
                            throw new InvalidBnfFormatException(Reader, 1, "BNF parser expected ']' and/or '}' but found '.'.");
                        }
                        Reader.ReadLine();
                        break;
                    }
                    else
                    {
                        if (':' != Reader.Read())
                        {
                            throw new InvalidBnfFormatException(Reader, 1, "BNF parser expected ':'.");
                        }
                        var token = "";
                        streamPosition = Reader.BaseStream.Position;
                        if (!EatSymbol(out token))
                        {
                            throw new InvalidBnfFormatException(Reader, Reader.BaseStream.Position - streamPosition, "BNF parser expected token.");
                        }
                        ex = new ReferenceOperator(token);

                        EatWhitespace();
                        if (',' == Reader.Peek())
                        {
                            Reader.Read();

                            var tokenName = "";
                            EatWhitespace();
                            streamPosition = Reader.BaseStream.Position;
                            if (!EatSymbol(out tokenName))
                            {
                                throw new InvalidBnfFormatException(Reader, Reader.BaseStream.Position - streamPosition, "BNF parser expected token name.");
                            }
                            ex = new NamedReferenceOperator(tokenName, token);
                        }
                    }
                    Debug.Assert(ex != null, "BNF parsed expression is null!");
                    stackEx.Push(ex);

                    EatWhitespace();
                    while (new char[] { ']', '}' }.Contains <char>((char)Reader.Peek()))
                    {
                        var endOp = (char)Reader.Read();
                        while ((stackOp.Count > 0) && (stackOp.Peek() != endOp))
                        {
                            stackProcessOp();
                        }
                        if (stackOp.Count == 0)
                        {
                            throw new InvalidBnfFormatException(Reader, 0, "BNF parser found unmatched '" + endOp + "'.");
                        }
                        stackProcessOp();
                        EatWhitespace();
                    }

                    EatWhitespace();
                    if ('|' == Reader.Peek())
                    {
                        Reader.Read();
                        stackOp.Push('|');
                    }
                    else
                    {
                        while ((stackOp.Count > 0) && ('|' == stackOp.Peek()))
                        {
                            stackProcessOp();
                        }
                        stackOp.Push(' ');
                    }
                }
                if (stackEx.Count == 0)
                {
                    stackEx.Push(null);
                }
                BnfRule rule = null;
                if (production)
                {
                    rule = new BnfProduction(File.Bnf, new ReferenceOperator(symbol), stackEx.Pop());
                }
                else
                {
                    rule = new BnfDefinition(File.Bnf, new ReferenceOperator(symbol), stackEx.Pop());
                }
                return(rule);
            }
            return(null);
        }
    BnfRule Convert(EbnfRule E)
    {
        BnfRule B = null;

        if (ruleConversions.ContainsKey(E))
        {
            var footprint = ruleConversions [E];
            B = footprint.After;
        }
        else
        {
            BnfNonterminal bn = Convert(E.Nonterminal);

            List <ISymbol> terms = new List <ISymbol> ();
            var            p     = E.RightPart;
            if (p is EbnfEnumeration)
            {
                foreach (var pp in ((EbnfEnumeration)p).Parts)
                {
                    if (pp is EbnfNonterminal)
                    {
                        var name = (pp as EbnfNonterminal).Name;
                        var node = Bnf.AddNonterminal(name);
                        terms.Add(node);
                    }
                    else
                    {
                        if (pp is EbnfTerminal)
                        {
                            var node = (TerminalSymbol)pp;
                            terms.Add(node);
                        }
                        else
                        {
                            throw new ApplicationException();
                        }
                    }
                }
            }
            else
            {
                if (p is EbnfNonterminal)
                {
                    var name = (p as EbnfNonterminal).Name;
                    var node = Bnf.AddNonterminal(name);
                    terms.Add(node);
                }
                else
                {
                    if (p is EbnfTerminal)
                    {
                        var node = (TerminalSymbol)p;
                        terms.Add(node);
                    }
                    else
                    {
                        throw new ApplicationException();
                    }
                }
            }

            B = new BnfRule(bn, terms.ToArray());
            bn.Add(B);
            var footprint = new RuleConversionFootprint(E, B);
            ruleConversions.Add(E, footprint);
            ops.Add(footprint);
        }
        return(B);
    }