Example #1
0
        private static void ShowSimilarStates(LanguageData data)
        {
            int stateCount = data.ParserStates.Length;
            var grammar = data.Grammar;
            int[] terms = (from s in grammar.Symbols where s.IsTerminal select s.Index).ToArray();
            var table = data.ParserActionTable;
            var unpartitioned = Enumerable.Range(0, stateCount).ToList();
            var categories = new List<List<int>>();

            while (unpartitioned.Count != 0)
            {
                int p = unpartitioned[0];
                unpartitioned.RemoveAt(0);
                var category = new List<int> { p };

                for (int j = 1; j < unpartitioned.Count;)
                {
                    int q = unpartitioned[j];

                    if (AreCompatibleStates(data, terms, table, p, q))
                    {
                        unpartitioned.RemoveAt(j);
                        category.Add(q);
                    }
                    else
                    {
                        ++j;
                    }
                }

                categories.Add(category);

                Console.WriteLine("{ " + string.Join(", ", category) + "}");
            }
        }
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args)
 {
     BuildBody(
         emit,
         data,
         tokenId:    args[0],
         oldValue:   args[1],
         newValue:   args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
 public void BuildBody(EmitSyntax emit, LanguageData data, Ref<Args>[] args)
 {
     BuildBody(
         emit,
         data,
         ruleId:     args[0],
         ruleArgs:   args[1],
         argsStart:  args[2],
         ctx:        args[3],
         lookbackStart: args[4]);
 }
Example #4
0
 internal ReportData(
     IGrammarSource       source,
     LanguageData         data,
     ParserConflictInfo[] parserConflicts,
     DotState[]           parserStates)
 {
     this.source = source;
     this.data = data;
     this.parserConflicts = parserConflicts;
     this.parserStates = parserStates;
 }
Example #5
0
 public ContextCode(
     EmitSyntax       emit,
     Pipe<EmitSyntax> ldGlobalContextProvider,
     Pipe<EmitSyntax> ldLookback,
     LanguageData     data,
     ForeignContextProvider  contextProvider,
     LocalContextBinding[] localContexts = null)
 {
     this.emit = emit;
     this.ldGlobalContextProvider   = ldGlobalContextProvider;
     this.ldLookback      = ldLookback;
     this.contextProvider = contextProvider;
     this.localContexts   = localContexts;
 }
        public ClassSyntax BuildMethod(ClassSyntax context, string methodName, LanguageData data)
        {
            var args = context.Method()
                            .Static
                            .Returning(context.Types.Object)
                            .Named(methodName)
                            .BeginArgs();

            Def<Args> ruleId        =  args.Args.Generate("ruleId");
            Def<Args> ruleArgs      =  args.Args.Generate("ruleArgs");
            Def<Args> argsStart     =  args.Args.Generate("argsStart");
            Def<Args> ctx           =  args.Args.Generate("rootContext");
            Def<Args> stackLookback =  args.Args.Generate("startLookback");

            var emit = args
                    .Argument(context.Types.Int32, ruleId)
                    .Argument(context.Types.Import(typeof(Msg[])), ruleArgs)
                    .Argument(context.Types.Int32, argsStart)
                    .Argument(context.Types.Object, ctx)
                    .Argument(context.Types.Import(typeof(IStackLookback<Msg>)), stackLookback)
                    .EndArgs()

                .BeginBody();

            ruleId.Name        = "ruleId";
            ruleArgs.Name      = "args";
            argsStart.Name     = "argsStart";
            ctx.Name           = "ctx";
            stackLookback.Name = "stackLookback";

            BuildBody(
                emit,
                data,
                ruleId.GetRef(),
                ruleArgs.GetRef(),
                argsStart.GetRef(),
                ctx.GetRef(),
                stackLookback.GetRef());

            return emit.EndBody();
        }
 public TermFactoryGenerator(LanguageData data, Ref<Types> declaringType)
 {
     this.data = data;
     this.declaringType = declaringType;
 }
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> tokenId,
            Ref<Args> oldValue,
            Ref<Args> newValue,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            var mergers = data.Grammar.Mergers;

            if (mergers.Count == 0)
            {
                emit
                    .Ldarg(oldValue)
                    .Ret();

                return;
            }

            var contextResolverCode = new ContextCode(
                                            emit,
                                            il => il.Ldarg(ctx),
                                            il => il.Ldarg(lookbackStart),
                                            data,
                                            data.Grammar.GlobalContextProvider,
                                            data.LocalParseContexts);

            IActionCode code = new MergeCode(emit, contextResolverCode)
            {
                LoadOldValue = il => il.Ldarg(oldValue),
                LoadNewValue = il => il.Ldarg(newValue),
            };

            var tokenToRuleIndex = new MutableIntMap<int>(
                                        mergers.Select(
                                            merger =>
                                                new IntArrow<int>(merger.Symbol.Index, merger.Index)));
            tokenToRuleIndex.DefaultValue = -1;

            var ids = mergers.Select(m => m.Symbol.Index);
            IntInterval possibleBounds = new IntInterval(ids.Min(), ids.Max());
            var switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds);
            switchGenerator.Build(
                emit,
                il => il.Ldarg(tokenId),
                (il, value) =>
                {
                    if (value < 0)
                    {
                        emit
                            .Ldarg(newValue)
                            .Ret();
                    }
                    else
                    {
                        var merger = mergers[value];
                        var binding = merger.Joint.The<CilMerger>();
                        code = code
                            .Do(binding.Context.Load)
                            .Do(binding.ActionBuilder)
                            .Emit(il2 => il2.Ret())
                            ;
                    }
                });

            emit
                .Ret();
        }
        public ClassSyntax BuildMethod(ClassSyntax context, string methodName, LanguageData data)
        {
            var args = context.Method()
                            .Static
                            .Returning(context.Types.Object)
                            .Named(methodName)
                            .BeginArgs();

            Def<Args> tokenId       =  args.Args.Generate("token");
            Def<Args> oldValue      =  args.Args.Generate("oldValue");
            Def<Args> newValue      =  args.Args.Generate("newValue");
            Def<Args> ctx           =  args.Args.Generate("rootContext");
            Def<Args> stackLookback =  args.Args.Generate("startLookback");

            var emit = args
                    .Argument(context.Types.Int32, tokenId)
                    .Argument(context.Types.Object, oldValue)
                    .Argument(context.Types.Object, newValue)
                    .Argument(context.Types.Object, ctx)
                    .Argument(context.Types.Import(typeof(IStackLookback<Msg>)), stackLookback)
                    .EndArgs()

                .BeginBody();

            BuildBody(
                emit,
                data,
                tokenId.GetRef(),
                oldValue.GetRef(),
                newValue.GetRef(),
                ctx.GetRef(),
                stackLookback.GetRef());

            return emit.EndBody();
        }
