예제 #1
0
 public void Build(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
 {
     /* *
      * After much of the static analysis has been completed on the grammar, it's now time to generate the parser's full state transition detail.
      * */
     BuildGetValidSyntaxCore(compiler, parserBuilder, identityManager);
 }
예제 #2
0
 public void Build2(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
 {
     BuildCullAmbiguitiesCore(compiler, parserBuilder, identityManager);
     BuildGetValidSyntax(compiler, parserBuilder, identityManager);
     BuildDebuggerDisplayForSymbols(compiler, parserBuilder, identityManager);
     BuildVisitorModel(compiler, identityManager);
     BuildCullAmbiguities(compiler, parserBuilder, identityManager);
 }
예제 #3
0
        private void BuildGetValidSyntaxCore(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            var targetClassPartial = parserBuilder.ParserClass.Parts.Add();

            this._getValidSyntaxMethodImpl         = targetClassPartial.Methods.Add(new TypedName("GetValidSyntax", compiler.LexicalSymbolModel.ValidSymbols));
            this._getValidSyntaxMethod             = parserBuilder.ParserInterface.Methods.Add(new TypedName("GetValidSyntax", compiler.LexicalSymbolModel.ValidSymbols));
            this._getValidSyntaxMethodInternalImpl =
                targetClassPartial.Methods.Add(
                    new TypedName("GetValidSyntaxInternal", compiler.LexicalSymbolModel.ValidSymbols),
                    new TypedNameSeries(
                        new TypedName("state", RuntimeCoreType.Int32, identityManager),
                        new TypedName("ruleContext", compiler.RuleSymbolBuilder.ILanguageRuleSymbol),
                        new TypedName("initialPass", RuntimeCoreType.Boolean, identityManager)));
        }
예제 #4
0
        private void BuildCullAmbiguitiesCore(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0;

            if (!lexicallyAmbiguousModel)
            {
                return;
            }
            this._cullAmbiguities = this._getValidSyntaxMethodInternalImpl
                                    .Parent
                                    .Methods
                                    .Add(
                new TypedName("CullAmbiguitiesFrom", compiler.LexicalSymbolModel.ValidSymbols),
                new TypedNameSeries(
                    new TypedName("unambiguousSource", compiler.LexicalSymbolModel.ValidSymbols)));
            var allAmbiguities = compiler.LexicalSymbolModel.GenerateSymbolstoreVariation(new GrammarVocabulary(compiler.GrammarSymbols, compiler._GrammarSymbols.AmbiguousSymbols.ToArray()), "AllAmbiguities", string.Format("Returns a @s:{0}; value that represents all ambiguous identities.", compiler.LexicalSymbolModel.ValidSymbols.Name));

            allAmbiguities.Name          = "AllAmbiguities";
            this._AllAmbiguitiesField    = allAmbiguities;
            _cullAmbiguities.AccessLevel = AccessLevelModifiers.Public;
        }
예제 #5
0
        private void BuildCullAmbiguities(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0;

            if (!lexicallyAmbiguousModel)
            {
                return;
            }
            var runningAmbiguities = this._cullAmbiguities.Locals.Add(
                new TypedName("runningAmbiguities", compiler.LexicalSymbolModel.ValidSymbols), new DefaultValueExpression(compiler.LexicalSymbolModel.ValidSymbols));
            var resultAmbiguities = this._cullAmbiguities.Locals.Add(
                new TypedName("resultAmbiguities", compiler.LexicalSymbolModel.ValidSymbols), new DefaultValueExpression(compiler.LexicalSymbolModel.ValidSymbols));
            var unambiguousSource = this._cullAmbiguities.Parameters["unambiguousSource"];

            this._cullAmbiguities.Comment("Remove the ambiguities that are currently present, a larger multiple-symbol ambiguity may trump what was there due to the follow-union.");
            this._cullAmbiguities.Assign((IMemberReferenceExpression)unambiguousSource.GetReference(), AssignmentOperation.BitwiseExclusiveOrAssign, unambiguousSource.GetReference().BitwiseAnd(_AllAmbiguitiesField.GetReference()));
            bool first = true;

            foreach (var ambiguity in compiler._GrammarSymbols.AmbiguousSymbols)
            {
                var ambiguityDetail          = compiler.AmbiguityDetail[ambiguity];
                IBlockStatementParent target = this._cullAmbiguities;
                if (first)
                {
                    first = false;
                }
                else
                {
                    target = target.If(runningAmbiguities.GetReference().BitwiseAnd(ambiguityDetail.AmbiguityKeyReference.GetReference()).InequalTo(ambiguityDetail.AmbiguityKeyReference.GetReference()));
                }
                var assignmentCheck = target.If(unambiguousSource.BitwiseAnd(ambiguityDetail.AmbiguityKeyReference).EqualTo(ambiguityDetail.AmbiguityKeyReference));
                assignmentCheck.Assign(runningAmbiguities.GetReference(), AssignmentOperation.BitwiseOrAssign, ambiguityDetail.AmbiguityKeyReference.GetReference());
                assignmentCheck.Assign(resultAmbiguities.GetReference(), AssignmentOperation.BitwiseOrAssign, ambiguityDetail.AmbiguityReference.GetReference());
            }
            _cullAmbiguities.Return(resultAmbiguities.GetReference());
        }
예제 #6
0
        private void BuildGetValidSyntax(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0;
            var  advanceAdapters         =
                compiler
                .AdvanceMachines.Values
                .Select(k => k.All)
                .DefaultIfEmpty().Aggregate(
                    (a, b) =>
                    a.Concat(b));

            if (advanceAdapters == null)
            {
                advanceAdapters = new PredictionTreeDFAdapter[0];
            }
            var adapters              = compiler.FollowAdapters.Select(k => k.Value.AssociatedState).Concat(compiler.AllRuleAdapters.Select(k => k.Value.AssociatedState)).Concat(advanceAdapters.DefaultIfEmpty().Where(k => k != null).Select(k => k.AssociatedState)).Distinct().OrderBy(k => k.StateValue).ToArray();
            var distinctStateValues   = adapters.Select(k => k.StateValue).Distinct().ToArray();
            var stateSymbolStoreEntry =
                (from state in adapters
                 /* Since the other adapters are state-machines derived from the projection of a given state of a rule, normal adapters (derived from non-expanded lookahead) must be aggregated */
                 join normalAdapter in compiler.AllRuleAdapters on state equals normalAdapter.Value.AssociatedState into normalVariantSet
                 from normalAdapter in normalVariantSet.DefaultIfEmpty()
                 let fc = (normalAdapter.Value == null || normalAdapter.Value.OutgoingTransitions.Count == 0 || normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Count == 0) ? state.OutTransitions.FullCheck : normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate)
                          group new { State = state, Grammar = fc, GrammarStore = compiler.LexicalSymbolModel.GenerateSymbolstoreVariation(fc) } by new { Grammar = fc, IsEdge = state.IsEdge }).ToDictionary(k => k.Key, v => v.ToArray());
            var stateParam  = _getValidSyntaxMethodInternalImpl.Parameters["state"];
            var ruleContext = _getValidSyntaxMethodInternalImpl.Parameters["ruleContext"];
            var initialPass = _getValidSyntaxMethodInternalImpl.Parameters["initialPass"];

            if (!lexicallyAmbiguousModel)
            {
                _getValidSyntaxMethodInternalImpl.Parameters.Remove(initialPass);
                initialPass = null;
            }

            _getValidSyntaxMethodImpl.AccessLevel = AccessLevelModifiers.Public;

            var getSyntaxMethodImplInvocation = _getValidSyntaxMethodInternalImpl.GetReference().Invoke(parserBuilder._StateImpl.GetReference(), parserBuilder._CurrentContextImpl.GetReference());

            _getValidSyntaxMethodImpl.Return(getSyntaxMethodImplInvocation);
            if (lexicallyAmbiguousModel)
            {
                getSyntaxMethodImplInvocation.Arguments.Add(IntermediateGateway.TrueValue);
            }
            ITypedLocalMember pushAmbiguityContext = null;

            if (lexicallyAmbiguousModel)
            {
                pushAmbiguityContext = _getValidSyntaxMethodInternalImpl.Locals.Add(
                    new TypedName("pushAmbiguityContext", RuntimeCoreType.Boolean, identityManager),
                    IntermediateGateway.FalseValue);
            }

            ITypedLocalMember validResult = null;

            if (lexicallyAmbiguousModel)
            {
                validResult = _getValidSyntaxMethodInternalImpl.Locals.Add(
                    new TypedName("result", compiler.LexicalSymbolModel.ValidSymbols),
                    this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression());
            }

            var switchStatement = this._getValidSyntaxMethodInternalImpl.Switch(stateParam.GetReference());

            foreach (var uniqueGrammarSet in stateSymbolStoreEntry.Keys)
            {
                var           currentSet   = stateSymbolStoreEntry[uniqueGrammarSet];
                IExpression[] stateIndices = new IExpression[currentSet.Length];
                currentSet = currentSet.OrderBy(k => k.State.StateValue).ToArray();
                for (int stateIndex = 0; stateIndex < currentSet.Length; stateIndex++)
                {
                    stateIndices[stateIndex] = currentSet[stateIndex].State.StateValue.ToPrimitive();
                }

                var currentCase = switchStatement.Case(stateIndices);
                currentCase.Comment(currentSet[0].Grammar.ToString());
                if (uniqueGrammarSet.IsEdge)
                {
                    //Inject logic to look up in the stack.
                    if (lexicallyAmbiguousModel)
                    {
                        var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue));
                        nullCheck.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference()), IntermediateGateway.FalseValue)));
                        nullCheck.If(initialPass.GetReference())
                        .Assign(pushAmbiguityContext.GetReference(), IntermediateGateway.TrueValue);
                        nullCheck.CreateNext();
                        nullCheck.Next.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference());
                    }
                    else
                    {
                        var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue));
                        nullCheck.Return(currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference()))));
                        nullCheck.CreateNext();
                        nullCheck.Next.Return(currentSet[0].GrammarStore.GetReference());
                    }
                }
                else if (lexicallyAmbiguousModel)
                {
                    currentCase.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference());
                }
                else
                {
                    currentCase.Return(currentSet[0].GrammarStore.GetReference());
                }
            }
            if (lexicallyAmbiguousModel)
            {
                this._getValidSyntaxMethodInternalImpl.If(pushAmbiguityContext.GetReference())
                .Assign(validResult.GetReference(), AssignmentOperation.BitwiseOrAssign,
                        _cullAmbiguities.GetReference().Invoke(validResult.GetReference()));
            }
            if (lexicallyAmbiguousModel)
            {
                this._getValidSyntaxMethodInternalImpl.Return(validResult.GetReference());
            }
            else
            {
                this._getValidSyntaxMethodInternalImpl.Return(this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression());
            }
            this._getValidSyntaxMethodInternalImpl.AccessLevel = AccessLevelModifiers.Private;
        }
