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); } }
private static IEnumerable<IProduction> ZeroOrOne(INonTerminal identifier, ITerminal[] terminals) { // NonTerminal -> Terminal | <null> return new[]{ new Production(identifier, terminals), new Production(identifier) }; }
public IReadOnlyList<IProduction> RulesFor(INonTerminal symbol) { ReadWriteList<IProduction> list; if (!_productionIndex.TryGetValue(symbol, out list)) return EmptyProductionArray; return list; }
public IEnumerable<IProduction> RulesFor(INonTerminal symbol) { IList<IProduction> list; if (!_productionIndex.TryGetValue(symbol, out list)) return EmptyProductionArray; return list; }
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); }
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); }
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)); }
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); }
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(); }
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; }
public IReadOnlyList <IProduction> RulesFor(INonTerminal nonTerminal) { List <IProduction> list; if (!_leftHandSideToProductions.TryGetValue(nonTerminal, out list)) { return(EmptyProductionArray); } return(list); }
public IReadOnlyList <IProduction> RulesFor(INonTerminal symbol) { List <IProduction> list; if (!_productionIndex.TryGetValue(symbol, out list)) { return(EmptyProductionArray); } return(list); }
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); }
public IReadOnlyList <IProduction> RulesContainingSymbol(INonTerminal symbol) { UniqueList <IProduction> list; if (!_reverseLookup.TryGetValue(symbol, out list)) { return(EmptyProductionArray); } return(list); }
public Grammar( INonTerminal start, IEnumerable<IProduction> productions, IEnumerable<ILexerRule> ignoreRules) : this() { Start = start; AddProductions(productions ?? EmptyProductionArray); AddIgnoreRules(ignoreRules ?? EmptyLexerRuleArray); FindNullableSymbols(); }
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)}; }
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; }
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 }; }
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); }
/// <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; }
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); }
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); }
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); }
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>(); }
public IEnumerable<ILexerRule> LexerRulesFor(INonTerminal nonTerminal) { return _bnfGrammar.LexerRulesFor(nonTerminal); }
public ProductionExpression(INonTerminal leftHandSide) { ProductionModel = new ProductionModel(leftHandSide); }
public NonTerminalModel(INonTerminal value) { NonTerminal = value; }
public bool IsNullable(INonTerminal nonTerminal) { return(_nullable.Contains(nonTerminal)); }
private IEnumerable<IProductionRule> GetProductionRules(INonTerminal nonTerminal) { return from p in this.grammar.ProductionRules where p.Left[0] == nonTerminal select p; }
public IReadOnlyList <IProduction> RulesFor(INonTerminal nonTerminal) { return(_innerGrammar.RulesFor(nonTerminal)); }
public bool IsNullable(INonTerminal nonTerminal) { return(_innerGrammar.IsNullable(nonTerminal)); }
public void SetStartSymbol(INonTerminal <T> start) { startSymbol = (NonTerminal <T>)start; }
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; } }
private static IEnumerable<IProduction> Once(INonTerminal identifier, ITerminal[] terminals) { // NonTerminal -> Terminal return new[]{ new Production(identifier, terminals)}; }
public IReadOnlyList<IProduction> RulesFor(INonTerminal nonTerminal) { return _innerGrammar.RulesFor(nonTerminal); }
public IEnumerable<IProduction> RulesFor(INonTerminal nonTerminal) { return _bnfGrammar.RulesFor(nonTerminal); }
public InternalTreeNodeImpl(int origin, int location, INonTerminal symbol) : base(origin, location, TreeNodeType.Internal) { Symbol = symbol; ReadWriteChildren = new ReadWriteList<ITreeNode>(); }
public ProductionModel(INonTerminal leftHandSide) : this(new NonTerminalModel(leftHandSide)) { }
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();
public IReadOnlyList <IProduction> RulesContainingSymbol(INonTerminal nonTerminal) { return(_innerGrammar.RulesContainingSymbol(nonTerminal)); }
public bool IsNullable(INonTerminal nonTerminal) { return _nullable.Contains(nonTerminal); }
public bool IsNullable(INonTerminal nonTerminal) { return _innerGrammar.IsNullable(nonTerminal); }