Example #10
0
 private static bool HaveComptibleReductions(LanguageData data, ParserAction pAction, ParserAction qAction)
 {
     return 
         (
             pAction.Kind != ParserActionKind.Reduce
             && qAction.Kind != ParserActionKind.Reduce)
         ||
         (
             pAction.Kind == ParserActionKind.Reduce
             && qAction.Kind == ParserActionKind.Reduce
             && pAction.ProductionId == qAction.ProductionId
         );
 }
Example #11
0
 public ParserState(DotState dotState, LanguageData data)
 {
     this.dotState = dotState;
     this.data     = data;
 }
 public ParserAutomata(ReportData reportData)
 {
     this.data            = reportData.data;
     this.parserConflicts = reportData.parserConflicts;
     this.parserStates    = reportData.parserStates;
 }
Example #13
0
        private static bool AreCompatibleStates(LanguageData data, int[] terms, ITable<int> table, int p, int q)
        {
            foreach (int term in terms)
            {
                var pCell = table.Get(p, term);
                var qCell = table.Get(q, term);
                var pAction = ParserAction.Decode(pCell);
                var qAction = ParserAction.Decode(qCell);

                if (pCell != qCell 
                    && !HaveSameShifts(data, pAction, qAction))
                {
                    return false;
                }

                if (pAction.Kind == ParserActionKind.Conflict 
                    || qAction.Kind == ParserActionKind.Conflict)
                {
                    Console.WriteLine("Skipped conflicting {0}<->{1} states", p, q);
                    return false;
                }

                if (!HaveComptibleReductions(data, pAction, qAction))
                {
                    /*
                    Console.WriteLine(
                        "Skipped incompatible {0}<->{1} state reductions {2}<->{3}",
                        p, q,
                        pAction, qAction);
                    */

                    return false;
                }
            }

            return true;
        }
Example #14
0
        // Merging similar tokens (token equivalence classes) makes sense only 
        // after state compression
        private static void ShowSimilarTokens(LanguageData data)
        {
            var grammar = data.Grammar;

            int stateCount = data.ParserStates.Length;
            int startToken = PredefinedTokens.Count;
            int tokenCount = grammar.Symbols.Count;

            var table = data.ParserActionTable;
            var unpartitioned = Enumerable.Range(startToken, tokenCount - startToken).ToList();
            var categories = new List<List<int>>();

            while (unpartitioned.Count != 0)
            {
                int p = unpartitioned[0];
                unpartitioned.RemoveAt(0);
                var category = new List<int> { p };

                for (int j = 1; j < unpartitioned.Count;)
                {
                    int q = unpartitioned[j];

                    bool areSimilar = true;
                    for (int s = 0; s != stateCount; ++s)
                    {
                        var pCell = table.Get(s, p);
                        var qCell = table.Get(s, q);
                        if (pCell != qCell)
                        {
                            areSimilar = false;
                            break;
                        }
                    }

                    if (areSimilar)
                    {
                        unpartitioned.RemoveAt(j);
                        category.Add(q);
                    }
                    else
                    {
                        ++j;
                    }
                }

                categories.Add(category);

                Console.WriteLine("T{ " + string.Join(", ", category) + "}");
            }
        }
