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);
        }
Example #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);
         }
     }
 }
Example #3
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;
     }
 }
        private static IProductionRuleCaptureStructure BuildStructureFor(OilexerGrammarProductionRuleEntry entry, IProductionRuleSeries expressionSeries, IProductionRule expression, IOilexerGrammarFile source)
        {
            IProductionRuleCaptureStructure result = new ProductionRuleCaptureStructure(entry);

            foreach (var item in expression)
            {
                var current = BuildStructureFor(entry, expressionSeries, expression, item, source);
                result = result.Concat(current);
            }
            return(result);
        }
Example #5
0
        public static void ReplaceReferences(IOilexerGrammarFile source, IOilexerGrammarProductionRuleEntry target, IDictionary <IProductionRuleItem, IProductionRuleItem> elementToElementList)
        {
            OilexerGrammarProductionRuleEntry r            = (OilexerGrammarProductionRuleEntry)(target);
            IProductionRuleSeries             resultSeries = ReplaceReferences(source, ((IProductionRuleSeries)(r)).ToArray(), elementToElementList);

            r.Clear();
            foreach (var rule in resultSeries)
            {
                r.Add(rule);
            }
        }
Example #6
0
 internal static void ExpandTemplates(this IOilexerGrammarProductionRuleEntry entry, IList <IOilexerGrammarTokenEntry> availableStock, OilexerGrammarFile file, ICompilerErrorCollection errors)
 {
     while (entry.NeedsExpansion())
     {
         OilexerGrammarProductionRuleEntry e    = ((OilexerGrammarProductionRuleEntry)(entry));
         IProductionRuleSeries             iprs = entry.ExpandTemplates(availableStock, entry, file, errors);
         e.Clear();
         foreach (IProductionRule ipr in iprs)
         {
             e.Add(ipr);
         }
     }
 }
Example #7
0
        internal static void Expand(this IPreprocessorAddRuleDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors)
        {
            string search = directive.InsertTarget;

            if (search != null && search != string.Empty)
            {
                OilexerGrammarProductionRuleEntry foundItem = null;
                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;
                        }
                        else if (ipri is IRuleReferenceProductionRuleItem)
                        {
                            foundItem = (OilexerGrammarProductionRuleEntry)((IRuleReferenceProductionRuleItem)(ipri)).Reference;
                        }
                    }
                }
                if (foundItem == null)
                {
                    foreach (IOilexerGrammarEntry ie in file)
                    {
                        if (ie is OilexerGrammarProductionRuleEntry && ((OilexerGrammarProductionRuleEntry)ie).Name == search)
                        {
                            foundItem = ie as OilexerGrammarProductionRuleEntry;
                            break;
                        }
                    }
                }
                if (foundItem == null)
                {
                    errors.SourceError(OilexerGrammarCore.CompilerErrors.UndefinedAddRuleTarget, new LineColumnPair(directive.Line, directive.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), string.Join <IProductionRule>(" | ", directive.Rules), search);
                    return;
                }
                foreach (IProductionRule ipr in directive.Rules)
                {
                    foundItem.Add(ipr.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors));
                }
            }
        }
Example #8
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);
                }
            }
        }
        private static IProductionRuleCaptureStructuralItem BuildStructureFor(OilexerGrammarProductionRuleEntry entry, IProductionRuleSeries expressionSeries, IProductionRule expression, IProductionRuleItem item, IOilexerGrammarFile source)
        {
            IProductionRuleCaptureStructuralItem result = null;

            if (item is IProductionRuleGroupItem)
            {
                var ruleGroup = ((IProductionRuleGroupItem)(item));
                if (!ruleGroup.Name.IsEmptyOrNull() && AllAreUnnamedEquivalents(ruleGroup))
                {
                    SetAllNames(ruleGroup, ruleGroup.Name);
                }
                result = BuildStructureFor(entry, ruleGroup, source);
                if (result.ResultType == ResultedDataType.None && !item.Name.IsEmptyOrNull())
                {
                    if (ruleGroup.Count == 1 && ruleGroup[0].Count == 1)
                    {
                        var singleItem = ruleGroup[0][0];
                        if (singleItem is ILiteralCharReferenceProductionRuleItem)
                        {
                            if (singleItem.RepeatOptions == ScannableEntryItemRepeatInfo.None && ruleGroup.RepeatOptions == ScannableEntryItemRepeatInfo.None)
                            {
                                result.ResultType = ResultedDataType.Character;
                            }
                            else
                            {
                                result.ResultType = ResultedDataType.String;
                            }
                        }
                        else
                        {
                            result.ResultType = ResultedDataType.String;
                        }
                    }
                    else
                    {
                        result.ResultType = ResultedDataType.String;
                    }
                }
                else if (item.Name.IsEmptyOrNull())
                {
                    result.ResultType = ResultedDataType.PassThrough;
                }
                ((ControlledCollection <IProductionRuleSource>)(result.Sources)).baseList.Add(item);
            }
            else if (item is ILiteralReferenceProductionRuleItem)
            {
                var literalRefItem = (ILiteralReferenceProductionRuleItem)item;
                var inlinedRef     = ((InlinedTokenEntry)(literalRefItem.Source));
                result = new ProductionRuleLiteralTokenItemReferenceStructuralItem(literalRefItem.Source, literalRefItem, entry);
                if (inlinedRef.CaptureKind == RegularCaptureType.Transducer)
                {
                    result.ResultType = ResultedDataType.EnumerationItem;
                }
                else if (inlinedRef.CaptureKind == RegularCaptureType.ContextfulTransducer)
                {
                    result.ResultType = ResultedDataType.FlagEnumerationItem;
                }
            }
            else if (item is ITokenReferenceProductionRuleItem)
            {
                var tokenRefItem = ((ITokenReferenceProductionRuleItem)(item));
                var inlinedRef   = ((InlinedTokenEntry)(tokenRefItem.Reference));
                result = new ProductionRuleTokenReferenceStructuralItem((ITokenReferenceProductionRuleItem)item, entry);
                if (inlinedRef.CaptureKind == RegularCaptureType.Transducer)
                {
                    result.ResultType = ResultedDataType.Enumeration;
                }
                else
                {
                    result.ResultType = ResultedDataType.ImportType;
                }
            }
            else if (item is IRuleReferenceProductionRuleItem)
            {
                var ruleItem = (IRuleReferenceProductionRuleItem)item;
                result = new ProductionRuleCaptureReferenceStructuralItem(ruleItem, entry);
            }
            Deform(item, result, expression);

            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();
            }
        }
        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 IProductionRuleCaptureStructure BuildStructureFor(OilexerGrammarProductionRuleEntry entry, IOilexerGrammarFile source)
 {
     return(BuildStructureFor(entry, entry, source));
 }
 public ProductionRuleCaptureStructure(OilexerGrammarProductionRuleEntry owner)
 {
     this.Sources = new ControlledCollection <IProductionRuleSource>();
     this.owner   = owner;
 }