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
data/ext/cocor/Coco.atg
ADDED
@@ -0,0 +1,528 @@
|
|
1
|
+
/*-------------------------------------------------------------------------
|
2
|
+
Coco.ATG -- Attributed Grammar
|
3
|
+
Compiler Generator Coco/R,
|
4
|
+
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
|
5
|
+
extended by M. Loeberbauer & A. Woess, Univ. of Linz
|
6
|
+
ported to C++ by Csaba Balazs, University of Szeged
|
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
|
+
compile with:
|
31
|
+
Coco Coco.ATG -namespace Coco
|
32
|
+
-------------------------------------------------------------------------*/
|
33
|
+
$namespace=Coco
|
34
|
+
|
35
|
+
#include "Tab.h"
|
36
|
+
#include "DFA.h"
|
37
|
+
#include "ParserGen.h"
|
38
|
+
|
39
|
+
COMPILER Coco
|
40
|
+
|
41
|
+
int id;
|
42
|
+
int str;
|
43
|
+
|
44
|
+
FILE* trace; // other Coco objects referenced in this ATG
|
45
|
+
Tab *tab;
|
46
|
+
DFA *dfa;
|
47
|
+
ParserGen *pgen;
|
48
|
+
|
49
|
+
bool genScanner;
|
50
|
+
wchar_t* tokenString; // used in declarations of literal tokens
|
51
|
+
wchar_t* noString; // used in declarations of literal tokens
|
52
|
+
|
53
|
+
// This method will be called by the contructor if it exits.
|
54
|
+
// This support is specific to the C++ version of Coco/R.
|
55
|
+
void Init() {
|
56
|
+
tab = NULL;
|
57
|
+
dfa = NULL;
|
58
|
+
pgen = NULL;
|
59
|
+
id = 0;
|
60
|
+
str = 1;
|
61
|
+
tokenString = NULL;
|
62
|
+
noString = coco_string_create(L"-none-");
|
63
|
+
}
|
64
|
+
|
65
|
+
// Uncomment this method if cleanup is necessary,
|
66
|
+
// this method will be called by the destructor if it exists.
|
67
|
+
// This support is specific to the C++ version of Coco/R.
|
68
|
+
// void Destroy() {
|
69
|
+
// nothing to do
|
70
|
+
// }
|
71
|
+
/*-------------------------------------------------------------------------*/
|
72
|
+
|
73
|
+
CHARACTERS
|
74
|
+
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_".
|
75
|
+
digit = "0123456789".
|
76
|
+
cr = '\r'.
|
77
|
+
lf = '\n'.
|
78
|
+
tab = '\t'.
|
79
|
+
stringCh = ANY - '"' - '\\' - cr - lf.
|
80
|
+
charCh = ANY - '\'' - '\\' - cr - lf.
|
81
|
+
printable = '\u0020' .. '\u007e'.
|
82
|
+
hex = "0123456789abcdef".
|
83
|
+
|
84
|
+
TOKENS
|
85
|
+
ident = letter { letter | digit }.
|
86
|
+
number = digit { digit }.
|
87
|
+
string = '"' { stringCh | '\\' printable } '"'.
|
88
|
+
badString = '"' { stringCh | '\\' printable } (cr | lf).
|
89
|
+
char = '\'' ( charCh | '\\' printable { hex } ) '\''.
|
90
|
+
|
91
|
+
PRAGMAS
|
92
|
+
ddtSym = '$' { digit | letter }. (. tab->SetDDT(la->val); .)
|
93
|
+
optionSym = '$' letter { letter } '='
|
94
|
+
{ digit | letter
|
95
|
+
| '-' | '.' | ':'
|
96
|
+
}. (. tab->SetOption(la->val); .)
|
97
|
+
|
98
|
+
|
99
|
+
COMMENTS FROM "/*" TO "*/" NESTED
|
100
|
+
COMMENTS FROM "//" TO lf
|
101
|
+
|
102
|
+
IGNORE cr + lf + tab
|
103
|
+
|
104
|
+
/*-------------------------------------------------------------------------*/
|
105
|
+
|
106
|
+
PRODUCTIONS
|
107
|
+
|
108
|
+
Coco (. Symbol *sym; Graph *g, *g1, *g2; wchar_t* gramName = NULL; CharSet *s; .)
|
109
|
+
=
|
110
|
+
(. int beg = la->pos; int line = la->line; .)
|
111
|
+
{ // this section can be used
|
112
|
+
// for #include statements
|
113
|
+
ANY
|
114
|
+
} (. if (la->pos != beg) {
|
115
|
+
pgen->usingPos = new Position(beg, t->pos + coco_string_length(t->val), 0, line);
|
116
|
+
}
|
117
|
+
.)
|
118
|
+
|
119
|
+
"COMPILER" (. genScanner = true;
|
120
|
+
tab->ignored = new CharSet(); .)
|
121
|
+
ident (. gramName = coco_string_create(t->val);
|
122
|
+
beg = la->pos;
|
123
|
+
line = la->line;
|
124
|
+
.)
|
125
|
+
{ ANY } (. tab->semDeclPos = new Position(beg, la->pos, 0, line); .)
|
126
|
+
[ "IGNORECASE" (. dfa->ignoreCase = true; .) ] /* pdt */
|
127
|
+
[ "CHARACTERS" { SetDecl }]
|
128
|
+
[ "TOKENS" { TokenDecl<Node::t> }]
|
129
|
+
[ "PRAGMAS" { TokenDecl<Node::pr> }]
|
130
|
+
{ "COMMENTS" (. bool nested = false; .)
|
131
|
+
"FROM" TokenExpr<g1>
|
132
|
+
"TO" TokenExpr<g2>
|
133
|
+
[ "NESTED" (. nested = true; .)
|
134
|
+
] (. dfa->NewComment(g1->l, g2->l, nested); .)
|
135
|
+
}
|
136
|
+
{ "IGNORE" Set<s> (. tab->ignored->Or(s); .)
|
137
|
+
}
|
138
|
+
|
139
|
+
SYNC
|
140
|
+
"PRODUCTIONS" (. if (genScanner) dfa->MakeDeterministic();
|
141
|
+
tab->DeleteNodes();
|
142
|
+
.)
|
143
|
+
{ ident (. sym = tab->FindSym(t->val);
|
144
|
+
bool undef = (sym == NULL);
|
145
|
+
if (undef) sym = tab->NewSym(Node::nt, t->val, t->line);
|
146
|
+
else {
|
147
|
+
if (sym->typ == Node::nt) {
|
148
|
+
if (sym->graph != NULL) SemErr(L"name declared twice");
|
149
|
+
} else SemErr(L"this symbol kind not allowed on left side of production");
|
150
|
+
sym->line = t->line;
|
151
|
+
}
|
152
|
+
bool noAttrs = (sym->attrPos == NULL);
|
153
|
+
sym->attrPos = NULL;
|
154
|
+
.)
|
155
|
+
[ AttrDecl<sym> ] (. if (!undef)
|
156
|
+
if (noAttrs != (sym->attrPos == NULL))
|
157
|
+
SemErr(L"attribute mismatch between declaration and use of this symbol");
|
158
|
+
.)
|
159
|
+
[ SemText<.sym->semPos.> ] WEAK
|
160
|
+
'='
|
161
|
+
Expression<g> (. sym->graph = g->l;
|
162
|
+
tab->Finish(g);
|
163
|
+
.)
|
164
|
+
WEAK
|
165
|
+
'.'
|
166
|
+
}
|
167
|
+
"END" ident (. if (!coco_string_equal(gramName, t->val))
|
168
|
+
SemErr(L"name does not match grammar name");
|
169
|
+
tab->gramSy = tab->FindSym(gramName);
|
170
|
+
if (tab->gramSy == NULL)
|
171
|
+
SemErr(L"missing production for grammar name");
|
172
|
+
else {
|
173
|
+
sym = tab->gramSy;
|
174
|
+
if (sym->attrPos != NULL)
|
175
|
+
SemErr(L"grammar symbol must not have attributes");
|
176
|
+
}
|
177
|
+
tab->noSym = tab->NewSym(Node::t, L"???", 0); // noSym gets highest number
|
178
|
+
tab->SetupAnys();
|
179
|
+
tab->RenumberPragmas();
|
180
|
+
if (tab->ddt[2]) tab->PrintNodes();
|
181
|
+
if (errors->count == 0) {
|
182
|
+
wprintf(L"checking\n");
|
183
|
+
tab->CompSymbolSets();
|
184
|
+
if (tab->ddt[7]) tab->XRef();
|
185
|
+
if (tab->GrammarOk()) {
|
186
|
+
wprintf(L"parser");
|
187
|
+
pgen->WriteParser();
|
188
|
+
if (genScanner) {
|
189
|
+
wprintf(L" + scanner");
|
190
|
+
dfa->WriteScanner();
|
191
|
+
if (tab->ddt[0]) dfa->PrintStates();
|
192
|
+
}
|
193
|
+
wprintf(L" generated\n");
|
194
|
+
if (tab->ddt[8]) pgen->WriteStatistics();
|
195
|
+
}
|
196
|
+
}
|
197
|
+
if (tab->ddt[6]) tab->PrintSymbolTable();
|
198
|
+
.)
|
199
|
+
'.'
|
200
|
+
.
|
201
|
+
|
202
|
+
/*------------------------------------------------------------------------------------*/
|
203
|
+
|
204
|
+
SetDecl (. CharSet *s; .)
|
205
|
+
=
|
206
|
+
ident (. wchar_t *name = coco_string_create(t->val);
|
207
|
+
CharClass *c = tab->FindCharClass(name);
|
208
|
+
if (c != NULL) SemErr(L"name declared twice");
|
209
|
+
.)
|
210
|
+
'=' Set<s> (. if (s->Elements() == 0) SemErr(L"character set must not be empty");
|
211
|
+
tab->NewCharClass(name, s);
|
212
|
+
.)
|
213
|
+
'.'
|
214
|
+
.
|
215
|
+
|
216
|
+
/*------------------------------------------------------------------------------------*/
|
217
|
+
|
218
|
+
Set<CharSet* &s> (. CharSet *s2; .)
|
219
|
+
=
|
220
|
+
SimSet<s>
|
221
|
+
{ '+' SimSet<s2> (. s->Or(s2); .)
|
222
|
+
| '-' SimSet<s2> (. s->Subtract(s2); .)
|
223
|
+
}
|
224
|
+
.
|
225
|
+
|
226
|
+
/*------------------------------------------------------------------------------------*/
|
227
|
+
|
228
|
+
SimSet<CharSet* &s> (. int n1, n2; .)
|
229
|
+
= (. s = new CharSet(); .)
|
230
|
+
( ident (. CharClass *c = tab->FindCharClass(t->val);
|
231
|
+
if (c == NULL) SemErr(L"undefined name"); else s->Or(c->set);
|
232
|
+
.)
|
233
|
+
| string (.
|
234
|
+
wchar_t *subName2 = coco_string_create(t->val, 1, coco_string_length(t->val)-2);
|
235
|
+
wchar_t *name = tab->Unescape(subName2);
|
236
|
+
coco_string_delete(subName2);
|
237
|
+
wchar_t ch;
|
238
|
+
int len = coco_string_length(name);
|
239
|
+
for(int i=0; i < len; i++) {
|
240
|
+
ch = name[i];
|
241
|
+
if (dfa->ignoreCase) {
|
242
|
+
if ((L'A' <= ch) && (ch <= L'Z')) ch = ch - (L'A' - L'a'); // ch.ToLower()
|
243
|
+
}
|
244
|
+
s->Set(ch);
|
245
|
+
}
|
246
|
+
coco_string_delete(name);
|
247
|
+
.)
|
248
|
+
| Char<n1> (. s->Set(n1); .)
|
249
|
+
[ ".." Char<n2> (. for (int i = n1; i <= n2; i++) s->Set(i); .)
|
250
|
+
]
|
251
|
+
| "ANY" (. s = new CharSet(); s->Fill(); .)
|
252
|
+
)
|
253
|
+
.
|
254
|
+
|
255
|
+
/*--------------------------------------------------------------------------------------*/
|
256
|
+
|
257
|
+
Char<int &n>
|
258
|
+
=
|
259
|
+
char (. n = 0;
|
260
|
+
wchar_t* subName = coco_string_create(t->val, 1, coco_string_length(t->val)-2);
|
261
|
+
wchar_t* name = tab->Unescape(subName);
|
262
|
+
coco_string_delete(subName);
|
263
|
+
|
264
|
+
// "<= 1" instead of "== 1" to allow the escape sequence '\0' in c++
|
265
|
+
if (coco_string_length(name) <= 1) n = name[0];
|
266
|
+
else SemErr(L"unacceptable character value");
|
267
|
+
coco_string_delete(name);
|
268
|
+
if (dfa->ignoreCase && (((wchar_t) n) >= 'A') && (((wchar_t) n) <= 'Z')) n += 32;
|
269
|
+
.)
|
270
|
+
.
|
271
|
+
|
272
|
+
/*------------------------------------------------------------------------------------*/
|
273
|
+
|
274
|
+
TokenDecl<int typ> (. wchar_t* name = NULL; int kind; Symbol *sym; Graph *g; .)
|
275
|
+
=
|
276
|
+
Sym<name, kind> (. sym = tab->FindSym(name);
|
277
|
+
if (sym != NULL) SemErr(L"name declared twice");
|
278
|
+
else {
|
279
|
+
sym = tab->NewSym(typ, name, t->line);
|
280
|
+
sym->tokenKind = Symbol::fixedToken;
|
281
|
+
}
|
282
|
+
tokenString = NULL;
|
283
|
+
.)
|
284
|
+
SYNC
|
285
|
+
( '=' TokenExpr<g> '.' (. if (kind == str) SemErr(L"a literal must not be declared with a structure");
|
286
|
+
tab->Finish(g);
|
287
|
+
if (tokenString == NULL || coco_string_equal(tokenString, noString))
|
288
|
+
dfa->ConvertToStates(g->l, sym);
|
289
|
+
else { // TokenExpr is a single string
|
290
|
+
if ((*(tab->literals))[tokenString] != NULL)
|
291
|
+
SemErr(L"token string declared twice");
|
292
|
+
tab->literals->Set(tokenString, sym);
|
293
|
+
dfa->MatchLiteral(tokenString, sym);
|
294
|
+
}
|
295
|
+
.)
|
296
|
+
| (. if (kind == id) genScanner = false;
|
297
|
+
else dfa->MatchLiteral(sym->name, sym);
|
298
|
+
.)
|
299
|
+
)
|
300
|
+
[ SemText<.sym->semPos.> (. if (typ != Node::pr) SemErr(L"semantic action not allowed here"); .)
|
301
|
+
]
|
302
|
+
.
|
303
|
+
|
304
|
+
/*------------------------------------------------------------------------------------*/
|
305
|
+
|
306
|
+
AttrDecl<Symbol *sym>
|
307
|
+
=
|
308
|
+
'<' (. int beg = la->pos; int col = la->col; int line = la->line; .)
|
309
|
+
{ ANY
|
310
|
+
| badString (. SemErr(L"bad string in attributes"); .)
|
311
|
+
}
|
312
|
+
'>' (. if (t->pos > beg)
|
313
|
+
sym->attrPos = new Position(beg, t->pos, col, line); .)
|
314
|
+
| "<." (. int beg = la->pos; int col = la->col; int line = la->line; .)
|
315
|
+
{ ANY
|
316
|
+
| badString (. SemErr(L"bad string in attributes"); .)
|
317
|
+
}
|
318
|
+
".>" (. if (t->pos > beg)
|
319
|
+
sym->attrPos = new Position(beg, t->pos, col, line); .)
|
320
|
+
.
|
321
|
+
|
322
|
+
/*------------------------------------------------------------------------------------*/
|
323
|
+
|
324
|
+
Expression<Graph* &g> (. Graph *g2; .)
|
325
|
+
=
|
326
|
+
Term<g> (. bool first = true; .)
|
327
|
+
{ WEAK
|
328
|
+
'|'
|
329
|
+
Term<g2> (. if (first) { tab->MakeFirstAlt(g); first = false; }
|
330
|
+
tab->MakeAlternative(g, g2);
|
331
|
+
.)
|
332
|
+
}
|
333
|
+
.
|
334
|
+
|
335
|
+
/*------------------------------------------------------------------------------------*/
|
336
|
+
|
337
|
+
Term<Graph* &g> (. Graph *g2; Node *rslv = NULL; g = NULL; .)
|
338
|
+
=
|
339
|
+
( [ (. rslv = tab->NewNode(Node::rslv, (Symbol*)NULL, la->line); .)
|
340
|
+
Resolver<.rslv->pos.> (. g = new Graph(rslv); .)
|
341
|
+
]
|
342
|
+
Factor<g2> (. if (rslv != NULL) tab->MakeSequence(g, g2);
|
343
|
+
else g = g2; .)
|
344
|
+
{ Factor<g2> (. tab->MakeSequence(g, g2); .)
|
345
|
+
}
|
346
|
+
| (. g = new Graph(tab->NewNode(Node::eps, (Symbol*)NULL, 0)); .)
|
347
|
+
) (. if (g == NULL) // invalid start of Term
|
348
|
+
g = new Graph(tab->NewNode(Node::eps, (Symbol*)NULL, 0)); .)
|
349
|
+
.
|
350
|
+
|
351
|
+
/*------------------------------------------------------------------------------------*/
|
352
|
+
|
353
|
+
Factor<Graph* &g> (. wchar_t* name = NULL; int kind; Position *pos; bool weak = false;
|
354
|
+
g = NULL;
|
355
|
+
.)
|
356
|
+
=
|
357
|
+
( [ "WEAK" (. weak = true; .)
|
358
|
+
]
|
359
|
+
Sym<name, kind> (. Symbol *sym = tab->FindSym(name);
|
360
|
+
if (sym == NULL && kind == str)
|
361
|
+
sym = (Symbol*)((*(tab->literals))[name]);
|
362
|
+
bool undef = (sym == NULL);
|
363
|
+
if (undef) {
|
364
|
+
if (kind == id)
|
365
|
+
sym = tab->NewSym(Node::nt, name, 0); // forward nt
|
366
|
+
else if (genScanner) {
|
367
|
+
sym = tab->NewSym(Node::t, name, t->line);
|
368
|
+
dfa->MatchLiteral(sym->name, sym);
|
369
|
+
} else { // undefined string in production
|
370
|
+
SemErr(L"undefined string in production");
|
371
|
+
sym = tab->eofSy; // dummy
|
372
|
+
}
|
373
|
+
}
|
374
|
+
int typ = sym->typ;
|
375
|
+
if (typ != Node::t && typ != Node::nt)
|
376
|
+
SemErr(L"this symbol kind is not allowed in a production");
|
377
|
+
if (weak) {
|
378
|
+
if (typ == Node::t) typ = Node::wt;
|
379
|
+
else SemErr(L"only terminals may be weak");
|
380
|
+
}
|
381
|
+
Node *p = tab->NewNode(typ, sym, t->line);
|
382
|
+
g = new Graph(p);
|
383
|
+
.)
|
384
|
+
[ Attribs<p> (. if (kind != id) SemErr(L"a literal must not have attributes"); .)
|
385
|
+
] (. if (undef)
|
386
|
+
sym->attrPos = p->pos; // dummy
|
387
|
+
else if ((p->pos == NULL) != (sym->attrPos == NULL))
|
388
|
+
SemErr(L"attribute mismatch between declaration and use of this symbol");
|
389
|
+
.)
|
390
|
+
| '(' Expression<g> ')'
|
391
|
+
| '[' Expression<g> ']' (. tab->MakeOption(g); .)
|
392
|
+
| '{' Expression<g> '}' (. tab->MakeIteration(g); .)
|
393
|
+
| SemText<pos> (. Node *p = tab->NewNode(Node::sem, (Symbol*)NULL, 0);
|
394
|
+
p->pos = pos;
|
395
|
+
g = new Graph(p);
|
396
|
+
.)
|
397
|
+
| "ANY" (. Node *p = tab->NewNode(Node::any, (Symbol*)NULL, 0); // p.set is set in tab->SetupAnys
|
398
|
+
g = new Graph(p);
|
399
|
+
.)
|
400
|
+
| "SYNC" (. Node *p = tab->NewNode(Node::sync, (Symbol*)NULL, 0);
|
401
|
+
g = new Graph(p);
|
402
|
+
.)
|
403
|
+
) (. if (g == NULL) // invalid start of Factor
|
404
|
+
g = new Graph(tab->NewNode(Node::eps, (Symbol*)NULL, 0));
|
405
|
+
.)
|
406
|
+
.
|
407
|
+
|
408
|
+
/*------------------------------------------------------------------------------------*/
|
409
|
+
|
410
|
+
Resolver<Position* &pos>
|
411
|
+
=
|
412
|
+
"IF" "(" (. int beg = la->pos; int col = la->col; int line = la->line; .)
|
413
|
+
Condition (. pos = new Position(beg, t->pos, col, line); .)
|
414
|
+
.
|
415
|
+
|
416
|
+
/*------------------------------------------------------------------------------------*/
|
417
|
+
|
418
|
+
Condition = { "(" Condition | ANY } ")" .
|
419
|
+
|
420
|
+
/*------------------------------------------------------------------------------------*/
|
421
|
+
|
422
|
+
TokenExpr<Graph* &g> (. Graph *g2; .)
|
423
|
+
=
|
424
|
+
TokenTerm<g> (. bool first = true; .)
|
425
|
+
{ WEAK
|
426
|
+
'|'
|
427
|
+
TokenTerm<g2> (. if (first) { tab->MakeFirstAlt(g); first = false; }
|
428
|
+
tab->MakeAlternative(g, g2);
|
429
|
+
.)
|
430
|
+
}
|
431
|
+
.
|
432
|
+
|
433
|
+
/*------------------------------------------------------------------------------------*/
|
434
|
+
|
435
|
+
TokenTerm<Graph* &g> (. Graph *g2; .)
|
436
|
+
=
|
437
|
+
TokenFactor<g>
|
438
|
+
{ TokenFactor<g2> (. tab->MakeSequence(g, g2); .)
|
439
|
+
}
|
440
|
+
[ "CONTEXT"
|
441
|
+
'(' TokenExpr<g2> (. tab->SetContextTrans(g2->l); dfa->hasCtxMoves = true;
|
442
|
+
tab->MakeSequence(g, g2); .)
|
443
|
+
')'
|
444
|
+
]
|
445
|
+
.
|
446
|
+
|
447
|
+
/*------------------------------------------------------------------------------------*/
|
448
|
+
|
449
|
+
TokenFactor<Graph* &g> (. wchar_t* name = NULL; int kind; .)
|
450
|
+
=
|
451
|
+
(. g = NULL; .)
|
452
|
+
( Sym<name, kind> (. if (kind == id) {
|
453
|
+
CharClass *c = tab->FindCharClass(name);
|
454
|
+
if (c == NULL) {
|
455
|
+
SemErr(L"undefined name");
|
456
|
+
c = tab->NewCharClass(name, new CharSet());
|
457
|
+
}
|
458
|
+
Node *p = tab->NewNode(Node::clas, (Symbol*)NULL, 0); p->val = c->n;
|
459
|
+
g = new Graph(p);
|
460
|
+
tokenString = coco_string_create(noString);
|
461
|
+
} else { // str
|
462
|
+
g = tab->StrToGraph(name);
|
463
|
+
if (tokenString == NULL) tokenString = coco_string_create(name);
|
464
|
+
else tokenString = coco_string_create(noString);
|
465
|
+
}
|
466
|
+
.)
|
467
|
+
| '(' TokenExpr<g> ')'
|
468
|
+
| '[' TokenExpr<g> ']' (. tab->MakeOption(g); tokenString = coco_string_create(noString); .)
|
469
|
+
| '{' TokenExpr<g> '}' (. tab->MakeIteration(g); tokenString = coco_string_create(noString); .)
|
470
|
+
) (. if (g == NULL) // invalid start of TokenFactor
|
471
|
+
g = new Graph(tab->NewNode(Node::eps, (Symbol*)NULL, 0)); .)
|
472
|
+
.
|
473
|
+
|
474
|
+
/*------------------------------------------------------------------------------------*/
|
475
|
+
|
476
|
+
Sym<wchar_t* &name, int &kind>
|
477
|
+
= (. name = coco_string_create(L"???"); kind = id; .)
|
478
|
+
( ident (. kind = id; coco_string_delete(name); name = coco_string_create(t->val); .)
|
479
|
+
| (string (. coco_string_delete(name); name = coco_string_create(t->val); .)
|
480
|
+
| char (.
|
481
|
+
wchar_t *subName = coco_string_create(t->val, 1, coco_string_length(t->val)-2);
|
482
|
+
coco_string_delete(name);
|
483
|
+
name = coco_string_create_append(L"\"", subName);
|
484
|
+
coco_string_delete(subName);
|
485
|
+
coco_string_merge(name, L"\"");
|
486
|
+
.)
|
487
|
+
) (. kind = str;
|
488
|
+
if (dfa->ignoreCase) {
|
489
|
+
wchar_t *oldName = name;
|
490
|
+
name = coco_string_create_lower(name);
|
491
|
+
coco_string_delete(oldName);
|
492
|
+
}
|
493
|
+
if (coco_string_indexof(name, ' ') >= 0)
|
494
|
+
SemErr(L"literal tokens must not contain blanks"); .)
|
495
|
+
)
|
496
|
+
.
|
497
|
+
|
498
|
+
/*------------------------------------------------------------------------------------*/
|
499
|
+
|
500
|
+
Attribs<Node *p>
|
501
|
+
=
|
502
|
+
'<' (. int beg = la->pos; int col = la->col; int line = la->line; .)
|
503
|
+
{ ANY
|
504
|
+
| badString (. SemErr(L"bad string in attributes"); .)
|
505
|
+
}
|
506
|
+
'>' (. if (t->pos > beg) p->pos = new Position(beg, t->pos, col, line); .)
|
507
|
+
| "<." (. int beg = la->pos; int col = la->col; int line = la->line; .)
|
508
|
+
{ ANY
|
509
|
+
| badString (. SemErr(L"bad string in attributes"); .)
|
510
|
+
}
|
511
|
+
".>" (. if (t->pos > beg) p->pos = new Position(beg, t->pos, col, line); .)
|
512
|
+
.
|
513
|
+
|
514
|
+
/*------------------------------------------------------------------------------------*/
|
515
|
+
|
516
|
+
SemText<Position* &pos>
|
517
|
+
=
|
518
|
+
"(." (. int beg = la->pos; int col = la->col; int line = t->line; .)
|
519
|
+
{ ANY
|
520
|
+
| badString (. SemErr(L"bad string in semantic action"); .)
|
521
|
+
| "(." (. SemErr(L"missing end of previous semantic action"); .)
|
522
|
+
}
|
523
|
+
".)" (. pos = new Position(beg, t->pos, col, line); .)
|
524
|
+
.
|
525
|
+
|
526
|
+
/*------------------------------------------------------------------------------------*/
|
527
|
+
|
528
|
+
END Coco.
|