示例#1
0
 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);
     }
 }
示例#2
0
 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);
         }
     }
 }
示例#3
0
 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);
 }
示例#4
0
        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));
        }
示例#5
0
 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;
     }
 }
示例#6
0
        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));
        }
示例#7
0
 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);
 }
示例#8
0
 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);
     }
 }
示例#10
0
        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]);
            }
        }
示例#11
0
        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);
        }
示例#12
0
        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]);
                }
            }
        }
示例#13
0
        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);
            }
        }
示例#14
0
 public static bool NeedsDeliteralized(this IProductionRule rule)
 {
     foreach (IProductionRuleItem ruleItem in rule)
     {
         if (ruleItem.NeedsDeliteralized())
         {
             return(true);
         }
     }
     return(false);
 }
示例#15
0
 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);
 }
示例#16
0
        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);
 }
示例#18
0
 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;
 }
示例#20
0
 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);
 }
示例#21
0
        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);
        }
示例#23
0
        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);
        }
示例#25
0
        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);
            }
        }
示例#26
0
        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);
            }
        }
示例#28
0
		/// <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;
		}
示例#29
0
 public static void Normalize(double[][] expects, IProductionRule[][] rules)
 {
     ApplyToRules(x => x.Normalize(expects), rules);
 }
示例#30
0
        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]);
                }

            }
        }
示例#31
0
 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");
     }
 }
示例#32
0
        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;
            }
        }
示例#33
0
        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()
                       ));
        }
示例#34
0
 public Lr1Item(IProductionRule <T> productionRule, int dotLocation, ISet <Terminal <T> > lookaheads) : base(productionRule, dotLocation)
 {
     Lookaheads = new HashSet <Terminal <T> >();
     Lookaheads.UnionWith(lookaheads);
 }
示例#35
0
 public Lr0Item(IProductionRule <T> productionRule, int dotLocation)
 {
     DotLocation    = dotLocation;
     ProductionRule = productionRule;
 }
示例#36
0
 public static void Smoothing(double alpha, IProductionRule[][] rules)
 {
     ApplyToRules(x => x.Smoothing(alpha), rules);
 }
示例#37
0
 public IEnumerable <object> GetValues(IProductionRule production)
 {
     return(GetValues <object>(production.Token.Id));
 }
示例#38
0
 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);
             }
         }
     }
 }
示例#39
0
        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]);
                }
            }
        }
示例#40
0
        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]);
                }
            }
        }
示例#41
0
 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);
                 }
             }
             );
         }
     }
     );
 }
示例#42
0
 public static void ClearRules(IProductionRule[][] rules)
 {
     ApplyToRules(x => x.ClearScore(), rules);
 }