ruco-cpp 0.2.1
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 +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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 938f24b2c00ffbe663d224f8a4bdc7e83ffd1399
|
4
|
+
data.tar.gz: f90f9b5745a5366f5094fe1ecffa697429204e1c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9bf140c850998e1cfa9e4bde933861ce4cf30f84c3ed7ecfdb0a433d526d2ab359578e244eb86b1839b54fcaed3855c3487653b5db937e394aab2203faffdff
|
7
|
+
data.tar.gz: 80b235765f865e55b913c40ef547895d521d31382a6ff28dca478713ac866b5802bcea22f05bc7ae91f0af8bb33c34f0bf8bf898807a629e3454fa83ba659033
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "rake/extensiontask"
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
gemspec = Gem::Specification.load('ruco.gemspec')
|
8
|
+
Rake::ExtensionTask.new do |ext|
|
9
|
+
ext.name = 'cocor'
|
10
|
+
ext.ext_dir = 'ext/cocor'
|
11
|
+
ext.lib_dir = 'lib/cocor'
|
12
|
+
ext.gem_spec = gemspec
|
13
|
+
ext.source_pattern = "*.{c,cpp}"
|
14
|
+
end
|
15
|
+
|
16
|
+
task :default => [:test]
|
17
|
+
task :test => [:compile, :spec]
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ruco"
|
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
|
data/bin/ruco
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "ruco"
|
4
|
+
require "cocor"
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
if ARGV.length < 1
|
8
|
+
puts "Usage: ruco <grammar.ruco> [Grammar Name]"
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
|
12
|
+
file = ARGV[0]
|
13
|
+
grammar_name = File.basename file, ".ruco"
|
14
|
+
grammar_name = ARGV[1] if ARGV[1]
|
15
|
+
|
16
|
+
rr = Ruco::Ruco.new grammar_name.capitalize do
|
17
|
+
instance_eval(File.read(file), file)
|
18
|
+
end
|
19
|
+
|
20
|
+
File.write("#{grammar_name}.atg",rr.generate_atg)
|
21
|
+
File.write("#{grammar_name}.hpp",rr.generate_header)
|
22
|
+
File.write("parse_#{grammar_name}.cpp",rr.generate_libcpp)
|
23
|
+
File.write("parse_#{grammar_name}.hpp",rr.generate_libhpp)
|
24
|
+
FileUtils.cp(File.join(Gem.datadir("ruco"), "picojson", "picojson.h"),"picojson.hpp")
|
25
|
+
|
26
|
+
atg = File.join(Dir.pwd, "#{grammar_name}.atg")
|
27
|
+
datadir = Gem.datadir "ruco"
|
28
|
+
puts atg
|
29
|
+
|
30
|
+
Cocor.compile atg, datadir, grammar_name.capitalize, "#{Dir.pwd}/"
|
data/bin/setup
ADDED
@@ -0,0 +1,359 @@
|
|
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
|
+
/*----------------------------------------------------------------------
|
30
|
+
Parser.h Specification
|
31
|
+
-----------------------------------------------------------------------*/
|
32
|
+
|
33
|
+
-->begin
|
34
|
+
|
35
|
+
#if !defined(-->prefixCOCO_PARSER_H__)
|
36
|
+
#define -->prefixCOCO_PARSER_H__
|
37
|
+
|
38
|
+
-->headerdef
|
39
|
+
|
40
|
+
#include "Scanner.h"
|
41
|
+
|
42
|
+
-->namespace_open
|
43
|
+
|
44
|
+
class ParserException {
|
45
|
+
|
46
|
+
int line,col;
|
47
|
+
std::wstring message;
|
48
|
+
|
49
|
+
public:
|
50
|
+
ParserException(int line, int col, std::wstring message) :
|
51
|
+
line(line), col(col), message(message)
|
52
|
+
{
|
53
|
+
}
|
54
|
+
|
55
|
+
int LineNumber() const
|
56
|
+
{
|
57
|
+
return line;
|
58
|
+
}
|
59
|
+
|
60
|
+
int ColumnNumber() const
|
61
|
+
{
|
62
|
+
return col;
|
63
|
+
}
|
64
|
+
|
65
|
+
std::wstring GetMessage() const
|
66
|
+
{
|
67
|
+
return message;
|
68
|
+
}
|
69
|
+
};
|
70
|
+
|
71
|
+
class Errors {
|
72
|
+
public:
|
73
|
+
int count; // number of errors detected
|
74
|
+
std::vector<ParserException> warnings;
|
75
|
+
|
76
|
+
Errors();
|
77
|
+
void SynErr(int line, int col, int n);
|
78
|
+
void Error(int line, int col, const wchar_t *s);
|
79
|
+
void Warning(int line, int col, const wchar_t *s);
|
80
|
+
void Warning(const wchar_t *s);
|
81
|
+
void Exception(const wchar_t *s);
|
82
|
+
|
83
|
+
}; // Errors
|
84
|
+
|
85
|
+
class Parser {
|
86
|
+
private:
|
87
|
+
-->constantsheader
|
88
|
+
Token *dummyToken;
|
89
|
+
int errDist;
|
90
|
+
int minErrDist;
|
91
|
+
|
92
|
+
void SynErr(int n);
|
93
|
+
void Get();
|
94
|
+
void Expect(int n);
|
95
|
+
bool StartOf(int s);
|
96
|
+
void ExpectWeak(int n, int follow);
|
97
|
+
bool WeakSeparator(int n, int syFol, int repFol);
|
98
|
+
|
99
|
+
public:
|
100
|
+
Scanner *scanner;
|
101
|
+
Errors *errors;
|
102
|
+
|
103
|
+
Token *t; // last recognized token
|
104
|
+
Token *la; // lookahead token
|
105
|
+
|
106
|
+
-->declarations
|
107
|
+
|
108
|
+
Parser(Scanner *scanner);
|
109
|
+
~Parser();
|
110
|
+
void SemErr(const wchar_t* msg);
|
111
|
+
|
112
|
+
-->productionsheader
|
113
|
+
void Parse();
|
114
|
+
|
115
|
+
}; // end Parser
|
116
|
+
|
117
|
+
-->namespace_close
|
118
|
+
|
119
|
+
#endif
|
120
|
+
|
121
|
+
-->implementation
|
122
|
+
|
123
|
+
/*----------------------------------------------------------------------
|
124
|
+
Parser.cpp Specification
|
125
|
+
-----------------------------------------------------------------------*/
|
126
|
+
|
127
|
+
-->begin
|
128
|
+
|
129
|
+
#include <wchar.h>
|
130
|
+
#include "Parser.h"
|
131
|
+
#include "Scanner.h"
|
132
|
+
|
133
|
+
|
134
|
+
-->namespace_open
|
135
|
+
|
136
|
+
void Parser::SynErr(int n) {
|
137
|
+
if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
|
138
|
+
errDist = 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
void Parser::SemErr(const wchar_t* msg) {
|
142
|
+
if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
|
143
|
+
errDist = 0;
|
144
|
+
}
|
145
|
+
|
146
|
+
void Parser::Get() {
|
147
|
+
for (;;) {
|
148
|
+
t = la;
|
149
|
+
la = scanner->Scan();
|
150
|
+
if (la->kind <= maxT) { ++errDist; break; }
|
151
|
+
-->pragmas
|
152
|
+
if (dummyToken != t) {
|
153
|
+
dummyToken->kind = t->kind;
|
154
|
+
dummyToken->pos = t->pos;
|
155
|
+
dummyToken->col = t->col;
|
156
|
+
dummyToken->line = t->line;
|
157
|
+
dummyToken->next = NULL;
|
158
|
+
coco_string_delete(dummyToken->val);
|
159
|
+
dummyToken->val = coco_string_create(t->val);
|
160
|
+
t = dummyToken;
|
161
|
+
}
|
162
|
+
la = t;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
void Parser::Expect(int n) {
|
167
|
+
if (la->kind==n) Get(); else { SynErr(n); }
|
168
|
+
}
|
169
|
+
|
170
|
+
void Parser::ExpectWeak(int n, int follow) {
|
171
|
+
if (la->kind == n) Get();
|
172
|
+
else {
|
173
|
+
SynErr(n);
|
174
|
+
while (!StartOf(follow)) Get();
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
bool Parser::WeakSeparator(int n, int syFol, int repFol) {
|
179
|
+
if (la->kind == n) {Get(); return true;}
|
180
|
+
else if (StartOf(repFol)) {return false;}
|
181
|
+
else {
|
182
|
+
SynErr(n);
|
183
|
+
while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
|
184
|
+
Get();
|
185
|
+
}
|
186
|
+
return StartOf(syFol);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
-->productions
|
191
|
+
|
192
|
+
|
193
|
+
// If the user declared a method Init and a mehtod Destroy they should
|
194
|
+
// be called in the contructur and the destructor respctively.
|
195
|
+
//
|
196
|
+
// The following templates are used to recognize if the user declared
|
197
|
+
// the methods Init and Destroy.
|
198
|
+
|
199
|
+
template<typename T>
|
200
|
+
struct ParserInitExistsRecognizer {
|
201
|
+
template<typename U, void (U::*)() = &U::Init>
|
202
|
+
struct ExistsIfInitIsDefinedMarker{};
|
203
|
+
|
204
|
+
struct InitIsMissingType {
|
205
|
+
char dummy1;
|
206
|
+
};
|
207
|
+
|
208
|
+
struct InitExistsType {
|
209
|
+
char dummy1; char dummy2;
|
210
|
+
};
|
211
|
+
|
212
|
+
// exists always
|
213
|
+
template<typename U>
|
214
|
+
static InitIsMissingType is_here(...);
|
215
|
+
|
216
|
+
// exist only if ExistsIfInitIsDefinedMarker is defined
|
217
|
+
template<typename U>
|
218
|
+
static InitExistsType is_here(ExistsIfInitIsDefinedMarker<U>*);
|
219
|
+
|
220
|
+
enum { InitExists = (sizeof(is_here<T>(NULL)) == sizeof(InitExistsType)) };
|
221
|
+
};
|
222
|
+
|
223
|
+
template<typename T>
|
224
|
+
struct ParserDestroyExistsRecognizer {
|
225
|
+
template<typename U, void (U::*)() = &U::Destroy>
|
226
|
+
struct ExistsIfDestroyIsDefinedMarker{};
|
227
|
+
|
228
|
+
struct DestroyIsMissingType {
|
229
|
+
char dummy1;
|
230
|
+
};
|
231
|
+
|
232
|
+
struct DestroyExistsType {
|
233
|
+
char dummy1; char dummy2;
|
234
|
+
};
|
235
|
+
|
236
|
+
// exists always
|
237
|
+
template<typename U>
|
238
|
+
static DestroyIsMissingType is_here(...);
|
239
|
+
|
240
|
+
// exist only if ExistsIfDestroyIsDefinedMarker is defined
|
241
|
+
template<typename U>
|
242
|
+
static DestroyExistsType is_here(ExistsIfDestroyIsDefinedMarker<U>*);
|
243
|
+
|
244
|
+
enum { DestroyExists = (sizeof(is_here<T>(NULL)) == sizeof(DestroyExistsType)) };
|
245
|
+
};
|
246
|
+
|
247
|
+
// The folloing templates are used to call the Init and Destroy methods if they exist.
|
248
|
+
|
249
|
+
// Generic case of the ParserInitCaller, gets used if the Init method is missing
|
250
|
+
template<typename T, bool = ParserInitExistsRecognizer<T>::InitExists>
|
251
|
+
struct ParserInitCaller {
|
252
|
+
static void CallInit(T *t) {
|
253
|
+
// nothing to do
|
254
|
+
}
|
255
|
+
};
|
256
|
+
|
257
|
+
// True case of the ParserInitCaller, gets used if the Init method exists
|
258
|
+
template<typename T>
|
259
|
+
struct ParserInitCaller<T, true> {
|
260
|
+
static void CallInit(T *t) {
|
261
|
+
t->Init();
|
262
|
+
}
|
263
|
+
};
|
264
|
+
|
265
|
+
// Generic case of the ParserDestroyCaller, gets used if the Destroy method is missing
|
266
|
+
template<typename T, bool = ParserDestroyExistsRecognizer<T>::DestroyExists>
|
267
|
+
struct ParserDestroyCaller {
|
268
|
+
static void CallDestroy(T *t) {
|
269
|
+
// nothing to do
|
270
|
+
}
|
271
|
+
};
|
272
|
+
|
273
|
+
// True case of the ParserDestroyCaller, gets used if the Destroy method exists
|
274
|
+
template<typename T>
|
275
|
+
struct ParserDestroyCaller<T, true> {
|
276
|
+
static void CallDestroy(T *t) {
|
277
|
+
t->Destroy();
|
278
|
+
}
|
279
|
+
};
|
280
|
+
|
281
|
+
void Parser::Parse() {
|
282
|
+
t = NULL;
|
283
|
+
la = dummyToken = new Token();
|
284
|
+
la->val = coco_string_create(L"Dummy Token");
|
285
|
+
Get();
|
286
|
+
-->parseRoot
|
287
|
+
}
|
288
|
+
|
289
|
+
Parser::Parser(Scanner *scanner) {
|
290
|
+
-->constants
|
291
|
+
ParserInitCaller<Parser>::CallInit(this);
|
292
|
+
dummyToken = NULL;
|
293
|
+
t = la = NULL;
|
294
|
+
minErrDist = 2;
|
295
|
+
errDist = minErrDist;
|
296
|
+
this->scanner = scanner;
|
297
|
+
errors = new Errors();
|
298
|
+
}
|
299
|
+
|
300
|
+
bool Parser::StartOf(int s) {
|
301
|
+
const bool T = true;
|
302
|
+
const bool x = false;
|
303
|
+
|
304
|
+
-->initialization
|
305
|
+
|
306
|
+
return set[s][la->kind];
|
307
|
+
}
|
308
|
+
|
309
|
+
Parser::~Parser() {
|
310
|
+
ParserDestroyCaller<Parser>::CallDestroy(this);
|
311
|
+
delete errors;
|
312
|
+
delete dummyToken;
|
313
|
+
}
|
314
|
+
|
315
|
+
Errors::Errors() {
|
316
|
+
count = 0;
|
317
|
+
}
|
318
|
+
|
319
|
+
void Errors::SynErr(int line, int col, int n) {
|
320
|
+
wchar_t* s;
|
321
|
+
switch (n) {
|
322
|
+
-->errors
|
323
|
+
default:
|
324
|
+
{
|
325
|
+
wchar_t format[20];
|
326
|
+
coco_swprintf(format, 20, L"error %d", n);
|
327
|
+
s = coco_string_create(format);
|
328
|
+
}
|
329
|
+
break;
|
330
|
+
}
|
331
|
+
throw ParserException(line, col, s);
|
332
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
333
|
+
coco_string_delete(s);
|
334
|
+
count++;
|
335
|
+
}
|
336
|
+
|
337
|
+
void Errors::Error(int line, int col, const wchar_t *s) {
|
338
|
+
throw ParserException(line, col, s);
|
339
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
340
|
+
count++;
|
341
|
+
}
|
342
|
+
|
343
|
+
void Errors::Warning(int line, int col, const wchar_t *s) {
|
344
|
+
warnings.push_back(ParserException(line, col, s));
|
345
|
+
//wprintf(L"-- line %d col %d: %ls\n", line, col, s);
|
346
|
+
}
|
347
|
+
|
348
|
+
void Errors::Warning(const wchar_t *s) {
|
349
|
+
warnings.push_back(ParserException(0, 0, s));
|
350
|
+
//wprintf(L"%ls\n", s);
|
351
|
+
}
|
352
|
+
|
353
|
+
void Errors::Exception(const wchar_t* s) {
|
354
|
+
throw ParserException(0, 0, s);
|
355
|
+
//wprintf(L"%ls", s);
|
356
|
+
exit(1);
|
357
|
+
}
|
358
|
+
|
359
|
+
-->namespace_close
|