Example #1
0
        public Grammar(
            INonTerminal start,
            IReadOnlyList <IProduction> productions,
            IReadOnlyList <ILexerRule> ignoreRules,
            IReadOnlyList <ILexerRule> triviaRules)
        {
            _productions = new IndexedList <IProduction>();
            _ignores     = new IndexedList <ILexerRule>();
            _trivia      = new IndexedList <ILexerRule>();

            _transativeNullableSymbols = new UniqueList <INonTerminal>();
            _symbolsReverseLookup      = new Dictionary <INonTerminal, UniqueList <IProduction> >();
            _lexerRules = new IndexedList <ILexerRule>();
            _leftHandSideToProductions = new Dictionary <INonTerminal, List <IProduction> >();
            _dottedRuleRegistry        = new DottedRuleRegistry();
            _symbolPaths = new Dictionary <ISymbol, UniqueList <ISymbol> >();

            Start = start;
            AddProductions(productions ?? EmptyProductionArray);
            AddIgnoreRules(ignoreRules ?? EmptyLexerRuleArray);
            AddTriviaRules(triviaRules ?? EmptyLexerRuleArray);

            _rightRecursiveSymbols = CreateRightRecursiveSymbols(_dottedRuleRegistry, _symbolPaths);
            FindNullableSymbols(_symbolsReverseLookup, _transativeNullableSymbols);
        }
        public void TestShiftReduceError()
        {
            INonTerminal <string> ifStatement = null;

            try
            {
                // This configuration is not a valid LR1 parser. It contains shift reduce conflicts
                // clasical dangling else case
                var configurator = ParserFactory.Configure <string>();
                var ident        = configurator.CreateTerminal("[a-z]+");
                ident.DebugName = "ident";

                ifStatement           = configurator.CreateNonTerminal();
                ifStatement.DebugName = "ifStatement";

                var statement = configurator.CreateNonTerminal();
                statement.DebugName = "statement";

                ifStatement.AddProduction("if", "\\(", ident, "\\)", "then", statement);
                ifStatement.AddProduction("if", "\\(", ident, "\\)", "then", statement, "else", statement);

                statement.AddProduction(ifStatement);
                statement.AddProduction(ident, "=", ident);

                configurator.LexerSettings.CreateLexer = false;
                configurator.CreateParser();

                Assert.Fail("No exception for ambiguous grammar");
            }
            catch (ShiftReduceConflictException <string> e)
            {
                Assert.AreEqual(ifStatement, e.ReduceSymbol);
                Assert.AreEqual("else", e.ShiftSymbol.DebugName);
            }
        }
Example #3
0
 private static IEnumerable<IProduction> ZeroOrOne(INonTerminal identifier, ITerminal[] terminals)
 {
     // NonTerminal -> Terminal | <null>
     return new[]{
             new Production(identifier, terminals),
             new Production(identifier) };
 }
Example #4
0
 public IReadOnlyList<IProduction> RulesFor(INonTerminal symbol)
 {
     ReadWriteList<IProduction> list;
     if (!_productionIndex.TryGetValue(symbol, out list))
         return EmptyProductionArray;
     return list;
 }
Example #5
0
 public IEnumerable<IProduction> RulesFor(INonTerminal symbol)
 {
     IList<IProduction> list;
     if (!_productionIndex.TryGetValue(symbol, out list))
         return EmptyProductionArray;
     return list;
 }
Example #6
0
        protected void ReunparseCheckTS <TRoot>(INonTerminal <TRoot> root, string parseFileName, bool leftToRight)
        {
            string sourceText   = File.ReadAllText(GetParseFilePath(parseFileName));
            TRoot  astRootValue = ParseTextAndCheckTS(root, sourceText, parseFileName).RootAstValue;

            ReunparseCheck(root.AsNonTerminal(), astRootValue, sourceText, parseFileName, leftToRight);
        }
