using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.Concurrent; using System.Threading.Tasks; using System.Threading; using System.Diagnostics; using glue.Collections.XSpinLock; using glue.Extensions.String; using glue.Debugging; using glue.Tokenization; using agree.Parse; using glue.Collections.ReadOnly; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// partial class Program { static Program() { foreach (var qq in tests) { qq.warr = qq.input.ToLower().Split(' '); } } public static void ConsoleMsg(ConsoleColor color, String fmt, params String[] args) { lock (Console.Out) { Console.ForegroundColor = color; Console.WriteLine(fmt, args); Console.ResetColor(); } } public static bool f_unif_delay; bool f_sonly; ILookup<String,TestLexicalEntry> lex_index; class SO : agree.ISysObj { public string SysObjName { get { return "TestSysObj"; } } public IReadOnlyDictionary<string, agree.ISysObj> SysObjChildren { get { return ReadOnlyDictionary<String, agree.ISysObj>.Empty; } } public agree.ISysObj SysObjParent { get { return this; } } public string SysObjDescription { get { return "TestSysObj description"; } } }; SO so = new SO(); async Task<TestChart> Parse(bool print_enable, TokenizedString ts, TestGrammarRule[] rules) { //var zzz = ts.Select(tok => // { // TestEdge te = lex_index[tok.Text].Self; //new TestEdge { s = //{ lex_index[tok.Text]); TestChart chart = new TestChart(so, ts, rules, null); chart.SetDebugOutput(Console.Out); await chart.ParseAsync(); //await chart.ParseB(); return chart; } #if false Task<TestChart> ParseDetach(bool print_enable, String[] warr, TestGrammarRule[] rules) { return TaskEx.Run<Task<TestChart>>(() => Parse(print_enable, warr, rules)).Unwrap(); } #endif bool f_print, f_loop, f_show_chart, f_show_hash, f_show_iter, f_detach, f_each, f_nohash; int iter, i_testitem; int printing; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static List<Task> lt; void ProgramMain(String[] args) { TaskScheduler.UnobservedTaskException += new EventHandler<UnobservedTaskExceptionEventArgs>(TaskScheduler_UnobservedTaskException); f_print = args.Contains("-output"); int c_tasks_desired = 1; String arg = args.FirstOrDefault(a => a.StartsWith("-tasks:")); if (arg != null) c_tasks_desired = Math.Max(int.Parse(arg.Substring(7)), 1); i_testitem = -1; arg = args.FirstOrDefault(a => a.StartsWith("-testitem:")); if (arg != null) i_testitem = int.Parse(arg.Substring(10)); if (i_testitem < 0 || i_testitem >= tests.Length) i_testitem = -1; f_loop = c_tasks_desired > 1 || args.Contains("-loop"); f_show_chart = args.Contains("-showchart"); f_show_hash = args.Contains("-showhash"); f_show_iter = args.Contains("-showiter"); f_sonly = args.Contains("-sonly"); f_unif_delay = args.Contains("-unifdelay"); f_detach = args.Contains("-detach"); f_nohash = args.Contains("-nohash"); f_each = args.Contains("-each"); if (f_each) c_tasks_desired = tests.Length; iter = 0; printing = 0; lex_index = lex.SelectMany(x => x.Value.Select(pos => { return new TestLexicalEntry(x.Key, new TestEdge(null, pos)); })) .ToLookup(le => le.Lemmata[0]); /*List<Task>*/ lt = new List<Task>(); for (int i=0; i < c_tasks_desired; i++) { int test_no = f_each ? i : i_testitem; Console.WriteLine("{0}: test #{1}", i, test_no); lt.Add(DoOneParserAsyncDetach(i, test_no)); } Thread.Sleep(100); if (!f_loop) { try { TaskEx.WhenAll(lt).Wait(); } catch (Exception ex) { Console.WriteLine(ex); } } if (f_loop || Debugger.IsAttached) { Console.ReadKey(); Console.ResetColor(); } Environment.Exit(0); } void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { Debugger.Break(); } Task<TestChart> DoOneParserAsyncDetach(int i, int test_no) { return Task.Factory.StartNew<Task<TestChart>>(async () => { bool print = f_print && (Interlocked.CompareExchange(ref printing, 1, 0) == 0); TestChart q = null; do { q = await DoOneParserAsync(print, test_no); if (f_print) Console.Out.WriteLineColor("$magenta {0}: test #{1} done", i, test_no); } while (f_loop); return q; }, CancellationToken.None, TaskCreationOptions.AttachedToParent, TaskScheduler.Default).Unwrap(); } async Task<TestChart> DoOneParserAsync(bool print, int test_no) { if (test_no == -1) test_no = rnd.Next(tests.Length); TestItem tst = tests[test_no]; int iter_local = Interlocked.Increment(ref iter); if (print) Console.Out.WriteLineColor(CancellationToken.None, "$magenta Test #{0}, using TestItem {1}", iter_local, test_no); TestChart c = await Parse(print, new TokenizedString(tst.warr," "), tst.rules); if (f_show_iter && (iter % 100 == 0)) Console.WriteLine(iter); int oh=0; if (!f_nohash) { oh = OverallHash(c); if (tst.hash != 0 && oh != tst.hash) throw new Exception(String.Format("error: hash {0:X8} expected {1:X8}", oh, tst.hash)); } // part that we don't need to wait on if (print) await TaskEx.Run(() => { if (f_show_chart) lock (Console.Out) { PrintChart(tst.warr, c); } if (f_show_hash && !f_nohash) Console.WriteLine(Environment.NewLine + "overall hash: {0:X8}", oh); }); return c; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int GetTreeHashCode(TestChart.DerivedPassiveEdge e) { int h = 0; Action<TestChart.DerivedPassiveEdge> f = null; f = (ce) => { TestChart.DerivedPassiveEdge dce = ce as TestChart.DerivedPassiveEdge; if (dce != null) foreach (TestChart.DerivedPassiveEdge cce in dce.Daughters) f(cce); h ^= ce.Self.s.GetHashCode(); h ^= ce.ChartSpan.GetHashCode(); }; f(e); return ((h >> 16) ^ h) & 0xFFFF; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int OverallHash(TestChart chart) { int overall_hash = 0; foreach (TestChart.DerivedPassiveEdge dce in chart.DerivationTopEdges(uint.MaxValue)) { unchecked { overall_hash += GetTreeHashCode(dce); } } return overall_hash; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void PrintChart(String[] warr, TestChart chart) { Console.WriteLine(); int i_d = 0; foreach (TestChart.DerivedPassiveEdge dce in chart.DerivationTopEdges(uint.MaxValue) .Where(e => !f_sonly || (e.Self.s == "S" && e.ChartSpan==chart.EntireSpan)) .OrderBy(e => GetTreeHashCode(e)) ) { Console.WriteLine("... Derivation #{0} {1:X4} ...", i_d++, GetTreeHashCode(dce)); for (IEnumerable<TestChart.DerivedPassiveEdge> iece = Enumerable.Repeat(dce, 1); iece.Any(); iece = iece.OfType<TestChart.DerivedPassiveEdge>().SelectMany(ee => ee.Daughters.OfType<TestChart.DerivedPassiveEdge>())) { int cpos = 0; foreach (TestChart.DerivedPassiveEdge xce in iece) { //String k = xce.Contents.s; //String k = xce.GetHashCode().ToString("X8"); String k = xce.Self.s; #if false if (xce is TestChart.NAryDerivedChartEdge) { uint sid = (xce as TestChart.NAryDerivedChartEdge)._rb_seq_id; k += "-" + (sid == uint.MaxValue ? "n/a" : sid.ToString()); } #endif String s0 = new String(' ', (xce.ChartSpan.StartIndex - cpos) * 11); int w = xce.ChartSpan.Length * 11 - 1; String s2 = k.PadLeft(w / 2 + k.Length / 2, '=').PadRight(w, '=') + " "; Console.Write(s0 + s2); cpos = xce.ChartSpan.EndIndex + 1; } Console.WriteLine(); } Console.Write(new String(' ', dce.ChartSpan.StartIndex * 11)); for (int i = dce.ChartSpan.StartIndex; i <= dce.ChartSpan.EndIndex; i++) Console.Write(warr[i].PadLeft(10) + " "); Console.WriteLine(); Console.WriteLine(); } #if false Chart.Layout layout = chart.GetLayout; for (int j = layout.Max(e => e.Count); j >= 0; j--) { foreach (List<ChartEdge> ccb in layout) { if (j < ccb.Count) { Console.Write(ccb[j].Parent.s.PadLeft(10, '=') + ); } else Console.Write(new String(' ', 10)); Console.Write(' '); } Console.WriteLine(); } for (int i = 0; i < warr.Length; i++) { Console.Write(warr[i].PadLeft(10) + " "); } Console.WriteLine(); #elif false #if false for (int span=1; span <= chart.ColumnCount; span++) { for (int i=0; i < chart.ColumnCount - (span - 1); i++) { chart.chart[i][span - 1] = chart.chart[i][span - 1] ?? new List<ChartEdge>(); chart.chart[i][span - 1].Add(new TestChartEdge(new ChartSpan(i, (uint)span), new TfsEdge(String.Format("{0}-{1}", i, span)))); } } #endif #if false for (int span=chart.ColumnCount; span > 0; span--) { //Console.Write("{0}:", span); List<ChartEdge> lce; List<ChartEdge>[] span_cols = chart.CopiedSpansOfLength(span); int mod = chart.ColumnCount - (span - 1); bool f_any = false; for (int i_col=0; ; i_col += span) { if (i_col >= mod) { Console.WriteLine(); i_col = i_col % mod; if (i_col == 0) { if (!f_any) break; f_any = false; } Console.Write(new String(' ', 11 * i_col)); } if ((lce = span_cols[i_col]) != null) { ChartEdge ce = lce[0]; Console.Write(ce.Contents.s.PadLeft(10, '=') + new String('=', 11 * (ce.Span.Length - 1))); lce.RemoveAt(0); if (lce.Count == 0) span_cols[i_col] = null; f_any = true; } else Console.Write(new String(' ', 11 * span)); Console.Write(' '); } } #endif #else /* for (int j = chart.RightwardsEdges(uint.MaxValue).Max(e => e.Count()); j >= 0; j--) { foreach (ConcurrentList<ChartEdge> ccb in chart) { if (j < ccb.Count) { Console.Write(ccb[j].Contents.s.PadLeft(10, '=')); } else Console.Write(new String(' ', 10)); Console.Write(' '); } Console.WriteLine(); } for (int i = 0; i < warr.Length; i++) { Console.Write(warr[i].PadLeft(10) + " "); } Console.WriteLine(); * */ #endif } };