예제 #7
0
        private void BuildDebuggerDisplayForSymbols(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager)
        {
            var extensionsClass = compiler.RuleSymbolBuilder.ILanguageRuleSymbol.Assembly.DefaultNamespace.Parts.Add().Classes.Add("{0}Extensions", compiler.Source.Options.AssemblyName);

            extensionsClass.AccessLevel     = AccessLevelModifiers.Internal;
            extensionsClass.SpecialModifier = SpecialClassModifier.Static;
            this.ExtensionsClass            = extensionsClass;
            var symbolDebuggerDisplay = extensionsClass.Methods.Add(
                new TypedName("SymbolDebuggerDisplay", RuntimeCoreType.String, identityManager),
                new TypedNameSeries(
                    new TypedName("symbol", compiler.SymbolStoreBuilder.Identities)));
            var symbol = symbolDebuggerDisplay.Parameters["symbol"];

            var constantEntries = (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarConstantEntrySymbol>()
                                   where !(s.Source is IOilexerGrammarTokenEofEntry)
                                   let literalItem = s.Source.Branches[0][0] as ILiteralTokenItem
                                                     where literalItem != null
                                                     orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString()
                                   select new { LiteralItem = literalItem, Symbol = s }).ToArray();
            var constantItems =
                (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarConstantItemSymbol>()
                 let literalItem = s.SourceItem
                                   orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString()
                 select new { LiteralItem = literalItem, Symbol = s }).ToArray();

            var ambiguousItems =
                (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarAmbiguousSymbol>()
                 let literalConstantEntry = (IGrammarConstantEntrySymbol)s.FirstOrDefault(aSym => aSym is IGrammarConstantEntrySymbol && constantEntries.Any(ce => ce.Symbol == aSym))
                                            let literalConstantItem = (IGrammarConstantItemSymbol)s.FirstOrDefault(aSym => aSym is IGrammarConstantItemSymbol && constantItems.Any(ci => ci.Symbol == aSym))
                                                                      where literalConstantEntry != null || literalConstantItem != null
                                                                      let literalItem = literalConstantEntry != null ? literalConstantEntry.Source.Branches[0][0] as ILiteralTokenItem : literalConstantItem.SourceItem
                                                                                        orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString()
                 select new { LiteralItem = literalItem, Symbol = s }).ToArray();

            var mainSwitch = symbolDebuggerDisplay.Switch(symbol.GetReference());

            //compiler.TokenSymbolDetail
            foreach (var constantEntry in constantEntries)
            {
                var symbolDet   = compiler.TokenSymbolDetail[constantEntry.Symbol];
                var currentCase = mainSwitch.Case(symbolDet.Identity.GetReference());
                var fN          = symbolDet.Symbol.Source.FileName;
                if (fN.ToLower().StartsWith(compiler.Source.RelativeRoot))
                {
                    currentCase.Comment(string.Format("In .{0} on line {1}, column {2}", fN.Substring(compiler.Source.RelativeRoot.Length), constantEntry.LiteralItem.Line, constantEntry.LiteralItem.Column));
                }
                else
                {
                    currentCase.Comment(string.Format("In {0} on line {1}, column {2}", fN, constantEntry.LiteralItem.Line, constantEntry.LiteralItem.Column));
                }
                currentCase.Return(constantEntry.LiteralItem.Value.ToString().ToPrimitive());
            }
            foreach (var constantItem in constantItems)
            {
                var symbolDet   = compiler.TokenSymbolDetail[constantItem.Symbol];
                var currentCase = mainSwitch.Case(symbolDet.Identity.GetReference());
                var fN          = symbolDet.Symbol.Source.FileName;
                if (fN.ToLower().StartsWith(compiler.Source.RelativeRoot))
                {
                    currentCase.Comment(string.Format("In .{0} on line {1}, column {2}", fN.Substring(compiler.Source.RelativeRoot.Length), constantItem.LiteralItem.Line, constantItem.LiteralItem.Column));
                }
                else
                {
                    currentCase.Comment(string.Format("In {0} on line {1}, column {2}", fN, constantItem.LiteralItem.Line, constantItem.LiteralItem.Column));
                }
                currentCase.Return(constantItem.LiteralItem.Value.ToString().ToPrimitive());
            }

            foreach (var ambiguousItem in ambiguousItems)
            {
                var           identityField    = compiler.LexicalSymbolModel.GetIdentitySymbolField(ambiguousItem.Symbol);
                var           currentCase      = mainSwitch.Case(identityField.GetReference());
                StringBuilder ambiguityBuilder = new StringBuilder();
                ambiguityBuilder.Append("Ambiguity {");
                bool first = true;
                foreach (var ambigSymbol in ambiguousItem.Symbol)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        ambiguityBuilder.Append(", ");
                    }
                    ambiguityBuilder.Append(ambigSymbol.ElementName);
                }
                ambiguityBuilder.Append("} :");
                ambiguityBuilder.Append(ambiguousItem.LiteralItem.Value.ToString().ToPrimitive());
                currentCase.Return(ambiguityBuilder.ToString().ToPrimitive());
            }

            mainSwitch.Case(true).Return(symbol.GetReference().GetMethod("ToString").Invoke());

            this.SymbolDebuggerDisplay        = symbolDebuggerDisplay;
            symbolDebuggerDisplay.AccessLevel = AccessLevelModifiers.Public;
            compiler.SymbolStoreBuilder.Identities.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute)))
            {
                string.Format("{{{0}.{1}.{2}(this),nq}}", extensionsClass.NamespaceName, extensionsClass.Name, symbolDebuggerDisplay.Name)
            });
            compiler.FixedTokenBaseBuilder.LanguageFixedToken.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute)))
            {
                string.Format("{{{0}.{1}.{2}(Identity),nq}}", extensionsClass.NamespaceName, extensionsClass.Name, symbolDebuggerDisplay.Name)
            });
            compiler.VariableTokenBaseBuilder.LanguageVariableToken.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute)))
            {
                "{Value,nq}"
            });
            compiler.RootRuleBuilder.LanguageRuleRoot.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute)))
            {
                "{Context.Identity,nq}: {Context}"
            });
        }