Example #7
0
            public NonTerminalProduction(IParserConfigurator <T> configurator, INonTerminal <T> resultSymbol, object[] symbols)
            {
                this.resultSymbol = resultSymbol;
                this.symbols      = new ISymbol <T> [symbols.Length]; // Move production symbols to the list
                int i = 0;

                foreach (object part in symbols)
                {
                    if (part is string regex)
                    {
                        if (configurator.LexerSettings.EscapeLiterals)
                        {
                            regex = Regex.Escape(regex);
                        }

                        this.symbols[i]           = configurator.CreateTerminal(regex, null, true);
                        this.symbols[i].DebugName = part as string; // Set debug name to unescaped string, so it's easy on the eyes.
                    }
                    else
                    {
                        this.symbols[i] = (ISymbol <T>)symbols[i];
                    }

                    ++i;
                }
            }
        public void TestACalculator()
        {
            // This is a full on integration test that builds a parser and performs a simple calculation.
            var configurator = ParserFactory.Configure <int>();

            ITerminal <int> number = configurator.CreateTerminal("\\d+", int.Parse);

            number.DebugName = "number";

            INonTerminal <int> expr = configurator.CreateNonTerminal();

            expr.DebugName = "expr";
            INonTerminal <int> term = configurator.CreateNonTerminal();

            term.DebugName = "term";
            INonTerminal <int> factor = configurator.CreateNonTerminal();

            factor.DebugName = "factor";

            expr.AddProduction(expr, "+", term).SetReduceFunction(s => s[0] + s[2]);
            expr.AddProduction(expr, "-", term).SetReduceFunction(s => s[0] - s[2]);
            expr.AddProduction(term).SetReduceFunction(s => s[0]);

            term.AddProduction(term, "*", factor).SetReduceFunction(s => s[0] * s[2]);
            term.AddProduction(term, "/", factor).SetReduceFunction(s => s[0] / s[2]);
            term.AddProduction(factor).SetReduceFunction(s => s[0]);

            factor.AddProduction(number).SetReduceFunction(s => s[0]);
            factor.AddProduction("(", expr, ")").SetReduceFunction(s => s[1]);

            var parser = configurator.CreateParser();
            int result = parser.Parse(new StringReader("2-2-5"));

            Assert.AreEqual(-5, result);
        }
Example #9
0
 public Production(INonTerminal leftHandSide, params ISymbol[] rightHandSide)
 {
     Assert.IsNotNull(leftHandSide, "leftHandSide");
     Assert.IsNotNull(rightHandSide, "rightHandSide");
     LeftHandSide = leftHandSide;
     _rightHandSide = new ReadOnlyList<ISymbol>(new List<ISymbol>(rightHandSide));
 }
Example #10
0
 public Production(INonTerminal leftHandSide, params ISymbol[] rightHandSide)
 {
     Assert.IsNotNull(leftHandSide, nameof(leftHandSide));
     Assert.IsNotNull(rightHandSide, nameof(rightHandSide));
     LeftHandSide   = leftHandSide;
     _rightHandSide = new List <ISymbol>(new List <ISymbol>(rightHandSide));
     _hashCode      = ComputeHashCode();
 }
        public static INonTerminal <T> CreateNonTerminal <T>(this IParserConfigurator <T> conf, string name)
        {
            INonTerminal <T> nter = conf.CreateNonTerminal();

            nter.DebugName = name;

            return(nter);
        }
Example #12
0
 public Production(INonTerminal leftHandSide, params ISymbol[] rightHandSide)
 {
     Assert.IsNotNull(leftHandSide, nameof(leftHandSide));
     Assert.IsNotNull(rightHandSide, nameof(rightHandSide));
     LeftHandSide = leftHandSide;
     _rightHandSide = new ReadWriteList<ISymbol>(new List<ISymbol>(rightHandSide));
     _hashCode = ComputeHashCode();
 }
Example #13
0
 public IEnumerable<ILexerRule> LexerRulesFor(INonTerminal symbol)
 {
     var key = HashUtil.ComputeHash(
         symbol.SymbolType.GetHashCode(),
         symbol.Value.GetHashCode());
     IList<ILexerRule> list;
     if (!_lexerRuleIndex.TryGetValue(key, out list))
         return EmptyLexerRuleArray;
     return list;
 }
