public void ProductionExpressionShouldSupportAlterationOfStringAndLexerRule()
        {
            ProductionExpression
                S = "S";
            BaseLexerRule
                a = new StringLiteralLexerRule("a");
            S.Rule = (Expr)"b" | a;

            Assert.IsNotNull(S.ProductionModel);
            Assert.AreEqual(2, S.ProductionModel.Alterations.Count);
            Assert.AreEqual(1, S.ProductionModel.Alterations[0].Symbols.Count);
            Assert.AreEqual(1, S.ProductionModel.Alterations[1].Symbols.Count);
        }
        IEnumerable<ProductionModel> Factor(EbnfFactor factor, ProductionModel currentProduction)
        {
            switch (factor.NodeType)
            {
                case EbnfNodeType.EbnfFactorGrouping:
                    var grouping = factor as EbnfFactorGrouping;
                    foreach (var production in Grouping(grouping, currentProduction))
                        yield return production;
                    break;

                case EbnfNodeType.EbnfFactorOptional:
                    var optional = factor as EbnfFactorOptional;
                    foreach (var production in Optional(optional, currentProduction))
                        yield return production;
                    break;

                case EbnfNodeType.EbnfFactorRepetition:
                    var repetition = factor as EbnfFactorRepetition;
                    foreach (var production in Repetition(repetition, currentProduction))
                        yield return production;
                    break;

                case EbnfNodeType.EbnfFactorIdentifier:
                    var identifier = factor as EbnfFactorIdentifier;
                    var nonTerminal = GetNonTerminalFromQualifiedIdentifier(identifier.QualifiedIdentifier);
                    currentProduction.AddWithAnd(new NonTerminalModel(nonTerminal));
                    break;

                case EbnfNodeType.EbnfFactorLiteral:
                    var literal = factor as EbnfFactorLiteral;
                    var stringLiteralRule = new StringLiteralLexerRule(literal.Value);
                    currentProduction.AddWithAnd( new LexerRuleModel(stringLiteralRule));
                    break;

                case EbnfNodeType.EbnfFactorRegex:
                    var regex = factor as EbnfFactorRegex;
                    var nfa = _thompsonConstructionAlgorithm.Transform(regex.Regex);
                    var dfa = _subsetConstructionAlgorithm.Transform(nfa);
                    var dfaLexerRule = new DfaLexerRule(dfa, regex.Regex.ToString());
                    currentProduction.AddWithAnd(new LexerRuleModel(dfaLexerRule));
                    break;
            }
        }
        public void ProductionExpressionShouldSupportConcatenationOfTwoBaseLexerRules()
        {
            ProductionExpression
                S = "S";
            BaseLexerRule
                a = new StringLiteralLexerRule("a"),
                b = new StringLiteralLexerRule("b");
            S.Rule = (Expr) a + b;

            Assert.IsNotNull(S.ProductionModel);
            Assert.AreEqual(1, S.ProductionModel.Alterations.Count);
            Assert.AreEqual(2, S.ProductionModel.Alterations[0].Symbols.Count);
        }
        public void GrammarModelToGrammarShouldCreateGrammar()
        {
            var grammarModel = new GrammarModel();

            var S = new ProductionModel("S");
            var A = new ProductionModel("A");
            var B = new ProductionModel("B");

            var a = new StringLiteralLexerRule("a");
            var b = new StringLiteralLexerRule("b");
            var space = new StringLiteralLexerRule(" ");

            S.AddWithAnd(A.LeftHandSide);
            S.AddWithAnd(B.LeftHandSide);
            S.AddWithOr(B.LeftHandSide);
            A.AddWithAnd(new LexerRuleModel(a));
            B.AddWithAnd(new LexerRuleModel(b));

            grammarModel.Productions.Add(S);
            grammarModel.Productions.Add(A);
            grammarModel.Productions.Add(B);

            grammarModel.IgnoreRules.Add(new LexerRuleModel(space));

            grammarModel.Start = S;

            var grammar = grammarModel.ToGrammar();
            Assert.AreEqual(4, grammar.Productions.Count);
            Assert.AreEqual(1, grammar.Ignores.Count);
        }