s2 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|