Example #14
0
        public IReadOnlyList <IProduction> RulesFor(INonTerminal nonTerminal)
        {
            List <IProduction> list;

            if (!_leftHandSideToProductions.TryGetValue(nonTerminal, out list))
            {
                return(EmptyProductionArray);
            }
            return(list);
        }
Example #15
0
        public IReadOnlyList <IProduction> RulesFor(INonTerminal symbol)
        {
            List <IProduction> list;

            if (!_productionIndex.TryGetValue(symbol, out list))
            {
                return(EmptyProductionArray);
            }
            return(list);
        }
Example #16
0
        protected static ParseTree <TRoot> ParseTextAndCheckTS <TRoot>(INonTerminal <TRoot> root, string sourceText, string parseFileName = null)
        {
            ParseTree <TRoot> parseTree = parseFileName != null
                ? parser.Parse(sourceText, parseFileName, root)
                : parser.Parse(sourceText, root);

            CheckParseTree(parseTree);

            return(parseTree);
        }
Example #17
0
        public IReadOnlyList <IProduction> RulesContainingSymbol(INonTerminal symbol)
        {
            UniqueList <IProduction> list;

            if (!_reverseLookup.TryGetValue(symbol, out list))
            {
                return(EmptyProductionArray);
            }
            return(list);
        }
Example #18
0
 public Grammar(
     INonTerminal start,
     IEnumerable<IProduction> productions,
     IEnumerable<ILexerRule> ignoreRules)
     : this()
 {
     Start = start;
     AddProductions(productions ?? EmptyProductionArray);
     AddIgnoreRules(ignoreRules ?? EmptyLexerRuleArray);
     FindNullableSymbols();
 }
Example #19
0
        private static IEnumerable<IProduction> ZeroOrMany(INonTerminal identifier, ITerminal[] terminals)
        {
            var recursiveProductionSymbols = new List<ISymbol>();
            recursiveProductionSymbols.Add(identifier);
            recursiveProductionSymbols.AddRange(terminals);

            // NonTerminal -> NonTerminal Terminal | <null>
            return new[]{
                new Production(identifier, recursiveProductionSymbols.ToArray()),
                new Production(identifier)};
        }
Example #20
0
 public Grammar(INonTerminal start, IProduction[] productions, ILexerRule[] lexerRules, ILexerRule[] ignore)
 {
     Assert.IsNotNullOrEmpty(productions, "productions");
     Assert.IsNotNull(start, "start");
     _productionIndex = CreateProductionIndex(productions);
     _lexerRuleIndex = CreateLexerRuleIndex(lexerRules);
     Productions = new ReadOnlyList<IProduction>(productions ?? EmptyProductionArray);
     LexerRules = new ReadOnlyList<ILexerRule>(lexerRules ?? EmptyLexerRuleArray);
     Ignores = new ReadOnlyList<ILexerRule>(ignore ?? EmptyLexerRuleArray);
     Start = start;
 }
Example #21
0
 public FluentRule(FluentParserConfigurator configurator, INonTerminal <object> nonTerminal)
 {
     this.configurator = configurator;
     this.nonTerminal  = (NonTerminal <object>)nonTerminal;
     productionList    = new List <List <ProductionElement> > {
         new List <ProductionElement>()
     };
     funcList = new List <Func <dynamic, object> > {
         null
     };
 }
Example #22
0
        private void SetSymbol(IInternalForestNode node)
        {
            switch (node.NodeType)
            {
            case Forest.ForestNodeType.Symbol:
                Symbol = (node as ISymbolForestNode).Symbol as INonTerminal;
                break;

            case Forest.ForestNodeType.Intermediate:
                Symbol = (node as IIntermediateForestNode).State.DottedRule.Production.LeftHandSide;
                break;
            }
        }
        public void TestCanMultiplyDefineTerminalStringsInConfiguration()
        {
            var configurator = ParserFactory.Configure <int>();
            INonTerminal <int> nonTerminal = configurator.CreateNonTerminal();

            nonTerminal.DebugName = "NonTerm";
            nonTerminal.AddProduction("this", "is", "a", "string");
            nonTerminal.AddProduction("this", "is", "a", "test");

            var parser = configurator.CreateParser();

            Assert.IsNotNull(parser);
        }
