private static IProductionRuleCaptureStructure BuildStructureFor(OilexerGrammarProductionRuleEntry entry, IProductionRuleSeries expressionSeries, IOilexerGrammarFile source) { IProductionRuleCaptureStructure result = null; HashList <HashList <string> > currentResultVariants = new HashList <HashList <string> >(); foreach (var expression in expressionSeries) { var current = BuildStructureFor(entry, expressionSeries, expression, source); if (result == null) { result = current; } else { result = result.Union(current); } var dataSet = new HashList <string>(current.Keys); if (!currentResultVariants.Any(k => k.SequenceEqual(dataSet))) { currentResultVariants.Add(dataSet); } } foreach (var variant in currentResultVariants) { result.Structures.Add(variant); } if (expressionSeries == entry) { ((ControlledCollection <IProductionRuleSource>)result.Sources).baseList.Add(entry); } result.ResultedTypeName = string.Format("{0}{1}{2}", source.Options.RulePrefix, entry.Name, source.Options.RuleSuffix); return(result); }
internal static void ObtainReplacements(IProductionRuleCaptureStructure structure, Dictionary <IProductionRuleSource, IProductionRuleCaptureStructuralItem> result) { foreach (var element in structure.Keys) { ObtainReplacements(structure[element], result); } }
private static void Deform(IProductionRuleItem item, IProductionRuleCaptureStructuralItem structuralItem, IProductionRule owner) { /* * * Items reduced to their max are for recognizer sections.. * */ if (!(item is IProductionRuleGroupItem)) { if ((item.RepeatOptions.Options & ScannableEntryItemRepeatOptions.MaxReduce) == ScannableEntryItemRepeatOptions.MaxReduce && string.IsNullOrEmpty(item.Name)) { return; } switch (item.RepeatOptions.Options & (ScannableEntryItemRepeatOptions.OneOrMore | ScannableEntryItemRepeatOptions.ZeroOrMore | ScannableEntryItemRepeatOptions.ZeroOrOne)) { case ScannableEntryItemRepeatOptions.ZeroOrOne: structuralItem.Optional = true; break; case ScannableEntryItemRepeatOptions.ZeroOrMore: case ScannableEntryItemRepeatOptions.OneOrMore: switch (structuralItem.ResultType) { case ResultedDataType.ImportType: structuralItem.ResultType = ResultedDataType.ImportTypeList; break; } structuralItem.Optional = true; break; } } else { IProductionRuleCaptureStructure structure = (IProductionRuleCaptureStructure)structuralItem; var groupItem = (IProductionRuleGroupItem)item; switch (item.RepeatOptions.Options & (ScannableEntryItemRepeatOptions.OneOrMore | ScannableEntryItemRepeatOptions.ZeroOrMore | ScannableEntryItemRepeatOptions.ZeroOrOne)) { case ScannableEntryItemRepeatOptions.ZeroOrOne: structuralItem.Optional = true; break; case ScannableEntryItemRepeatOptions.ZeroOrMore: case ScannableEntryItemRepeatOptions.OneOrMore: foreach (var subItem in structure.Values) { switch (subItem.ResultType) { case ResultedDataType.ImportType: subItem.ResultType = ResultedDataType.ImportTypeList; break; } } structuralItem.Optional = true; break; } } }
public IProductionRuleCaptureStructure Union(IProductionRuleCaptureStructure second) { if (this.Count == 0) { return(second); } else if (second.Count == 0) { return(this); } var result = new ProductionRuleCaptureStructure(this.owner); var left = this.Keys.Except(second.Keys).ToArray(); var middle = this.Keys.Intersect(second.Keys).ToArray(); var right = second.Keys.Except(this.Keys).ToArray(); foreach (var element in left) { result._Add(element, this[element]); } foreach (var element in middle) { var leftElement = this[element]; var rightElement = second[element]; var middleElement = leftElement.Union(rightElement); result._Add(element, middleElement); } foreach (var element in right) { result._Add(element, second[element]); } if (this.ResultType == second.ResultType) { result.ResultType = this.ResultType; } else { result.ResultType = ResultedDataType.ComplexType; } result.ResultedTypeName = this.ResultedTypeName ?? second.ResultedTypeName; ((ControlledCollection <IProductionRuleSource>)(result.Sources)).AddRange(this.Sources.ToArray()); ((ControlledCollection <IProductionRuleSource>)(result.Sources)).AddRange(second.Sources.ToArray()); result.Optional = this.Optional || second.Optional; return(result); }
private static void BuildStructureConstructors(IProductionRuleCaptureStructure targetStructure, OilexerGrammarProductionRuleEntry structureRoot, ITypeIdentityManager identityManager) { int stateIndex = 0; foreach (var element in targetStructure.Values) { element.StateIndex = stateIndex++; } IEnumerable <IEnumerable <Tuple <IProductionRuleCaptureStructuralItem, bool> > > validVariations = new IEnumerable <Tuple <IProductionRuleCaptureStructuralItem, bool> > [0]; var firstOrDefSeries = (IProductionRuleSeries)targetStructure.Sources.FirstOrDefault(k => k is IProductionRuleSeries); var firstOrDefProductionRule = (IOilexerGrammarProductionRuleEntry)targetStructure.Sources.FirstOrDefault(k => k is IOilexerGrammarProductionRuleEntry); var optg = PickOptionalGroups(firstOrDefProductionRule == null ? firstOrDefSeries : firstOrDefProductionRule, targetStructure); foreach (var parameterSet in targetStructure.Structures) { var limitedSet = (from param in parameterSet join item in targetStructure.Keys on param equals item select new { Name = item, Item = targetStructure[item] }).ToArray(); var optionalSet = (from l in limitedSet where l.Item.Optional select l).ToArray(); if (limitedSet.Length > 0) { var parameterPermutations = VariateSeries(new LockedLinkedList <IProductionRuleCaptureStructuralItem>(from l in limitedSet select l.Item).First, optg).Distinct(); validVariations = validVariations.Concat(parameterPermutations); foreach (var variation in parameterPermutations) { bool[] parameterStateFlags = (from k in variation.ToArray() select k.Item2).ToArray(); List <string> parameterResult = new List <string>(); for (int parameterIndex = 0; parameterIndex < parameterStateFlags.Length; parameterIndex++) { if (parameterStateFlags[parameterIndex]) { var limitedEntry = limitedSet[parameterIndex]; parameterResult.Add(limitedEntry.Name); } } //if (!resultantParameterSets.Any(k => k.SequenceEqual(parameterResult))) // resultantParameterSets.Add(parameterResult); } } } List <IEnumerable <Tuple <IProductionRuleCaptureStructuralItem, bool> > > toRemove = new List <IEnumerable <Tuple <IProductionRuleCaptureStructuralItem, bool> > >(); var exclusiveDistinctions = (from set in validVariations.Distinct().ToArray() let parameters = from parameter in set where parameter.Item2 select parameter.Item1 orderby string.Join(string.Empty, from k in parameters select k.BucketName) select new HashList <IProductionRuleCaptureStructuralItem>(parameters)).Distinct(); var stateField = targetStructure.ResultClass.Fields.Add(new TypedName("state", identityManager.ObtainTypeReference(RuntimeCoreType.Int32))); var toStringMethod = targetStructure.ResultClass.Methods.Add(new TypedName("ToString", identityManager.ObtainTypeReference(RuntimeCoreType.String))); toStringMethod.AccessLevel = AccessLevelModifiers.Public; toStringMethod.IsOverride = true; var toStringStateSwitch = toStringMethod.Switch(stateField.GetReference()); toStringMethod.Return(identityManager.ObtainTypeReference(RuntimeCoreType.String).GetTypeExpression().GetField("Empty")); var formatMethod = identityManager.ObtainTypeReference(RuntimeCoreType.String).GetTypeExpression().GetMethod("Format"); foreach (var parameterSetVariation in exclusiveDistinctions) { TypedNameSeries currentCtorTNS = new TypedNameSeries(); int currentStateValue = 0; foreach (var parameterEntry in parameterSetVariation) { var parameterName = parameterEntry.BucketName; var currentElement = targetStructure[parameterName]; IType parameterType = null; switch (currentElement.ResultType) { case ResultedDataType.EnumerationItem: case ResultedDataType.Flag: parameterType = identityManager.ObtainTypeReference(RuntimeCoreType.Boolean); break; case ResultedDataType.Enumeration: IProductionRuleCaptureStructure enumStructure = (IProductionRuleCaptureStructure)currentElement; parameterType = enumStructure.AggregateSetEnum ?? enumStructure.ResultEnumSet[0]; break; case ResultedDataType.ComplexType: IProductionRuleCaptureStructure dualStructure = (IProductionRuleCaptureStructure)currentElement; parameterType = dualStructure.ResultInterface; break; case ResultedDataType.Counter: parameterType = identityManager.ObtainTypeReference(RuntimeCoreType.Int32); break; case ResultedDataType.Character: parameterType = identityManager.ObtainTypeReference(RuntimeCoreType.Char); break; case ResultedDataType.String: parameterType = identityManager.ObtainTypeReference(RuntimeCoreType.String); break; default: throw new InvalidOperationException("Unknown parameter type."); } currentStateValue |= (int)Math.Pow(2, parameterEntry.StateIndex); currentCtorTNS.Add(LowerFirstCharacter(parameterName), parameterType); } var currentCtor = targetStructure.ResultClass.Constructors.Add(currentCtorTNS); currentCtor.AccessLevel = AccessLevelModifiers.Public; currentCtor.Assign(stateField.GetReference(), currentStateValue.ToPrimitive()); var currentStateCase = toStringStateSwitch.Case(currentStateValue.ToPrimitive()); var currentInvocation = formatMethod.Invoke(); currentStateCase.Return(currentInvocation); var currentFormat = string.Empty.ToPrimitive(); currentInvocation.Arguments.Add(currentFormat); StringBuilder formatBuilder = new StringBuilder(); bool first = true; int currentParamIndex = 0; foreach (var parameterEntry in parameterSetVariation) { if (first) { first = false; } else { formatBuilder.Append(", "); } formatBuilder.AppendFormat("{{{0}}}", currentParamIndex++); var parameterName = parameterEntry.BucketName; var currentElement = targetStructure[parameterName]; IIntermediateFieldMember currentField = currentElement.AssociatedField; currentInvocation.Arguments.Add(currentField.GetReference()); currentCtor.Assign(currentField.GetReference(), currentCtor.Parameters[LowerFirstCharacter(parameterName)].GetReference()); } currentFormat.Value = formatBuilder.ToString(); } }
private static List <IProductionRuleCaptureStructuralItem> PollGroup(IProductionRuleSeries series, IProductionRuleCaptureStructure structure) { List <IProductionRuleCaptureStructuralItem> result = new List <IProductionRuleCaptureStructuralItem>(); foreach (var expression in series) { foreach (var item in expression) { var firstOrDef = structure.Values.FirstOrDefault(k => k.Sources.Contains(item)); if (firstOrDef != null) { result.Add(firstOrDef); } else if (item is IProductionRuleGroupItem) { result.AddRange(PollGroup((IProductionRuleGroupItem)item, structure)); } } } return(result); }
private static Dictionary <IProductionRuleGroupItem, List <IProductionRuleCaptureStructuralItem> > PickOptionalGroups(IProductionRuleSeries series, IProductionRuleCaptureStructure structure) { Dictionary <IProductionRuleGroupItem, List <IProductionRuleCaptureStructuralItem> > result = new Dictionary <IProductionRuleGroupItem, List <IProductionRuleCaptureStructuralItem> >(); foreach (var expression in series) { foreach (var item in expression) { if (item is IProductionRuleGroupItem) { var groupItem = (IProductionRuleGroupItem)item; if ((item.RepeatOptions.Options & ScannableEntryItemRepeatOptions.ZeroOrMore) == ScannableEntryItemRepeatOptions.ZeroOrMore || (item.RepeatOptions.Options & ScannableEntryItemRepeatOptions.ZeroOrOne) == ScannableEntryItemRepeatOptions.ZeroOrOne || (item.RepeatOptions.Options & ScannableEntryItemRepeatOptions.Specific) == ScannableEntryItemRepeatOptions.Specific && (!item.RepeatOptions.Min.HasValue || item.RepeatOptions.Min.Value == 0)) { /* * * Found an optional token group, now to search * within to see what we have inside. * */ var firstOrDef = structure.Values.FirstOrDefault(k => k.Sources.Contains(item)); if (firstOrDef != null) { result.Add(groupItem, new List <IProductionRuleCaptureStructuralItem>() { firstOrDef }); } else { var currentSet = PollGroup(groupItem, structure); if (currentSet.Count > 0) { result.Add(groupItem, currentSet); } } } else { var subResult = PickOptionalGroups(groupItem, structure); foreach (var element in subResult.Keys) { if (result.ContainsKey(element)) { result[element].AddRange(subResult[element]); } } } } } } return(result); }
internal static SelectiveTuple <Tuple <IIntermediateClassType, IIntermediateInterfaceType>, IIntermediateEnumType, Tuple <IIntermediateEnumType, IIntermediateEnumType[]> > CreateProgramStructure(IProductionRuleCaptureStructure targetStructure, IIntermediateNamespaceDeclaration owner, OilexerGrammarProductionRuleEntry structureRoot) { switch (targetStructure.ResultType) { case ResultedDataType.Enumeration: bool isFlagSet = targetStructure.Values.All(k => k.ResultType == ResultedDataType.FlagEnumerationItem); bool useBucketName = targetStructure != structureRoot.CaptureStructure; if (targetStructure.Count > sizeof(SlotType) * 8 && isFlagSet) { var chunkedSets = targetStructure.Values.ToArray().Chunk(sizeof(SlotType) * 8); IIntermediateEnumType[] resultSet = new IIntermediateEnumType[chunkedSets.Length]; IIntermediateEnumType aggregateSet = null; aggregateSet = owner.Parts.Add().Enums.Add("{0}Cases", targetStructure.ResultedTypeName); for (int chunkIndex = 0; chunkIndex < chunkedSets.Length; chunkIndex++) { var chunkSet = chunkedSets[chunkIndex]; int fieldIndex = 0; var resultEnum = resultSet[chunkIndex] = owner.Parts.Add().Enums.Add("Valid{0}Set{1}", useBucketName ? targetStructure.BucketName : structureRoot.Name, (chunkIndex + 1)); resultEnum.AccessLevel = AccessLevelModifiers.Public; resultEnum.Fields.Add("None"); #if x86 resultEnum.ValueType = EnumerationBaseType.UInt32; #elif x64 resultEnum.ValueType = EnumerationBaseType.UInt64; #endif foreach (var element in chunkSet) { switch (element.ResultType) { case ResultedDataType.EnumerationItem: resultEnum.Fields.Add(element.BucketName); break; case ResultedDataType.FlagEnumerationItem: var resultField = resultEnum.Fields.Add(element.BucketName, (SlotType)Math.Pow(2, fieldIndex++)); break; default: throw new InvalidOperationException("Enums are supposed to yield an " + "enumeration, result element is of an invalid type."); } aggregateSet.Fields.Add(element.BucketName); } } targetStructure.ResultEnumSet = resultSet; targetStructure.AggregateSetEnum = aggregateSet; return(new SelectiveTuple <Tuple <IIntermediateClassType, IIntermediateInterfaceType>, IIntermediateEnumType, Tuple <IIntermediateEnumType, IIntermediateEnumType[]> >(Tuple.Create(aggregateSet, resultSet))); } else { IIntermediateEnumType resultEnum = null; IIntermediateEnumType aggregateSet = null; if (isFlagSet) { aggregateSet = owner.Enums.Add("{0}Cases", targetStructure.ResultedTypeName); resultEnum = owner.Enums.Add("Valid{0}", useBucketName ? targetStructure.BucketName : structureRoot.Name); } else { resultEnum = owner.Enums.Add(targetStructure.ResultedTypeName); } resultEnum.AccessLevel = AccessLevelModifiers.Public; int numNonFlags = (from f in targetStructure.Values where f.ResultType == ResultedDataType.EnumerationItem select f).Count(); int flagFieldIndex = isFlagSet ? 0 : (int)(Math.Ceiling(Math.Log10(numNonFlags) / Math.Log10(2))); int regularFieldIndex = 1; #if x86 resultEnum.ValueType = EnumerationBaseType.UInt32; #elif x64 resultEnum.ValueType = EnumerationBaseType.UInt64; #endif resultEnum.Fields.Add("None", (SlotType)0); foreach (var element in targetStructure) { switch (element.Value.ResultType) { case ResultedDataType.EnumerationItem: resultEnum.Fields.Add(element.Value.BucketName, (SlotType)regularFieldIndex++); break; case ResultedDataType.FlagEnumerationItem: var resultField = resultEnum.Fields.Add(element.Value.BucketName, (SlotType)Math.Pow(2, flagFieldIndex++)); break; default: throw new InvalidOperationException("Enums are supposed to yield an " + "enumeration, result element is an of invalid type."); } if (isFlagSet) { aggregateSet.Fields.Add(element.Value.BucketName); } } targetStructure.ResultEnumSet = new IIntermediateEnumType[1] { resultEnum }; targetStructure.AggregateSetEnum = aggregateSet; return(new SelectiveTuple <Tuple <IIntermediateClassType, IIntermediateInterfaceType>, IIntermediateEnumType, Tuple <IIntermediateEnumType, IIntermediateEnumType[]> >(resultEnum)); } case ResultedDataType.ComplexType: var resultClass = owner.Classes.Add(targetStructure.ResultedTypeName); var resultInterface = owner.Interfaces.Add("I{0}", targetStructure.ResultedTypeName); resultInterface.AccessLevel = AccessLevelModifiers.Public; resultClass.AccessLevel = AccessLevelModifiers.Internal; resultClass.ImplementedInterfaces.ImplementInterfaceQuick(resultInterface); targetStructure.ResultClass = resultClass; targetStructure.ResultInterface = resultInterface; foreach (var element in targetStructure.Values) { IType simpleType; switch (element.ResultType) { case ResultedDataType.Enumeration: case ResultedDataType.ComplexType: IProductionRuleCaptureStructure cts = element as IProductionRuleCaptureStructure; if (cts == null) { throw new InvalidOperationException("Complex types are supposed to be IProductionRuleCaptureStructure instances."); } cts.ResultedTypeName = string.Format("{0}{1}", targetStructure.ResultedTypeName, cts.Name); var currentResult = CreateProgramStructure(cts, owner, structureRoot); currentResult.Visit( dualClassInterface => { var interfaceProp = resultInterface.Properties.Add(new TypedName(cts.BucketName, dualClassInterface.Item2), true, false); var classProp = resultClass.Properties.Add(new TypedName(cts.BucketName, dualClassInterface.Item2), true, false); classProp.AccessLevel = AccessLevelModifiers.Public; var classField = resultClass.Fields.Add(new TypedName("_{0}", dualClassInterface.Item2, LowerFirstCharacter(cts.BucketName))); classField.AccessLevel = AccessLevelModifiers.Private; classProp.GetMethod.Return(classField.GetReference()); cts.AssociatedField = classField; }, enumeration => { var interfaceProp = resultInterface.Properties.Add(new TypedName(cts.BucketName, enumeration), true, false); var classProp = resultClass.Properties.Add(new TypedName(cts.BucketName, enumeration), true, false); classProp.AccessLevel = AccessLevelModifiers.Public; var classField = resultClass.Fields.Add(new TypedName("_{0}", enumeration, LowerFirstCharacter(cts.BucketName))); classField.AccessLevel = AccessLevelModifiers.Private; classProp.GetMethod.Return(classField.GetReference()); cts.AssociatedField = classField; }, aggregateWithValidSet => { var enumeration = aggregateWithValidSet.Item1; var interfaceProp = resultInterface.Properties.Add(new TypedName(cts.BucketName, enumeration), true, false); var classProp = resultClass.Properties.Add(new TypedName(cts.BucketName, enumeration), true, false); classProp.AccessLevel = AccessLevelModifiers.Public; var classField = resultClass.Fields.Add(new TypedName("_{0}", enumeration, LowerFirstCharacter(cts.BucketName))); classField.AccessLevel = AccessLevelModifiers.Private; classProp.GetMethod.Return(classField.GetReference()); cts.AssociatedField = classField; }, () => { throw new InvalidOperationException("Complex types are supposed to yield a complex type, result type unknown"); }); break; case ResultedDataType.EnumerationItem: case ResultedDataType.Flag: simpleType = owner.IdentityManager.ObtainTypeReference(RuntimeCoreType.Boolean); goto simpleType; case ResultedDataType.Counter: simpleType = owner.IdentityManager.ObtainTypeReference(RuntimeCoreType.Int32); goto simpleType; case ResultedDataType.Character: simpleType = owner.IdentityManager.ObtainTypeReference(RuntimeCoreType.Char); goto simpleType; case ResultedDataType.String: simpleType = owner.IdentityManager.ObtainTypeReference(RuntimeCoreType.String); goto simpleType; default: break; } continue; simpleType: { var interfaceProp = resultInterface.Properties.Add(new TypedName(element.BucketName, simpleType), true, false); var classProp = resultClass.Properties.Add(new TypedName(element.BucketName, simpleType), true, false); classProp.AccessLevel = AccessLevelModifiers.Public; var classField = resultClass.Fields.Add(new TypedName("_{0}", simpleType, LowerFirstCharacter(element.BucketName))); classField.AccessLevel = AccessLevelModifiers.Private; classProp.GetMethod.Return(classField.GetReference()); element.AssociatedField = classField; } } BuildStructureConstructors(targetStructure, structureRoot, owner.IdentityManager); return(new SelectiveTuple <Tuple <IIntermediateClassType, IIntermediateInterfaceType>, IIntermediateEnumType, Tuple <IIntermediateEnumType, IIntermediateEnumType[]> >(Tuple.Create(resultClass, resultInterface))); case ResultedDataType.PassThrough: return(null); default: throw new InvalidOperationException(); } }
internal static Dictionary <IProductionRuleSource, IProductionRuleCaptureStructuralItem> ObtainReplacements(IProductionRuleCaptureStructure structure) { Dictionary <IProductionRuleSource, IProductionRuleCaptureStructuralItem> result = new Dictionary <IProductionRuleSource, IProductionRuleCaptureStructuralItem>(); ObtainReplacements(structure, result); return(result); }