redsnow 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +34 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +20 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +21 -0
  8. data/README.md +62 -0
  9. data/Rakefile +36 -0
  10. data/Vagrantfile +20 -0
  11. data/ext/snowcrash/Makefile +64 -0
  12. data/ext/snowcrash/Vagrantfile +20 -0
  13. data/ext/snowcrash/bin/snowcrash +0 -0
  14. data/ext/snowcrash/common.gypi +163 -0
  15. data/ext/snowcrash/config.gypi +10 -0
  16. data/ext/snowcrash/config.mk +5 -0
  17. data/ext/snowcrash/configure +213 -0
  18. data/ext/snowcrash/provisioning.sh +15 -0
  19. data/ext/snowcrash/snowcrash.gyp +141 -0
  20. data/ext/snowcrash/src/ActionParser.h +503 -0
  21. data/ext/snowcrash/src/AssetParser.h +215 -0
  22. data/ext/snowcrash/src/BlockUtility.h +186 -0
  23. data/ext/snowcrash/src/Blueprint.h +283 -0
  24. data/ext/snowcrash/src/BlueprintParser.h +347 -0
  25. data/ext/snowcrash/src/BlueprintParserCore.h +190 -0
  26. data/ext/snowcrash/src/BlueprintSection.h +140 -0
  27. data/ext/snowcrash/src/BlueprintUtility.h +126 -0
  28. data/ext/snowcrash/src/CBlueprint.cc +600 -0
  29. data/ext/snowcrash/src/CBlueprint.h +354 -0
  30. data/ext/snowcrash/src/CSourceAnnotation.cc +140 -0
  31. data/ext/snowcrash/src/CSourceAnnotation.h +106 -0
  32. data/ext/snowcrash/src/CodeBlockUtility.h +189 -0
  33. data/ext/snowcrash/src/DescriptionSectionUtility.h +156 -0
  34. data/ext/snowcrash/src/HTTP.cc +46 -0
  35. data/ext/snowcrash/src/HTTP.h +105 -0
  36. data/ext/snowcrash/src/HeaderParser.h +289 -0
  37. data/ext/snowcrash/src/ListBlockUtility.h +273 -0
  38. data/ext/snowcrash/src/ListUtility.h +95 -0
  39. data/ext/snowcrash/src/MarkdownBlock.cc +176 -0
  40. data/ext/snowcrash/src/MarkdownBlock.h +93 -0
  41. data/ext/snowcrash/src/MarkdownParser.cc +266 -0
  42. data/ext/snowcrash/src/MarkdownParser.h +88 -0
  43. data/ext/snowcrash/src/ParameterDefinitonParser.h +570 -0
  44. data/ext/snowcrash/src/ParametersParser.h +252 -0
  45. data/ext/snowcrash/src/Parser.cc +71 -0
  46. data/ext/snowcrash/src/Parser.h +29 -0
  47. data/ext/snowcrash/src/ParserCore.cc +120 -0
  48. data/ext/snowcrash/src/ParserCore.h +82 -0
  49. data/ext/snowcrash/src/PayloadParser.h +672 -0
  50. data/ext/snowcrash/src/Platform.h +54 -0
  51. data/ext/snowcrash/src/RegexMatch.h +32 -0
  52. data/ext/snowcrash/src/ResourceGroupParser.h +195 -0
  53. data/ext/snowcrash/src/ResourceParser.h +584 -0
  54. data/ext/snowcrash/src/SectionUtility.h +142 -0
  55. data/ext/snowcrash/src/Serialize.cc +52 -0
  56. data/ext/snowcrash/src/Serialize.h +69 -0
  57. data/ext/snowcrash/src/SerializeJSON.cc +601 -0
  58. data/ext/snowcrash/src/SerializeJSON.h +21 -0
  59. data/ext/snowcrash/src/SerializeYAML.cc +336 -0
  60. data/ext/snowcrash/src/SerializeYAML.h +21 -0
  61. data/ext/snowcrash/src/SourceAnnotation.h +177 -0
  62. data/ext/snowcrash/src/StringUtility.h +109 -0
  63. data/ext/snowcrash/src/SymbolTable.h +83 -0
  64. data/ext/snowcrash/src/UriTemplateParser.cc +195 -0
  65. data/ext/snowcrash/src/UriTemplateParser.h +243 -0
  66. data/ext/snowcrash/src/Version.h +39 -0
  67. data/ext/snowcrash/src/csnowcrash.cc +23 -0
  68. data/ext/snowcrash/src/csnowcrash.h +38 -0
  69. data/ext/snowcrash/src/posix/RegexMatch.cc +99 -0
  70. data/ext/snowcrash/src/snowcrash.cc +18 -0
  71. data/ext/snowcrash/src/snowcrash.h +41 -0
  72. data/ext/snowcrash/src/snowcrash/snowcrash.cc +170 -0
  73. data/ext/snowcrash/src/win/RegexMatch.cc +78 -0
  74. data/ext/snowcrash/sundown/CONTRIBUTING.md +10 -0
  75. data/ext/snowcrash/sundown/Makefile +83 -0
  76. data/ext/snowcrash/sundown/Makefile.win +33 -0
  77. data/ext/snowcrash/sundown/examples/smartypants.c +72 -0
  78. data/ext/snowcrash/sundown/examples/sundown.c +80 -0
  79. data/ext/snowcrash/sundown/html/houdini.h +37 -0
  80. data/ext/snowcrash/sundown/html/houdini_href_e.c +108 -0
  81. data/ext/snowcrash/sundown/html/houdini_html_e.c +84 -0
  82. data/ext/snowcrash/sundown/html/html.c +647 -0
  83. data/ext/snowcrash/sundown/html/html.h +77 -0
  84. data/ext/snowcrash/sundown/html/html_smartypants.c +389 -0
  85. data/ext/snowcrash/sundown/html_block_names.txt +25 -0
  86. data/ext/snowcrash/sundown/src/autolink.c +297 -0
  87. data/ext/snowcrash/sundown/src/autolink.h +51 -0
  88. data/ext/snowcrash/sundown/src/buffer.c +225 -0
  89. data/ext/snowcrash/sundown/src/buffer.h +96 -0
  90. data/ext/snowcrash/sundown/src/html_blocks.h +206 -0
  91. data/ext/snowcrash/sundown/src/markdown.c +2701 -0
  92. data/ext/snowcrash/sundown/src/markdown.h +147 -0
  93. data/ext/snowcrash/sundown/src/src_map.c +200 -0
  94. data/ext/snowcrash/sundown/src/src_map.h +58 -0
  95. data/ext/snowcrash/sundown/src/stack.c +81 -0
  96. data/ext/snowcrash/sundown/src/stack.h +29 -0
  97. data/ext/snowcrash/sundown/sundown.def +20 -0
  98. data/ext/snowcrash/tools/gyp/AUTHORS +11 -0
  99. data/ext/snowcrash/tools/gyp/DEPS +24 -0
  100. data/ext/snowcrash/tools/gyp/OWNERS +1 -0
  101. data/ext/snowcrash/tools/gyp/PRESUBMIT.py +120 -0
  102. data/ext/snowcrash/tools/gyp/buildbot/buildbot_run.py +190 -0
  103. data/ext/snowcrash/tools/gyp/codereview.settings +10 -0
  104. data/ext/snowcrash/tools/gyp/data/win/large-pdb-shim.cc +12 -0
  105. data/ext/snowcrash/tools/gyp/gyp +8 -0
  106. data/ext/snowcrash/tools/gyp/gyp.bat +5 -0
  107. data/ext/snowcrash/tools/gyp/gyp_main.py +18 -0
  108. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSNew.py +340 -0
  109. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSProject.py +208 -0
  110. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSSettings.py +1063 -0
  111. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSToolFile.py +58 -0
  112. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUserFile.py +147 -0
  113. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSUtil.py +267 -0
  114. data/ext/snowcrash/tools/gyp/pylib/gyp/MSVSVersion.py +409 -0
  115. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.py +537 -0
  116. data/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
  117. data/ext/snowcrash/tools/gyp/pylib/gyp/common.py +521 -0
  118. data/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
  119. data/ext/snowcrash/tools/gyp/pylib/gyp/easy_xml.py +157 -0
  120. data/ext/snowcrash/tools/gyp/pylib/gyp/flock_tool.py +49 -0
  121. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.py +0 -0
  122. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
  123. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/android.py +1069 -0
  124. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/cmake.py +1143 -0
  125. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/dump_dependency_json.py +81 -0
  126. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/eclipse.py +335 -0
  127. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypd.py +87 -0
  128. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/gypsh.py +56 -0
  129. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.py +2181 -0
  130. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
  131. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/msvs.py +3335 -0
  132. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/ninja.py +2156 -0
  133. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.py +1224 -0
  134. data/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
  135. data/ext/snowcrash/tools/gyp/pylib/gyp/input.py +2809 -0
  136. data/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
  137. data/ext/snowcrash/tools/gyp/pylib/gyp/mac_tool.py +510 -0
  138. data/ext/snowcrash/tools/gyp/pylib/gyp/msvs_emulation.py +972 -0
  139. data/ext/snowcrash/tools/gyp/pylib/gyp/ninja_syntax.py +160 -0
  140. data/ext/snowcrash/tools/gyp/pylib/gyp/ordered_dict.py +289 -0
  141. data/ext/snowcrash/tools/gyp/pylib/gyp/win_tool.py +292 -0
  142. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.py +1440 -0
  143. data/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
  144. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.py +2889 -0
  145. data/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
  146. data/ext/snowcrash/tools/gyp/pylib/gyp/xml_fix.py +69 -0
  147. data/ext/snowcrash/tools/gyp/pylintrc +307 -0
  148. data/ext/snowcrash/tools/gyp/samples/samples +81 -0
  149. data/ext/snowcrash/tools/gyp/samples/samples.bat +5 -0
  150. data/ext/snowcrash/tools/gyp/setup.py +19 -0
  151. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.pbfilespec +27 -0
  152. data/ext/snowcrash/tools/gyp/tools/Xcode/Specifications/gyp.xclangspec +226 -0
  153. data/ext/snowcrash/tools/gyp/tools/emacs/gyp.el +252 -0
  154. data/ext/snowcrash/tools/gyp/tools/graphviz.py +100 -0
  155. data/ext/snowcrash/tools/gyp/tools/pretty_gyp.py +155 -0
  156. data/ext/snowcrash/tools/gyp/tools/pretty_sln.py +168 -0
  157. data/ext/snowcrash/tools/gyp/tools/pretty_vcproj.py +329 -0
  158. data/ext/snowcrash/tools/homebrew/snowcrash.rb +11 -0
  159. data/ext/snowcrash/vcbuild.bat +184 -0
  160. data/lib/redsnow.rb +31 -0
  161. data/lib/redsnow/binding.rb +132 -0
  162. data/lib/redsnow/blueprint.rb +365 -0
  163. data/lib/redsnow/object.rb +18 -0
  164. data/lib/redsnow/parseresult.rb +107 -0
  165. data/lib/redsnow/version.rb +4 -0
  166. data/provisioning.sh +20 -0
  167. data/redsnow.gemspec +35 -0
  168. data/test/_helper.rb +15 -0
  169. data/test/fixtures/sample-api-ast.json +97 -0
  170. data/test/fixtures/sample-api.apib +20 -0
  171. data/test/redsnow_binding_test.rb +35 -0
  172. data/test/redsnow_parseresult_test.rb +50 -0
  173. data/test/redsnow_test.rb +285 -0
  174. metadata +358 -0