Example #24
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="nonTerminal"></param>
		/// <param name="input">The input string.</param>
		/// <param name="substring">The substring interval.</param>
		/// <returns></returns>
		private bool ApplyAny(INonTerminal nonTerminal, string input, IntervalInt32 substring)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(nonTerminal != null);
			Contract.Requires<ArgumentNullException>(input != null);
			#endregion
			var productionRules = GetProductionRules(nonTerminal);
			foreach(var rule in productionRules)
			{
				bool success = Apply(rule, input, substring);
				if (success) return true;
			}
			return false;
		}
Example #25
0
        public ImmutableDictionary <IProduction, int> HandleClosure(INonTerminal nonTerminal)
        {
            var result = ImmutableDictionary <IProduction, int> .Empty;

            foreach (var production in _pipelinePayload.AugmentedGrammar.Productions)
            {
                if (production.NonTerminal == nonTerminal && !result.ContainsKey(production))
                {
                    result = result.Add(production, 0);
                }
            }

            return(result);
        }
Example #26
0
        public bool IsNullable(INonTerminal nonTerminal)
        {
            List <IProduction> productionList;

            if (!_leftHandSideToProductions.TryGetValue(nonTerminal, out productionList))
            {
                return(true);
            }
            if (productionList.Count > 0)
            {
                return(false);
            }
            return(productionList[0].RightHandSide.Count == 0);
        }
Example #27
0
        public Grammar(
            INonTerminal start,
            IReadOnlyList <IProduction> productions,
            IReadOnlyList <ILexerRule> ignoreRules)
        {
            _productions     = new List <IProduction>();
            _ignores         = new List <ILexerRule>();
            _productionIndex = new Dictionary <INonTerminal, List <IProduction> >();
            _ignoreIndex     = new Dictionary <int, List <ILexerRule> >();
            _nullable        = new UniqueList <INonTerminal>();
            _reverseLookup   = new Dictionary <INonTerminal, UniqueList <IProduction> >();

            Start = start;
            AddProductions(productions ?? EmptyProductionArray);
            AddIgnoreRules(ignoreRules ?? EmptyLexerRuleArray);
            FindNullableSymbols(_reverseLookup, _nullable);
        }
Example #28
0
        private void ReduceOneLeftHandSide(int iLoc, int origLoc, INonTerminal lhsSym)
        {
            var frameSet       = Chart.Sets[origLoc];
            var transitionItem = frameSet.FindCachedDottedRuleSetTransition(lhsSym);

            if (transitionItem != null)
            {
                LeoReductionOperation(iLoc, transitionItem);
            }
            else
            {
                for (var i = 0; i < frameSet.States.Count; i++)
                {
                    var stateFrame = frameSet.States[i];
                    EarleyReductionOperation(iLoc, stateFrame, lhsSym);
                }
            }
        }
        public void TestReduceReduceConflict()
        {
            // Represents the grammar
            //
            // x := t | y
            // t := "A"
            // y := "A"
            //
            INonTerminal <object> y = null, t = null;

            try
            {
                var configurator        = ParserFactory.Configure <object>();
                INonTerminal <object> x = configurator.CreateNonTerminal();
                x.DebugName = "X";

                t           = configurator.CreateNonTerminal();
                t.DebugName = "T";

                y           = configurator.CreateNonTerminal();
                y.DebugName = "Y";

                x.AddProduction(t);
                x.AddProduction(y);

                t.AddProduction("A");
                y.AddProduction("A");

                configurator.CreateParser();
                Assert.Fail();
            }
            catch (ReduceReduceConflictException <object> e)
            {
                Assert.AreEqual(y, e.NewReduceSymbol);
                Assert.AreEqual(t, e.PreviousReduceSymbol);
            }
        }
 public InternalTreeNodeImpl(int origin, int location, INonTerminal symbol)
     : base(origin, location, TreeNodeType.Internal)
 {
     Symbol            = symbol;
     ReadWriteChildren = new List <ITreeNode>();
 }
