public override void ExportToCsv(string filename) { var output = new StreamWriter(filename); var orderedLookaheads = Lookaheads.OrderBy(l => l.Value); output.WriteLine("," + String.Join(",", orderedLookaheads.Select(l => l.Key))); for (var i = 0; i < Items.Count; ++i) { output.Write($"{i},"); output.Write(String.Join(",", orderedLookaheads.Select(l => this[i, l.Key]) .Select(alts => alts.Count == 0 ? "" : alts.Count == 1 ? alts.Single().ToString() : String.Join("/", alts)))); output.WriteLine(); } output.Close(); }
public override void ExportToCsv(string filename) { var output = new StreamWriter(filename); var orderedLookaheads = Lookaheads.OrderBy(l => l.Value); output.WriteLine("," + String.Join(",", orderedLookaheads.Select(l => l.Key))); foreach (var nt in NonterminalSymbols.Keys) { output.Write($"{nt},"); output.Write(String.Join(",", orderedLookaheads.Select(l => this[nt, l.Key]) .Select(alts => alts.Count == 0 ? "" : alts.Count == 1 ? alts.Single().ToString() : String.Join("/", alts)))); output.WriteLine(); } output.Close(); }
public override List <Message> CheckValidity() { var errors = new List <Message>(); for (var itemIdx = 0; itemIdx < Actions.GetLength(0); ++itemIdx) { for (var lookaheadIdx = 0; lookaheadIdx < Actions.GetLength(1); ++lookaheadIdx) { if (Actions[itemIdx, lookaheadIdx].Count > 1) { /// Сразу вытаскиваем токен, по которому возникает неоднозначность var lookahead = Lookaheads.FirstOrDefault(l => l.Value == lookaheadIdx).Key; /// Формируем строковые представления действий, которые по этому токену можно сделать var actions = Actions[itemIdx, lookaheadIdx].Select(a => a is ReduceAction ? $"{a.ActionName} по ветке {GrammarObject.Userify(((ReduceAction)a).ReductionAlternative)} нетерминала {GrammarObject.Userify(((ReduceAction)a).ReductionAlternative.NonterminalSymbolName)}" : $"{a.ActionName}").ToList(); var messageText = $"Грамматика не является LR(1): для токена {GrammarObject.Userify(lookahead)} и состояния{Environment.NewLine}" + $"\t\t{ToString(itemIdx, lookahead, "\t\t")}{Environment.NewLine}" + $"\tвозможны действия:{Environment.NewLine}" + "\t\t" + String.Join(Environment.NewLine + "\t\t", actions); /// Для Shift/Reduce конфликта кидаем предупреждение, а не соо об ошибке if (Actions[itemIdx, lookaheadIdx].Count == 2 && Actions[itemIdx, lookaheadIdx].Any(a => a is ReduceAction) && Actions[itemIdx, lookaheadIdx].Any(a => a is ShiftAction)) { errors.Add(Message.Warning( messageText, null, "LanD" )); } else { errors.Add(Message.Error( messageText, null, "LanD" )); } } } } /// Проверяем состояния на наличие нескольких пунктов перед Any for (var i = 0; i < Items.Count; ++i) { if (Items[i].GroupBy(m => new { m.Alternative, m.Position }) .Where(g => g.First().Next == Grammar.ANY_TOKEN_NAME).Count() > 1) { errors.Add(Message.Error( $"Any-конфликт: согласно состоянию{Environment.NewLine}" + $"\t\t{ToString(i, null, "\t\t")}{Environment.NewLine}" + $"\tпрефикс, оканчивающийся на Any может быть разобран несколькими способами", null, "LanD" )); } } return(errors); }