void _ValidateExpression(EbnfExpression expr, IDictionary <string, int> refCounts, IList <EbnfMessage> messages) { var l = expr as EbnfLiteralExpression; if (null != l) { var i = GetIdForExpression(l); // don't count itself. only things just like itself if (null != i && !ReferenceEquals(Productions[i].Expression, l)) { refCounts[i] += 1; } } var rx = expr as EbnfRegexExpression; if (null != rx) { try { FA.Parse(rx.Value); } catch (ExpectingException) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 12, "Invalid regular expression", expr.Line, expr.Column, expr.Position)); } var i = GetIdForExpression(rx); if (null != i && !ReferenceEquals(Productions[i].Expression, l)) { refCounts[i] += 1; } } var r = expr as EbnfRefExpression; if (null != r) { int rc; if (null == r.Symbol) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 4, "Null reference expression", expr.Line, expr.Column, expr.Position)); return; } if (!refCounts.TryGetValue(r.Symbol, out rc)) { messages.Add( new EbnfMessage( EbnfErrorLevel.Error, 1, string.Concat( "Reference to undefined symbol \"", r.Symbol, "\""), expr.Line, expr.Column, expr.Position)); return; } refCounts[r.Symbol] = rc + 1; return; } var b = expr as EbnfBinaryExpression; if (null != b) { if (null == b.Left && null == b.Right) { messages.Add( new EbnfMessage( EbnfErrorLevel.Warning, 3, "Nil expression", expr.Line, expr.Column, expr.Position)); return; } _ValidateExpression(b.Left, refCounts, messages); _ValidateExpression(b.Right, refCounts, messages); return; } var u = expr as EbnfUnaryExpression; if (null != u) { if (null == u.Expression) { messages.Add( new EbnfMessage( EbnfErrorLevel.Warning, 3, "Nil expression", expr.Line, expr.Column, expr.Position)); return; } _ValidateExpression(u.Expression, refCounts, messages); } }