Example #15
0
        private static ParserAction GetShift(LanguageData data, ParserAction x)
        {
            switch (x.Kind)
            {
                case ParserActionKind.Shift:
                case ParserActionKind.ShiftReduce:
                    return x;
                case ParserActionKind.Conflict:
                    int start = x.Value1;
                    int count = x.Value2;
                    int last = start + count;
                    for (; start != last; ++start)
                    {
                        var cAction = ParserAction.Decode(data.ParserConflictActionTable[start]);
                        switch (cAction.Kind)
                        {
                            case ParserActionKind.Shift:
                            case ParserActionKind.ShiftReduce:
                                return cAction;
                        }
                    }

                    break;
            }

            return ParserAction.FailAction;
        }
Example #16
0
 private static bool HaveSameShifts(LanguageData data, ParserAction x, ParserAction y)
 {
     var xShift = GetShift(data, x);
     var yShift = GetShift(data, y);
     return xShift == yShift;
 }
        public void BuildBody(
            EmitSyntax emit, 
            LanguageData data,
            Ref<Args> ruleId,
            Ref<Args> ruleArgs,
            Ref<Args> argsStart,
            Ref<Args> ctx,
            Ref<Args> lookbackStart)
        {
            Def<Labels> returnLabel = emit.Labels.Generate();

            var contextCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new ProductionCode(
                emit,
                contextCode,
                ldRuleArgs:  il => il.Ldarg(ruleArgs),
                ldArgsStart: il => il.Ldarg(argsStart),
                returnLabel: returnLabel);

            var defaultLabel = emit.Labels.Generate();
            var endWithSingleResultLabel = emit.Labels.Generate();
            var jumpTable = new Ref<Labels>[data.Grammar.Productions.Count];
            for (int i = 0; i != jumpTable.Length; ++i)
            {
                jumpTable[i] = emit.Labels.Generate().GetRef();
            }

            emit
                .Do(il => il.Ldarg(ruleId))
                .Switch(jumpTable)
                .Br(defaultLabel.GetRef());

            foreach (var prod in data.Grammar.Productions)
            {
                emit.Label(jumpTable[prod.Index].Def);

                if (0 == prod.Actions.Count)
                {
                    // Augumented start rule has null action and should never be invoked.
                    // Also it is possible that for some platforms production may have default
                    // action.
                    emit.Ldnull();
                }
                else
                {
                    foreach (var action in prod.Actions)
                    {
                        code = GenerateActionCode(code, action);
                    }
                }

                emit.Br(endWithSingleResultLabel.GetRef());
            }

            emit
                .Label(defaultLabel)
                .Ldnull()
                .Label(endWithSingleResultLabel)
                .Label(returnLabel)
                .Ret();
        }
Example #18
0
        public void BuildBody(
            EmitSyntax emit,
            LanguageData data,
            Ref <Args> tokenId,
            Ref <Args> oldValue,
            Ref <Args> newValue,
            Ref <Args> ctx,
            Ref <Args> lookbackStart)
        {
            var mergers = data.Grammar.Mergers;

            if (mergers.Count == 0)
            {
                emit
                .Ldarg(oldValue)
                .Ret();

                return;
            }

            var contextResolverCode = new ContextCode(
                emit,
                il => il.Ldarg(ctx),
                il => il.Ldarg(lookbackStart),
                data,
                data.Grammar.GlobalContextProvider,
                data.LocalParseContexts);

            IActionCode code = new MergeCode(emit, contextResolverCode)
            {
                LoadOldValue = il => il.Ldarg(oldValue),
                LoadNewValue = il => il.Ldarg(newValue),
            };

            var tokenToRuleIndex = new MutableIntMap <int>(
                mergers.Select(
                    merger =>
                    new IntArrow <int>(merger.Symbol.Index, merger.Index)));

            tokenToRuleIndex.DefaultValue = -1;

            var         ids             = mergers.Select(m => m.Symbol.Index);
            IntInterval possibleBounds  = new IntInterval(ids.Min(), ids.Max());
            var         switchGenerator = SwitchGenerator.Sparse(tokenToRuleIndex, possibleBounds);

            switchGenerator.Build(
                emit,
                il => il.Ldarg(tokenId),
                (il, value) =>
            {
                if (value < 0)
                {
                    emit
                    .Ldarg(newValue)
                    .Ret();
                }
                else
                {
                    var merger  = mergers[value];
                    var binding = merger.Joint.The <CilMerger>();
                    code        = code
                                  .Do(binding.Context.Load)
                                  .Do(binding.ActionBuilder)
                                  .Emit(il2 => il2.Ret())
                    ;
                }
            });

            emit
            .Ret();
        }