Example #31
0
 public IEnumerable<ILexerRule> LexerRulesFor(INonTerminal nonTerminal)
 {
     return _bnfGrammar.LexerRulesFor(nonTerminal);
 }
Example #32
0
 public ProductionExpression(INonTerminal leftHandSide)
 {
     ProductionModel = new ProductionModel(leftHandSide);
 }
Example #33
0
 public NonTerminalModel(INonTerminal value)
 {
     NonTerminal = value;
 }
Example #34
0
 public bool IsNullable(INonTerminal nonTerminal)
 {
     return(_nullable.Contains(nonTerminal));
 }
Example #35
0
		private IEnumerable<IProductionRule> GetProductionRules(INonTerminal nonTerminal)
		{
			return from p in this.grammar.ProductionRules
				   where p.Left[0] == nonTerminal
				   select p;
		}
Example #36
0
 public IReadOnlyList <IProduction> RulesFor(INonTerminal nonTerminal)
 {
     return(_innerGrammar.RulesFor(nonTerminal));
 }
Example #37
0
 public bool IsNullable(INonTerminal nonTerminal)
 {
     return(_innerGrammar.IsNullable(nonTerminal));
 }
Example #38
0
 public void SetStartSymbol(INonTerminal <T> start)
 {
     startSymbol = (NonTerminal <T>)start;
 }
Example #39
0
 public NonTerminalModel(INonTerminal value)
 {
     NonTerminal = value;
 }
Example #40
0
        private void SetSymbol(IInternalForestNode node)
        {
            switch (node.NodeType)
            {
                case Forest.ForestNodeType.Symbol:
                    Symbol = (node as ISymbolForestNode).Symbol as INonTerminal;
                    break;

                case Forest.ForestNodeType.Intermediate:
                    Symbol = (node as IIntermediateForestNode).State.Production.LeftHandSide;
                    break;
            }
        }
Example #41
0
 private static IEnumerable<IProduction> Once(INonTerminal identifier, ITerminal[] terminals)
 {
     // NonTerminal -> Terminal
     return new[]{
         new Production(identifier, terminals)};
 }
Example #42
0
 public IReadOnlyList<IProduction> RulesFor(INonTerminal nonTerminal)
 {
     return _innerGrammar.RulesFor(nonTerminal);
 }
Example #43
0
 public IEnumerable<IProduction> RulesFor(INonTerminal nonTerminal)
 {
     return _bnfGrammar.RulesFor(nonTerminal);
 }
Example #44
0
 public InternalTreeNodeImpl(int origin, int location, INonTerminal symbol)
     : base(origin, location, TreeNodeType.Internal)
 {
     Symbol = symbol;
     ReadWriteChildren = new ReadWriteList<ITreeNode>();
 }
Example #45
0
 public ProductionModel(INonTerminal leftHandSide)
     : this(new NonTerminalModel(leftHandSide))
 {
 }
Example #46
0
 public bool IsTransativeNullable(INonTerminal nonTerminal)
 {
     return(_transativeNullableSymbols.Contains(nonTerminal));
 }
 public static void AddReduceProduction <T>(this INonTerminal <T> symb, params object[] args) => symb.AddProduction(args).SetReduceToFirst();
Example #48
0
 public IReadOnlyList <IProduction> RulesContainingSymbol(INonTerminal nonTerminal)
 {
     return(_innerGrammar.RulesContainingSymbol(nonTerminal));
 }
Example #49
0
 public bool IsNullable(INonTerminal nonTerminal)
 {
     return _nullable.Contains(nonTerminal);
 }
Example #50
0
 public bool IsNullable(INonTerminal nonTerminal)
 {
     return _innerGrammar.IsNullable(nonTerminal);
 }
Example #51
0
 public ProductionExpression(INonTerminal leftHandSide)
 {
     ProductionModel = new ProductionModel(leftHandSide);
 }
Example #52
0
 public ProductionModel(INonTerminal leftHandSide)
     : this(new NonTerminalModel(leftHandSide))
 {
 }