s2 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +22 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/s2/s2_parse/Makefile +52 -0
- data/ext/s2/s2_parse/Parser.cpp +525 -0
- data/ext/s2/s2_parse/Parser.h +130 -0
- data/ext/s2/s2_parse/S2.hpp +246 -0
- data/ext/s2/s2_parse/Scanner.cpp +796 -0
- data/ext/s2/s2_parse/Scanner.h +263 -0
- data/ext/s2/s2_parse/extconf.rb +5 -0
- data/ext/s2/s2_parse/parse_s2.cpp +630 -0
- data/ext/s2/s2_parse/parse_s2.hpp +42 -0
- data/ext/s2/s2_parse/picojson.hpp +1299 -0
- data/ext/s2/s2_parse/s2.atg +321 -0
- data/ext/s2/s2_parse/s2.ruco +93 -0
- data/ext/s2/s2_parse/s2_parse.cpp +70 -0
- data/lib/s2.rb +5 -0
- data/lib/s2/display.rb +21 -0
- data/lib/s2/internal/c.rb +128 -0
- data/lib/s2/s2_parse.rb +18 -0
- data/lib/s2/version.rb +3 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3a232c697c2e478ea56ab0c9415680a947028f0a
|
4
|
+
data.tar.gz: 4e412809b106617c09827e6178057dfa26834456
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d135fb15245f3e367efc5369b9155cd581b2470cfc6e1a2ab2b5b9d0fc2a98b5b2a7e7ccbf50e8ecf9d2cd775db058ab055e8e1b9cdab1b01514f4489a10392b
|
7
|
+
data.tar.gz: be3388124cd3498ce6a6d09c13f3ded004dc4fa74f0d1a68a2d431db13c1c05137abce71742f92a876706d770afe26f4bb981e5ee419d44f55050b09f8eaf960
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "rake/extensiontask"
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
gemspec = Gem::Specification.load('s2.gemspec')
|
9
|
+
Rake::ExtensionTask.new do |ext|
|
10
|
+
ext.name = 's2_parse'
|
11
|
+
ext.ext_dir = 'ext/s2/s2_parse'
|
12
|
+
ext.lib_dir = 'lib/s2/s2_parse'
|
13
|
+
ext.gem_spec = gemspec
|
14
|
+
ext.source_pattern = "*.{c,cpp}"
|
15
|
+
end
|
16
|
+
|
17
|
+
task :regen_parser do
|
18
|
+
sh %{cd ext/s2/s2_parse && bundle exec ruco s2.ruco && rm *.old}
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => [:test]
|
22
|
+
task :test => [:regen_parser, :compile, :spec]
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "s2"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
V = 0
|
2
|
+
AT_0 := @
|
3
|
+
AT_1 :=
|
4
|
+
REDIR_0 := > /dev/null
|
5
|
+
REDIR_1 :=
|
6
|
+
AT = $(AT_$(V))
|
7
|
+
REDIR = $(REDIR_$(V))
|
8
|
+
|
9
|
+
CXXFLAGS=-g -Wall -std=gnu++11
|
10
|
+
|
11
|
+
LDFLAGS=
|
12
|
+
TARGET=s2_parse
|
13
|
+
SRCDIR=.
|
14
|
+
SRC=$(shell find $(SRCDIR) -name "*.cpp")
|
15
|
+
OUT=obj
|
16
|
+
OBJS=$(SRC:%.cpp=$(OUT)/%.o)
|
17
|
+
DEPS=$(SRC:%.cpp=$(OUT)/%.d)
|
18
|
+
NODEPS=clean
|
19
|
+
|
20
|
+
.PHONY = all clean
|
21
|
+
|
22
|
+
.SECONDEXPANSION:
|
23
|
+
|
24
|
+
all: $(TARGET)
|
25
|
+
$(AT)echo "Build complete"
|
26
|
+
|
27
|
+
clean:
|
28
|
+
$(AT)-rm -rf $(TARGET) $(OUT)
|
29
|
+
|
30
|
+
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
|
31
|
+
-include $(DEPS)
|
32
|
+
endif
|
33
|
+
|
34
|
+
$(TARGET): $(OBJS) $(LUA)
|
35
|
+
$(AT)echo [LINK] $@
|
36
|
+
$(AT)$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
37
|
+
|
38
|
+
%/.f:
|
39
|
+
$(AT)echo [MKDIR] $(dir $@)
|
40
|
+
$(AT)mkdir -p $(dir $@)
|
41
|
+
$(AT)touch $@
|
42
|
+
|
43
|
+
$(OUT)/%.d:%.cpp $$(@D)/.f
|
44
|
+
$(AT)echo [DEP] $<
|
45
|
+
$(AT)$(CXX) $(CXXFLAGS) -MM -MT '$(patsubst %.d,%.o,$@)' $< -MF $@
|
46
|
+
|
47
|
+
$(OUT)/%.o:%.cpp $(OUT)/%.d
|
48
|
+
$(AT)echo [C++] $<
|
49
|
+
$(AT)$(CXX) $< $(CXXFLAGS) -c -o $@
|
50
|
+
|
51
|
+
.PRECIOUS: %/.f
|
52
|
+
|
@@ -0,0 +1,525 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
#include <wchar.h>
|
4
|
+
#include "Parser.h"
|
5
|
+
#include "Scanner.h"
|
6
|
+
|
7
|
+
|
8
|
+
namespace S2 {
|
9
|
+
|
10
|
+
|
11
|
+
void Parser::SynErr(int n) {
|
12
|
+
if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
|
13
|
+
errDist = 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
void Parser::SemErr(const wchar_t* msg) {
|
17
|
+
if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
|
18
|
+
errDist = 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
void Parser::Get() {
|
22
|
+
for (;;) {
|
23
|
+
t = la;
|
24
|
+
la = scanner->Scan();
|
25
|
+
if (la->kind <= maxT) { ++errDist; break; }
|
26
|
+
if (la->kind == _ddtSym) {
|
27
|
+
}
|
28
|
+
if (la->kind == _optionSym) {
|
29
|
+
}
|
30
|
+
|
31
|
+
if (dummyToken != t) {
|
32
|
+
dummyToken->kind = t->kind;
|
33
|
+
dummyToken->pos = t->pos;
|
34
|
+
dummyToken->col = t->col;
|
35
|
+
dummyToken->line = t->line;
|
36
|
+
dummyToken->next = NULL;
|
37
|
+
coco_string_delete(dummyToken->val);
|
38
|
+
dummyToken->val = coco_string_create(t->val);
|
39
|
+
t = dummyToken;
|
40
|
+
}
|
41
|
+
la = t;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
void Parser::Expect(int n) {
|
46
|
+
if (la->kind==n) Get(); else { SynErr(n); }
|
47
|
+
}
|
48
|
+
|
49
|
+
void Parser::ExpectWeak(int n, int follow) {
|
50
|
+
if (la->kind == n) Get();
|
51
|
+
else {
|
52
|
+
SynErr(n);
|
53
|
+
while (!StartOf(follow)) Get();
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
bool Parser::WeakSeparator(int n, int syFol, int repFol) {
|
58
|
+
if (la->kind == n) {Get(); return true;}
|
59
|
+
else if (StartOf(repFol)) {return false;}
|
60
|
+
else {
|
61
|
+
SynErr(n);
|
62
|
+
while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
|
63
|
+
Get();
|
64
|
+
}
|
65
|
+
return StartOf(syFol);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
void Parser::S2() {
|
70
|
+
s2 = std::make_shared<class S2>();
|
71
|
+
unsigned curline = la->line, curcol = la->col;
|
72
|
+
StatementPtr statement;
|
73
|
+
while (la->kind == 15 /* "[" */ || la->kind == 17 /* "struct" */ || la->kind == 20 /* "import" */) {
|
74
|
+
Statement(statement);
|
75
|
+
s2->statements.push_back(statement);
|
76
|
+
}
|
77
|
+
s2->_line = curline; s2->_col = curcol;
|
78
|
+
}
|
79
|
+
|
80
|
+
void Parser::Statement(StatementPtr& production) {
|
81
|
+
unsigned curline = la->line, curcol = la->col;
|
82
|
+
StructurePtr structure;
|
83
|
+
ImportPtr import;
|
84
|
+
if (la->kind == 15 /* "[" */ || la->kind == 17 /* "struct" */) {
|
85
|
+
Structure(structure);
|
86
|
+
production = structure;
|
87
|
+
} else if (la->kind == 20 /* "import" */) {
|
88
|
+
Import(import);
|
89
|
+
production = import;
|
90
|
+
} else SynErr(22);
|
91
|
+
production->_line = curline; production->_col = curcol;
|
92
|
+
}
|
93
|
+
|
94
|
+
void Parser::TypeVariable(TypeVariablePtr& production) {
|
95
|
+
production = std::make_shared<class TypeVariable>();
|
96
|
+
unsigned curline = la->line, curcol = la->col;
|
97
|
+
Expect(_customTokenTypeVariable);
|
98
|
+
production->content = t->val;
|
99
|
+
production->_line = curline; production->_col = curcol;
|
100
|
+
}
|
101
|
+
|
102
|
+
void Parser::StructName(StructNamePtr& production) {
|
103
|
+
production = std::make_shared<class StructName>();
|
104
|
+
unsigned curline = la->line, curcol = la->col;
|
105
|
+
Expect(_pascalcase);
|
106
|
+
production->content = t->val;
|
107
|
+
production->_line = curline; production->_col = curcol;
|
108
|
+
}
|
109
|
+
|
110
|
+
void Parser::MemberName(MemberNamePtr& production) {
|
111
|
+
production = std::make_shared<class MemberName>();
|
112
|
+
unsigned curline = la->line, curcol = la->col;
|
113
|
+
Expect(_camelcase);
|
114
|
+
production->content = t->val;
|
115
|
+
production->_line = curline; production->_col = curcol;
|
116
|
+
}
|
117
|
+
|
118
|
+
void Parser::NumberLiteral(NumberLiteralPtr& production) {
|
119
|
+
production = std::make_shared<class NumberLiteral>();
|
120
|
+
unsigned curline = la->line, curcol = la->col;
|
121
|
+
Expect(_number);
|
122
|
+
production->content = t->val;
|
123
|
+
production->_line = curline; production->_col = curcol;
|
124
|
+
}
|
125
|
+
|
126
|
+
void Parser::StringLiteral(StringLiteralPtr& production) {
|
127
|
+
production = std::make_shared<class StringLiteral>();
|
128
|
+
unsigned curline = la->line, curcol = la->col;
|
129
|
+
Expect(_string);
|
130
|
+
production->content = t->val;
|
131
|
+
production->_line = curline; production->_col = curcol;
|
132
|
+
}
|
133
|
+
|
134
|
+
void Parser::TypeIdentifier(TypeIdentifierPtr& production) {
|
135
|
+
production = std::make_shared<class TypeIdentifier>();
|
136
|
+
unsigned curline = la->line, curcol = la->col;
|
137
|
+
StructNamePtr structname;
|
138
|
+
TypeVariablePtr typevariable;
|
139
|
+
TypeParameterArgumentsPtr typeparameterarguments;
|
140
|
+
if (la->kind == _pascalcase) {
|
141
|
+
StructName(structname);
|
142
|
+
production->structname = structname;
|
143
|
+
} else if (la->kind == _customTokenTypeVariable) {
|
144
|
+
TypeVariable(typevariable);
|
145
|
+
production->typevariable = typevariable;
|
146
|
+
} else SynErr(23);
|
147
|
+
if (la->kind == 10 /* "<" */) {
|
148
|
+
TypeParameterArguments(typeparameterarguments);
|
149
|
+
production->typeparameterarguments.push_back(typeparameterarguments);
|
150
|
+
}
|
151
|
+
production->_line = curline; production->_col = curcol;
|
152
|
+
}
|
153
|
+
|
154
|
+
void Parser::TypeParameterArguments(TypeParameterArgumentsPtr& production) {
|
155
|
+
production = std::make_shared<class TypeParameterArguments>();
|
156
|
+
unsigned curline = la->line, curcol = la->col;
|
157
|
+
TypeExpressionPtr typeexpression;
|
158
|
+
Expect(10 /* "<" */);
|
159
|
+
TypeExpression(typeexpression);
|
160
|
+
production->typeexpressions.push_back(typeexpression);
|
161
|
+
while (la->kind == 11 /* "," */) {
|
162
|
+
Get();
|
163
|
+
TypeExpression(typeexpression);
|
164
|
+
production->typeexpressions.push_back(typeexpression);
|
165
|
+
}
|
166
|
+
Expect(12 /* ">" */);
|
167
|
+
production->_line = curline; production->_col = curcol;
|
168
|
+
}
|
169
|
+
|
170
|
+
void Parser::TypeExpression(TypeExpressionPtr& production) {
|
171
|
+
unsigned curline = la->line, curcol = la->col;
|
172
|
+
TypeIdentifierPtr typeidentifier;
|
173
|
+
TypeIdentifier(typeidentifier);
|
174
|
+
production = typeidentifier;
|
175
|
+
production->_line = curline; production->_col = curcol;
|
176
|
+
}
|
177
|
+
|
178
|
+
void Parser::TypeDeclaration(TypeDeclarationPtr& production) {
|
179
|
+
production = std::make_shared<class TypeDeclaration>();
|
180
|
+
unsigned curline = la->line, curcol = la->col;
|
181
|
+
StructNamePtr structname;
|
182
|
+
TypeParametersPtr typeparameters;
|
183
|
+
StructName(structname);
|
184
|
+
production->structname = structname;
|
185
|
+
if (la->kind == 10 /* "<" */) {
|
186
|
+
TypeParameters(typeparameters);
|
187
|
+
production->typeparameters.push_back(typeparameters);
|
188
|
+
}
|
189
|
+
production->_line = curline; production->_col = curcol;
|
190
|
+
}
|
191
|
+
|
192
|
+
void Parser::TypeParameters(TypeParametersPtr& production) {
|
193
|
+
production = std::make_shared<class TypeParameters>();
|
194
|
+
unsigned curline = la->line, curcol = la->col;
|
195
|
+
TypeVariablePtr typevariable;
|
196
|
+
Expect(10 /* "<" */);
|
197
|
+
TypeVariable(typevariable);
|
198
|
+
production->typevariables.push_back(typevariable);
|
199
|
+
while (la->kind == 11 /* "," */) {
|
200
|
+
Get();
|
201
|
+
TypeVariable(typevariable);
|
202
|
+
production->typevariables.push_back(typevariable);
|
203
|
+
}
|
204
|
+
Expect(12 /* ">" */);
|
205
|
+
production->_line = curline; production->_col = curcol;
|
206
|
+
}
|
207
|
+
|
208
|
+
void Parser::NumberLit(NumberLitPtr& production) {
|
209
|
+
production = std::make_shared<class NumberLit>();
|
210
|
+
unsigned curline = la->line, curcol = la->col;
|
211
|
+
NumberLiteralPtr numberliteral;
|
212
|
+
NumberLiteral(numberliteral);
|
213
|
+
production->numberliteral = numberliteral;
|
214
|
+
production->_line = curline; production->_col = curcol;
|
215
|
+
}
|
216
|
+
|
217
|
+
void Parser::Expression(ExpressionPtr& production) {
|
218
|
+
unsigned curline = la->line, curcol = la->col;
|
219
|
+
NumberLitPtr numberlit;
|
220
|
+
NumberLit(numberlit);
|
221
|
+
production = numberlit;
|
222
|
+
production->_line = curline; production->_col = curcol;
|
223
|
+
}
|
224
|
+
|
225
|
+
void Parser::AttributeParam(AttributeParamPtr& production) {
|
226
|
+
production = std::make_shared<class AttributeParam>();
|
227
|
+
unsigned curline = la->line, curcol = la->col;
|
228
|
+
MemberNamePtr membername;
|
229
|
+
ExpressionPtr expression;
|
230
|
+
MemberName(membername);
|
231
|
+
production->membername = membername;
|
232
|
+
Expect(13 /* "=" */);
|
233
|
+
Expression(expression);
|
234
|
+
production->expression = expression;
|
235
|
+
production->_line = curline; production->_col = curcol;
|
236
|
+
}
|
237
|
+
|
238
|
+
void Parser::AttributeParamList(AttributeParamListPtr& production) {
|
239
|
+
production = std::make_shared<class AttributeParamList>();
|
240
|
+
unsigned curline = la->line, curcol = la->col;
|
241
|
+
AttributeParamPtr attributeparam;
|
242
|
+
Expect(14 /* ":" */);
|
243
|
+
AttributeParam(attributeparam);
|
244
|
+
production->attributeparams.push_back(attributeparam);
|
245
|
+
while (la->kind == 11 /* "," */) {
|
246
|
+
Get();
|
247
|
+
AttributeParam(attributeparam);
|
248
|
+
production->attributeparams.push_back(attributeparam);
|
249
|
+
}
|
250
|
+
production->_line = curline; production->_col = curcol;
|
251
|
+
}
|
252
|
+
|
253
|
+
void Parser::Attribute(AttributePtr& production) {
|
254
|
+
production = std::make_shared<class Attribute>();
|
255
|
+
unsigned curline = la->line, curcol = la->col;
|
256
|
+
TypeExpressionPtr typeexpression;
|
257
|
+
AttributeParamListPtr attributeparamlist;
|
258
|
+
Expect(15 /* "[" */);
|
259
|
+
TypeExpression(typeexpression);
|
260
|
+
production->typeexpression = typeexpression;
|
261
|
+
if (la->kind == 14 /* ":" */) {
|
262
|
+
AttributeParamList(attributeparamlist);
|
263
|
+
production->attributeparamlists.push_back(attributeparamlist);
|
264
|
+
}
|
265
|
+
Expect(16 /* "]" */);
|
266
|
+
production->_line = curline; production->_col = curcol;
|
267
|
+
}
|
268
|
+
|
269
|
+
void Parser::Member(MemberPtr& production) {
|
270
|
+
production = std::make_shared<class Member>();
|
271
|
+
unsigned curline = la->line, curcol = la->col;
|
272
|
+
AttributePtr attribute;
|
273
|
+
TypeIdentifierPtr typeidentifier;
|
274
|
+
MemberNamePtr membername;
|
275
|
+
while (la->kind == 15 /* "[" */) {
|
276
|
+
Attribute(attribute);
|
277
|
+
production->attributes.push_back(attribute);
|
278
|
+
}
|
279
|
+
TypeIdentifier(typeidentifier);
|
280
|
+
production->typeidentifier = typeidentifier;
|
281
|
+
MemberName(membername);
|
282
|
+
production->membernames.push_back(membername);
|
283
|
+
while (la->kind == 11 /* "," */) {
|
284
|
+
Get();
|
285
|
+
MemberName(membername);
|
286
|
+
production->membernames.push_back(membername);
|
287
|
+
}
|
288
|
+
production->_line = curline; production->_col = curcol;
|
289
|
+
}
|
290
|
+
|
291
|
+
void Parser::Structure(StructurePtr& production) {
|
292
|
+
production = std::make_shared<class Structure>();
|
293
|
+
unsigned curline = la->line, curcol = la->col;
|
294
|
+
AttributePtr attribute;
|
295
|
+
TypeDeclarationPtr typedeclaration;
|
296
|
+
MemberPtr member;
|
297
|
+
while (la->kind == 15 /* "[" */) {
|
298
|
+
Attribute(attribute);
|
299
|
+
production->attributes.push_back(attribute);
|
300
|
+
}
|
301
|
+
Expect(17 /* "struct" */);
|
302
|
+
TypeDeclaration(typedeclaration);
|
303
|
+
production->typedeclaration = typedeclaration;
|
304
|
+
Expect(18 /* "{" */);
|
305
|
+
Member(member);
|
306
|
+
production->members.push_back(member);
|
307
|
+
while (la->kind == _pascalcase || la->kind == _customTokenTypeVariable || la->kind == 15 /* "[" */) {
|
308
|
+
Member(member);
|
309
|
+
production->members.push_back(member);
|
310
|
+
}
|
311
|
+
Expect(19 /* "}" */);
|
312
|
+
production->_line = curline; production->_col = curcol;
|
313
|
+
}
|
314
|
+
|
315
|
+
void Parser::Import(ImportPtr& production) {
|
316
|
+
production = std::make_shared<class Import>();
|
317
|
+
unsigned curline = la->line, curcol = la->col;
|
318
|
+
StringLiteralPtr stringliteral;
|
319
|
+
Expect(20 /* "import" */);
|
320
|
+
StringLiteral(stringliteral);
|
321
|
+
production->stringliteral = stringliteral;
|
322
|
+
production->_line = curline; production->_col = curcol;
|
323
|
+
}
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
// If the user declared a method Init and a mehtod Destroy they should
|
329
|
+
// be called in the contructur and the destructor respctively.
|
330
|
+
//
|
331
|
+
// The following templates are used to recognize if the user declared
|
332
|
+
// the methods Init and Destroy.
|
333
|
+
|
334
|
+
template<typename T>
|
335
|
+
struct ParserInitExistsRecognizer {
|
336
|
+
template<typename U, void (U::*)() = &U::Init>
|
337
|
+
struct ExistsIfInitIsDefinedMarker{};
|
338
|
+
|
339
|
+
struct InitIsMissingType {
|
340
|
+
char dummy1;
|
341
|
+
};
|
342
|
+
|
343
|
+
struct InitExistsType {
|
344
|
+
char dummy1; char dummy2;
|
345
|
+
};
|
346
|
+
|
347
|
+
// exists always
|
348
|
+
template<typename U>
|
349
|
+
static InitIsMissingType is_here(...);
|
350
|
+
|
351
|
+
// exist only if ExistsIfInitIsDefinedMarker is defined
|
352
|
+
template<typename U>
|
353
|
+
static InitExistsType is_here(ExistsIfInitIsDefinedMarker<U>*);
|
354
|
+
|
355
|
+
enum { InitExists = (sizeof(is_here<T>(NULL)) == sizeof(InitExistsType)) };
|
356
|
+
};
|
357
|
+
|
358
|
+
template<typename T>
|
359
|
+
struct ParserDestroyExistsRecognizer {
|
360
|
+
template<typename U, void (U::*)() = &U::Destroy>
|
361
|
+
struct ExistsIfDestroyIsDefinedMarker{};
|
362
|
+
|
363
|
+
struct DestroyIsMissingType {
|
364
|
+
char dummy1;
|
365
|
+
};
|
366
|
+
|
367
|
+
struct DestroyExistsType {
|
368
|
+
char dummy1; char dummy2;
|
369
|
+
};
|
370
|
+
|
371
|
+
// exists always
|
372
|
+
template<typename U>
|
373
|
+
static DestroyIsMissingType is_here(...);
|
374
|
+
|
375
|
+
// exist only if ExistsIfDestroyIsDefinedMarker is defined
|
376
|
+
template<typename U>
|
377
|
+
static DestroyExistsType is_here(ExistsIfDestroyIsDefinedMarker<U>*);
|
378
|
+
|
379
|
+
enum { DestroyExists = (sizeof(is_here<T>(NULL)) == sizeof(DestroyExistsType)) };
|
380
|
+
};
|
381
|
+
|
382
|
+
// The folloing templates are used to call the Init and Destroy methods if they exist.
|
383
|
+
|
384
|
+
// Generic case of the ParserInitCaller, gets used if the Init method is missing
|
385
|
+
template<typename T, bool = ParserInitExistsRecognizer<T>::InitExists>
|
386
|
+
struct ParserInitCaller {
|
387
|
+
static void CallInit(T *t) {
|
388
|
+
// nothing to do
|
389
|
+
}
|
390
|
+
};
|
391
|
+
|
392
|
+
// True case of the ParserInitCaller, gets used if the Init method exists
|
393
|
+
template<typename T>
|
394
|
+
struct ParserInitCaller<T, true> {
|
395
|
+
static void CallInit(T *t) {
|
396
|
+
t->Init();
|
397
|
+
}
|
398
|
+
};
|
399
|
+
|
400
|
+
// Generic case of the ParserDestroyCaller, gets used if the Destroy method is missing
|
401
|
+
template<typename T, bool = ParserDestroyExistsRecognizer<T>::DestroyExists>
|
402
|
+
struct ParserDestroyCaller {
|
403
|
+
static void CallDestroy(T *t) {
|
404
|
+
// nothing to do
|
405
|
+
}
|
406
|
+
};
|
407
|
+
|
408
|
+
// True case of the ParserDestroyCaller, gets used if the Destroy method exists
|
409
|
+
template<typename T>
|
410
|
+
struct ParserDestroyCaller<T, true> {
|
411
|
+
static void CallDestroy(T *t) {
|
412
|
+
t->Destroy();
|
413
|
+
}
|
414
|
+
};
|
415
|
+
|
416
|
+
void Parser::Parse() {
|
417
|
+
t = NULL;
|
418
|
+
la = dummyToken = new Token();
|
419
|
+
la->val = coco_string_create(L"Dummy Token");
|
420
|
+
Get();
|
421
|
+
S2();
|
422
|
+
Expect(0);
|
423
|
+
}
|
424
|
+
|
425
|
+
Parser::Parser(Scanner *scanner) {
|
426
|
+
maxT = 21;
|
427
|
+
|
428
|
+
ParserInitCaller<Parser>::CallInit(this);
|
429
|
+
dummyToken = NULL;
|
430
|
+
t = la = NULL;
|
431
|
+
minErrDist = 2;
|
432
|
+
errDist = minErrDist;
|
433
|
+
this->scanner = scanner;
|
434
|
+
errors = new Errors();
|
435
|
+
}
|
436
|
+
|
437
|
+
bool Parser::StartOf(int s) {
|
438
|
+
const bool T = true;
|
439
|
+
const bool x = false;
|
440
|
+
|
441
|
+
static bool set[1][23] = {
|
442
|
+
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x}
|
443
|
+
};
|
444
|
+
|
445
|
+
|
446
|
+
|
447
|
+
return set[s][la->kind];
|
448
|
+
}
|
449
|
+
|
450
|
+
Parser::~Parser() {
|
451
|
+
ParserDestroyCaller<Parser>::CallDestroy(this);
|
452
|
+
delete errors;
|
453
|
+
delete dummyToken;
|
454
|
+
}
|
455
|
+
|
456
|
+
Errors::Errors() {
|
457
|
+
count = 0;
|
458
|
+
}
|
459
|
+
|
460
|
+
void Errors::SynErr(int line, int col, int n) {
|
461
|
+
wchar_t* s;
|
462
|
+
switch (n) {
|
463
|
+
case 0: s = coco_string_create(L"EOF expected"); break;
|
464
|
+
case 1: s = coco_string_create(L"pascalcase expected"); break;
|
465
|
+
case 2: s = coco_string_create(L"camelcase expected"); break;
|
466
|
+
case 3: s = coco_string_create(L"number expected"); break;
|
467
|
+
case 4: s = coco_string_create(L"hexinteger expected"); break;
|
468
|
+
case 5: s = coco_string_create(L"string expected"); break;
|
469
|
+
case 6: s = coco_string_create(L"badString expected"); break;
|
470
|
+
case 7: s = coco_string_create(L"char expected"); break;
|
471
|
+
case 8: s = coco_string_create(L"endOfLine expected"); break;
|
472
|
+
case 9: s = coco_string_create(L"customTokenTypeVariable expected"); break;
|
473
|
+
case 10: s = coco_string_create(L"\"<\" expected"); break;
|
474
|
+
case 11: s = coco_string_create(L"\",\" expected"); break;
|
475
|
+
case 12: s = coco_string_create(L"\">\" expected"); break;
|
476
|
+
case 13: s = coco_string_create(L"\"=\" expected"); break;
|
477
|
+
case 14: s = coco_string_create(L"\":\" expected"); break;
|
478
|
+
case 15: s = coco_string_create(L"\"[\" expected"); break;
|
479
|
+
case 16: s = coco_string_create(L"\"]\" expected"); break;
|
480
|
+
case 17: s = coco_string_create(L"\"struct\" expected"); break;
|
481
|
+
case 18: s = coco_string_create(L"\"{\" expected"); break;
|
482
|
+
case 19: s = coco_string_create(L"\"}\" expected"); break;
|
483
|
+
case 20: s = coco_string_create(L"\"import\" expected"); break;
|
484
|
+
case 21: s = coco_string_create(L"??? expected"); break;
|
485
|
+
case 22: s = coco_string_create(L"invalid Statement"); break;
|
486
|
+
case 23: s = coco_string_create(L"invalid TypeIdentifier"); break;
|
487
|
+
|
488
|
+
default:
|
489
|
+
{
|
490
|
+
wchar_t format[20];
|
491
|
+
coco_swprintf(format, 20, L"error %d", n);
|
492
|
+
s = coco_string_create(format);
|
493
|
+
}
|
494
|
+
break;
|
495
|
+
}
|
496
|
+
throw ParserException(line, col, s);
|
497
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
498
|
+
coco_string_delete(s);
|
499
|
+
count++;
|
500
|
+
}
|
501
|
+
|
502
|
+
void Errors::Error(int line, int col, const wchar_t *s) {
|
503
|
+
throw ParserException(line, col, s);
|
504
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
505
|
+
count++;
|
506
|
+
}
|
507
|
+
|
508
|
+
void Errors::Warning(int line, int col, const wchar_t *s) {
|
509
|
+
warnings.push_back(ParserException(line, col, s));
|
510
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
511
|
+
}
|
512
|
+
|
513
|
+
void Errors::Warning(const wchar_t *s) {
|
514
|
+
warnings.push_back(ParserException(0, 0, s));
|
515
|
+
//wprintf(L"%ls\n", s);
|
516
|
+
}
|
517
|
+
|
518
|
+
void Errors::Exception(const wchar_t* s) {
|
519
|
+
throw ParserException(0, 0, s);
|
520
|
+
//wprintf(L"%ls", s);
|
521
|
+
exit(1);
|
522
|
+
}
|
523
|
+
|
524
|
+
} // namespace
|
525
|
+
|