public IList <EbnfMessage> DeclareImplicitTerminals() { var result = new List <EbnfMessage>(); var terms = new HashSet <EbnfExpression>(); var done = new HashSet <EbnfExpression>(); foreach (var prod in Productions) { _VisitFetchTerminals(prod.Value.Expression, terms); if (prod.Value.Expression.IsTerminal) { done.Add(prod.Value.Expression); } } foreach (var term in terms) { if (!done.Contains(term)) { var prod = new EbnfProduction(); prod.Expression = ((ICloneable)term).Clone() as EbnfExpression; var newId = _GetImplicitTermId(); Productions.Add(newId, prod); result.Add(new EbnfMessage(EbnfErrorLevel.Message, -1, "Terminal was implicitly declared.", term.Line, term.Column, term.Position)); } } return(result); }
static IList <EbnfMessage> _TryParseProduction(ParseNode pn, out KeyValuePair <string, EbnfProduction> result) { Debug.Assert(EbnfParser.production == pn.SymbolId, "Not positioned on production"); var msgs = new List <EbnfMessage>(); string name = pn.Children[0].Value; if ("production" == name) { Debugger.Break(); } var prod = new EbnfProduction(); prod.SetLocationInfo(pn.Line, pn.Column, pn.Position); var i = 0; if (EbnfParser.lt == pn.Children[1].SymbolId) { i = 2; while (EbnfParser.gt != pn.Children[i].SymbolId) { var attrnode = pn.Children[i]; var attrname = attrnode.Children[0].Value; var attrval = (object)true; if (3 == attrnode.Children.Count) { var s = attrnode.Children[2].Children[0].Value; if (!ParseContext.Create(s).TryParseJsonValue(out attrval)) { attrval = null; } } prod.Attributes.Add(attrname, attrval); ++i; if (EbnfParser.comma == pn.Children[i].SymbolId) { ++i; } } ++i; } ++i; EbnfExpression e; _TryParseExpressions(pn, i, out e); prod.Expression = e; result = new KeyValuePair <string, EbnfProduction>(name, prod); return(msgs); }
static void _ParseAttribute(EbnfDocument doc, string id, EbnfProduction prod, ParseContext pc) { pc.TrySkipCCommentsAndWhiteSpace(); var attrid = _ParseIdentifier(pc); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('=', '>', ','); object val = true; if ('=' == pc.Current) { pc.Advance(); val = pc.ParseJsonValue(); } pc.Expecting(',', '>'); prod.Attributes[attrid] = val; pc.TrySkipCCommentsAndWhiteSpace(); }
static void _ParseAttributes(EbnfDocument doc, string id, EbnfProduction prod, ParseContext pc) { pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('<'); pc.Advance(); while (-1 != pc.Current && '>' != pc.Current) { _ParseAttribute(doc, id, prod, pc); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(',', '>'); if (',' == pc.Current) { pc.Advance(); } } pc.Expecting('>'); pc.Advance(); pc.TrySkipCCommentsAndWhiteSpace(); }
static void _ParseProduction(EbnfDocument doc, ParseContext pc) { pc.TrySkipCCommentsAndWhiteSpace(); var line = pc.Line; var column = pc.Column; var position = pc.Position; var id = _ParseIdentifier(pc); pc.TrySkipCCommentsAndWhiteSpace(); EbnfProduction prod = null; if (!doc.Productions.TryGetValue(id, out prod)) { prod = new EbnfProduction(); doc.Productions.Add(id, prod); } if ('<' == pc.Current) { _ParseAttributes(doc, id, prod, pc); pc.TrySkipCCommentsAndWhiteSpace(); } pc.Expecting('='); pc.Advance(); pc.Expecting(); var expr = _ParseExpression(doc, pc); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting(';'); pc.Advance(); pc.TrySkipCCommentsAndWhiteSpace(); // transform this into an OrExpression with the previous if (null != prod.Expression) { prod.Expression = new EbnfOrExpression(prod.Expression, expr); } else { prod.Expression = expr; } prod.SetLocationInfo(line, column, position); }