@@ -0,0 +1,347 @@
1
+ //
2
+ // BlueprintParser.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 4/16/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_BLUEPRINTPARSER_H
10
+ #define SNOWCRASH_BLUEPRINTPARSER_H
11
+
12
+ #include <functional>
13
+ #include <sstream>
14
+ #include <iterator>
15
+ #include "Blueprint.h"
16
+ #include "BlueprintParserCore.h"
17
+ #include "ResourceParser.h"
18
+ #include "ResourceGroupParser.h"
19
+
20
+ namespace snowcrashconst {
21
+
22
+ const char* const ExpectedAPINameMessage = "expected API name, e.g. '# <API Name>'";
23
+ }
24
+
25
+ namespace snowcrash {
26
+
27
+ /** Internal list items classifier, Blueprint Context */
28
+ template <>
29
+ FORCEINLINE SectionType ClassifyInternaListBlock<Blueprint>(const BlockIterator& begin,
30
+ const BlockIterator& end) {
31
+ return UndefinedSectionType;
32
+ }
33
+
34
+ /** Block Classifier, Blueprint Context */
35
+ template <>
36
+ FORCEINLINE SectionType ClassifyBlock<Blueprint>(const BlockIterator& begin,
37
+ const BlockIterator& end,
38
+ const SectionType& context) {
39
+
40
+ if (HasResourceGroupSignature(*begin) ||
41
+ HasResourceSignature(*begin))
42
+ return ResourceGroupSectionType; // Treat Resource as anonymous resource group
43
+
44
+ return (context == ResourceGroupSectionType) ? UndefinedSectionType : BlueprintSectionType;
45
+ }
46
+
47
+
48
+ /** Blueprint SectionType Parser */
49
+ template<>
50
+ struct SectionParser<Blueprint> {
51
+
52
+ static ParseSectionResult ParseSection(const BlueprintSection& section,
53
+ const BlockIterator& cur,
54
+ BlueprintParserCore& parser,
55
+ Blueprint& output) {
56
+
57
+ ParseSectionResult result = std::make_pair(Result(), cur);
58
+
59
+ switch (section.type) {
60
+
61
+ case BlueprintSectionType:
62
+ result = HandleBlueprintDescriptionBlock(section, cur, parser, output);
63
+ break;
64
+
65
+ case ResourceGroupSectionType:
66
+ result = HandleResourceGroup(section, cur, parser, output);
67
+ break;
68
+
69
+ default:
70
+ result.first.error = UnexpectedBlockError(section, cur, parser.sourceData);
71
+ break;
72
+ }
73
+
74
+ return result;
75
+ }
76
+
77
+ static void Finalize(const SectionBounds& bounds,
78
+ BlueprintParserCore& parser,
79
+ Blueprint& blueprint,
80
+ Result& result) {}
81
+
82
+ /**
83
+ * \brief Checks API Blueprint name issues warning or error if name does not exists.
84
+ * \param cur Cursor to the expected name header block
85
+ * \param blueprint Blueprint to check.
86
+ * \param parser A parser's instance.
87
+ * \param result Check result report.
88
+ * \result Returns false if a name is missing AND RequireBlueprintNameOption is set. True otherwise.
89
+ */
90
+ static bool CheckBlueprintName(const BlockIterator& cur,
91
+ const Blueprint& blueprint,
92
+ BlueprintParserCore& parser,
93
+ Result& result) {
94
+
95
+ if (!blueprint.name.empty())
96
+ return true;
97
+
98
+ if (parser.options & RequireBlueprintNameOption) {
99
+
100
+ // ERR: No API name specified
101
+ result.error = Error(snowcrashconst::ExpectedAPINameMessage,
102
+ BusinessError,
103
+ MapSourceDataBlock(cur->sourceMap, parser.sourceData));
104
+ return false;
105
+ }
106
+
107
+ // WARN: No API name specified
108
+ result.warnings.push_back(Warning(snowcrashconst::ExpectedAPINameMessage,
109
+ APINameWarning,
110
+ MapSourceDataBlock(cur->sourceMap, parser.sourceData)));
111
+
112
+ return true;
113
+ }
114
+
115
+ // Returns true if given block is first block in document
116
+ // after metadata block, false otherwise.
117
+ static bool IsFirstBlock(const BlockIterator& cur,
118
+ const SectionBounds& bounds,
119
+ const Blueprint& blueprint) {
120
+
121
+ if (blueprint.metadata.empty())
122
+ return cur == bounds.first;
123
+
124
+ return std::distance(bounds.first, cur) == 1;
125
+ }
126
+
127
+ static ParseSectionResult HandleBlueprintDescriptionBlock(const BlueprintSection& section,
128
+ const BlockIterator& cur,
129
+ BlueprintParserCore& parser,
130
+ Blueprint& output) {
131
+
132
+ ParseSectionResult result = std::make_pair(Result(), cur);
133
+ BlockIterator sectionCur(cur);
134
+
135
+ // API Name
136
+ bool isFirstBlock = IsFirstBlock(cur, section.bounds, output);
137
+ if (isFirstBlock &&
138
+ sectionCur->type == HeaderBlockType) {
139
+
140
+ output.name = cur->content;
141
+
142
+ // Check ambiguity
143
+ CheckHeaderBlock<Blueprint>(section, sectionCur, parser.sourceData, result.first);
144
+
145
+ // Check Name
146
+ if (!CheckBlueprintName(sectionCur, output, parser, result.first))
147
+ return result;
148
+
149
+ result.second = ++sectionCur;
150
+ return result;
151
+ }
152
+
153
+ // Metadata
154
+ if (isFirstBlock &&
155
+ sectionCur->type == ParagraphBlockType) {
156
+
157
+ result = ParseMetadataBlock(sectionCur, section.bounds, parser, output);
158
+ if (result.second != sectionCur)
159
+ return result;
160
+ }
161
+
162
+ // Description
163
+ result = ParseDescriptionBlock<Blueprint>(section, sectionCur, parser.sourceData, output);
164
+
165
+ // Check Name
166
+ if (isFirstBlock)
167
+ CheckBlueprintName(sectionCur, output, parser, result.first);
168
+
169
+ return result;
170
+ }
171
+
172
+ static ParseSectionResult HandleResourceGroup(const BlueprintSection& section,
173
+ const BlockIterator& cur,
174
+ BlueprintParserCore& parser,
175
+ Blueprint& output)
176
+ {
177
+
178
+ // Mandatory name check
179
+ ParseSectionResult result = std::make_pair(Result(), cur);
180
+ if (IsFirstBlock(cur, section.bounds, output) &&
181
+ !CheckBlueprintName(cur, output, parser, result.first))
182
+ return result;
183
+
184
+ // Parser resource group
185
+ ResourceGroup resourceGroup;
186
+ result = ResourceGroupParser::Parse(cur,
187
+ section.bounds.second,
188
+ section,
189
+ parser,
190
+ resourceGroup);
191
+
192
+ if (result.first.error.code != Error::OK)
193
+ return result;
194
+
195
+ Collection<ResourceGroup>::const_iterator duplicate = FindResourceGroup(parser.blueprint, resourceGroup);
196
+ if (duplicate != parser.blueprint.resourceGroups.end()) {
197
+
198
+ // WARN: duplicate group
199
+ std::stringstream ss;
200
+ if (resourceGroup.name.empty()) {
201
+ ss << "anonymous group";
202
+ }
203
+ else {
204
+ ss << "group '" << resourceGroup.name << "'";
205
+ }
206
+ ss << " is already defined";
207
+
208
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, section.bounds.second, section.bounds, parser.sourceData);
209
+ result.first.warnings.push_back(Warning(ss.str(),
210
+ DuplicateWarning,
211
+ sourceBlock));
212
+ }
213
+
214
+ output.resourceGroups.push_back(resourceGroup); // FIXME: C++11 move
215
+ return result;
216
+ }
217
+
218
+
219
+ static ParseSectionResult ParseMetadataBlock(const BlockIterator& cur,
220
+ const SectionBounds& bounds,
221
+ BlueprintParserCore& parser,
222
+ Blueprint& output) {
223
+
224
+ typedef Collection<Metadata>::type MetadataCollection;
225
+ typedef Collection<Metadata>::iterator MetadataCollectionIterator;
226
+ MetadataCollection metadataCollection;
227
+
228
+ ParseSectionResult result = std::make_pair(Result(), cur);
229
+ SourceData content = cur->content;
230
+ TrimStringEnd(content);
231
+ std::vector<std::string> lines = Split(content, '\n');
232
+ for (std::vector<std::string>::iterator line = lines.begin();
233
+ line != lines.end();
234
+ ++line) {
235
+
236
+ Metadata metadata;
237
+ if (KeyValueFromLine(*line, metadata))
238
+ metadataCollection.push_back(metadata);
239
+ }
240
+
241
+ if (lines.size() == metadataCollection.size()) {
242
+
243
+ // Check duplicates
244
+ std::vector<std::string> duplicateKeys;
245
+ for (MetadataCollectionIterator it = metadataCollection.begin();
246
+ it != metadataCollection.end();
247
+ ++it) {
248
+
249
+ MetadataCollectionIterator from = it;
250
+ if (++from == metadataCollection.end())
251
+ break;
252
+
253
+ MetadataCollectionIterator duplicate = std::find_if(from,
254
+ metadataCollection.end(),
255
+ std::bind2nd(MatchFirsts<Metadata>(), *it));
256
+
257
+ if (duplicate != metadataCollection.end() &&
258
+ std::find(duplicateKeys.begin(), duplicateKeys.end(), it->first) == duplicateKeys.end()) {
259
+
260
+ duplicateKeys.push_back(it->first);
261
+
262
+ // WARN: duplicate metada definition
263
+ std::stringstream ss;
264
+ ss << "duplicate definition of '" << it->first << "'";
265
+
266
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, bounds.second, bounds, parser.sourceData);
267
+ result.first.warnings.push_back(Warning(ss.str(),
268
+ DuplicateWarning,
269
+ sourceBlock));
270
+ }
271
+ }
272
+
273
+ // Insert parsed metadata into output
274
+ output.metadata.insert(output.metadata.end(),
275
+ metadataCollection.begin(),
276
+ metadataCollection.end());
277
+
278
+ ++result.second;
279
+ }
280
+ else if (!metadataCollection.empty()) {
281
+ // WARN: malformed metadata block
282
+ SourceCharactersBlock sourceBlock = CharacterMapForBlock(cur, bounds.second, bounds, parser.sourceData);
283
+ result.first.warnings.push_back(Warning("ignoring possible metadata, expected"
284
+ " '<key> : <value>', one one per line",
285
+ FormattingWarning,
286
+ sourceBlock));
287
+ }
288
+
289
+ return result;
290
+ }
291
+ };
292
+
293
+ typedef BlockParser<Blueprint, SectionParser<Blueprint> > BlueprintParserInner;
294
+
295
+
296
+ //
297
+ // Blueprint Parser
298
+ //
299
+ class BlueprintParser {
300
+ public:
301
+ // Parse Markdown AST into API Blueprint AST
302
+ static void Parse(const SourceData& sourceData,
303
+ const MarkdownBlock::Stack& source,
304
+ BlueprintParserOptions options,
305
+ Result& result,
306
+ Blueprint& blueprint) {
307
+
308
+ BlueprintParserCore parser(options, sourceData, blueprint);
309
+ BlueprintSection rootSection(std::make_pair(source.begin(), source.end()));
310
+ ParseSectionResult sectionResult = BlueprintParserInner::Parse(source.begin(),
311
+ source.end(),
312
+ rootSection,
313
+ parser,
314
+ blueprint);
315
+ result += sectionResult.first;
316
+
317
+ #ifdef DEBUG
318
+ PrintSymbolTable(parser.symbolTable);
319
+ #endif
320
+ if (result.error.code != Error::OK)
321
+ return;
322
+
323
+ PostParseCheck(sourceData, source, parser, result);
324
+ }
325
+
326
+ /**
327
+ * Perform additional post-parsing result checks.
328
+ * Mainly to focused on running checking when top-level parser is not executed.
329
+ */
330
+ static void PostParseCheck(const SourceData& sourceData,
331
+ const MarkdownBlock::Stack& source,
332
+ BlueprintParserCore& parser,
333
+ Result& result) {
334
+
335
+ if ((parser.options & RequireBlueprintNameOption) &&
336
+ parser.blueprint.name.empty()){
337
+
338
+ // ERR: No API name specified
339
+ result.error = Error(snowcrashconst::ExpectedAPINameMessage,
340
+ BusinessError,
341
+ MapSourceDataBlock(MakeSourceDataBlock(0, 0), parser.sourceData));
342
+ }
343
+ }
344
+ };
345
+ }
346
+
347
+ #endif
@@ -0,0 +1,190 @@
1
+ //
2
+ // BlueprintParserCore.h
3
+ // snowcrash
4
+ //
5
+ // Created by Zdenek Nemec on 5/4/13.
6
+ // Copyright (c) 2013 Apiary Inc. All rights reserved.
7
+ //
8
+
9
+ #ifndef SNOWCRASH_BLUEPRINTPARSERCORE_H
10
+ #define SNOWCRASH_BLUEPRINTPARSERCORE_H
11
+
12
+ #include <algorithm>
13
+ #include <sstream>
14
+ #include "ParserCore.h"
15
+ #include "SourceAnnotation.h"
16
+ #include "MarkdownBlock.h"
17
+ #include "BlueprintSection.h"
18
+ #include "HTTP.h"
19
+ #include "Blueprint.h"
20
+ #include "BlueprintUtility.h"
21
+ #include "StringUtility.h"
22
+ #include "SymbolTable.h"
23
+
24
+ namespace snowcrash {
25
+
26
+ /**
27
+ * \brief Blueprint Parser Options.
28
+ *
29
+ * Controls blueprint parser behavior.
30
+ */
31
+ enum BlueprintParserOption {
32
+ RenderDescriptionsOption = (1 << 0), /// < Render Markdown in description.
33
+ RequireBlueprintNameOption = (1 << 1) /// < Treat missing blueprint name as error
34
+ };
35
+
36
+ typedef unsigned int BlueprintParserOptions;
37
+
38
+ /**
39
+ * \brief Parsing subroutine result
40
+ *
41
+ * Consists of a parsing result report (first) and
42
+ * %BlockIterator (second) pointing to the last parsed
43
+ * markdown block.
44
+ */
45
+ typedef std::pair<Result, BlockIterator> ParseSectionResult;
46
+
47
+
48
+ /**
49
+ * Parser Core Data
50
+ */
51
+ struct BlueprintParserCore {
52
+ BlueprintParserCore(BlueprintParserOptions opts,
53
+ const SourceData& src,
54
+ const Blueprint& bp)
55
+ : options(opts), sourceData(src), blueprint(bp) {}
56
+
57
+ /** Parser Options */
58
+ BlueprintParserOptions options;
59
+
60
+ /** Symbol Table */
61
+ SymbolTable symbolTable;
62
+
63
+ /** Source Data */
64
+ const SourceData& sourceData;
65
+
66
+ /** AST being parsed **/
67
+ const Blueprint& blueprint;
68
+
69
+ private:
70
+ BlueprintParserCore();
71
+ BlueprintParserCore(const BlueprintParserCore&);
72
+ BlueprintParserCore& operator=(const BlueprintParserCore&);
73
+ };
74
+
75
+ /**
76
+ * SectionType Parser prototype.
77
+ */
78
+ template<class T>
79
+ struct SectionParser {
80
+
81
+ /**
82
+ * \brief Parse section's blocks.
83
+ * \param section Actual section being parsed.
84
+ * \param cur Cursor within the section boundaries.
85
+ * \param parser Parser instance.
86
+ * \param output AST node parsed.
87
+ * \return %ParseSectionResult pointing to the last block parsed & including
88
+ * any possible source annotations in the form of results or warnings.
89
+ */
90
+ static ParseSectionResult ParseSection(const BlueprintSection& section,
91
+ const BlockIterator& cur,
92
+ BlueprintParserCore& parser,
93
+ T& output);
94
+
95
+ /**
96
+ * \brief Optional post-parse processing.
97
+ */
98
+ static void Finalize(const SectionBounds& bounds,
99
+ BlueprintParserCore& parser,
100
+ T& output,
101
+ Result& result);
102
+ };
103
+
104
+ /**
105
+ * \brief Internal list items classifier prototype.
106
+ *
107
+ * The classifier might look ahead.
108
+ * DO NOT provide generic implementation.
109
+ */
110
+ template <class T>
111
+ FORCEINLINE SectionType ClassifyInternaListBlock(const BlockIterator& begin,
112
+ const BlockIterator& end);
113
+ /**
114
+ * \brief Classify a block with children list items.
115
+ *
116
+ * Classifies internal list block & descend to children list block classifiers.
117
+ * DO NOT provide generic implementation.
118
+ */
119
+ template <class T>
120
+ FORCEINLINE SectionType ClassifyChildrenListBlock(const BlockIterator& begin,
121
+ const BlockIterator& end);
122
+
123
+ /**
124
+ * \brief Block Classifier prototype.
125
+ *
126
+ * The classifier might look ahead.
127
+ */
128
+ template <class T>
129
+ FORCEINLINE SectionType ClassifyBlock(const BlockIterator& begin,
130
+ const BlockIterator& end,
131
+ const SectionType& context);
132
+
133
+ // Forward declaration of classifier helpers
134
+ extern bool HasResourceGroupSignature(const MarkdownBlock& block);
135
+ extern bool HasActionSignature(const MarkdownBlock& block);
136
+ extern bool HasResourceSignature(const MarkdownBlock& block);
137
+ extern bool HasPayloadSignature(const BlockIterator& begin, const BlockIterator& end);
138
+ extern bool HasPayloadAssetSignature(const BlockIterator& begin, const BlockIterator& end);
139
+ extern bool HasAssetSignature(const BlockIterator& begin, const BlockIterator& end);
140
+ extern bool HasHeaderSignature(const BlockIterator& begin, const BlockIterator& end);
141
+ extern bool HasParametersSignature(const BlockIterator& begin, const BlockIterator& end);
142
+
143
+ /**
144
+ * \brief A Markdown block parser.
145
+ *
146
+ * Iterates over blocks classifying sections and calling relevant %SectionParser P<T>.
147
+ */
148
+ template <class T, class P>
149
+ struct BlockParser : public P {
150
+
151
+ // Iterate blocks, classify & parse
152
+ static ParseSectionResult Parse(const BlockIterator& begin,
153
+ const BlockIterator& end,
154
+ const BlueprintSection& parentSection,
155
+ BlueprintParserCore& parser,
156
+ T& output) {
157
+ Result result;
158
+ SectionType currentSectionType = UndefinedSectionType;
159
+ BlockIterator currentBlock = begin;
160
+ while (currentBlock != end) {
161
+
162
+ currentSectionType = ClassifyBlock<T>(currentBlock, end, currentSectionType);
163
+ BlueprintSection currentSection(currentSectionType, std::make_pair(begin, end), parentSection);
164
+
165
+ ParseSectionResult sectionResult = P::ParseSection(currentSection,
166
+ currentBlock,
167
+ parser,
168
+ output);
169
+
170
+ result += sectionResult.first;
171
+ if (result.error.code != Error::OK)
172
+ break;
173
+
174
+ if (sectionResult.second == currentBlock)
175
+ break;
176
+
177
+ currentBlock = sectionResult.second;
178
+
179
+ if (currentSectionType == UndefinedSectionType)
180
+ break;
181
+ }
182
+
183
+ P::Finalize(std::make_pair(begin, currentBlock), parser, output, result);
184
+
185
+ return std::make_pair(result, currentBlock);
186
+ }
187
+ };
188
+ }
189
+
190
+ #endif