static void _VisitUnreferenced(XbnfDocument doc, XbnfExpression expr, HashSet <string> result) { var r = expr as XbnfRefExpression; if (null != r) { if (!doc.Productions.Contains(r.Symbol)) { result.Add(r.Symbol); } return; } var u = expr as XbnfUnaryExpression; if (null != u) { _VisitUnreferenced(doc, u.Expression, result); return; } var b = expr as XbnfBinaryExpression; if (null != b) { _VisitUnreferenced(doc, b.Left, result); _VisitUnreferenced(doc, b.Right, result); return; } }
static IList <IList <string> > _GetDysOptional(XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfOptionalExpression ope) { var l = new List <IList <string> >(); if (null != ope.Expression) { l.AddRange(_GetDysjunctions(d, syms, tmap, attrs, rules, p, ope.Expression)); var ll = new List <string>(); if (!l.Contains(ll, OrderedCollectionEqualityComparer <string> .Default)) { l.Add(ll); } } return(l); }
public static IList <IMessage> TryCreateGenerationInfo(XbnfDocument document, out XbnfGenerationInfo genInfo) { var includes = new XbnfImportList(); _GatherIncludes(document, includes); var incs = new List <XbnfDocument>(); incs.Add(document); foreach (var inc in includes) { incs.Add(inc.Document); } var doc = XbnfDocument.Merge(incs); var cfg = new CfgDocument(); return(_TryToGenInfo(doc, cfg, out genInfo)); }
public static List <string> GetSymbolTable(XbnfGenerationInfo info, out int termStart) { var result = new List <string>(); var seen = new HashSet <string>(); XbnfDocument xbnf = info.Xbnf; var cfg = info.Cfg; foreach (var s in cfg.FillNonTerminals()) { if (seen.Add(s)) { result.Add(s); } } termStart = result.Count; var ts = new List <string>(); foreach (var prod in xbnf.Productions) { if (prod.IsTerminal) { ts.Add(prod.Name); } } foreach (var s in ts) { //if (0 != string.Compare("#ERROR", s, StringComparison.InvariantCulture) && 0 != string.Compare("#EOS", s, StringComparison.InvariantCulture)) //{ if (seen.Add(s)) { result.Add(s); } //} } result.Add("#EOS"); result.Add("#ERROR"); return(result); }
static IList <IList <string> > _GetDysConcat(XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfConcatExpression ce) { var l = new List <IList <string> >(); if (null == ce.Right) { if (null == ce.Left) { return(l); } foreach (var ll in _GetDysjunctions(d, syms, tmap, attrs, rules, p, ce.Left)) { l.Add(new List <string>(ll)); } return(l); } else if (null == ce.Left) { foreach (var ll in _GetDysjunctions(d, syms, tmap, attrs, rules, p, ce.Right)) { l.Add(new List <string>(ll)); } return(l); } foreach (var ll in _GetDysjunctions(d, syms, tmap, attrs, rules, p, ce.Left)) { foreach (var ll2 in _GetDysjunctions(d, syms, tmap, attrs, rules, p, ce.Right)) { var ll3 = new List <string>(); ll3.AddRange(ll); ll3.AddRange(ll2); if (!l.Contains(ll3, OrderedCollectionEqualityComparer <string> .Default)) { l.Add(ll3); } } } return(l); }
static void _GatherIncludes(XbnfDocument doc, XbnfImportList result) { for (int ic = doc.Includes.Count, i = 0; i < ic; ++i) { var inc = doc.Includes[i]; var found = false; for (int jc = result.Count, j = 0; j < jc; ++j) { var fn = result[i].Document.FileOrUrl; if (!string.IsNullOrEmpty(fn) && 0 == string.Compare(fn, inc.Document.FileOrUrl)) { found = true; break; } } if (!found) { result.Add(inc); _GatherIncludes(inc.Document, result); } } }
static IList <IList <string> > _GetDysOr(XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfOrExpression oe) { var l = new List <IList <string> >(); if (null == oe.Left) { l.Add(new List <string>()); } else { foreach (var ll in _GetDysjunctions(d, syms, tmap, attrs, rules, p, oe.Left)) { if (!l.Contains(ll, OrderedCollectionEqualityComparer <string> .Default)) { l.Add(ll); } } } if (null == oe.Right) { var ll = new List <string>(); if (!l.Contains(ll, OrderedCollectionEqualityComparer <string> .Default)) { l.Add(ll); } } else { foreach (var ll in _GetDysjunctions(d, syms, tmap, attrs, rules, p, oe.Right)) { if (!l.Contains(ll, OrderedCollectionEqualityComparer <string> .Default)) { l.Add(ll); } } } return(l); }
static IList <IList <string> > _GetDysRepeat(XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfRepeatExpression re) { string sid = null; var sr = re.Expression as XbnfRefExpression; if (null != d && null != sr) { sid = string.Concat(sr.Symbol, "List"); } if (string.IsNullOrEmpty(sid)) { var cc = re.Expression as XbnfConcatExpression; if (null != cc) { sr = cc.Right as XbnfRefExpression; if (null != sr) { sid = string.Concat(sr.Symbol, "ListTail"); } } } if (string.IsNullOrEmpty(sid)) { sid = string.Concat(p.Name, "List"); } var listId = sid; var i = 2; var ss = listId; while (syms.Contains(ss)) { ss = string.Concat(listId, i.ToString()); ++i; } syms.Add(ss); listId = ss; var attr = new XbnfAttribute("collapsed", true); var attr2 = new XbnfAttribute("nowarn", true); var attr3 = new XbnfAttribute("factored", true); var attrlist = new XbnfAttributeList(); attrlist.Add(attr); attrlist.Add(attr2); attrlist.Add(attr3); attrs.Add(listId, attrlist); var expr = new XbnfOrExpression( new XbnfConcatExpression( new XbnfRefExpression(listId), re.Expression), re.Expression);; foreach (var nt in _GetDysjunctions(d, syms, tmap, attrs, rules, p, expr)) { var l = new List <string>(); var r = new KeyValuePair <string, IList <string> >(listId, l); foreach (var s in nt) { if (1 < r.Value.Count && null == s) { continue; } r.Value.Add(s); } rules.Add(r); } if (!re.IsOptional) { return(new List <IList <string> >(new IList <string>[] { new List <string>(new string[] { listId }) })); } else { var res = new List <IList <string> >(); res.Add(new List <string>(new string[] { listId })); res.Add(new List <string>()); return(res); } }
static IList <IList <string> > _GetDysjunctions( XbnfDocument d, ICollection <string> syms, IDictionary <XbnfExpression, string> tmap, IDictionary <string, XbnfAttributeList> attrs, IList <KeyValuePair <string, IList <string> > > rules, XbnfProduction p, XbnfExpression e ) { var le = e as XbnfLiteralExpression; if (null != le) { var res = new List <IList <string> >(); var l = new List <string>(); l.Add(tmap[le]); res.Add(l); return(res); } var rxe = e as XbnfRegexExpression; if (null != rxe) { var res = new List <IList <string> >(); var l = new List <string>(); l.Add(tmap[rxe]); res.Add(l); return(res); } var rfe = e as XbnfRefExpression; if (null != rfe) { var res = new List <IList <string> >(); var l = new List <string>(); l.Add(rfe.Symbol); res.Add(l); return(res); } var ce = e as XbnfConcatExpression; if (null != ce) { return(_GetDysConcat(d, syms, tmap, attrs, rules, p, ce)); } var oe = e as XbnfOrExpression; if (null != oe) { return(_GetDysOr(d, syms, tmap, attrs, rules, p, oe)); } var ope = e as XbnfOptionalExpression; if (null != ope) { return(_GetDysOptional(d, syms, tmap, attrs, rules, p, ope)); } var re = e as XbnfRepeatExpression; if (null != re) { return(_GetDysRepeat(d, syms, tmap, attrs, rules, p, re)); } throw new NotSupportedException("The specified expression type is not supported."); }
static string _ToRegex(XbnfDocument d, XbnfExpression e, bool first, bool gplex = false) { var le = e as XbnfLiteralExpression; if (null != le) { var s = _EscapeLiteral(XbnfNode.Escape(le.Value), !gplex); if (gplex) { s = string.Concat("\"", s, "\""); } return(s); } var rxe = e as XbnfRegexExpression; if (null != rxe) { var r = rxe.Value; if (gplex) { r = r.Replace("\"", "\\\""); } return(first ? r : string.Concat("(", r, ")")); } var rfe = e as XbnfRefExpression; if (null != rfe) { _ToRegex(d, d.Productions[rfe.Symbol].Expression, first, gplex); } var re = e as XbnfRepeatExpression; if (null != re) { if (re.IsOptional) { return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")*")); } else { return(string.Concat("(", _ToRegex(d, re.Expression, true, gplex), ")+")); } } var oe = e as XbnfOrExpression; if (null != oe) { if (!first) { return(string.Concat("(", _ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex), ")")); } else { return(string.Concat(_ToRegex(d, oe.Left, false, gplex), "|", _ToRegex(d, oe.Right, false, gplex))); } } var oc = e as XbnfConcatExpression; if (null != oc) { return(string.Concat(_ToRegex(d, oc.Left, false, gplex), _ToRegex(d, oc.Right, false, gplex))); } var ope = e as XbnfOptionalExpression; if (null != ope) { return(string.Concat("(", _ToRegex(d, ope.Expression, true, gplex), ")?")); } return(""); }
static IList <IMessage> _TryToGenInfo(XbnfDocument document, CfgDocument cfg, out XbnfGenerationInfo genInfo) { genInfo = default(XbnfGenerationInfo); var hasErrors = false; var result = new List <IMessage>(); var syms = new HashSet <string>(); // gather the attributes and production names for (int ic = document.Productions.Count, i = 0; i < ic; ++i) { var p = document.Productions[i]; if (!syms.Add(p.Name)) { result.Add(new XbnfMessage(ErrorLevel.Error, -1, string.Format("Duplicate production {0} defined.", p.Name), p.Line, p.Column, p.Position, document.FileOrUrl)); hasErrors = true; } if (0 < p.Attributes.Count) { CfgAttributeList attrs; if (!cfg.AttributeSets.TryGetValue(p.Name, out attrs)) { attrs = new CfgAttributeList(); cfg.AttributeSets.Add(p.Name, attrs); } for (int jc = p.Attributes.Count, j = 0; j < jc; ++j) { var attr = p.Attributes[j]; attrs.Add(new CfgAttribute(attr.Name, attr.Value)); } } } // use a list dictionary to keep these in order var tmap = new ListDictionary <XbnfExpression, string>(); var attrSets = new Dictionary <string, XbnfAttributeList>(); var rules = new List <KeyValuePair <string, IList <string> > >(); // below are scratch var working = new HashSet <XbnfExpression>(); var done = new HashSet <XbnfExpression>(); // now get the terminals and their ids, declaring if necessary for (int ic = document.Productions.Count, i = 0; i < ic; ++i) { var p = document.Productions[i]; if (p.IsTerminal) { string name; if (!tmap.TryGetValue(p.Expression, out name)) { tmap.Add(p.Expression, p.Name); } else { if (name != p.Name) { result.Add(new CfgMessage(ErrorLevel.Error, -1, string.Format("{0} attempts to redefine terminal {1}", name, p.Name), p.Line, p.Column, p.Position, document.FileOrUrl)); hasErrors = true; } } done.Add(p.Expression); } else { _VisitFetchTerminals(p.Expression, working); } } if (hasErrors) { return(result); } foreach (var term in working) { if (!done.Contains(term)) { var newId = _GetImplicitTermId(syms); var found = false; var prod = document.GetProductionForExpression(term); if (null != prod) { found = true; // recycle this symbol newId = prod.Name; } if (!found) { document.Productions.Add(new XbnfProduction(newId, term)); } tmap.Add(term, newId); } } // tmap now contains ALL of our terminal definitions from all of our imports // now we can use tmap and syms to help solve the rest of our productions var ntd = new Dictionary <string, IList <IList <string> > >(); for (int ic = document.Productions.Count, i = 0; i < ic; ++i) { var p = document.Productions[i]; if (!p.IsTerminal) { var dys = _GetDysjunctions(document, syms, tmap, attrSets, rules, p, p.Expression); IList <IList <string> > odys; if (ntd.TryGetValue(p.Name, out odys)) { result.Add(new XbnfMessage(ErrorLevel.Error, -1, string.Format("The {0} production was specified more than once", p.Name), p.Line, p.Column, p.Position, document.FileOrUrl)); hasErrors = true; } ntd.Add(p.Name, dys); if (hasErrors) { return(result); } } } // now that we've done that, build the rest of our attributes foreach (var sattrs in attrSets) { CfgAttributeList attrs; if (!cfg.AttributeSets.TryGetValue(sattrs.Key, out attrs)) { attrs = new CfgAttributeList(); cfg.AttributeSets.Add(sattrs.Key, attrs); } for (int jc = sattrs.Value.Count, j = 0; j < jc; ++j) { var attr = sattrs.Value[j]; attrs.Add(new CfgAttribute(attr.Name, attr.Value)); } } // now write our main rules foreach (var nt in ntd) { foreach (var l in nt.Value) { cfg.Rules.Add(new CfgRule(nt.Key, l)); } } // build our secondary rules foreach (var rule in rules) { cfg.Rules.Add(new CfgRule(rule.Key, rule.Value)); } if (hasErrors) { return(result); } genInfo.Xbnf = document; genInfo.TerminalMap = tmap; genInfo.Cfg = cfg; cfg.RebuildCache(); return(result); }
public XbnfImport(XbnfDocument document) { Document = document; }
internal static XbnfProduction Parse(LexContext pc) { var result = new XbnfProduction(); pc.TrySkipCCommentsAndWhiteSpace(); var l = pc.Line; var c = pc.Column; var p = pc.Position; // read identifier result.Name = ParseIdentifier(pc); // read attributes if ('<' == pc.Current) { pc.Advance(); while (-1 != pc.Current && '>' != pc.Current) { result.Attributes.Add(XbnfAttribute.Parse(pc)); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('>', ','); if (',' == pc.Current) { pc.Advance(); } } pc.Expecting('>'); pc.Advance(); } pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('='); pc.Advance(); result.Expression = XbnfExpression.Parse(pc); pc.Expecting(';', '='); result.SetLocation(l, c, p); if (';' == pc.Current) { pc.Advance(); return(result); } if ('=' == pc.Current) { pc.Advance(); pc.Expecting('>'); pc.Advance(); pc.TrySkipCCommentsAndWhiteSpace(); pc.Expecting('{'); pc.Advance(); l = pc.Line; c = pc.Column; p = pc.Position; var s = XbnfDocument.ReadCode(pc); pc.Expecting('}'); pc.Advance(); result.Action = new XbnfCode(s); result.SetLocation(l, c, p); } return(result); }
/*static int Test() * { * string input; * using (var sr = new StreamReader(@"..\..\data2.json")) * input = sr.ReadToEnd(); * var tokenizer = new JsonTokenizer(input); * var xbnf = XbnfDocument.ReadFrom(@"..\..\json.xbnf"); * XbnfGenerationInfo info; * XbnfConvert.TryCreateGenerationInfo(xbnf, out info); * int ts; * var symbols =XbnfConvert.GetSymbolTable(info, out ts); * CfgGlrParseTable parseTable; * info.Cfg.RebuildCache(); * info.Cfg.TryToGlrParseTable(out parseTable, LRTableKind.Lalr1); * var errorSentinels = new List<int>(); * var i = 0; * var parseAttributes = new ParseAttribute[symbols.Count][]; * foreach(var attrs in info.Cfg.AttributeSets) * { * var id = symbols.IndexOf(attrs.Key); * int jc = attrs.Value.Count; * parseAttributes[id] = new ParseAttribute[jc]; * for(var j=0;j<jc;++j) * { * var attr = attrs.Value[j]; * parseAttributes[id][j] = new ParseAttribute(attr.Name, attr.Value); * if ("errorSentinel" == attr.Name && attr.Value is bool && ((bool)attr.Value)) * errorSentinels.Add(id); * * } ++i; * } * for (i = 0; i < parseAttributes.Length; i++) * if (null == parseAttributes[i]) * parseAttributes[i] = new ParseAttribute[0]; * * var parser = new GlrTableParser(parseTable.ToArray(symbols), symbols.ToArray(), parseAttributes, errorSentinels.ToArray(),tokenizer); * foreach (var pt in parser.ParseReductions(false, true, false)) * { * Console.WriteLine(pt.ToString("t")); * } * return 0; * }*/ public static int Run(string[] args, TextReader stdin, TextWriter stdout, TextWriter stderr) { int result = 0; TextWriter output = null; string inputfile = null; string outputfile = null; string rolexfile = null; string codenamespace = null; string codelanguage = null; string codeclass = null; string yaccfile = null; bool verbose = false; bool noshared = false; bool ifstale = false; bool fast = false; bool noparser = false; try { if (0 == args.Length) { _PrintUsage(stderr); return(-1); } if (args[0].StartsWith("/")) { throw new ArgumentException("Missing input file."); } // process the command line args inputfile = args[0]; for (var i = 1; i < args.Length; ++i) { switch (args[i]) { case "/namespace": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codenamespace = args[i]; break; case "/class": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codeclass = args[i]; break; case "/language": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance codelanguage = args[i]; break; case "/output": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance outputfile = args[i]; break; case "/yacc": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance yaccfile = args[i]; break; case "/ifstale": ifstale = true; break; case "/fast": fast = true; break; case "/noparser": noparser = true; break; case "/noshared": noshared = true; break; case "/verbose": verbose = true; break; case "/rolex": if (args.Length - 1 == i) // check if we're at the end { throw new ArgumentException(string.Format("The parameter \"{0}\" is missing an argument", args[i].Substring(1))); } ++i; // advance rolexfile = args[i]; break; default: throw new ArgumentException(string.Format("Unknown switch {0}", args[i])); } } if (null != outputfile && noparser) { throw new ArgumentException("<noparser> and <ouputfile> cannot both be specified.", "outputfile"); } if (null == codeclass) { if (null != outputfile) { codeclass = Path.GetFileNameWithoutExtension(outputfile); } else { codeclass = Path.GetFileNameWithoutExtension(inputfile); } } // override the options with our document's options var doc = XbnfDocument.ReadFrom(inputfile); var oi = -1; oi = doc.Options.IndexOf("outputfile"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (null != s) { outputfile = s; if ("" == outputfile) { outputfile = null; } } // if it's specified in the doc we need to make it doc relative if (null != outputfile) { if (!Path.IsPathRooted(outputfile)) { var dir = Path.GetDirectoryName(Path.GetFullPath(inputfile)); outputfile = Path.GetFullPath(Path.Combine(dir, outputfile)); } } } oi = doc.Options.IndexOf("rolexfile"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (null != s) { rolexfile = s; if ("" == rolexfile) { rolexfile = null; } } // if it's specified in the doc we need to make it doc relative if (null != rolexfile) { if (!Path.IsPathRooted(rolexfile)) { var dir = Path.GetDirectoryName(Path.GetFullPath(inputfile)); rolexfile = Path.GetFullPath(Path.Combine(dir, rolexfile)); } } } oi = doc.Options.IndexOf("yaccfile"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (null != s) { rolexfile = s; if ("" == yaccfile) { yaccfile = null; } } // if it's specified in the doc we need to make it doc relative if (null != yaccfile) { if (!Path.IsPathRooted(yaccfile)) { var dir = Path.GetDirectoryName(Path.GetFullPath(inputfile)); rolexfile = Path.GetFullPath(Path.Combine(dir, yaccfile)); } } } oi = doc.Options.IndexOf("codenamespace"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (null != s) { codenamespace = s; } } oi = doc.Options.IndexOf("codelanguage"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (!string.IsNullOrEmpty(s)) { codelanguage = s; } } oi = doc.Options.IndexOf("codeclass"); if (-1 < oi) { var o = doc.Options[oi].Value; var s = o as string; if (null != s) { codeclass = s; if ("" == codeclass) { if (null != outputfile) { codeclass = Path.GetFileNameWithoutExtension(outputfile); } else { codeclass = Path.GetFileNameWithoutExtension(inputfile); } } } } oi = doc.Options.IndexOf("verbose"); if (-1 < oi) { var o = doc.Options[oi].Value; if (o is bool) { verbose = (bool)o; } } oi = doc.Options.IndexOf("fast"); if (-1 < oi) { var o = doc.Options[oi].Value; if (o is bool) { fast = (bool)o; } } if (fast && null != codelanguage) { throw new ArgumentException("<codelanguage> and <fast> cannot both be specified. The <fast> option is C# only."); } var stale = true; if (ifstale) { stale = false; if (!stale && null != rolexfile) { if (_IsStale(inputfile, rolexfile)) { stale = true; } } if (!stale && null != yaccfile) { if (_IsStale(inputfile, yaccfile)) { stale = true; } } if (!stale) { var files = XbnfDocument.GetResources(inputfile); foreach (var s in files) { if (_IsStale(s, outputfile)) { stale = true; break; } } } // see if our exe has changed if (!stale && null != outputfile && _IsStale(CodeBase, outputfile)) { stale = true; } } if (!stale) { stderr.WriteLine("Skipped building of the following because they were not stale:"); if (null != outputfile) { stderr.WriteLine("Output file: " + outputfile); } if (null != rolexfile) { stderr.WriteLine("Rolex file: " + rolexfile); } if (null != yaccfile) { stderr.WriteLine("YACC file: " + yaccfile); } } else { stderr.WriteLine("{0} is building the following:", Name); if (null != outputfile) { stderr.WriteLine("Output file: " + outputfile); } if (null != rolexfile) { stderr.WriteLine("Rolex file: " + rolexfile); } if (null != yaccfile) { stderr.WriteLine("YACC file: " + yaccfile); } if (string.IsNullOrEmpty(codelanguage)) { if (!string.IsNullOrEmpty(outputfile)) { codelanguage = Path.GetExtension(outputfile); if (codelanguage.StartsWith(".")) { codelanguage = codelanguage.Substring(1); } } if (string.IsNullOrEmpty(codelanguage)) { codelanguage = "cs"; } } var isLexerOnly = true; if (doc.HasNonTerminalProductions) { isLexerOnly = false; } else { foreach (var include in doc.Includes) { if (include.Document.HasNonTerminalProductions) { isLexerOnly = false; break; } } } // we need to prepare it by marking every terminal // with an attribute if it isn't already. we use // "terminal" because it doesn't impact terminals // in any way, but this way the CfgDocument can // "see" them. for (int ic = doc.Productions.Count, i = 0; i < ic; ++i) { var p = doc.Productions[i]; if (p.IsTerminal && 0 == p.Attributes.Count) { p.Attributes.Add(new XbnfAttribute("terminal", true)); } } XbnfGenerationInfo genInfo; var msgs = XbnfConvert.TryCreateGenerationInfo(doc, out genInfo); foreach (var msg in msgs) { if (verbose || ErrorLevel.Information != msg.ErrorLevel) { stderr.WriteLine(msg); } } foreach (var msg in msgs) { if (msg.ErrorLevel == ErrorLevel.Error) { throw new Exception(msg.ToString()); } } CfgDocument primaryCfg = genInfo.Cfg; doc = genInfo.Xbnf; if (!isLexerOnly) { if (verbose) { stderr.WriteLine("Final grammar:"); stderr.WriteLine(primaryCfg.ToString()); stderr.WriteLine(); } foreach (var msg in msgs) { if (msg.ErrorLevel == ErrorLevel.Error) { throw new Exception(msg.ToString()); } } if (!noparser) { var ccu = CodeGenerator.GenerateCompileUnit(genInfo, codeclass, codenamespace, fast); ccu.Namespaces.Add(new CodeNamespace(codenamespace ?? "")); var ccuNS = ccu.Namespaces[ccu.Namespaces.Count - 1]; var ccuShared = CodeGenerator.GenerateSharedCompileUnit(codenamespace); ccu.ReferencedAssemblies.Add(typeof(TypeConverter).Assembly.GetName().ToString()); if (fast) { CD.CodeDomVisitor.Visit(ccu, (ctx) => { var vd = ctx.Target as CodeVariableDeclarationStatement; if (null != vd && CD.CodeDomResolver.IsNullOrVoidType(vd.Type)) { vd.Type = C.Type("var"); } }, CD.CodeDomVisitTargets.All & ~(CD.CodeDomVisitTargets.Expressions | CD.CodeDomVisitTargets.Comments | CD.CodeDomVisitTargets.Attributes | CD.CodeDomVisitTargets.Directives | CD.CodeDomVisitTargets.Types | CD.CodeDomVisitTargets.TypeRefs)); CD.CodeDomVisitor.Visit(ccuShared, (ctx) => { var vd = ctx.Target as CodeVariableDeclarationStatement; if (null != vd && CD.CodeDomResolver.IsNullOrVoidType(vd.Type)) { vd.Type = C.Type("var"); } }, CD.CodeDomVisitTargets.All & ~(CD.CodeDomVisitTargets.Expressions | CD.CodeDomVisitTargets.Comments | CD.CodeDomVisitTargets.Attributes | CD.CodeDomVisitTargets.Directives | CD.CodeDomVisitTargets.Types | CD.CodeDomVisitTargets.TypeRefs)); } else { SlangPatcher.Patch(ccu, ccuShared); var co = SlangPatcher.GetNextUnresolvedElement(ccu); if (null != co) { stderr.WriteLine("Warning: Not all of the elements could be resolved. The generated code may not be correct in all languages."); stderr.WriteLine(" Next unresolved: {0}", C.ToString(co).Trim()); } } if (!noshared) { CodeGenerator.ImportCompileUnit(ccuNS, ccuShared); } var prov = CodeDomProvider.CreateProvider(codelanguage); if (null != outputfile) { var sw = new StreamWriter(outputfile); sw.BaseStream.SetLength(0); output = sw; } else { output = stdout; } var opts = new CodeGeneratorOptions(); opts.VerbatimOrder = true; opts.BlankLinesBetweenMembers = false; prov.GenerateCodeFromCompileUnit(ccu, output, opts); output.Flush(); output.Close(); output = null; } } else { stderr.WriteLine("{0} skipped parser generation because there are no non-terminals and no imports defined.", Name); } if (null != rolexfile) { var sw = new StreamWriter(rolexfile); sw.BaseStream.SetLength(0); output = sw; output.WriteLine(XbnfConvert.ToRolexSpec(genInfo)); output.Flush(); output.Close(); output = null; } if (null != yaccfile) { var sw = new StreamWriter(yaccfile); sw.BaseStream.SetLength(0); output = sw; output.WriteLine(genInfo.Cfg.ToString("y")); output.Flush(); output.Close(); output = null; } } } #if !DEBUG catch (Exception ex) { result = _ReportError(ex, stderr); } #endif finally { stderr.Close(); stdout.Close(); if (outputfile != null && null != output) { output.Close(); } } return(result); }