ruco-cpp 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +17 -0
  3. data/bin/console +14 -0
  4. data/bin/ruco +30 -0
  5. data/bin/setup +7 -0
  6. data/data/ruco/Parser.frame +359 -0
  7. data/data/ruco/Scanner.frame +896 -0
  8. data/data/ruco/picojson/Changes +14 -0
  9. data/data/ruco/picojson/LICENSE +25 -0
  10. data/data/ruco/picojson/Makefile +8 -0
  11. data/data/ruco/picojson/README.mkdn +183 -0
  12. data/data/ruco/picojson/examples/github-issues.cc +110 -0
  13. data/data/ruco/picojson/examples/iostream.cc +70 -0
  14. data/data/ruco/picojson/examples/streaming.cc +76 -0
  15. data/data/ruco/picojson/picojson.h +1299 -0
  16. data/ext/cocor/Action.cpp +81 -0
  17. data/ext/cocor/Action.h +59 -0
  18. data/ext/cocor/ArrayList.cpp +79 -0
  19. data/ext/cocor/ArrayList.h +52 -0
  20. data/ext/cocor/BitArray.cpp +156 -0
  21. data/ext/cocor/BitArray.h +68 -0
  22. data/ext/cocor/CharClass.cpp +42 -0
  23. data/ext/cocor/CharClass.h +48 -0
  24. data/ext/cocor/CharSet.cpp +166 -0
  25. data/ext/cocor/CharSet.h +68 -0
  26. data/ext/cocor/Coco.atg +528 -0
  27. data/ext/cocor/Coco.cpp +173 -0
  28. data/ext/cocor/Comment.cpp +45 -0
  29. data/ext/cocor/Comment.h +51 -0
  30. data/ext/cocor/Copyright.frame +27 -0
  31. data/ext/cocor/DFA.cpp +865 -0
  32. data/ext/cocor/DFA.h +132 -0
  33. data/ext/cocor/Generator.cpp +182 -0
  34. data/ext/cocor/Generator.h +61 -0
  35. data/ext/cocor/Graph.h +59 -0
  36. data/ext/cocor/HashTable.cpp +115 -0
  37. data/ext/cocor/HashTable.h +84 -0
  38. data/ext/cocor/Makefile +11 -0
  39. data/ext/cocor/Melted.cpp +39 -0
  40. data/ext/cocor/Melted.h +51 -0
  41. data/ext/cocor/Node.cpp +69 -0
  42. data/ext/cocor/Node.h +86 -0
  43. data/ext/cocor/Parser.cpp +925 -0
  44. data/ext/cocor/Parser.frame +326 -0
  45. data/ext/cocor/Parser.h +153 -0
  46. data/ext/cocor/ParserGen.cpp +486 -0
  47. data/ext/cocor/ParserGen.h +99 -0
  48. data/ext/cocor/Position.cpp +37 -0
  49. data/ext/cocor/Position.h +46 -0
  50. data/ext/cocor/README.md +12 -0
  51. data/ext/cocor/Scanner.cpp +833 -0
  52. data/ext/cocor/Scanner.frame +897 -0
  53. data/ext/cocor/Scanner.h +291 -0
  54. data/ext/cocor/Sets.h +84 -0
  55. data/ext/cocor/SortedList.cpp +141 -0
  56. data/ext/cocor/SortedList.h +68 -0
  57. data/ext/cocor/State.cpp +77 -0
  58. data/ext/cocor/State.h +55 -0
  59. data/ext/cocor/StringBuilder.cpp +88 -0
  60. data/ext/cocor/StringBuilder.h +29 -0
  61. data/ext/cocor/Symbol.cpp +61 -0
  62. data/ext/cocor/Symbol.h +70 -0
  63. data/ext/cocor/Tab.cpp +1248 -0
  64. data/ext/cocor/Tab.h +245 -0
  65. data/ext/cocor/Target.cpp +41 -0
  66. data/ext/cocor/Target.h +48 -0
  67. data/ext/cocor/build.bat +3 -0
  68. data/ext/cocor/build.sh +4 -0
  69. data/ext/cocor/coc.bat +1 -0
  70. data/ext/cocor/coc.sh +2 -0
  71. data/ext/cocor/cocor_ruby_ext.cpp +124 -0
  72. data/ext/cocor/cygBuild.bat +1 -0
  73. data/ext/cocor/extconf.rb +5 -0
  74. data/ext/cocor/mingwbuild.bat +2 -0
  75. data/ext/cocor/mkmf.log +57 -0
  76. data/ext/cocor/zipsources.bat +1 -0
  77. data/lib/cocor.rb +14 -0
  78. data/lib/ruco/version.rb +3 -0
  79. data/lib/ruco.rb +728 -0
  80. metadata +195 -0
