1 using System;
2 using System.Collections;
3 using System.IO;
4
5 namespace soulcm.scm2html
6 {
7 public class GrammarHtmlGeneratorVisitor : Visitor
8 {
9 public GrammarHtmlGeneratorVisitor(bool verbose_, HashMap<GrammarParser*, Grammar*>& parserGrammarMap_, HashMap<RuleParser*, Rule*>& parserRuleMap_, HashMap<LexerFile*, Grammar*>& lexerGrammarMap_, HashMap<Expression*, Rule*>& lexerRuleMap_, HashMap<ustring, LexerFile*>& lexerMap_, const ustring& styleFilePath_) :
10 verbose(verbose_), parserGrammarMap(parserGrammarMap_), parserRuleMap(parserRuleMap_), lexerGrammarMap(lexerGrammarMap_), lexerRuleMap(lexerRuleMap_), lexerMap(lexerMap_), styleFilePath(styleFilePath_), ruleTable(null), ruleBodyElement(null), currentGrammar(null), lexerFile(null)
11 {
12 }
13 public Grammar* GetGrammar(GrammarParser* parser) const
14 {
15 HashMap<GrammarParser*, Grammar*>.ConstIterator it = parserGrammarMap.CFind(parser);
16 if (it != parserGrammarMap.CEnd())
17 {
18 return it->second;
19 }
20 else
21 {
22 throw Exception("grammar for parser \'" + ToUtf8(parser->Name()) + "\' not found");
23 }
24 }
25 public Rule* GetRule(RuleParser* parser) const
26 {
27 HashMap<RuleParser*, Rule*>.ConstIterator it = parserRuleMap.CFind(parser);
28 if (it != parserRuleMap.CEnd())
29 {
30 return it->second;
31 }
32 else
33 {
34 throw Exception("rule for parser \'" + ToUtf8(parser->Name()) + "\' not found");
35 }
36 }
37 public override void Visit(Char& symbol)
38 {
39 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
40 spanElement->SetAttribute(u"class", u"ruleChar");
41 ustring s = CharStr(symbol.Chr());
42 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
43 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
44 }
45 public override void Visit(Any& symbol)
46 {
47 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
48 spanElement->SetAttribute(u"class", u"ruleOp");
49 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u".")));
50 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
51 }
52 public override void Visit(Range& symbol)
53 {
54 if (symbol.Start() == symbol.End())
55 {
56 UniquePtr<System.Dom.Element> startSpanElement(new System.Dom.Element(u"span"));
57 startSpanElement->SetAttribute(u"class", u"ruleCharSet");
58 ustring s = CharStr(symbol.Start());
59 startSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
60 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(startSpanElement.Release()));
61 }
62 else
63 {
64 UniquePtr<System.Dom.Element> startSpanElement(new System.Dom.Element(u"span"));
65 startSpanElement->SetAttribute(u"class", u"ruleCharSet");
66 ustring s = CharStr(symbol.Start());
67 startSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
68 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(startSpanElement.Release()));
69 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
70 spanElement->SetAttribute(u"class", u"ruleOp");
71 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.EntityReference(u"#8209")));
72 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
73 UniquePtr<System.Dom.Element> endSpanElement(new System.Dom.Element(u"span"));
74 endSpanElement->SetAttribute(u"class", u"ruleCharSet");
75 ustring t = CharStr(symbol.End());
76 endSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(t)));
77 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(endSpanElement.Release()));
78 }
79 }
80 public override void Visit(Class& symbol)
81 {
82 UniquePtr<System.Dom.Element> leftSpanElement(new System.Dom.Element(u"span"));
83 leftSpanElement->SetAttribute(u"class", u"ruleOp");
84 leftSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"[")));
85 if (symbol.Inverse())
86 {
87 leftSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"^")));
88 }
89 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(leftSpanElement.Release()));
90 for (Symbol* symbol : symbol.Symbols())
91 {
92 symbol->Accept(*this);
93 }
94 UniquePtr<System.Dom.Element> rightSpanElement(new System.Dom.Element(u"span"));
95 rightSpanElement->SetAttribute(u"class", u"ruleOp");
96 rightSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"]")));
97 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(rightSpanElement.Release()));
98 }
99 public override void Visit(Alt& alt)
100 {
101 alt.Left()->Accept(*this);
102 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
103 spanElement->SetAttribute(u"class", u"ruleOp");
104 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" | ")));
105 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
106 alt.Right()->Accept(*this);
107 }
108 public override void Visit(Cat& cat)
109 {
110 bool chars = cat.Left()->IsCharSymbolExpr() && cat.Right()->IsCharSymbolExpr();
111 cat.Left()->Accept(*this);
112 if (!chars)
113 {
114 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
115 spanElement->SetAttribute(u"class", u"ruleOp");
116 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" ")));
117 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
118 }
119 cat.Right()->Accept(*this);
120 }
121 public override void Visit(Kleene& kleene)
122 {
123 kleene.Child()->Accept(*this);
124 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
125 spanElement->SetAttribute(u"class", u"ruleOp");
126 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"*")));
127 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
128 }
129 public override void Visit(Pos& pos)
130 {
131 pos.Child()->Accept(*this);
132 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
133 spanElement->SetAttribute(u"class", u"ruleOp");
134 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"+")));
135 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
136 }
137 public override void Visit(Opt& opt)
138 {
139 opt.Child()->Accept(*this);
140 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
141 spanElement->SetAttribute(u"class", u"ruleOp");
142 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"?")));
143 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
144 }
145 public override void Visit(ParenExpr& parenExpr)
146 {
147 UniquePtr<System.Dom.Element> leftSpanElement(new System.Dom.Element(u"span"));
148 leftSpanElement->SetAttribute(u"class", u"ruleOp");
149 leftSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"(")));
150 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(leftSpanElement.Release()));
151 parenExpr.Child()->Accept(*this);
152 UniquePtr<System.Dom.Element> rightSpanElement(new System.Dom.Element(u"span"));
153 rightSpanElement->SetAttribute(u"class", u"ruleOp");
154 rightSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u")")));
155 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(rightSpanElement.Release()));
156 }
157 public override void Visit(SymbolExpr& symbolExpr)
158 {
159 symbolExpr.GetSymbol()->Accept(*this);
160 }
161 public override void Visit(RefExpr& refExpr)
162 {
163 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
164 spanElement->SetAttribute(u"class", u"lexerRule");
165 UniquePtr<System.Dom.Element> linkElement(new System.Dom.Element(u"a"));
166 linkElement->SetAttribute(u"class", u"lexerRule");
167 ustring linkText;
168 HashMap<LexerFile*, Grammar*>.ConstIterator grammarIt = lexerGrammarMap.CFind(lexerFile);
169 if (grammarIt != lexerGrammarMap.CEnd())
170 {
171 Grammar* grammar = grammarIt->second;
172 linkText.Append(grammar->HtmlFileName());
173 }
174 else
175 {
176 throw Exception("lexical grammar not found");
177 }
178 Expression* expression = lexerFile->GetExpressions()->Get(refExpr.ExprId());
179 Rule* rule = null;
180 HashMap<Expression*, Rule*>.ConstIterator ruleIt = lexerRuleMap.CFind(expression);
181 if (ruleIt != lexerRuleMap.CEnd())
182 {
183 rule = ruleIt->second;
184 linkText.Append(u"#").Append(rule->Name());
185 }
186 else
187 {
188 throw Exception("lexical rule not found");
189 }
190 linkElement->SetAttribute(u"href", linkText);
191 AppendRuleName(linkElement.Get(), rule->Name());
192 spanElement->AppendChild(UniquePtr<System.Dom.Node>(linkElement.Release()));
193 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
194 }
195 public override void Visit(EmptyParser& parser)
196 {
197 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
198 spanElement->SetAttribute(u"class", u"ruleOp");
199 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"<empty>")));
200 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
201 }
202 public override void Visit(AnyParser& parser)
203 {
204 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
205 spanElement->SetAttribute(u"class", u"ruleOp");
206 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"<any>")));
207 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
208 }
209 public override void Visit(TokenParser& parser)
210 {
211 ustring keyword;
212 if ((lexerFile != null))
213 {
214 Keywords* keywords = lexerFile->GetKeywords();
215 if ((keywords != null))
216 {
217 keyword = keywords->GetKeyword(parser.TokenName());
218 }
219 }
220 if (!keyword.IsEmpty())
221 {
222 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
223 spanElement->SetAttribute(u"class", u"ruleKeyword");
224 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(keyword)));
225 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
226 }
227 else
228 {
229 RegExpression* regEx = null;
230 if ((lexerFile != null))
231 {
232 LexerStatement* statement = lexerFile->GetLexer()->GetStatement(parser.TokenName());
233 if ((statement != null))
234 {
235 regEx = statement->RegEx();
236 }
237 }
238 if ((regEx != null))
239 {
240 regEx->Accept(*this);
241 }
242 else
243 {
244 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
245 spanElement->SetAttribute(u"class", u"ruleString");
246 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(parser.TokenName())));
247 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
248 }
249 }
250 }
251 public override void Visit(CharParser& parser)
252 {
253 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
254 spanElement->SetAttribute(u"class", u"ruleChar");
255 ustring s = CharStr(parser.Chr());
256 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
257 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
258 }
259 public override void Visit(StringParser& parser)
260 {
261 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
262 spanElement->SetAttribute(u"class", u"ruleString");
263 ustring s = StringStr(parser.Str());
264 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
265 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
266 }
267 public override void Visit(CharSetParser& parser)
268 {
269 ustring text = u"[";
270 if (parser.Set().Inverse())
271 {
272 text.Append(u"^");
273 }
274 for (const System.Parsing.Range& range : parser.Set().Ranges())
275 {
276 text.Append(CharStr(cast<uchar>(range.first)));
277 if (range.last != range.first)
278 {
279 text.Append('-', 1).Append(CharStr(cast<uchar>(range.last)));
280 }
281 }
282 text.Append(']', 1);
283 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
284 spanElement->SetAttribute(u"class", u"ruleCharSet");
285 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(text)));
286 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
287 }
288 public override void Visit(OptionalParser& parser)
289 {
290 parser.Child()->Accept(*this);
291 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
292 spanElement->SetAttribute(u"class", u"ruleOp");
293 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"?")));
294 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
295 }
296 public override void Visit(KleeneParser& parser)
297 {
298 parser.Child()->Accept(*this);
299 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
300 spanElement->SetAttribute(u"class", u"ruleOp");
301 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"*")));
302 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
303 }
304 public override void Visit(PositiveParser& parser)
305 {
306 parser.Child()->Accept(*this);
307 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
308 spanElement->SetAttribute(u"class", u"ruleOp");
309 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"+")));
310 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
311 }
312 public override void Visit(ExpectationParser& parser)
313 {
314 parser.Child()->Accept(*this);
315 }
316 public override void Visit(GroupingParser& parser)
317 {
318 if (parser.Parent() == null || parser.Parent()->IsAction() || ((parser.Parent()->IsPostfix() || parser.ParentIsList()) && parser.Child()->IsAction()))
319 {
320 parser.Child()->Accept(*this);
321 }
322 else
323 {
324 UniquePtr<System.Dom.Element> leftSpanElement(new System.Dom.Element(u"span"));
325 leftSpanElement->SetAttribute(u"class", u"ruleOp");
326 leftSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u"(")));
327 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(leftSpanElement.Release()));
328 parser.Child()->Accept(*this);
329 UniquePtr<System.Dom.Element> rightSpanElement(new System.Dom.Element(u"span"));
330 rightSpanElement->SetAttribute(u"class", u"ruleOp");
331 rightSpanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u")")));
332 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(rightSpanElement.Release()));
333 }
334 }
335 public override void Visit(SequenceParser& parser)
336 {
337 if (parser.Left()->IsEmptyOrEmptyActionParser())
338 {
339 if (!parser.Right()->IsEmptyOrEmptyActionParser())
340 {
341 parser.Right()->Accept(*this);
342 }
343 }
344 else if (parser.Right()->IsEmptyOrEmptyActionParser())
345 {
346 if (!parser.Left()->IsEmptyOrEmptyActionParser())
347 {
348 parser.Left()->Accept(*this);
349 }
350 }
351 else
352 {
353 parser.Left()->Accept(*this);
354 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
355 spanElement->SetAttribute(u"class", u"ruleOp");
356 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" ")));
357 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
358 parser.Right()->Accept(*this);
359 }
360 }
361 public override void Visit(AlternativeParser& parser)
362 {
363 parser.Left()->Accept(*this);
364 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
365 spanElement->SetAttribute(u"class", u"ruleOp");
366 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" | ")));
367 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
368 parser.Right()->Accept(*this);
369 }
370 public override void Visit(DifferenceParser& parser)
371 {
372 parser.Left()->Accept(*this);
373 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
374 spanElement->SetAttribute(u"class", u"ruleOp");
375 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" ")));
376 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.EntityReference(u"minus")));
377 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" ")));
378 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
379 parser.Right()->Accept(*this);
380 }
381 public override void Visit(ListParser& parser)
382 {
383 parser.Left()->Accept(*this);
384 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
385 spanElement->SetAttribute(u"class", u"ruleOp");
386 spanElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(u" % ")));
387 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
388 parser.Right()->Accept(*this);
389 }
390 public override void Visit(ActionParser& parser)
391 {
392 parser.Child()->Accept(*this);
393 }
394 public override void Visit(NonterminalParser& parser)
395 {
396 UniquePtr<System.Dom.Element> spanElement(new System.Dom.Element(u"span"));
397 spanElement->SetAttribute(u"class", u"ruleLink");
398 UniquePtr<System.Dom.Element> linkElement(new System.Dom.Element(u"a"));
399 linkElement->SetAttribute(u"class", u"ruleLink");
400 RuleParser* ruleParser = parser.Rule();
401 GrammarParser* grammarParser = ruleParser->GetGrammar();
402 Rule* rule = GetRule(ruleParser);
403 ustring linkText;
404 if (grammarParser == currentGrammar)
405 {
406 linkText.Append(u"#").Append(rule->Name());
407 }
408 else
409 {
410 Grammar* grammar = GetGrammar(grammarParser);
411 linkText.Append(grammar->HtmlFileName()).Append(u"#").Append(rule->Name());
412 }
413 linkElement->SetAttribute(u"href", linkText);
414 AppendRuleName(linkElement.Get(), rule->Name());
415 spanElement->AppendChild(UniquePtr<System.Dom.Node>(linkElement.Release()));
416 ruleBodyElement->AppendChild(UniquePtr<System.Dom.Node>(spanElement.Release()));
417 }
418 public override void Visit(RuleParser& parser)
419 {
420 UniquePtr<System.Dom.Element> trElement(new System.Dom.Element(u"tr"));
421 Rule* rule = GetRule(&parser);
422 trElement->SetAttribute(u"id", rule->Name());
423 UniquePtr<System.Dom.Element> tdNameElement(new System.Dom.Element(u"td"));
424 tdNameElement->SetAttribute(u"class", u"grammarFirstCol");
425 UniquePtr<System.Dom.Element> ruleSpanElement(new System.Dom.Element(u"span"));
426 ruleSpanElement->SetAttribute(u"class", u"rule");
427 AppendRuleName(ruleSpanElement.Get(), rule->Name());
428 tdNameElement->AppendChild(UniquePtr<System.Dom.Node>(ruleSpanElement.Release()));
429 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdNameElement.Release()));
430 UniquePtr<System.Dom.Element> tdArrowElement(new System.Dom.Element(u"td"));
431 tdArrowElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.EntityReference(u"rarr")));
432 tdArrowElement->SetAttribute(u"class", u"grammarSecondCol");
433 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdArrowElement.Release()));
434 UniquePtr<System.Dom.Element> tdRuleBodyElement(new System.Dom.Element(u"td"));
435 tdRuleBodyElement->SetAttribute(u"class", u"grammarThirdCol");
436 tdRuleBodyElement->SetAttribute(u"xml:space", u"preserve");
437 ruleBodyElement = tdRuleBodyElement.Get();
438 parser.Definition()->Accept(*this);
439 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdRuleBodyElement.Release()));
440 ruleTable->AppendChild(UniquePtr<System.Dom.Node>(trElement.Release()));
441 }
442 public override void Visit(GrammarParser& parser)
443 {
444 Grammar* grammar = GetGrammar(&parser);
445 GrammarParser* prevGrammar = currentGrammar;
446 currentGrammar = &parser;
447 LexerFile* prevLexerFile = lexerFile;
448 HashMap<ustring, LexerFile*>.ConstIterator it = lexerMap.CFind(parser.Lexer());
449 if (it != lexerMap.CEnd())
450 {
451 lexerFile = it->second;
452 }
453 UniquePtr<System.Dom.Document> grammarDoc(new System.Dom.Document());
454 UniquePtr<System.Dom.Element> htmlElement(new System.Dom.Element(u"html"));
455 UniquePtr<System.Dom.Element> headElement(new System.Dom.Element(u"head"));
456 UniquePtr<System.Dom.Element> metaElement(new System.Dom.Element(u"meta"));
457 metaElement->SetAttribute(u"charset", u"utf-8");
458 headElement->AppendChild(UniquePtr<System.Dom.Node>(metaElement.Release()));
459 UniquePtr<System.Dom.Element> titleElement(new System.Dom.Element(u"title"));
460 titleElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(grammar->Title())));
461 headElement->AppendChild(UniquePtr<System.Dom.Node>(titleElement.Release()));
462 UniquePtr<System.Dom.Element> linkElement(new System.Dom.Element(u"link"));
463 linkElement->SetAttribute(u"rel", u"stylesheet");
464 linkElement->SetAttribute(u"type", u"text/css");
465 linkElement->SetAttribute(u"href", styleFilePath);
466 headElement->AppendChild(UniquePtr<System.Dom.Node>(linkElement.Release()));
467 htmlElement->AppendChild(UniquePtr<System.Dom.Node>(headElement.Release()));
468 UniquePtr<System.Dom.Element> bodyElement(new System.Dom.Element(u"body"));
469 UniquePtr<System.Dom.Element> headerElement(new System.Dom.Element(u"h1"));
470 headerElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(grammar->Title())));
471 bodyElement->AppendChild(UniquePtr<System.Dom.Node>(headerElement.Release()));
472 UniquePtr<System.Dom.Element> tableElement(new System.Dom.Element(u"table"));
473 tableElement->SetAttribute(u"class", u"grammar");
474 ruleTable = tableElement.Get();
475 int n = cast<int>(parser.Rules().Count());
476 for (int i = 0; i < n; ++i;)
477 {
478 parser.Rules()[i]->Accept(*this);
479 }
480 bodyElement->AppendChild(UniquePtr<System.Dom.Node>(tableElement.Release()));
481 htmlElement->AppendChild(UniquePtr<System.Dom.Node>(bodyElement.Release()));
482 grammarDoc->AppendChild(UniquePtr<System.Dom.Node>(htmlElement.Release()));
483 StreamWriter htmlFile = File.CreateText(grammar->HtmlFilePath());
484 System.Text.CodeFormatter formatter(htmlFile);
485 formatter.SetIndentSize(1);
486 grammarDoc->Write(formatter);
487 currentGrammar = prevGrammar;
488 lexerFile = prevLexerFile;
489 if (verbose)
490 {
491 Console.Out() << "==> " << grammar->HtmlFilePath() << endl();
492 }
493 }
494 public override void Visit(ParserFile& parserFile)
495 {
496 for (const UniquePtr<GrammarParser>& grammar : parserFile.Parsers())
497 {
498 grammar->Accept(*this);
499 }
500 }
501 public override void Visit(Domain& domain)
502 {
503 for (ParserFile* parserFile : domain.ParserFiles())
504 {
505 parserFile->Accept(*this);
506 }
507 }
508 public override void Visit(LexerFile& lexerFile)
509 {
510 this->lexerFile = &lexerFile;
511 HashMap<LexerFile*, Grammar*>.ConstIterator it = lexerGrammarMap.CFind(this->lexerFile);
512 if (it != lexerGrammarMap.CEnd())
513 {
514 Grammar* grammar = it->second;
515 UniquePtr<System.Dom.Document> grammarDoc(new System.Dom.Document());
516 UniquePtr<System.Dom.Element> htmlElement(new System.Dom.Element(u"html"));
517 UniquePtr<System.Dom.Element> headElement(new System.Dom.Element(u"head"));
518 UniquePtr<System.Dom.Element> metaElement(new System.Dom.Element(u"meta"));
519 metaElement->SetAttribute(u"charset", u"utf-8");
520 headElement->AppendChild(UniquePtr<System.Dom.Node>(metaElement.Release()));
521 UniquePtr<System.Dom.Element> titleElement(new System.Dom.Element(u"title"));
522 titleElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(grammar->Title())));
523 headElement->AppendChild(UniquePtr<System.Dom.Node>(titleElement.Release()));
524 UniquePtr<System.Dom.Element> linkElement(new System.Dom.Element(u"link"));
525 linkElement->SetAttribute(u"rel", u"stylesheet");
526 linkElement->SetAttribute(u"type", u"text/css");
527 linkElement->SetAttribute(u"href", styleFilePath);
528 headElement->AppendChild(UniquePtr<System.Dom.Node>(linkElement.Release()));
529 htmlElement->AppendChild(UniquePtr<System.Dom.Node>(headElement.Release()));
530 UniquePtr<System.Dom.Element> bodyElement(new System.Dom.Element(u"body"));
531 UniquePtr<System.Dom.Element> headerElement(new System.Dom.Element(u"h1"));
532 headerElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(grammar->Title())));
533 bodyElement->AppendChild(UniquePtr<System.Dom.Node>(headerElement.Release()));
534 UniquePtr<System.Dom.Element> tableElement(new System.Dom.Element(u"table"));
535 tableElement->SetAttribute(u"class", u"grammar");
536 ruleTable = tableElement.Get();
537 int n = cast<int>(grammar->Rules().Count());
538 for (int i = 0; i < n; ++i;)
539 {
540 Rule* rule = grammar->Rules()[i].Get();
541 UniquePtr<System.Dom.Element> trElement(new System.Dom.Element(u"tr"));
542 trElement->SetAttribute(u"id", rule->Name());
543 UniquePtr<System.Dom.Element> tdNameElement(new System.Dom.Element(u"td"));
544 tdNameElement->SetAttribute(u"class", u"grammarFirstCol");
545 UniquePtr<System.Dom.Element> ruleSpanElement(new System.Dom.Element(u"span"));
546 ruleSpanElement->SetAttribute(u"class", u"rule");
547 AppendRuleName(ruleSpanElement.Get(), rule->Name());
548 tdNameElement->AppendChild(UniquePtr<System.Dom.Node>(ruleSpanElement.Release()));
549 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdNameElement.Release()));
550 UniquePtr<System.Dom.Element> tdArrowElement(new System.Dom.Element(u"td"));
551 tdArrowElement->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.EntityReference(u"rarr")));
552 tdArrowElement->SetAttribute(u"class", u"grammarSecondCol");
553 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdArrowElement.Release()));
554 UniquePtr<System.Dom.Element> tdRuleBodyElement(new System.Dom.Element(u"td"));
555 tdRuleBodyElement->SetAttribute(u"class", u"grammarThirdCol");
556 tdRuleBodyElement->SetAttribute(u"xml:space", u"preserve");
557 ruleBodyElement = tdRuleBodyElement.Get();
558 rule->GetExpression()->RegEx()->Accept(*this);
559 trElement->AppendChild(UniquePtr<System.Dom.Node>(tdRuleBodyElement.Release()));
560 ruleTable->AppendChild(UniquePtr<System.Dom.Node>(trElement.Release()));
561 }
562 bodyElement->AppendChild(UniquePtr<System.Dom.Node>(tableElement.Release()));
563 htmlElement->AppendChild(UniquePtr<System.Dom.Node>(bodyElement.Release()));
564 grammarDoc->AppendChild(UniquePtr<System.Dom.Node>(htmlElement.Release()));
565 StreamWriter htmlFile = File.CreateText(grammar->HtmlFilePath());
566 System.Text.CodeFormatter formatter(htmlFile);
567 formatter.SetIndentSize(1);
568 grammarDoc->Write(formatter);
569 if (verbose)
570 {
571 Console.Out() << "==> " << grammar->HtmlFilePath() << endl();
572 }
573 }
574 else
575 {
576 throw Exception("lexical grammar not found");
577 }
578 }
579 private bool verbose;
580 private HashMap<GrammarParser*, Grammar*>& parserGrammarMap;
581 private HashMap<RuleParser*, Rule*>& parserRuleMap;
582 private HashMap<LexerFile*, Grammar*>& lexerGrammarMap;
583 private HashMap<Expression*, Rule*>& lexerRuleMap;
584 private HashMap<ustring, LexerFile*>& lexerMap;
585 private LexerFile* lexerFile;
586 private ustring styleFilePath;
587 private System.Dom.Element* ruleTable;
588 private System.Dom.Element* ruleBodyElement;
589 private GrammarParser* currentGrammar;
590 }
591
592 public void AppendRuleName(System.Dom.Element* parent, const ustring& name)
593 {
594 for (uchar c : name)
595 {
596 ustring s(c);
597 if (c == '-')
598 {
599 parent->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.EntityReference(u"#8209")));
600 }
601 else
602 {
603 parent->AppendChild(UniquePtr<System.Dom.Node>(new System.Dom.Text(s)));
604 }
605 }
606 }
607 }