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 ValidateNoUndeclaredCharsets(CharsetExpression expr) { if (expr is CharsetBinaryExpression) { var b = expr as CharsetBinaryExpression; ValidateNoUndeclaredCharsets(b.Left); ValidateNoUndeclaredCharsets(b.Right); } else if (expr is CharsetNameExpression) { var b = expr as CharsetNameExpression; if (!IsReservedCharsetName(b.Name) && !CharsetDefinitions.Any(x => x.Name == b.Name)) { throw new GrammarException(b.Location, $"nome {{{b.Name}}} não declarado"); } } }
private void ValidateNoRecursionCharset(CharsetExpression r, HashSet <string> stack) { if (r is CharsetNameExpression) { var rr = r as CharsetNameExpression; if (stack.Contains(rr.Name)) { throw new GrammarException(r.Location, $"recursão infinita para {{{rr.Name}}}"); } stack.Add(rr.Name); if (IsReservedCharsetName(rr.Name)) { return; } ValidateNoRecursionCharset(CharsetDefinitions.First(x => x.Name == rr.Name).Expression, stack); } else if (r is CharsetBinaryExpression) { var b = r as CharsetBinaryExpression; ValidateNoRecursionCharset(b.Left, stack); ValidateNoRecursionCharset(b.Right, stack); } }