public static IProductionRule Deliteralize(this IProductionRule rule, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (rule.NeedsDeliteralized()) { List <IProductionRuleItem> result = new List <IProductionRuleItem>(); foreach (IProductionRuleItem ruleItem in rule) { IProductionRuleItem resultItem = null; if (ruleItem.NeedsDeliteralized()) { resultItem = ruleItem.Deliteralize(currentEntry, availableStock, file, errors); } else { resultItem = ruleItem; } if (resultItem != null) { result.Add(resultItem); } } if (result.Count == 0) { return(null); } return(new ProductionRule(result, rule.FileName, rule.Column, rule.Line, rule.Position)); } else { return(rule); } }
public static void FinalLink(this IOilexerGrammarProductionRuleEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (entry.NeedsFinalLinking()) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule currentItem in entry) { IProductionRule resultIPR = null; if (currentItem.NeedsFinalLinking()) { resultIPR = currentItem.FinalLink(entry, file, errors); } else { resultIPR = currentItem; } if (resultIPR != null) { result.Add(resultIPR); } } OilexerGrammarProductionRuleEntry r = ((OilexerGrammarProductionRuleEntry)(entry)); r.Clear(); foreach (IProductionRule ipr in result) { r.Add(ipr); } } }
public static IProductionRuleSeries Deliteralize(this IProductionRuleSeries series, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (series.NeedsDeliteralized()) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule ipr in series) { IProductionRule resultIPR = null; if (ipr.NeedsDeliteralized()) { resultIPR = ipr.Deliteralize(currentEntry, availableStock, file, errors); } else { resultIPR = ipr; } if (resultIPR != null) { result.Add(resultIPR); } } if (result.Count == 0) { return(null); } return(new ProductionRuleSeries(result)); } return(series); }
internal static IProductionRuleSeries Expand(this IProductionRuleSeries series, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule ipr in series) { IProductionRule resultedItem = null; if (ipr.HasExpansion()) { resultedItem = ipr.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); } else { resultedItem = ipr; } if (resultedItem == null) { continue; } result.Add(resultedItem); } if (result.Count == 0) { return(null); } return(new ProductionRuleSeries(result)); }
public static void Deliteralize(this IOilexerGrammarProductionRuleEntry entry, IList <IOilexerGrammarTokenEntry> availableStock, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (entry.NeedsDeliteralized()) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule ipr in entry) { IProductionRule resultIPR = null; if (ipr.NeedsDeliteralized()) { resultIPR = ipr.Deliteralize(entry, availableStock, file, errors); } else { resultIPR = ipr; } if (resultIPR != null) { result.Add(resultIPR); } } OilexerGrammarProductionRuleEntry r = ((OilexerGrammarProductionRuleEntry)(entry)); r.Clear(); foreach (IProductionRule ipr in result) { r.Add(ipr); } //currentEntry = null; } }
public static IProductionRule ReplaceReferences(IOilexerGrammarFile source, IProductionRule target, IDictionary <IProductionRuleItem, IProductionRuleItem> elementToElementList) { List <IProductionRuleItem> result = new List <IProductionRuleItem>(); foreach (var item in target) { if (elementToElementList.ContainsKey(item)) { result.Add(elementToElementList[item]); } else { if (item is IProductionRuleGroupItem && ContainsReferences(source, item, elementToElementList)) { var gItem = ((IProductionRuleGroupItem)(item)); var rItemElements = ReplaceReferences(source, gItem.ToArray(), elementToElementList); ProductionRuleGroupItem rItem = new ProductionRuleGroupItem(rItemElements.ToArray(), gItem.Column, gItem.Line, gItem.Position); rItem.Name = gItem.Name; rItem.RepeatOptions = gItem.RepeatOptions; result.Add(rItem); } else { result.Add(item); } } } return(new ProductionRule(result, target.FileName, target.Column, target.Line, target.Position)); }
internal static bool NeedsExpansion(this IProductionRule series, IOilexerGrammarProductionRuleEntry entry) { foreach (IProductionRuleItem item in series) { if (item is ITemplateReferenceProductionRuleItem) { return(true); } else if (item is ITemplateParamReferenceProductionRuleItem) { return(true); } else if (item is IProductionRuleGroupItem) { var gItem = (IProductionRuleGroupItem)item; if (gItem.Count == 0) { return(true); } else if (gItem.Name.IsEmptyOrNull() && gItem.Count == 1 && gItem[0].Count == 1 && gItem.RepeatOptions == ScannableEntryItemRepeatInfo.None) { return(true); } if (gItem.NeedsExpansion(entry)) { return(true); } } } return(false); }
public static void GetTokenReferences(this IProductionRule rule, IList <IOilexerGrammarTokenEntry> list) { foreach (IProductionRuleItem ruleItem in rule) { ruleItem.GetTokenReferences(list); } }
private static void ReplaceTokenReference(IProductionRule target, IOilexerGrammarTokenEntry sourceElement, InlinedTokenEntry destination) { foreach (var item in target) { ReplaceTokenReference(item, sourceElement, destination); } }
public void Add(IProductionRule rule) { var xrule = (TerminalRule)rule; for (int i = 0; i < scores.Length; ++i) { scores [i] = MathHelper.LogAdd (scores [i], xrule.scores [i]); } }
private void Fire(IProductionRule <T> rule, T wm) { var before = CloneJson(wm); rule.Action(wm); var after = CloneJson(wm); _log.Add(new RuleRunLog <T>(before, after, rule)); _agenda.Remove(rule); }
public void Add(IProductionRule rule) { var xrule = (UnaryRule)rule; for (int i = 0; i < scores.Length; ++i) { for (int j = 0; j < scores[i].Length; ++j) { scores [i] [j] = MathHelper.LogAdd (scores [i] [j], xrule.scores [i] [j]); } } }
internal static IProductionRule Expand(this IProductionRule rule, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (rule.HasExpansion()) { List <IProductionRuleItem> result = new List <IProductionRuleItem>(); foreach (IProductionRuleItem item in rule) { IProductionRuleItem ipri = null; if (item.HasExpansion()) { ipri = item.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); } else { ipri = item.Clone(); } if (ipri == null) { continue; } result.Add(ipri); } rebuildResult: List <IProductionRuleItem> rebuiltResult = new List <IProductionRuleItem>(); foreach (IProductionRuleItem ipri in result) { if (ipri is IProductionRuleGroupItem && ((IProductionRuleGroupItem)(ipri)).Count == 1 && (ipri.Name == null || ipri.Name == string.Empty) && ipri.RepeatOptions == ScannableEntryItemRepeatInfo.None) { foreach (IProductionRuleItem iprii in ((IProductionRuleGroupItem)(ipri))[0]) { rebuiltResult.Add(iprii); } } else { rebuiltResult.Add(ipri); } } if (rebuiltResult.Count != result.Count) { result = rebuiltResult; goto rebuildResult; } if (result.Count == 0) { return(null); } return(new ProductionRule(result, rule.FileName, rule.Column, rule.Line, rule.Position)); } else { return(rule); } }
public static bool NeedsDeliteralized(this IProductionRule rule) { foreach (IProductionRuleItem ruleItem in rule) { if (ruleItem.NeedsDeliteralized()) { return(true); } } return(false); }
public static bool ContainsReferences(IOilexerGrammarFile source, IProductionRule target, IDictionary <IProductionRuleItem, IProductionRuleItem> elementToElementList) { foreach (var item in target) { if (ContainsReferences(source, item, elementToElementList)) { return(true); } } return(false); }
internal static IProductionRuleItem Expand(this IPreprocessorConditionalReturnDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { IProductionRule[] result = new IProductionRule[directive.Result.Length]; for (int i = 0; i < directive.Result.Length; i++) { result[i] = directive.Result[i].Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); } var resultG = new ProductionRuleGroupItem(result, directive.Column, directive.Line, directive.Position); return(resultG); }
private static bool AllAreUnnamedEquivalents(IProductionRule rule, ref IProductionRuleItem rootItem) { foreach (var item in rule) { if (!AllAreUnnamedEquivalents(item, ref rootItem)) { return(false); } } return(true); }
internal static bool HasExpansion(this IProductionRule rule) { foreach (IProductionRuleItem ruleItem in rule) { if (ruleItem.HasExpansion()) { return(true); } } return(false); }
public static IPreprocessorDirective ResolveProductionRuleItem<T>(this IPreprocessorDirective item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { switch (item.Type) { case EntryPreprocessorType.If: case EntryPreprocessorType.IfNotDefined: case EntryPreprocessorType.IfDefined: case EntryPreprocessorType.ElseIf: case EntryPreprocessorType.ElseIfDefined: case EntryPreprocessorType.Else: IPreprocessorIfDirective ipid = ((IPreprocessorIfDirective)(item)); PreprocessorIfDirective pid = new PreprocessorIfDirective(item.Type, ((IPreprocessorIfDirective)item).Condition, entry.FileName, item.Column, item.Line, item.Position); foreach (IPreprocessorDirective ipd in ipid.Body) ((PreprocessorIfDirective.DirectiveBody)(pid.Body)).Add(ipd.ResolveProductionRuleItem(entry, file, errors)); if (ipid.Next != null) pid.Next = (IPreprocessorIfDirective)ipid.Next.ResolveProductionRuleItem(entry, file, errors); return pid; case EntryPreprocessorType.DefineRule: IPreprocessorDefineRuleDirective ipdd = ((IPreprocessorDefineRuleDirective)(item)); IProductionRule[] dr = new IProductionRule[ipdd.DefinedRules.Length]; for (int i = 0; i < ipdd.DefinedRules.Length; i++) { dr[i] = ipdd.DefinedRules[i].Clone(); dr[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorDefineRuleDirective(ipdd.DeclareTarget, dr, ipdd.Column, ipdd.Line, ipdd.Position); case EntryPreprocessorType.AddRule: IPreprocessorAddRuleDirective ipard = ((IPreprocessorAddRuleDirective)(item)); IProductionRule[] ar = new IProductionRule[ipard.Rules.Length]; for (int i = 0; i < ipard.Rules.Length; i++) { ar[i] = ipard.Rules[i].Clone(); ar[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorAddRuleDirective(ipard.InsertTarget, ar, ipard.Column, ipard.Line, ipard.Position); case EntryPreprocessorType.Throw: return item; case EntryPreprocessorType.Return: IPreprocessorConditionalReturnDirective ipcrd = ((IPreprocessorConditionalReturnDirective)(item)); IProductionRule[] crd = new IProductionRule[ipcrd.Result.Length]; for (int i = 0; i < ipcrd.Result.Length; i++) { crd[i] = ipcrd.Result[i].Clone(); crd[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorConditionalReturnDirective(crd, ipcrd.Column, ipcrd.Line, ipcrd.Position); } return item; }
public static bool NeedsFinalLinking(this IProductionRule rule) { if (rule.Count == 0) { return(true); } foreach (IProductionRuleItem ruleItem in rule) { if (ruleItem.NeedsFinalLinking()) { return(true); } } return(false); }
private static IEnumerable <IProductionRuleItem> GetProductionRuleItems(IProductionRule rule) { foreach (var item in rule) { yield return(item); if (item is IProductionRuleGroupItem) { foreach (var entry in GetProductionRuleSeriesItems((IProductionRuleGroupItem)item)) { yield return(entry); } } } }
private static void ResolveProductionRule<T>(this IProductionRule rule, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { /* * * Copy the source, can't use just a standard IEnumerable because by design * it only enumerates the source when requested. If we tamper with the source, * before enumerating the transitionFirst time, the results are distorted. * */ IList<IProductionRuleItem> rCopy = new List<IProductionRuleItem>(rule); ProductionRule pr = rule as ProductionRule; IEnumerable<IProductionRuleItem> finalVersion = from item in rCopy select (item.ResolveProductionRuleItem(entry, file, errors)); pr.BaseCollection.Clear(); foreach (IProductionRuleItem iti in finalVersion) pr.BaseCollection.Add(iti); }
internal static void Expand(this IPreprocessorDefineRuleDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { string search = directive.DeclareTarget; if (search != null && search != string.Empty) { if (argumentLookup.ContainsParameter(search)) { IProductionRuleTemplatePart part = argumentLookup.GetParameter(search); IProductionRuleSeries iprs = argumentLookup[part]; if (iprs.Count == 1 && iprs[0].Count == 1) { IProductionRuleItem ipri = iprs[0][0]; if (ipri is ISoftReferenceProductionRuleItem) { ISoftReferenceProductionRuleItem n = (ISoftReferenceProductionRuleItem)ipri; search = n.PrimaryName; } } } /* ToDo: Evaluate the depth necessary to institute a lock associated to the base list on the oilexer grammar file type. */ IOilexerGrammarEntry[] fileElements; lock (file) fileElements = file.ToArray(); foreach (IOilexerGrammarEntry ie in fileElements) { if (ie is IOilexerGrammarNamedEntry && ((IOilexerGrammarNamedEntry)ie).Name == search) { errors.SourceError(OilexerGrammarCore.CompilerErrors.DuplicateTermDefined, new LineColumnPair(directive.Line, directive.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), search); return; } } OilexerGrammarProductionRuleEntry insertedItem = new OilexerGrammarProductionRuleEntry(search, entry.ScanMode, entry.FileName, directive.Column, directive.Line, directive.Position); lock (file) file.Add(insertedItem); foreach (IProductionRule ipr in directive.DefinedRules) { IProductionRule expanded = ipr.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); insertedItem.Add(expanded); } } }
public static SyntacticalNFAState BuildNFA(this IProductionRule rule, IGrammarSymbolSet symbols, ControlledDictionary <IOilexerGrammarProductionRuleEntry, SyntacticalDFARootState> lookup, Dictionary <IProductionRuleSource, IProductionRuleCaptureStructuralItem> replacements) { SyntacticalNFAState state = null; foreach (var item in rule) { if (state == null) { state = item.BuildNFA(symbols, lookup, replacements); } else { var nextState = item.BuildNFA(symbols, lookup, replacements); if (nextState != null) { state.Concat(nextState); } } } return(state); }
public static IProductionRule FinalLink(this IProductionRule rule, IOilexerGrammarProductionRuleEntry currentEntry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (rule.NeedsFinalLinking()) { List <IProductionRuleItem> result = new List <IProductionRuleItem>(); foreach (IProductionRuleItem currentItem in rule) { IProductionRuleItem resultItem = null; if (currentItem.NeedsFinalLinking()) { resultItem = currentItem.FinalLink(currentEntry, file, errors); } else { resultItem = currentItem; } if (resultItem != null) { result.Add(resultItem); } } /* * * If the only element remaining after template expansion * was an empty group, the current expression is * unnecessary. * */ if (result.Count == 0) { return(null); } return(new ProductionRule(result, rule.FileName, rule.Column, rule.Line, rule.Position)); } else { return(rule); } }
public static IProductionRuleSeries FinalLink(this IProductionRuleSeries series, IOilexerGrammarProductionRuleEntry currentEntry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (series.NeedsFinalLinking()) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule current in series) { IProductionRule resultIPR = null; if (current.NeedsFinalLinking()) { resultIPR = current.FinalLink(currentEntry, file, errors); } else { resultIPR = current; } /* * * It can be null because methods like this for * production rule series return null when the * set was empty. * * * A good example is groups. * */ if (resultIPR != null) { result.Add(resultIPR); } } if (result.Count == 0) { return(null); } return(new ProductionRuleSeries(result)); } return(series); }
private static void CleanupRule(IProductionRule expression) { List <IProductionRuleGroupItem> terminalList = new List <IProductionRuleGroupItem>(); foreach (var item in expression) { if (item is IProductionRuleGroupItem) { var gItem = (IProductionRuleGroupItem)item; if (gItem.Count == 0) { terminalList.Add(gItem); } else { CleanupRule(gItem); } } } foreach (var item in terminalList) { ((ProductionRule)(expression)).baseList.Remove(item); } }
/// <summary> /// Applies the specified rule to the specified part of the input. /// </summary> /// <param name="rule">The rule to apply.</param> /// <param name="input">The input string.</param> /// <param name="substring">The substring interval.</param> /// <returns><see langword="true"/> when the rule could be applied; /// otherwise, <see langword="false"/>.</returns> private bool Apply(IProductionRule rule, string input, IntervalInt32 substring) { #region Contract Contract.Requires<ArgumentNullException>(rule != null); Contract.Requires<ArgumentNullException>(input != null); // TODO: The rule must be context-free. That is: must have exactly one symbol, a non-terminal, on the left-hand side. #endregion foreach(IntervalInt32[] partition in GetPartitions(substring, rule.Right.Count)) { // First try all terminals. bool terminalsMatch = true; for (int i = 0; i < rule.Right.Count; i++) { if (!(rule.Right[i] is ITerminal)) continue; ITerminal terminal = (ITerminal)rule.Right[i]; if (!terminal.Match(input, partition[i].Start, (int)partition[i].Length)) { terminalsMatch = false; break; } } if (!terminalsMatch) continue; // Then recursively try all non-terminals. bool nonTerminalsMatch = true; for (int i = 0; i < rule.Right.Count; i++) { if (!(rule.Right[i] is INonTerminal)) continue; INonTerminal nonTerminal = (INonTerminal)rule.Right[i]; if (!ApplyAny(nonTerminal, input, partition[i])) { nonTerminalsMatch = false; break; } } if (!nonTerminalsMatch) continue; return true; } return false; }
public static void Normalize(double[][] expects, IProductionRule[][] rules) { ApplyToRules(x => x.Normalize(expects), rules); }
public static void CopyRules(IProductionRule[][] src, IProductionRule[][] dest) { if (src == null) { return; } for (int i = 0; i < src.Length; ++i) { if (src [i] == null) { continue; } for (int j = 0; j < src[i].Length; ++j) { if (src [i] [j] == null) { continue; } src [i] [j].CopyTo(dest [i] [j]); } } }
public void CopyTo(IProductionRule rule) { if (rule is TerminalRule) { this.CopyTo ((TerminalRule)rule); } else { throw new Exception ("binary rule can only copy to binary rules"); } }
private void SetActionTable(short[,] table, int state, int tokenNumber, short value) { // This is an error condition, find out what sort of exception it is short oldValue = table[state, tokenNumber]; if ((oldValue != value) && (oldValue != short.MinValue)) { try { if (oldValue < 0 && value < 0) // Both values are reduce. Throw a reduce reduce conflict. This is not solveable. NOTE: Bison takes the first rule (here 'oldValue') { throw new ReduceReduceConflictException <T>("Grammar contains a reduce reduce conflict"); } int shiftTokenNumber = tokenNumber; int reduceRuleNumber; short shiftValue; short reduceValue; if (oldValue < 0) { // The old value was a reduce, the new must be a shift shiftValue = value; reduceValue = oldValue; reduceRuleNumber = -(oldValue + 1); } else { // TODO: Unsure if this is a real case. The only testcases that end up here are retarded tests which are cyclic in nature. // TODO: These cases always fail later on anyway due to conflicts. // The old value was a shift, the new value must be a reduce shiftValue = oldValue; reduceValue = value; reduceRuleNumber = -(value + 1); } // Check if these tokens have declared precedences and associativity // If they do, we might be able to act on this. Terminal <T> shiftingTerminal = grammar.AllSymbols.OfType <Terminal <T> >().First(f => f.TokenNumber == shiftTokenNumber); IPrecedenceGroup shiftPrecedence = grammar.GetPrecedence(shiftingTerminal); IProductionRule <T> productionRule = reductionRules[reduceRuleNumber].Item1; // If the rule has a context dependent precedence, use that. Otherwise use the reduce precedence of the last terminal symbol in the production rules precedence IPrecedenceGroup reducePrecedence = productionRule.ContextPrecedence ?? grammar.GetPrecedence(productionRule.Symbols.Reverse().OfType <ITerminal <T> >().FirstOrDefault()); // If either rule has no precedence this is not a legal course of action. // TODO: In bison this is apparently cool, it prefers to shift in this case. I don't know why, but this seems like a dangerous course of action to me. if (shiftPrecedence == null || reducePrecedence == null) { throw new ShiftReduceConflictException <T>("Grammar contains a shift reduce conflict") { ShiftSymbol = shiftingTerminal, ReduceSymbol = productionRule.ResultSymbol, } } ; if (shiftPrecedence.Precedence < reducePrecedence.Precedence) { table[state, tokenNumber] = reduceValue; // Precedence of reduce is higher, choose to reduce } else if (shiftPrecedence.Precedence > reducePrecedence.Precedence) { table[state, tokenNumber] = shiftValue; // Shift precedence is higher. Shift } // Both tokens are in the same precedence group! It's now up to the associativity // The two tokens CANNOT have different associativity, due to how the configuration works which throws up if you try to multiple-define the precedence else if (shiftPrecedence.Associativity == AssociativityDirection.Left) { table[state, tokenNumber] = reduceValue; // Prefer reducing } else if (shiftPrecedence.Associativity == AssociativityDirection.Right) { table[state, tokenNumber] = shiftValue; // Prefer shifting } else // if (shiftPrecedence.Associativity == AssociativityDirection.NonAssociative) <- this is implied { throw new ShiftReduceConflictException <T>("Grammar contains a shift reduce conflict (Nonassociative)") { ShiftSymbol = shiftingTerminal, ReduceSymbol = productionRule.ResultSymbol, } }; // Unresolveable } catch (AmbiguousGrammarException ex) { // Fill in more information on the error and rethrow the error ex.StateNumber = state; ex.TokenNumber = tokenNumber; ex.PreviousValue = oldValue; ex.NewValue = value; throw; } } else { table[state, tokenNumber] = value; } }
internal IParser <T> CreateParser() { // First order of business is to create the canonical list of LR1 states, or at least we are going to go through // them as we merge the sets together. // This starts with augmenting the grammar with an accept symbol, then we derive the // grammar from that IProductionRule <T> start = grammar.Start; // Get the first and follow sets for all nonterminal symbols ISet <NonTerminal <T> > nullable = CalculateNullable(); TerminalSet <T> first = CalculateFirst(nullable); // So, we are going to calculate the LR1 closure for the start symbol, which should // be the augmented accept state of the grammar. // The closure is all states which are accessible by the dot at the left hand side of the // item. List <Lr1ItemSet <T> > itemSets = new List <Lr1ItemSet <T> > { Closure(new List <Lr1Item <T> > { new Lr1Item <T>(start, 0, new HashSet <Terminal <T> > { grammar.EndOfInputTerminal }) }, first, nullable) }; List <GotoSetTransition> gotoSetTransitions = new List <GotoSetTransition>(); // Repeat until nothing gets added any more // This is neccessary since we are merging sets as we go, which changes things around. bool added; do { added = false; for (int i = 0; i < itemSets.Count; ++i) { Lr1ItemSet <T> itemSet = itemSets[i]; foreach (ISymbol <T> symbol in grammar.AllSymbols) { // Calculate the itemset for by goto for each symbol in the grammar Lr1ItemSet <T> gotoSet = Goto(itemSet, symbol); // If there is anything found in the set if (gotoSet.Any()) { // Do a closure on the goto set and see if it's already present in the sets of items that we have // if that is not the case add it to the item set gotoSet = Closure(gotoSet, first, nullable); Lr1ItemSet <T> oldGotoSet = itemSets.Find(f => f.CoreEquals(gotoSet)); if (oldGotoSet == null) { // Add goto set to itemsets itemSets.Add(gotoSet); // Add a transition gotoSetTransitions.Add(new GotoSetTransition { From = itemSet, OnSymbol = symbol, To = gotoSet }); added = true; } else { // Already found the set // Merge the lookaheads for all rules oldGotoSet.MergeLookaheads(gotoSet); // Add a transition if it already isn't there GotoSetTransition nt = new GotoSetTransition { From = itemSet, OnSymbol = symbol, To = oldGotoSet }; if (!gotoSetTransitions.Any(a => (a.From == nt.From) && (a.OnSymbol == nt.OnSymbol) && (a.To == nt.To))) { gotoSetTransitions.Add(nt); } } } } } } while (added); LRParseTable <T> parseTable = CreateParseTable(itemSets, gotoSetTransitions); // Create a new parser using that parse table and some additional information that needs // to be available for the runtime parsing to work. return(new LRParser <T>( parseTable, (grammar.ErrorToken as Terminal <T>).TokenNumber, grammar.EndOfInputTerminal.TokenNumber, grammar.AllSymbols.OfType <Terminal <T> >().Select(f => f.DebugName).ToArray() )); }
public Lr1Item(IProductionRule <T> productionRule, int dotLocation, ISet <Terminal <T> > lookaheads) : base(productionRule, dotLocation) { Lookaheads = new HashSet <Terminal <T> >(); Lookaheads.UnionWith(lookaheads); }
public Lr0Item(IProductionRule <T> productionRule, int dotLocation) { DotLocation = dotLocation; ProductionRule = productionRule; }
public static void Smoothing(double alpha, IProductionRule[][] rules) { ApplyToRules(x => x.Smoothing(alpha), rules); }
public IEnumerable <object> GetValues(IProductionRule production) { return(GetValues <object>(production.Token.Id)); }
public static void ApplyToRules(Action<IProductionRule> act, IProductionRule[][][] rules) { foreach (var x in rules.Where(x => x != null)) { foreach (var y in x.Where(y => y != null)) { foreach (var z in y.Where(z => z != null)) { act(z); } } } }
public static void CollectTagMass(double[][] mass, IProductionRule[][] rules) { List<double>[][] pmassList = new List<double>[mass.Length][]; for (int i = 0; i < pmassList.Length; ++i) { pmassList [i] = new List<double>[mass [i].Length]; for (int j = 0; j < pmassList[i].Length; ++j) { pmassList [i] [j] = new List<double>(); } } ApplyToRules(x => x.CollectMass(pmassList), rules); for (int p = 0; p < pmassList.Length; ++p) { for (int sp = 0; sp < pmassList[p].Length; ++sp) { var pl = pmassList [p] [sp]; if (pl.Count == 0) { continue; } double xmass = NanYUtilityLib.MathHelper.LogAdd(pl.ToArray()); mass [p] [sp] = NanYUtilityLib.MathHelper.LogAdd(xmass, mass [p] [sp]); } } }
public static void ApplyToRules(Action<IProductionRule, IProductionRule> act, IProductionRule[][] firstArg, IProductionRule[][] secondArg) { for (int i = 0; i < firstArg.Length; ++i) { if (firstArg [i] == null) { continue; } for (int j = 0; j < firstArg[i].Length; ++j) { if (firstArg [i] [j] == null) { continue; } act(firstArg [i] [j], secondArg [i] [j]); } } }
public static void ApplyToRules(Action<IProductionRule> act, IProductionRule[][] rules) { Array.ForEach(rules, x => { if (x != null) { Array.ForEach(x, y => { if (y != null) { act(y); } } ); } } ); }
public static void ClearRules(IProductionRule[][] rules) { ApplyToRules(x => x.ClearScore(), rules); }