Skip to content

Commit a816a21

Browse files
authored
Merge pull request #2135 from wilzbach/generate-grammar
Automatically generate the grammar overview
2 parents f6c6003 + 57b9970 commit a816a21

File tree

5 files changed

+117
-1914
lines changed

5 files changed

+117
-1914
lines changed

ddoc_preprocessor.d

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ All unknown options are passed to the compiler.
4949
args = args[0..pos].chain("-".only, args[pos..$].dropOne).array;
5050

5151
// transform and extend the ddoc page
52+
text = genGrammar(text);
5253
text = genHeader(text);
5354

5455
// inject custom, "dynamic" macros
@@ -194,3 +195,61 @@ auto genHeader(string fileText)
194195
return updateDdocTag(fileText, ddocKey, newContent);
195196
}
196197

198+
// parse the menu from the Ddoc file
199+
auto specTocEntries()
200+
{
201+
alias Entry = Tuple!(string, "name", string, "title", string, "fileName");
202+
Entry[] entries;
203+
204+
static immutable specDir = __FILE_FULL_PATH__.dirName.buildNormalizedPath("spec");
205+
static immutable mainFile = specDir.buildPath("./spec.ddoc");
206+
207+
auto specText = mainFile.readText;
208+
if (!specText.findSkip("SUBMENU2"))
209+
writeln("Menu file has an invalid format.");
210+
foreach (line; specText.splitter("\n"))
211+
{
212+
enum ddocEntryStart = "$(ROOT_DIR)spec/";
213+
if (line.find!(not!isWhite).startsWith(ddocEntryStart))
214+
{
215+
auto ps = line.splitter(ddocEntryStart).dropOne.front.splitter(",");
216+
auto name = ps.front.stripExtension.withExtension(".dd").to!string;
217+
auto fileName = specDir.buildPath(name);
218+
auto title = ps.dropOne.front.idup.strip;
219+
entries ~= Entry(name, title, fileName);
220+
}
221+
}
222+
return entries;
223+
}
224+
225+
// Automatically generate spec/grammar
226+
auto genGrammar(string fileText)
227+
{
228+
import std.uni : toLower;
229+
230+
enum ddocKey = "$(GRAMMAR_SUMMARY";
231+
auto newContent = ddocKey ~ "\n";
232+
233+
if (fileText.canFind(ddocKey))
234+
{
235+
foreach (i, entry; specTocEntries)
236+
{
237+
if (entry.fileName.endsWith("grammar.dd", "lex.dd", "simd.dd"))
238+
continue;
239+
240+
enum grammarKey = "$(GRAMMAR";
241+
auto text = entry.fileName.readText.find(grammarKey);
242+
if (text.length)
243+
newContent ~= "$(H2 $(LNAME2 %s, %s))\n".format(entry.title.toLower, entry.title);
244+
for (; text.length; text = text[ grammarKey.length .. $].find(grammarKey))
245+
{
246+
newContent ~= grammarKey;
247+
newContent ~= text.drop(grammarKey.length).untilClosingParentheses.to!string;
248+
newContent ~= ")\n";
249+
}
250+
}
251+
return updateDdocTag(fileText, ddocKey, newContent);
252+
}
253+
return fileText;
254+
}
255+

spec/declaration.dd

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ $(GNAME AltDeclaratorSuffixes):
7474

7575
$(GNAME AltDeclaratorSuffix):
7676
$(D [ ])
77-
$(D [) $(VEXPRESSION) $(D ])
77+
$(D [) $($(GLINK2 expression, AssignExpression)) $(D ])
7878
$(D [) $(GLINK Type) $(D ])
7979

8080
$(GNAME AltFuncDeclaratorSuffix):
@@ -135,8 +135,8 @@ $(GNAME BasicType2):
135135
$(GNAME BasicType2X):
136136
$(D *)
137137
$(D [ ])
138-
$(D [) $(VEXPRESSION) $(D ])
139-
$(D [) $(VEXPRESSION) .. $(VEXPRESSION) $(D ])
138+
$(D [) $($(GLINK2 expression, AssignExpression)) $(D ])
139+
$(D [) $($(GLINK2 expression, AssignExpression)) .. $($(GLINK2 expression, AssignExpression)) $(D ])
140140
$(D [) $(GLINK Type) $(D ])
141141
$(D delegate) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT)
142142
$(D function) $(GLINK2 function, Parameters) $(GLINK2 function, FunctionAttributes)$(OPT)
@@ -146,7 +146,7 @@ $(GNAME IdentifierList):
146146
$(I Identifier) $(D .) $(I IdentifierList)
147147
$(GLINK2 template, TemplateInstance)
148148
$(GLINK2 template, TemplateInstance) $(D .) $(I IdentifierList)
149-
$(I Identifier) $(D [) $(ASSIGNEXPRESSION) $(D].) $(I IdentifierList)
149+
$(I Identifier) $(D [) $($(GLINK2 expression, AssignExpression)) $(D].) $(I IdentifierList)
150150
)
151151

152152
$(GRAMMAR
@@ -189,7 +189,7 @@ $(GNAME NonVoidInitializer):
189189
$(GLINK StructInitializer)
190190

191191
$(GNAME ExpInitializer):
192-
$(ASSIGNEXPRESSION)
192+
$($(GLINK2 expression, AssignExpression))
193193

194194
$(GNAME ArrayInitializer):
195195
$(D [) $(GLINK ArrayMemberInitializations)$(OPT) $(D ])
@@ -201,7 +201,7 @@ $(GNAME ArrayMemberInitializations):
201201

202202
$(GNAME ArrayMemberInitialization):
203203
$(GLINK NonVoidInitializer)
204-
$(ASSIGNEXPRESSION) $(D :) $(GLINK NonVoidInitializer)
204+
$($(GLINK2 expression, AssignExpression)) $(D :) $(GLINK NonVoidInitializer)
205205

206206
$(GNAME StructInitializer):
207207
$(D {) $(GLINK StructMemberInitializers)$(OPT) $(D })
@@ -501,7 +501,7 @@ $(H2 $(LNAME2 typeof, $(D typeof)))
501501

502502
$(GRAMMAR
503503
$(GNAME Typeof):
504-
$(D typeof $(LPAREN)) $(EXPRESSION) $(D $(RPAREN))
504+
$(D typeof $(LPAREN)) $(GLINK2 expression, Expression) $(D $(RPAREN))
505505
$(D typeof $(LPAREN)) $(D return) $(D $(RPAREN))
506506
)
507507

@@ -748,7 +748,3 @@ $(SPEC_SUBNAV_PREV_NEXT module, Modules, type, Types)
748748
Macros:
749749
CHAPTER=5
750750
TITLE=Declarations
751-
ASSIGNEXPRESSION=$(GLINK2 expression, AssignExpression)
752-
EXPRESSION=$(GLINK2 expression, Expression)
753-
VEXPRESSION=$(ASSIGNEXPRESSION)
754-
_=

0 commit comments

Comments
 (0)