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]); }
internal ReportData( IGrammarSource source, LanguageData data, ParserConflictInfo[] parserConflicts, DotState[] parserStates) { this.source = source; this.data = data; this.parserConflicts = parserConflicts; this.parserStates = parserStates; }
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(); }
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 ); }
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; }
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; }
// 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) + "}"); } }
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; }
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(); }
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(); }