private void ValidateNoRecursionTerminal(Regex r, HashSet <string> stack) { if (r is ReferenceRegex) { var rr = r as ReferenceRegex; if (stack.Contains(rr.Reference)) { throw new GrammarException(r.Location, $"recursão infinita para o símbolo terminal {rr.Reference}"); } if (!RegexDefinitions.Any(x => x.Name == rr.Reference)) { throw new GrammarException(r.Location, $"terminal não declarado {rr.Reference}"); } stack.Add(rr.Reference); ValidateNoRecursionTerminal(RegexDefinitions.First(x => x.Name == rr.Reference).Regex, stack); } else if (r is CharsetRegex) { var cr = r as CharsetRegex; if (!CharsetDefinitions.Any(x => x.Name == cr.CharsetName) && !IsReservedCharsetName(cr.CharsetName)) { throw new GrammarException(r.Location, $"charset não declarado {{{cr.CharsetName}}}"); } } else { foreach (var item in r.Children) { ValidateNoRecursionTerminal(item, stack); } } }
private void ExtractKeywords() { Keywords = new HashSet <string>(this.Productions.SelectMany(x => x.Body.Where(y => y is TerminalSymbol).Cast <TerminalSymbol>() .Where(y => !RegexDefinitions.Any(z => z.Name == y.Name))).Select(x => x.Name)).ToList().AsReadOnly(); }