ruco-cpp 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +17 -0
- data/bin/console +14 -0
- data/bin/ruco +30 -0
- data/bin/setup +7 -0
- data/data/ruco/Parser.frame +359 -0
- data/data/ruco/Scanner.frame +896 -0
- data/data/ruco/picojson/Changes +14 -0
- data/data/ruco/picojson/LICENSE +25 -0
- data/data/ruco/picojson/Makefile +8 -0
- data/data/ruco/picojson/README.mkdn +183 -0
- data/data/ruco/picojson/examples/github-issues.cc +110 -0
- data/data/ruco/picojson/examples/iostream.cc +70 -0
- data/data/ruco/picojson/examples/streaming.cc +76 -0
- data/data/ruco/picojson/picojson.h +1299 -0
- data/ext/cocor/Action.cpp +81 -0
- data/ext/cocor/Action.h +59 -0
- data/ext/cocor/ArrayList.cpp +79 -0
- data/ext/cocor/ArrayList.h +52 -0
- data/ext/cocor/BitArray.cpp +156 -0
- data/ext/cocor/BitArray.h +68 -0
- data/ext/cocor/CharClass.cpp +42 -0
- data/ext/cocor/CharClass.h +48 -0
- data/ext/cocor/CharSet.cpp +166 -0
- data/ext/cocor/CharSet.h +68 -0
- data/ext/cocor/Coco.atg +528 -0
- data/ext/cocor/Coco.cpp +173 -0
- data/ext/cocor/Comment.cpp +45 -0
- data/ext/cocor/Comment.h +51 -0
- data/ext/cocor/Copyright.frame +27 -0
- data/ext/cocor/DFA.cpp +865 -0
- data/ext/cocor/DFA.h +132 -0
- data/ext/cocor/Generator.cpp +182 -0
- data/ext/cocor/Generator.h +61 -0
- data/ext/cocor/Graph.h +59 -0
- data/ext/cocor/HashTable.cpp +115 -0
- data/ext/cocor/HashTable.h +84 -0
- data/ext/cocor/Makefile +11 -0
- data/ext/cocor/Melted.cpp +39 -0
- data/ext/cocor/Melted.h +51 -0
- data/ext/cocor/Node.cpp +69 -0
- data/ext/cocor/Node.h +86 -0
- data/ext/cocor/Parser.cpp +925 -0
- data/ext/cocor/Parser.frame +326 -0
- data/ext/cocor/Parser.h +153 -0
- data/ext/cocor/ParserGen.cpp +486 -0
- data/ext/cocor/ParserGen.h +99 -0
- data/ext/cocor/Position.cpp +37 -0
- data/ext/cocor/Position.h +46 -0
- data/ext/cocor/README.md +12 -0
- data/ext/cocor/Scanner.cpp +833 -0
- data/ext/cocor/Scanner.frame +897 -0
- data/ext/cocor/Scanner.h +291 -0
- data/ext/cocor/Sets.h +84 -0
- data/ext/cocor/SortedList.cpp +141 -0
- data/ext/cocor/SortedList.h +68 -0
- data/ext/cocor/State.cpp +77 -0
- data/ext/cocor/State.h +55 -0
- data/ext/cocor/StringBuilder.cpp +88 -0
- data/ext/cocor/StringBuilder.h +29 -0
- data/ext/cocor/Symbol.cpp +61 -0
- data/ext/cocor/Symbol.h +70 -0
- data/ext/cocor/Tab.cpp +1248 -0
- data/ext/cocor/Tab.h +245 -0
- data/ext/cocor/Target.cpp +41 -0
- data/ext/cocor/Target.h +48 -0
- data/ext/cocor/build.bat +3 -0
- data/ext/cocor/build.sh +4 -0
- data/ext/cocor/coc.bat +1 -0
- data/ext/cocor/coc.sh +2 -0
- data/ext/cocor/cocor_ruby_ext.cpp +124 -0
- data/ext/cocor/cygBuild.bat +1 -0
- data/ext/cocor/extconf.rb +5 -0
- data/ext/cocor/mingwbuild.bat +2 -0
- data/ext/cocor/mkmf.log +57 -0
- data/ext/cocor/zipsources.bat +1 -0
- data/lib/cocor.rb +14 -0
- data/lib/ruco/version.rb +3 -0
- data/lib/ruco.rb +728 -0
- 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__)
|
data/ext/cocor/README.md
ADDED
@@ -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/)
|