@@ -0,0 +1,486 @@
1
+ /*-------------------------------------------------------------------------
2
+ ParserGen -- Generation of the Recursive Descent Parser
3
+ Compiler Generator Coco/R,
4
+ Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
5
+ ported to C++ by Csaba Balazs, University of Szeged
6
+ extended by M. Loeberbauer & A. Woess, Univ. of Linz
7
+ with improvements by Pat Terry, Rhodes University
8
+
9
+ This program is free software; you can redistribute it and/or modify it
10
+ under the terms of the GNU General Public License as published by the
11
+ Free Software Foundation; either version 2, or (at your option) any
12
+ later version.
13
+
14
+ This program is distributed in the hope that it will be useful, but
15
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
+ for more details.
18
+
19
+ You should have received a copy of the GNU General Public License along
20
+ with this program; if not, write to the Free Software Foundation, Inc.,
21
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
+
23
+ As an exception, it is allowed to write an extension of Coco/R that is
24
+ used as a plugin in non-free software.
25
+
26
+ If not otherwise stated, any source code generated by Coco/R (other than
27
+ Coco/R itself) does not fall under the GNU General Public License.
28
+ -------------------------------------------------------------------------*/
29
+
30
+ #include <ctype.h>
31
+ #include "ArrayList.h"
32
+ #include "ParserGen.h"
33
+ #include "Parser.h"
34
+ #include "BitArray.h"
35
+ #include "Scanner.h"
36
+ #include "Generator.h"
37
+
38
+ namespace Coco {
39
+
40
+ void ParserGen::Indent (int n) {
41
+ for (int i = 1; i <= n; i++) fwprintf(gen, L"\t");
42
+ }
43
+
44
+ // use a switch if more than 5 alternatives and none starts with a resolver, and no LL1 warning
45
+ bool ParserGen::UseSwitch (Node *p) {
46
+ BitArray *s1, *s2;
47
+ if (p->typ != Node::alt) return false;
48
+ int nAlts = 0;
49
+ s1 = new BitArray(tab->terminals->Count);
50
+ while (p != NULL) {
51
+ s2 = tab->Expected0(p->sub, curSy);
52
+ // must not optimize with switch statement, if there are ll1 warnings
53
+ if (s1->Overlaps(s2)) { return false; }
54
+ s1->Or(s2);
55
+ ++nAlts;
56
+ // must not optimize with switch-statement, if alt uses a resolver expression
57
+ if (p->sub->typ == Node::rslv) return false;
58
+ p = p->down;
59
+ }
60
+ return nAlts > 5;
61
+ }
62
+
63
+ int ParserGen::GenNamespaceOpen(const wchar_t *nsName) {
64
+ if (nsName == NULL || coco_string_length(nsName) == 0) {
65
+ return 0;
66
+ }
67
+ const int len = coco_string_length(nsName);
68
+ int startPos = 0;
69
+ int nrOfNs = 0;
70
+ do {
71
+ int curLen = coco_string_indexof(nsName + startPos, COCO_CPP_NAMESPACE_SEPARATOR);
72
+ if (curLen == -1) { curLen = len - startPos; }
73
+ wchar_t *curNs = coco_string_create(nsName, startPos, curLen);
74
+ fwprintf(gen, L"namespace %ls {\n", curNs);
75
+ coco_string_delete(curNs);
76
+ startPos = startPos + curLen + 1;
77
+ if (startPos < len && nsName[startPos] == COCO_CPP_NAMESPACE_SEPARATOR) {
78
+ ++startPos;
79
+ }
80
+ ++nrOfNs;
81
+ } while (startPos < len);
82
+ return nrOfNs;
83
+ }
84
+
85
+ void ParserGen::GenNamespaceClose(int nrOfNs) {
86
+ for (int i = 0; i < nrOfNs; ++i) {
87
+ fwprintf(gen, L"} // namespace\n");
88
+ }
89
+ }
90
+
91
+ void ParserGen::CopySourcePart (Position *pos, int indent) {
92
+ // Copy text described by pos from atg to gen
93
+ int ch, i;
94
+ if (pos != NULL) {
95
+ buffer->SetPos(pos->beg); ch = buffer->Read();
96
+ if (tab->emitLines && pos->line) {
97
+ fwprintf(gen, L"\n#line %d \"%ls\"\n", pos->line, tab->srcName);
98
+ }
99
+ Indent(indent);
100
+ while (buffer->GetPos() <= pos->end) {
101
+ while (ch == CR || ch == LF) { // eol is either CR or CRLF or LF
102
+ fwprintf(gen, L"\n"); Indent(indent);
103
+ if (ch == CR) { ch = buffer->Read(); } // skip CR
104
+ if (ch == LF) { ch = buffer->Read(); } // skip LF
105
+ for (i = 1; i <= pos->col && (ch == ' ' || ch == '\t'); i++) {
106
+ // skip blanks at beginning of line
107
+ ch = buffer->Read();
108
+ }
109
+ if (buffer->GetPos() > pos->end) goto done;
110
+ }
111
+ fwprintf(gen, L"%lc", ch);
112
+ ch = buffer->Read();
113
+ }
114
+ done:
115
+ if (indent > 0) fwprintf(gen, L"\n");
116
+ }
117
+ }
118
+
119
+ void ParserGen::GenErrorMsg (int errTyp, Symbol *sym) {
120
+ errorNr++;
121
+ const int formatLen = 1000;
122
+ wchar_t format[formatLen];
123
+ coco_swprintf(format, formatLen, L"\t\t\tcase %d: s = coco_string_create(L\"", errorNr);
124
+ coco_string_merge(err, format);
125
+ if (errTyp == tErr) {
126
+ if (sym->name[0] == L'"') {
127
+ coco_swprintf(format, formatLen, L"%ls expected", tab->Escape(sym->name));
128
+ coco_string_merge(err, format);
129
+ } else {
130
+ coco_swprintf(format, formatLen, L"%ls expected", sym->name);
131
+ coco_string_merge(err, format);
132
+ }
133
+ } else if (errTyp == altErr) {
134
+ coco_swprintf(format, formatLen, L"invalid %ls", sym->name);
135
+ coco_string_merge(err, format);
136
+ } else if (errTyp == syncErr) {
137
+ coco_swprintf(format, formatLen, L"this symbol not expected in %ls", sym->name);
138
+ coco_string_merge(err, format);
139
+ }
140
+ coco_swprintf(format, formatLen, L"\"); break;\n");
141
+ coco_string_merge(err, format);
142
+ }
143
+
144
+ int ParserGen::NewCondSet (BitArray *s) {
145
+ for (int i = 1; i < symSet->Count; i++) // skip symSet[0] (reserved for union of SYNC sets)
146
+ if (Sets::Equals(s, (BitArray*)(*symSet)[i])) return i;
147
+ symSet->Add(s->Clone());
148
+ return symSet->Count - 1;
149
+ }
150
+
151
+ void ParserGen::GenCond (BitArray *s, Node *p) {
152
+ if (p->typ == Node::rslv) CopySourcePart(p->pos, 0);
153
+ else {
154
+ int n = Sets::Elements(s);
155
+ if (n == 0) fwprintf(gen, L"false"); // happens if an ANY set matches no symbol
156
+ else if (n <= maxTerm) {
157
+ Symbol *sym;
158
+ for (int i=0; i<tab->terminals->Count; i++) {
159
+ sym = (Symbol*)((*(tab->terminals))[i]);
160
+ if ((*s)[sym->n]) {
161
+ fwprintf(gen, L"la->kind == ");
162
+ WriteSymbolOrCode(gen, sym);
163
+ --n;
164
+ if (n > 0) fwprintf(gen, L" || ");
165
+ }
166
+ }
167
+ } else
168
+ fwprintf(gen, L"StartOf(%d)", NewCondSet(s));
169
+ }
170
+ }
171
+
172
+ void ParserGen::PutCaseLabels (BitArray *s) {
173
+ Symbol *sym;
174
+ for (int i=0; i<tab->terminals->Count; i++) {
175
+ sym = (Symbol*)((*(tab->terminals))[i]);
176
+ if ((*s)[sym->n]) {
177
+ fwprintf(gen, L"case ");
178
+ WriteSymbolOrCode(gen, sym);
179
+ fwprintf(gen, L": ");
180
+ }
181
+ }
182
+ }
183
+
184
+ void ParserGen::GenCode (Node *p, int indent, BitArray *isChecked) {
185
+ Node *p2;
186
+ BitArray *s1, *s2;
187
+ while (p != NULL) {
188
+ if (p->typ == Node::nt) {
189
+ Indent(indent);
190
+ fwprintf(gen, L"%ls(", p->sym->name);
191
+ CopySourcePart(p->pos, 0);
192
+ fwprintf(gen, L");\n");
193
+ } else if (p->typ == Node::t) {
194
+ Indent(indent);
195
+ // assert: if isChecked[p->sym->n] is true, then isChecked contains only p->sym->n
196
+ if ((*isChecked)[p->sym->n]) fwprintf(gen, L"Get();\n");
197
+ else {
198
+ fwprintf(gen, L"Expect(");
199
+ WriteSymbolOrCode(gen, p->sym);
200
+ fwprintf(gen, L");\n");
201
+ }
202
+ } if (p->typ == Node::wt) {
203
+ Indent(indent);
204
+ s1 = tab->Expected(p->next, curSy);
205
+ s1->Or(tab->allSyncSets);
206
+ fwprintf(gen, L"ExpectWeak(");
207
+ WriteSymbolOrCode(gen, p->sym);
208
+ fwprintf(gen, L", %d);\n", NewCondSet(s1));
209
+ } if (p->typ == Node::any) {
210
+ Indent(indent);
211
+ int acc = Sets::Elements(p->set);
212
+ if (tab->terminals->Count == (acc + 1) || (acc > 0 && Sets::Equals(p->set, isChecked))) {
213
+ // either this ANY accepts any terminal (the + 1 = end of file), or exactly what's allowed here
214
+ fwprintf(gen, L"Get();\n");
215
+ } else {
216
+ GenErrorMsg(altErr, curSy);
217
+ if (acc > 0) {
218
+ fwprintf(gen, L"if ("); GenCond(p->set, p); fwprintf(gen, L") Get(); else SynErr(%d);\n", errorNr);
219
+ } else fwprintf(gen, L"SynErr(%d); // ANY node that matches no symbol\n", errorNr);
220
+ }
221
+ } if (p->typ == Node::eps) { // nothing
222
+ } if (p->typ == Node::rslv) { // nothing
223
+ } if (p->typ == Node::sem) {
224
+ CopySourcePart(p->pos, indent);
225
+ } if (p->typ == Node::sync) {
226
+ Indent(indent);
227
+ GenErrorMsg(syncErr, curSy);
228
+ s1 = p->set->Clone();
229
+ fwprintf(gen, L"while (!("); GenCond(s1, p); fwprintf(gen, L")) {");
230
+ fwprintf(gen, L"SynErr(%d); Get();", errorNr); fwprintf(gen, L"}\n");
231
+ } if (p->typ == Node::alt) {
232
+ s1 = tab->First(p);
233
+ bool equal = Sets::Equals(s1, isChecked);
234
+ bool useSwitch = UseSwitch(p);
235
+ if (useSwitch) { Indent(indent); fwprintf(gen, L"switch (la->kind) {\n"); }
236
+ p2 = p;
237
+ while (p2 != NULL) {
238
+ s1 = tab->Expected(p2->sub, curSy);
239
+ Indent(indent);
240
+ if (useSwitch) {
241
+ PutCaseLabels(s1); fwprintf(gen, L"{\n");
242
+ } else if (p2 == p) {
243
+ fwprintf(gen, L"if ("); GenCond(s1, p2->sub); fwprintf(gen, L") {\n");
244
+ } else if (p2->down == NULL && equal) { fwprintf(gen, L"} else {\n");
245
+ } else {
246
+ fwprintf(gen, L"} else if ("); GenCond(s1, p2->sub); fwprintf(gen, L") {\n");
247
+ }
248
+ GenCode(p2->sub, indent + 1, s1);
249
+ if (useSwitch) {
250
+ Indent(indent); fwprintf(gen, L"\tbreak;\n");
251
+ Indent(indent); fwprintf(gen, L"}\n");
252
+ }
253
+ p2 = p2->down;
254
+ }
255
+ Indent(indent);
256
+ if (equal) {
257
+ fwprintf(gen, L"}\n");
258
+ } else {
259
+ GenErrorMsg(altErr, curSy);
260
+ if (useSwitch) {
261
+ fwprintf(gen, L"default: SynErr(%d); break;\n", errorNr);
262
+ Indent(indent); fwprintf(gen, L"}\n");
263
+ } else {
264
+ fwprintf(gen, L"} "); fwprintf(gen, L"else SynErr(%d);\n", errorNr);
265
+ }
266
+ }
267
+ } if (p->typ == Node::iter) {
268
+ Indent(indent);
269
+ p2 = p->sub;
270
+ fwprintf(gen, L"while (");
271
+ if (p2->typ == Node::wt) {
272
+ s1 = tab->Expected(p2->next, curSy);
273
+ s2 = tab->Expected(p->next, curSy);
274
+ fwprintf(gen, L"WeakSeparator(");
275
+ WriteSymbolOrCode(gen, p2->sym);
276
+ fwprintf(gen, L",%d,%d) ", NewCondSet(s1), NewCondSet(s2));
277
+ s1 = new BitArray(tab->terminals->Count); // for inner structure
278
+ if (p2->up || p2->next == NULL) p2 = NULL; else p2 = p2->next;
279
+ } else {
280
+ s1 = tab->First(p2);
281
+ GenCond(s1, p2);
282
+ }
283
+ fwprintf(gen, L") {\n");
284
+ GenCode(p2, indent + 1, s1);
285
+ Indent(indent); fwprintf(gen, L"}\n");
286
+ } if (p->typ == Node::opt) {
287
+ s1 = tab->First(p->sub);
288
+ Indent(indent);
289
+ fwprintf(gen, L"if ("); GenCond(s1, p->sub); fwprintf(gen, L") {\n");
290
+ GenCode(p->sub, indent + 1, s1);
291
+ Indent(indent); fwprintf(gen, L"}\n");
292
+ }
293
+ if (p->typ != Node::eps && p->typ != Node::sem && p->typ != Node::sync)
294
+ isChecked->SetAll(false); // = new BitArray(Symbol.terminals.Count);
295
+ if (p->up) break;
296
+ p = p->next;
297
+ }
298
+ }
299
+
300
+
301
+ void ParserGen::GenTokensHeader() {
302
+ Symbol *sym;
303
+ int i;
304
+ bool isFirst = true;
305
+
306
+ fwprintf(gen, L"\tenum {\n");
307
+
308
+ // tokens
309
+ for (i=0; i<tab->terminals->Count; i++) {
310
+ sym = (Symbol*)((*(tab->terminals))[i]);
311
+ if (!isalpha(sym->name[0])) { continue; }
312
+
313
+ if (isFirst) { isFirst = false; }
314
+ else { fwprintf(gen , L",\n"); }
315
+
316
+ fwprintf(gen , L"\t\t_%ls=%d", sym->name, sym->n);
317
+ }
318
+
319
+ // pragmas
320
+ for (i=0; i<tab->pragmas->Count; i++) {
321
+ if (isFirst) { isFirst = false; }
322
+ else { fwprintf(gen , L",\n"); }
323
+
324
+ sym = (Symbol*)((*(tab->pragmas))[i]);
325
+ fwprintf(gen , L"\t\t_%ls=%d", sym->name, sym->n);
326
+ }
327
+
328
+ fwprintf(gen, L"\n\t};\n");
329
+ }
330
+
331
+ void ParserGen::GenCodePragmas() {
332
+ Symbol *sym;
333
+ for (int i=0; i<tab->pragmas->Count; i++) {
334
+ sym = (Symbol*)((*(tab->pragmas))[i]);
335
+ fwprintf(gen, L"\t\tif (la->kind == ");
336
+ WriteSymbolOrCode(gen, sym);
337
+ fwprintf(gen, L") {\n");
338
+ CopySourcePart(sym->semPos, 4);
339
+ fwprintf(gen, L"\t\t}\n");
340
+ }
341
+ }
342
+
343
+ void ParserGen::WriteSymbolOrCode(FILE *gen, const Symbol *sym) {
344
+ if (!isalpha(sym->name[0])) {
345
+ fwprintf(gen, L"%d /* %ls */", sym->n, sym->name);
346
+ } else {
347
+ fwprintf(gen, L"_%ls", sym->name);
348
+ }
349
+ }
350
+
351
+ void ParserGen::GenProductionsHeader() {
352
+ Symbol *sym;
353
+ for (int i=0; i<tab->nonterminals->Count; i++) {
354
+ sym = (Symbol*)((*(tab->nonterminals))[i]);
355
+ curSy = sym;
356
+ fwprintf(gen, L"\tvoid %ls(", sym->name);
357
+ CopySourcePart(sym->attrPos, 0);
358
+ fwprintf(gen, L");\n");
359
+ }
360
+ }
361
+
362
+ void ParserGen::GenProductions() {
363
+ Symbol *sym;
364
+ for (int i=0; i<tab->nonterminals->Count; i++) {
365
+ sym = (Symbol*)((*(tab->nonterminals))[i]);
366
+ curSy = sym;
367
+ fwprintf(gen, L"void Parser::%ls(", sym->name);
368
+ CopySourcePart(sym->attrPos, 0);
369
+ fwprintf(gen, L") {\n");
370
+ CopySourcePart(sym->semPos, 2);
371
+ GenCode(sym->graph, 2, new BitArray(tab->terminals->Count));
372
+ fwprintf(gen, L"}\n"); fwprintf(gen, L"\n");
373
+ }
374
+ }
375
+
376
+ void ParserGen::InitSets() {
377
+ fwprintf(gen, L"\tstatic bool set[%d][%d] = {\n", symSet->Count, tab->terminals->Count+1);
378
+
379
+ for (int i = 0; i < symSet->Count; i++) {
380
+ BitArray *s = (BitArray*)(*symSet)[i];
381
+ fwprintf(gen, L"\t\t{");
382
+ int j = 0;
383
+ Symbol *sym;
384
+ for (int k=0; k<tab->terminals->Count; k++) {
385
+ sym = (Symbol*)((*(tab->terminals))[k]);
386
+ if ((*s)[sym->n]) fwprintf(gen, L"T,"); else fwprintf(gen, L"x,");
387
+ ++j;
388
+ if (j%4 == 0) fwprintf(gen, L" ");
389
+ }
390
+ if (i == symSet->Count-1) fwprintf(gen, L"x}\n"); else fwprintf(gen, L"x},\n");
391
+ }
392
+ fwprintf(gen, L"\t};\n\n");
393
+ }
394
+
395
+ void ParserGen::WriteParser () {
396
+ Generator g = Generator(tab, errors);
397
+ int oldPos = buffer->GetPos(); // Pos is modified by CopySourcePart
398
+ symSet->Add(tab->allSyncSets);
399
+
400
+ fram = g.OpenFrame(L"Parser.frame");
401
+ gen = g.OpenGen(L"Parser.h");
402
+
403
+ Symbol *sym;
404
+ for (int i=0; i<tab->terminals->Count; i++) {
405
+ sym = (Symbol*)((*(tab->terminals))[i]);
406
+ GenErrorMsg(tErr, sym);
407
+ }
408
+
409
+ g.GenCopyright();
410
+ g.SkipFramePart(L"-->begin");
411
+
412
+ g.CopyFramePart(L"-->prefix");
413
+ g.GenPrefixFromNamespace();
414
+
415
+ g.CopyFramePart(L"-->prefix");
416
+ g.GenPrefixFromNamespace();
417
+
418
+ g.CopyFramePart(L"-->headerdef");
419
+
420
+ if (usingPos != NULL) {CopySourcePart(usingPos, 0); fwprintf(gen, L"\n");}
421
+ g.CopyFramePart(L"-->namespace_open");
422
+ int nrOfNs = GenNamespaceOpen(tab->nsName);
423
+
424
+ g.CopyFramePart(L"-->constantsheader");
425
+ GenTokensHeader(); /* ML 2002/09/07 write the token kinds */
426
+ fwprintf(gen, L"\tint maxT;\n");
427
+ g.CopyFramePart(L"-->declarations"); CopySourcePart(tab->semDeclPos, 0);
428
+ g.CopyFramePart(L"-->productionsheader"); GenProductionsHeader();
429
+ g.CopyFramePart(L"-->namespace_close");
430
+ GenNamespaceClose(nrOfNs);
431
+
432
+ g.CopyFramePart(L"-->implementation");
433
+ fclose(gen);
434
+
435
+ // Source
436
+ gen = g.OpenGen(L"Parser.cpp");
437
+
438
+ g.GenCopyright();
439
+ g.SkipFramePart(L"-->begin");
440
+ g.CopyFramePart(L"-->namespace_open");
441
+ nrOfNs = GenNamespaceOpen(tab->nsName);
442
+
443
+ g.CopyFramePart(L"-->pragmas"); GenCodePragmas();
444
+ g.CopyFramePart(L"-->productions"); GenProductions();
445
+ g.CopyFramePart(L"-->parseRoot"); fwprintf(gen, L"\t%ls();\n", tab->gramSy->name); if (tab->checkEOF) fwprintf(gen, L"\tExpect(0);");
446
+ g.CopyFramePart(L"-->constants");
447
+ fwprintf(gen, L"\tmaxT = %d;\n", tab->terminals->Count-1);
448
+ g.CopyFramePart(L"-->initialization"); InitSets();
449
+ g.CopyFramePart(L"-->errors"); fwprintf(gen, L"%ls", err);
450
+ g.CopyFramePart(L"-->namespace_close");
451
+ GenNamespaceClose(nrOfNs);
452
+ g.CopyFramePart(NULL);
453
+ fclose(gen);
454
+ buffer->SetPos(oldPos);
455
+ }
456
+
457
+
458
+ void ParserGen::WriteStatistics () {
459
+ fwprintf(trace, L"\n");
460
+ fwprintf(trace, L"%d terminals\n", tab->terminals->Count);
461
+ fwprintf(trace, L"%d symbols\n", tab->terminals->Count + tab->pragmas->Count +
462
+ tab->nonterminals->Count);
463
+ fwprintf(trace, L"%d nodes\n", tab->nodes->Count);
464
+ fwprintf(trace, L"%d sets\n", symSet->Count);
465
+ }
466
+
467
+
468
+ ParserGen::ParserGen (Parser *parser) {
469
+ maxTerm = 3;
470
+ CR = '\r';
471
+ LF = '\n';
472
+ tErr = 0;
473
+ altErr = 1;
474
+ syncErr = 2;
475
+ tab = parser->tab;
476
+ errors = parser->errors;
477
+ trace = parser->trace;
478
+ buffer = parser->scanner->buffer;
479
+ errorNr = -1;
480
+ usingPos = NULL;
481
+
482
+ symSet = new ArrayList();
483
+ err = NULL;
484
+ }
485
+
486
+ }; // namespace
@@ -0,0 +1,99 @@
1
+ /*-------------------------------------------------------------------------
2
+ ParserGen -- Generation of the Recursive Descent Parser
3
+ Compiler Generator Coco/R,
4
+ Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
5
+ ported to C++ by Csaba Balazs, University of Szeged
6
+ extended by M. Loeberbauer & A. Woess, Univ. of Linz
7
+ with improvements by Pat Terry, Rhodes University
8
+
9
+ This program is free software; you can redistribute it and/or modify it
10
+ under the terms of the GNU General Public License as published by the
11
+ Free Software Foundation; either version 2, or (at your option) any
12
+ later version.
13
+
14
+ This program is distributed in the hope that it will be useful, but
15
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
+ for more details.
18
+
19
+ You should have received a copy of the GNU General Public License along
20
+ with this program; if not, write to the Free Software Foundation, Inc.,
21
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
+
23
+ As an exception, it is allowed to write an extension of Coco/R that is
24
+ used as a plugin in non-free software.
25
+
26
+ If not otherwise stated, any source code generated by Coco/R (other than
27
+ Coco/R itself) does not fall under the GNU General Public License.
28
+ -------------------------------------------------------------------------*/
29
+
30
+ #if !defined(COCO_PARSERGEN_H__)
31
+ #define COCO_PARSERGEN_H__
32
+
33
+ #include "Position.h"
34
+ #include "Tab.h"
35
+ #include "Symbol.h"
36
+ #include "Scanner.h"
37
+ #include "DFA.h"
38
+
39
+ namespace Coco {
40
+
41
+ class Errors;
42
+ class Parser;
43
+ class BitArray;
44
+
45
+ class ParserGen
46
+ {
47
+ public:
48
+ int maxTerm; // sets of size < maxTerm are enumerated
49
+ char CR;
50
+ char LF;
51
+
52
+ int tErr; // error codes
53
+ int altErr;
54
+ int syncErr;
55
+
56
+ Position *usingPos; // "using" definitions from the attributed grammar
57
+
58
+ int errorNr; // highest parser error number
59
+ Symbol *curSy; // symbol whose production is currently generated
60
+ FILE* fram; // parser frame file
61
+ FILE* gen; // generated parser source file
62
+ wchar_t* err; // generated parser error messages
63
+ ArrayList *symSet;
64
+
65
+ Tab *tab; // other Coco objects
66
+ FILE* trace;
67
+ Errors *errors;
68
+ Buffer *buffer;
69
+
70
+ void Indent(int n);
71
+ bool UseSwitch(Node *p);
72
+ void CopyFramePart(const wchar_t* stop);
73
+ void CopySourcePart(Position *pos, int indent);
74
+ int GenNamespaceOpen(const wchar_t* nsName);
75
+ void GenNamespaceClose(int nrOfNs);
76
+ void GenErrorMsg(int errTyp, Symbol *sym);
77
+ int NewCondSet(BitArray *s);
78
+ void GenCond(BitArray *s, Node *p);
79
+ void PutCaseLabels(BitArray *s);
80
+ void GenCode(Node *p, int indent, BitArray *isChecked);
81
+ void GenTokens();
82
+ void GenTokensHeader();
83
+ void GenPragmas();
84
+ void GenPragmasHeader();
85
+ void GenCodePragmas();
86
+ void GenProductions();
87
+ void GenProductionsHeader();
88
+ void InitSets();
89
+ void OpenGen(const wchar_t* genName, bool backUp);
90
+ void WriteParser();
91
+ void WriteStatistics();
92
+ void WriteSymbolOrCode(FILE *gen, const Symbol *sym);
93
+ ParserGen (Parser *parser);
94
+
95
+ };
96
+
97
+ }; // namespace
98
+
99
+ #endif // !defined(COCO_PARSERGEN_H__)
@@ -0,0 +1,37 @@
1
+ /*-------------------------------------------------------------------------
2
+ Compiler Generator Coco/R,
3
+ Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
4
+ extended by M. Loeberbauer & A. Woess, Univ. of Linz
5
+ ported to C++ by Csaba Balazs, University of Szeged
6
+ with improvements by Pat Terry, Rhodes University
7
+
8
+ This program is free software; you can redistribute it and/or modify it
9
+ under the terms of the GNU General Public License as published by the
10
+ Free Software Foundation; either version 2, or (at your option) any
11
+ later version.
12
+
13
+ This program is distributed in the hope that it will be useful, but
14
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
+ for more details.
17
+
18
+ You should have received a copy of the GNU General Public License along
19
+ with this program; if not, write to the Free Software Foundation, Inc.,
20
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
+
22
+ As an exception, it is allowed to write an extension of Coco/R that is
23
+ used as a plugin in non-free software.
24
+
25
+ If not otherwise stated, any source code generated by Coco/R (other than
26
+ Coco/R itself) does not fall under the GNU General Public License.
27
+ -------------------------------------------------------------------------*/
28
+
29
+ #include "Position.h"
30
+
31
+ namespace Coco {
32
+
33
+ Position::Position(int beg, int end, int col, int line) {
34
+ this->beg = beg; this->end = end; this->col = col; this->line = line;
35
+ }
36
+
37
+ }; // namespace
@@ -0,0 +1,46 @@
1
+ /*-------------------------------------------------------------------------
2
+ Compiler Generator Coco/R,
3
+ Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
4
+ extended by M. Loeberbauer & A. Woess, Univ. of Linz
5
+ ported to C++ by Csaba Balazs, University of Szeged
6
+ with improvements by Pat Terry, Rhodes University
7
+
8
+ This program is free software; you can redistribute it and/or modify it
9
+ under the terms of the GNU General Public License as published by the
10
+ Free Software Foundation; either version 2, or (at your option) any
11
+ later version.
12
+
13
+ This program is distributed in the hope that it will be useful, but
14
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
+ for more details.
17
+
18
+ You should have received a copy of the GNU General Public License along
19
+ with this program; if not, write to the Free Software Foundation, Inc.,
20
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
+
22
+ As an exception, it is allowed to write an extension of Coco/R that is
23
+ used as a plugin in non-free software.
24
+
25
+ If not otherwise stated, any source code generated by Coco/R (other than
26
+ Coco/R itself) does not fall under the GNU General Public License.
27
+ -------------------------------------------------------------------------*/
28
+
29
+ #if !defined(COCO_POSITION_H__)
30
+ #define COCO_POSITION_H__
31
+
32
+ namespace Coco {
33
+
34
+ class Position { // position of source code stretch (e.g. semantic action, resolver expressions)
35
+ public:
36
+ int beg; // start relative to the beginning of the file
37
+ int end; // end of stretch
38
+ int col; // column number of start position
39
+ int line; // line number of beginnnig of source code stretch
40
+
41
+ Position(int beg, int end, int col, int line);
42
+ };
43
+
44
+ }; // namespace
45
+
46
+ #endif // !defined(COCO_POSITION_H__)
@@ -0,0 +1,12 @@
1
+ Coco/R
2
+ ------
3
+
4
+ This is a compiler generator for C++. To build the binary, run
5
+
6
+ make
7
+
8
+ The executable will be in this directory. Use it as you want.
9
+
10
+ Documentation is available at the original site for Coco/R.
11
+
12
+ [The Compiler Generator Coco/R website](http://www.ssw.uni-linz.ac.at/Coco/)