ruco-cpp 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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/)