gdstruct 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +7 -0
- data/MIT-LICENSE +18 -0
- data/README.md +196 -0
- data/Rakefile +11 -0
- data/lib/gdstruct/gds_007.rb +46 -0
- data/lib/gdstruct/version.rb +4 -0
- data/lib/gdstruct.rb +24 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c61b1b6f9dd5d07247a8d679c711d01c85fbf491
|
4
|
+
data.tar.gz: 97c45427b53b2cd18ff360ecc86ebb925269b51d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 26bdcfdba34d26ae4d9d9be9d11b41d99b2f760e9db6040dc77655adaedd1669ac7fc700fea43ec115c34fd1ebab8f8d78f5d8d5254cad616de98ca39f5b0c3e
|
7
|
+
data.tar.gz: 738352426ea88b5812726337fc54f49c9126c92380f3ecf05ee836a3692c8a921dca50851d6a5c90b73419e9c17ba29052ae42a639f6f1897e6e7754781811de
|
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2018 Ulrich Ramminger
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
gdstruct - GDS - General Data Structure
|
2
|
+
=======================================
|
3
|
+
|
4
|
+
A General Data Structure (GDS) is a universal, composable data structure, used to store any kind of data.
|
5
|
+
This could be for example the definition of configurations, specifications and data sets.
|
6
|
+
Typical usage is the definition of configurations, specifications and data sets.
|
7
|
+
The GDS language is a special DSL (domain specific language) for defining general data structures.
|
8
|
+
It uses a succinct, indentation-sensitive syntax which makes data representation clear and readable.
|
9
|
+
The building blocks for general data structures are hashes and arrays.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
============
|
13
|
+
|
14
|
+
~~~
|
15
|
+
gem install gdstruct
|
16
|
+
~~~
|
17
|
+
|
18
|
+
A Short Example
|
19
|
+
===============
|
20
|
+
|
21
|
+
~~~ruby
|
22
|
+
require "gdstruct"
|
23
|
+
|
24
|
+
h = GDstruct.c( <<-EOS )
|
25
|
+
:
|
26
|
+
a val a
|
27
|
+
b val b
|
28
|
+
EOS
|
29
|
+
|
30
|
+
# => h = { a: 'val a', b: 'val b' }
|
31
|
+
~~~
|
32
|
+
|
33
|
+
An Introduction
|
34
|
+
===============
|
35
|
+
|
36
|
+
The GDS language uses two basic symbols (__:__ and __,__) for the creation of hashes and arrays.
|
37
|
+
|
38
|
+
A colon (__:__) is used to define a hash.
|
39
|
+
A comma (__,__) is used to define an array.
|
40
|
+
|
41
|
+
Use indentation with two spaces for the definition of elements and for nested structures.
|
42
|
+
Tab characters are not allowed for indentation.
|
43
|
+
|
44
|
+
## Another Example
|
45
|
+
|
46
|
+
~~~
|
47
|
+
:
|
48
|
+
caption foo
|
49
|
+
credit bar
|
50
|
+
images
|
51
|
+
small
|
52
|
+
url http://mywebsite.com/image-small.jpg
|
53
|
+
dimensions
|
54
|
+
height 500
|
55
|
+
width 500
|
56
|
+
large
|
57
|
+
url http://mywebsite.com/image-large.jpg
|
58
|
+
dimensions
|
59
|
+
height 500
|
60
|
+
width 500
|
61
|
+
videos
|
62
|
+
small
|
63
|
+
preview http://mywebsite.com/video.m4v
|
64
|
+
dimensions
|
65
|
+
height 300
|
66
|
+
width 400
|
67
|
+
~~~
|
68
|
+
|
69
|
+
transforms to
|
70
|
+
|
71
|
+
~~~
|
72
|
+
{
|
73
|
+
:caption => 'foo',
|
74
|
+
:credit => 'bar',
|
75
|
+
:images => {
|
76
|
+
:small => {
|
77
|
+
:url => 'http://mywebsite.com/image-small.jpg',
|
78
|
+
:dimensions => {
|
79
|
+
:height => 500,
|
80
|
+
:width => 500
|
81
|
+
}
|
82
|
+
},
|
83
|
+
:large => {
|
84
|
+
:url => 'http://mywebsite.com/image-large.jpg',
|
85
|
+
:dimensions => {
|
86
|
+
:height => 500,
|
87
|
+
:width => 500
|
88
|
+
}
|
89
|
+
},
|
90
|
+
},
|
91
|
+
:videos => {
|
92
|
+
:small => {
|
93
|
+
:preview => 'http://mywebsite.com/video.m4v',
|
94
|
+
:dimensions => {
|
95
|
+
:height => 300,
|
96
|
+
:width => 400
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
~~~
|
102
|
+
|
103
|
+
## General Example
|
104
|
+
|
105
|
+
~~~
|
106
|
+
,
|
107
|
+
v1
|
108
|
+
: k2 v2
|
109
|
+
: k31 v31 | k32 v32 | k33 v33
|
110
|
+
k34 v34
|
111
|
+
k35 v35 | k36 v36
|
112
|
+
:
|
113
|
+
k41 v41
|
114
|
+
k42 v42
|
115
|
+
k43,
|
116
|
+
k44, 1 | 2 | 3
|
117
|
+
4 | 5
|
118
|
+
6
|
119
|
+
7
|
120
|
+
8 | 9
|
121
|
+
:k441 v441
|
122
|
+
v5
|
123
|
+
|
124
|
+
# => [ 'v1', { k2: 'v2' }, { k31: 'v31', k32: 'v32', k33: 'v33', k34: 'v34', k35: 'v35', k36: 'v36' },
|
125
|
+
{ k41: 'v41', k42: 'v42', k43: [], k44: [1, 2, 3, 4, 5, 6, 7, 8, 9, { k441: 'v441' } ] }, 'v5' ]
|
126
|
+
~~~
|
127
|
+
|
128
|
+
## Motivation and Features
|
129
|
+
|
130
|
+
* the focus is on the essential data
|
131
|
+
* structure and hierarchy is expressed using indentation (whitespace-sensitive) - avoids curly braces and square brackets
|
132
|
+
* uses a succinct and minimalist syntax - tries to avoid unnecessary characters
|
133
|
+
* in many cases colons, commas and quotes are not necessary
|
134
|
+
* less text makes data clearer and more readable
|
135
|
+
* for configuration and specification - replacement for XML, JSON, YAML
|
136
|
+
* for data/database seeding
|
137
|
+
* less text and less potential errors using schema definitions
|
138
|
+
* supports block comments, which could be nested
|
139
|
+
* allows also the definition of hash and array structures in a kind of restricted classic Ruby like syntax
|
140
|
+
* provides an alternative for Ruby hash and array definition without using eval(); can be used as a protection against code injection vulnerabilities, e.g. on web servers
|
141
|
+
|
142
|
+
|
143
|
+
## Schema specifiers
|
144
|
+
|
145
|
+
Schema specifiers can be used to predefine the keys of a hash or subhash.
|
146
|
+
When you specify the values you no longer need to name the key for each value.
|
147
|
+
This facilitates the input for hashes and prevents typos for keys.
|
148
|
+
In combination with the pipe symbol (__\|__), which allows to define multiple values on a single line,
|
149
|
+
this features a slim and clearly arranged, table-like style for data.
|
150
|
+
|
151
|
+
~~~
|
152
|
+
$country(name,capital,area,population,vehicleRegistrationCode,iso3166code,callingCode)
|
153
|
+
, $country /*
|
154
|
+
name capital area (km^2) population vehicleRegistrationCode iso3166code callingCode
|
155
|
+
---------------------------------------------------------------------------------------------------------------------------- */
|
156
|
+
: Deutschland | Berlin | 357_385 | 82_521_653 | D | DE | 49
|
157
|
+
: USA | Washington, D.C. | 9_833_520 | 325_719_178 | USA | US | 1
|
158
|
+
: China | Beijing | 9_596_961 | 1_403_500_365 | CHN | CN | 86
|
159
|
+
: India | New Dehli | 3_287_469 | 1_339_180_000 | IND | IN | 91
|
160
|
+
: Austria | Vienna | 83_878 | 8_822_267 | A | AT | 43
|
161
|
+
: Denmark | Copenhagen | 42_921 | 5_748_769 | DK | DK | 45
|
162
|
+
: Canada | Ottawa | 9_984_670 | 36_503_097 | CDN | CA | 1
|
163
|
+
: France | Paris | 643_801 | 66_991_000 | F | FR | 33
|
164
|
+
: Russia | Moscow | 17_075_400 | 144_526_636 | RUS | RU | 7
|
165
|
+
~~~
|
166
|
+
transforms to
|
167
|
+
~~~
|
168
|
+
[
|
169
|
+
{ :name=>"Deutschland", :capital=>"Berlin", :area=>357385, :population=>82521653, :vehicleRegistrationCode=>"D", :iso3166code=>"DE", :callingCode=>49 },
|
170
|
+
{ :name=>"USA", :capital=>"Washington, D.C.", :area=>9833520, :population=>325719178, :vehicleRegistrationCode=>"USA", :iso3166code=>"US", :callingCode=>1 },
|
171
|
+
{ :name=>"China", :capital=>"Beijing", :area=>9596961, :population=>1403500365, :vehicleRegistrationCode=>"CHN", :iso3166code=>"CN", :callingCode=>86 },
|
172
|
+
{ :name=>"India", :capital=>"New Dehli", :area=>3287469, :population=>1339180000, :vehicleRegistrationCode=>"IND", :iso3166code=>"IN", :callingCode=>91 },
|
173
|
+
{ :name=>"Austria", :capital=>"Vienna", :area=>83878, :population=>8822267, :vehicleRegistrationCode=>"A", :iso3166code=>"AT", :callingCode=>43 },
|
174
|
+
{ :name=>"Denmark", :capital=>"Copenhagen", :area=>42921, :population=>5748769, :vehicleRegistrationCode=>"DK", :iso3166code=>"DK", :callingCode=>45 },
|
175
|
+
{ :name=>"Canada", :capital=>"Ottawa", :area=>9984670, :population=>36503097, :vehicleRegistrationCode=>"CDN", :iso3166code=>"CA", :callingCode=>1 },
|
176
|
+
{ :name=>"France", :capital=>"Paris", :area=>643801, :population=>66991000, :vehicleRegistrationCode=>"F", :iso3166code=>"FR", :callingCode=>33 },
|
177
|
+
{ :name=>"Russia", :capital=>"Moscow", :area=>17075400, :population=>144526636, :vehicleRegistrationCode=>"RUS", :iso3166code=>"RU", :callingCode=>7 }
|
178
|
+
]
|
179
|
+
~~~
|
180
|
+
|
181
|
+
Futher Information
|
182
|
+
==================
|
183
|
+
|
184
|
+
You will find futher information here [https://urasepandia.de/gds.html](https://urasepandia.de/gds.html)
|
185
|
+
|
186
|
+
Maintainer
|
187
|
+
==========
|
188
|
+
|
189
|
+
Uli Ramminger <uli@urasepandia.de>
|
190
|
+
|
191
|
+
Copyright
|
192
|
+
=========
|
193
|
+
|
194
|
+
Copyright (c) 2018 Ulrich Ramminger
|
195
|
+
|
196
|
+
See MIT-LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
|
3
|
+
module LDLgeneratedLanguage
|
4
|
+
|
5
|
+
class Gds
|
6
|
+
require 'treetop'
|
7
|
+
|
8
|
+
class SyntaxError < ::StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parse( s )
|
12
|
+
@parserClass ||= begin
|
13
|
+
Treetop.load_from_string GrammarDef
|
14
|
+
instance_eval( 'Gds_007Parser' )
|
15
|
+
end
|
16
|
+
parser = @parserClass.new
|
17
|
+
|
18
|
+
parseTree = parser.parse( s )
|
19
|
+
|
20
|
+
unless parseTree
|
21
|
+
lineOfFailure = parser.failure_line # parser.failure_index == 0 ? 1 : parser.input[0..parser.failure_index].lines.size
|
22
|
+
columnOfFailure = parser.failure_column
|
23
|
+
|
24
|
+
puts "GDS: Error happend, while parsing the definition: line #{lineOfFailure}, column #{columnOfFailure}"
|
25
|
+
puts parser.failure_reason if parser.failure_reason
|
26
|
+
puts "--->"
|
27
|
+
|
28
|
+
puts parser.input.lines[((lineOfFailure-1-5)>0 ? (lineOfFailure-1-5) : 0)..(lineOfFailure-1)]
|
29
|
+
puts ' '*((parser.failure_column) -1) + '^'
|
30
|
+
puts "<---"
|
31
|
+
|
32
|
+
$stdout.flush
|
33
|
+
|
34
|
+
raise SyntaxError
|
35
|
+
end
|
36
|
+
|
37
|
+
parseTree.ast
|
38
|
+
end
|
39
|
+
|
40
|
+
GrammarDef = "grammar Gds_007\n\n rule top\n &{ |s| @indentationLevels = []; true }\n defs ''\n {\n def ast\n eval 'class ::LDLgeneratedLanguage::Gds_007_data; def self.globalvars; @@globalvars ||= {}; end; end'\n ::LDLgeneratedLanguage::Gds_007_data.globalvars.clear\n defs.ast\n end\n }\n end\n\n rule defs\n wscommnl* schemadefs ws defs2 \n {\n def ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schemata] = schemadefs.ast\n defs2.ast\n end\n }\n /\n wscommnl* defs2\n {\n def ast\n defs2.ast\n end\n }\n end\n\n rule schemadefs\n schemadef+ \n {\n def ast\n r = []\n elements.each do |e|\n r << e.ast\n end\n r\n end\n }\n end\n\n rule schemadef\n '$' schemaname ws '(' ws schema_fieldlist ws ')' wscommnl2 \n {\n def ast\n r = {}\n r.merge!( Hash[ :name, schemaname.ast ] )\n r.merge!( Hash[ :fields, schema_fieldlist.ast ] )\n r\n end\n }\n end\n\n rule schemaname\n identifier '' \n {\n def ast\n identifier.ast\n end\n }\n end\n\n rule schema_fieldlist\n schemafield ws ',' ws schema_fieldlist \n {\n def ast\n r = []\n r << schemafield.ast\n r.concat( schema_fieldlist.ast )\n r\n end\n }\n /\n schemafield '' \n {\n def ast\n r = []\n r << schemafield.ast\n r\n end\n }\n end\n\n rule schemafield\n identifier '' \n {\n def ast\n identifier.ast\n end\n }\n end\n\n rule defs2\n wscommnl2 ruby_standard_def wscommnl2\n {\n def ast\n ruby_standard_def.ast\n end\n }\n /\n wscommnl* special_indented_def\n {\n def ast\n special_indented_def.ast\n end\n }\n end\n\n rule ruby_standard_def\n hashdef ''\n {\n def ast\n hashdef.ast\n end\n }\n /\n arraydef ''\n {\n def ast\n arraydef.ast\n end\n }\n end\n\n rule special_indented_def\n hashdef_ind ''\n {\n def ast\n hashdef_ind.ast\n end\n }\n /\n arraydef_ind ''\n {\n def ast\n arraydef_ind.ast\n end\n }\n end\n\n rule hashdef\n '{' ws hashsubdefs ws '}' \n {\n def ast\n hashsubdefs.ast\n end\n }\n end\n\n rule arraydef\n '[' ws arraysubdefs ws ']' \n {\n def ast\n arraysubdefs.ast\n end\n }\n end\n\n rule hashsubdefs\n hashsubdef ws morehashsubdefs \n {\n def ast\n r = {}\n r.merge!( hashsubdef.ast )\n r.merge!( morehashsubdefs.ast )\n r\n end\n }\n /\n ''\n {\n def ast\n {}\n end\n }\n end\n\n rule morehashsubdefs\n morehashsubdef*\n {\n def ast\n r = {}\n elements.each { |e| r.merge!( e.ast ) }\n r\n end\n }\n end\n\n rule morehashsubdef\n ',' ws hashsubdef\n {\n def ast\n hashsubdef.ast\n end\n }\n end\n\n rule hashsubdef\n keyvaluedef ''\n {\n def ast\n keyvaluedef.ast\n end\n }\n /\n keydef ':' ws hashdef \n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, hashdef.ast ] )\n r\n end\n }\n /\n keydef ':' ws arraydef \n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, arraydef.ast ] )\n r\n end\n }\n end\n\n rule arraysubdefs\n arraysubdef ws morearraysubdefs \n {\n def ast\n r = []\n r << arraysubdef.ast\n r.concat( morearraysubdefs.ast )\n r\n end\n }\n /\n '' \n {\n def ast\n r = []\n r\n end\n }\n end\n\n rule morearraysubdefs\n morearraysubdef* \n {\n def ast\n r = []\n elements.each do |e|\n r << e.ast\n end\n r\n end\n }\n end\n\n rule morearraysubdef\n ',' ws arraysubdef\n {\n def ast\n arraysubdef.ast\n end\n }\n end\n\n rule arraysubdef\n valuedef ''\n {\n def ast\n valuedef.ast\n end\n }\n /\n arraydef ''\n {\n def ast\n arraydef.ast\n end\n }\n /\n hashdef ''\n {\n def ast\n hashdef.ast\n end\n }\n end\n\n rule hashdef_ind\n indentation ':' ws keyvaluedefs_ind \n &{ |s| level = s[0].text_value.length; @indentationLevels << level; true }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( keyvaluedefs_ind.ast )\n r.merge!( hashsubdefs_ind.ast )\n r\n end\n }\n /\n indentation ':' \n &{ |s| level = s[0].text_value.length; @indentationLevels << level; true }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n hashsubdefs_ind.ast\n end\n }\n end\n\n rule arraydef_ind\n indentation ',' ws '$' schemaname \n &{ |s| level = s[0].text_value.length; @indentationLevels << level; true }\n wscommnl+ arraysubdefs_schema_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] ||= []\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] << schemaname.ast\n res = arraysubdefs_schema_ind.ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema].pop\n res\n end\n }\n /\n indentation ',' ws valuedefs_ind \n &{ |s| level = s[0].text_value.length; @indentationLevels << level; true }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = []\n r.concat( valuedefs_ind.ast )\n r.concat( arraysubdefs_ind.ast )\n r\n end\n }\n /\n indentation ',' \n &{ |s| level = s[0].text_value.length; @indentationLevels << level; true }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n arraysubdefs_ind.ast\n end\n }\n end\n\n rule hashsubdefs_ind\n ( \n &{ |s| save = index; i = _nt_indentation; level = i.text_value.length; index = save; ok = (level == (2 + @indentationLevels.last)); ok }\n hashsubdef_ind '' \n )*\n {\n def ast\n r = {}\n elements.each { |e| r.merge!( e.hashsubdef_ind.ast ) }\n r\n end\n }\n end\n\n rule hashsubdef_ind\n indentation bc_0_l:(bc_0*) ws keyvaluedefs_ind \n &{ |s| level = s[0].text_value.length; (@indentationLevels.last + 2 == level) }\n wscommnl*\n {\n def ast\n keyvaluedefs_ind.ast\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws keydef ws ',' ws '$' schemaname \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_schema_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] ||= []\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] << schemaname.ast\n r = {}\n r.merge!( Hash[ keydef.ast, arraysubdefs_schema_ind.ast ] )\n res = r\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema].pop\n res\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws keydef ws ',' ws valuedefs_ind \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, begin [].concat( valuedefs_ind.ast ).concat( arraysubdefs_ind.ast ) end ] )\n r\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws keydef ws ',' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, arraysubdefs_ind.ast ] )\n r\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws keydef \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, hashsubdefs_ind.ast ] )\n r\n end\n }\n end\n\n rule arraysubdefs_ind\n ( \n &{ |s| save = index; i = _nt_indentation; level = i.text_value.length; index = save; ok = (level == (2 + @indentationLevels.last)); ok }\n arraysubdef_ind '' \n )*\n {\n def ast\n r = []\n elements.each do |e|\n e1 = e.arraysubdef_ind.ast\n if e1.is_a?( Array )\n r.concat e1\n else\n r << e1\n end\n end\n r\n end\n }\n end\n\n rule arraysubdef_ind\n indentation ':' ws keyvaluedefs_ind \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( keyvaluedefs_ind.ast )\n r.merge!( hashsubdefs_ind.ast )\n r\n end\n }\n /\n indentation ':' ws keyvaluedefs_ind \n &{ |s| level = s[0].text_value.length; (@indentationLevels.last + 2 == level) }\n wscommnl*\n {\n def ast\n keyvaluedefs_ind.ast\n end\n }\n /\n indentation ':' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n hashsubdefs_ind.ast\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws keydef ws ':' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, hashsubdefs_ind.ast ] )\n r\n end\n }\n /\n indentation ',' ws '$' schemaname \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_schema_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] ||= []\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema] << schemaname.ast\n res = arraysubdefs_schema_ind.ast\n ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema].pop\n [ res ]\n end\n }\n /\n indentation ',' ws valuedefs_ind \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = []\n r.concat( valuedefs_ind.ast )\n r.concat( arraysubdefs_ind.ast )\n [\n r\n ]\n end\n }\n /\n indentation ',' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n [\n arraysubdefs_ind.ast\n ]\n end\n }\n /\n indentation bc_0_l:(bc_0*) ws valuedefs_ind \n &{ |s| level = s[0].text_value.length; (@indentationLevels.last + 2 == level) }\n wscommnl*\n {\n def ast\n valuedefs_ind.ast\n end\n }\n end\n\n rule arraysubdefs_schema_ind\n ( \n &{ |s| save = index; i = _nt_indentation; level = i.text_value.length; index = save; ok = (level == (2 + @indentationLevels.last)); ok }\n arraysubdef_schema_ind '' \n )*\n {\n def ast\n r = []\n elements.each do |e|\n r << e.arraysubdef_schema_ind.ast\n end\n r\n end\n }\n end\n\n rule arraysubdef_schema_ind\n indentation ':' ws schemavaluedefs_ind \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n schemavaluedefs_ind.ast .each_with_index.map do |e,i|\n Hash[ ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schemata].find{|s| s[:name] == ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema].last }[:fields][i], e ]\n end.inject({}){ |res,e1| res.merge!(e1);res }.merge!( hashsubdefs_ind.ast )\n \n end\n }\n /\n indentation ':' ws schemavaluedefs_ind \n &{ |s| level = s[0].text_value.length; (@indentationLevels.last + 2 == level) }\n wscommnl*\n {\n def ast\n schemavaluedefs_ind.ast .each_with_index.map do |e,i|\n Hash[ ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schemata].find{|s| s[:name] == ::LDLgeneratedLanguage::Gds_007_data.globalvars[:schema].last }[:fields][i], e ]\n end.inject({}){ |res,e1| res.merge!(e1);res }\n \n end\n }\n /\n indentation ':' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n hashsubdefs_ind.ast\n end\n }\n /\n indentation keydef ws ':' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ hashsubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, hashsubdefs_ind.ast ] )\n r\n end\n }\n /\n indentation ',' \n &{ |s| level = s[0].text_value.length; ok = (@indentationLevels.last + 2 == level); if(ok); @indentationLevels << level; end; ok }\n wscommnl+ arraysubdefs_ind \n &{ |s| @indentationLevels.pop; true }\n wscommnl*\n {\n def ast\n arraysubdefs_ind.ast\n end\n }\n /\n indentation valuedef_ind \n &{ |s| level = s[0].text_value.length; (@indentationLevels.last + 2 == level) }\n wscommnl*\n {\n def ast\n valuedef_ind.ast\n end\n }\n end\n\n rule schemavaluedefs_ind\n schemavaluedef_ind ws '|' ws schemavaluedefs_ind \n {\n def ast\n r = []\n r << schemavaluedef_ind.ast\n r.concat( schemavaluedefs_ind.ast )\n r\n end\n }\n /\n schemavaluedef_ind '' \n {\n def ast\n r = []\n r << schemavaluedef_ind.ast\n r\n end\n }\n end\n\n rule schemavaluedef_ind\n valuedef_ind '' \n {\n def ast\n valuedef_ind.ast\n end\n }\n end\n\n rule keyvaluedefs_ind\n keyvaluedef_ind ws '|' ws keyvaluedefs_ind \n {\n def ast\n r = {}\n r.merge!( keyvaluedef_ind.ast )\n r.merge!( keyvaluedefs_ind.ast )\n r\n end\n }\n /\n keyvaluedef_ind ''\n {\n def ast\n keyvaluedef_ind.ast\n end\n }\n end\n\n rule keyvaluedef_ind\n keydef ws valuedef_ind \n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, valuedef_ind.ast ] )\n r\n end\n }\n end\n\n rule valuedef_ind\n valuedef_gen ''\n {\n def ast\n valuedef_gen.ast\n end\n }\n /\n special_value_ind ''\n {\n def ast\n special_value_ind.ast\n end\n }\n /\n string_no_leading_space ''\n {\n def ast\n string_no_leading_space.ast\n end\n }\n end\n\n rule keyvaluedef\n keydef ':' ws valuedef \n {\n def ast\n r = {}\n r.merge!( Hash[ keydef.ast, valuedef.ast ] )\n r\n end\n }\n end\n\n rule valuedefs_ind\n valuedef_ind ws '|' ws valuedefs_ind \n {\n def ast\n r = []\n r << valuedef_ind.ast\n r.concat( valuedefs_ind.ast )\n r\n end\n }\n /\n valuedef_ind '' \n {\n def ast\n r = []\n r << valuedef_ind.ast\n r\n end\n }\n end\n\n rule valuedef\n valuedef_gen ''\n {\n def ast\n valuedef_gen.ast\n end\n }\n /\n special_value ''\n {\n def ast\n special_value.ast\n end\n }\n end\n\n rule valuedef_gen\n number_float ''\n {\n def ast\n number_float.ast\n end\n }\n /\n number_int ''\n {\n def ast\n number_int.ast\n end\n }\n /\n rubysymbol ''\n {\n def ast\n rubysymbol.ast\n end\n }\n /\n string_with_quotes ''\n {\n def ast\n string_with_quotes.ast\n end\n }\n end\n\n rule special_value\n 'nil' \n {\n def ast\n nil\n end\n }\n /\n 'true' \n {\n def ast\n true\n end\n }\n /\n 'false' \n {\n def ast\n false\n end\n }\n end\n\n rule special_value_ind\n '!nil' \n {\n def ast\n nil\n end\n }\n /\n '!true' \n {\n def ast\n true\n end\n }\n /\n '!false' \n {\n def ast\n false\n end\n }\n end\n\n rule string_with_quotes\n string_with_doublequotes ''\n {\n def ast\n string_with_doublequotes.ast\n end\n }\n /\n string_with_singlequotes ''\n {\n def ast\n string_with_singlequotes.ast\n end\n }\n end\n\n rule string_with_doublequotes\n '\"' ws string_double_q ws '\"'\n {\n def ast\n string_double_q.ast\n end\n }\n end\n\n rule string_double_q\n ('\\\"' / !'\"' .)*\n {\n def ast\n text_value\n end\n }\n end\n\n rule string_with_singlequotes\n '\\'' ws string_single_q ws '\\''\n {\n def ast\n string_single_q.ast\n end\n }\n end\n\n rule string_single_q\n ('\\\\\\'' / !'\\'' .)*\n {\n def ast\n text_value\n end\n }\n end\n\n rule string_no_leading_space\n !' ' !',' !\"|\" !'#' !'/*' (!\"\\n\" !\"|\" !'#' !'/*' .)+ \n {\n def ast\n text_value.rstrip\n end\n }\n end\n\n rule keydef\n identifier ''\n {\n def ast\n identifier.ast\n end\n }\n end\n\n rule number_int\n octal_int ''\n {\n def ast\n octal_int.ast\n end\n }\n /\n binary_int ''\n {\n def ast\n binary_int.ast\n end\n }\n /\n hexa_int ''\n {\n def ast\n hexa_int.ast\n end\n }\n /\n decimal_int ''\n {\n def ast\n decimal_int.ast\n end\n }\n end\n\n rule octal_int\n ('-'/'+')? ( '0o' / '0' ) [0-7] ( [0-7] / '_' [0-7] )* \n {\n def ast\n text_value.to_i(8)\n end\n }\n end\n\n rule binary_int\n ('-'/'+')? '0b' [01] ( [01] / '_' [01] )* \n {\n def ast\n text_value.to_i(2)\n end\n }\n end\n\n rule hexa_int\n ('-'/'+')? '0x' [0-9a-fA-F] ( [0-9a-fA-F] / '_' [0-9a-fA-F] )* \n {\n def ast\n text_value.to_i(16)\n end\n }\n end\n\n rule decimal_int\n ('-'/'+')? ('0d')? [1-9] ( [0-9] / '_' [0-9] )* \n {\n def ast\n text_value.to_i\n end\n }\n end\n\n rule number_float\n [+-]? ( [0-9] / '_' [0-9] )* [.] [0-9] ( [0-9] / '_' [0-9] )* (('e'/'E') [+-]? [0-9] ( [0-9] / '_' [0-9] )* )? \n {\n def ast\n text_value.to_f\n end\n }\n end\n\n rule rubysymbol\n ':' rubysymbolcontent \n {\n def ast\n rubysymbolcontent.ast\n end\n }\n end\n\n rule rubysymbolcontent\n [a-zA-Z0-9_@\"'?/+*\\-]* \n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule bc_0\n &{ |s| @bc_0Level = 0; true }\n '/*' bc_0_sub '*/'\n {\n def ast\n \"/*\" + bc_0_sub.ast + \"*/\"\n end\n }\n end\n\n rule bc_0_sub\n '/*' \n &{ |s| @bc_0Level += 1; true }\n bc_0_sub\n {\n def ast\n '/*' + bc_0_sub.ast\n end\n }\n /\n '*/' \n &{ |s| ok = (@bc_0Level > 0); ok } \n &{ |s| @bc_0Level -= 1; true }\n bc_0_sub\n {\n def ast\n '*/' + bc_0_sub.ast\n end\n }\n /\n ( !\"/*\" !\"*/\" . )+ bc_0_sub\n {\n def ast\n text_value\n end\n }\n /\n ''\n {\n def ast\n ''\n end\n }\n end\n\n rule bc_0_onechar\n ( !\"*/\" . )\n {\n def ast\n text_value\n end\n }\n end\n\n rule wsc\n [ \\t] \n {\n }\n /\n bc_0 '' \n {\n }\n end\n\n rule identifier\n ([a-zA-Z_] [a-zA-Z0-9_]*)\n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule string_no_space\n [a-zA-Z0-9_/.:]+\n {\n def ast\n text_value\n end\n }\n end\n\n rule indentation\n ' '*\n end\n\n rule ws\n wsc*\n end\n\n rule icomm\n '#' \n end\n\n rule wscommnl\n ws ( icomm ( !\"\\n\" . )* )? \"\\n\"\n end\n\n rule wscommnl2\n ( icomm ( !\"\\n\" . )* \"\\n\" / \"\\n\" / wsc )*\n end\n\nend\n"
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#===============================================================================
|
46
|
+
|
data/lib/gdstruct.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
# file name : gdstruct.rb
|
3
|
+
#===============================================================================
|
4
|
+
=begin - Description
|
5
|
+
--------------------------------------------------------------------------------
|
6
|
+
|
7
|
+
--------------------------------------------------------------------------------
|
8
|
+
=end
|
9
|
+
#===============================================================================
|
10
|
+
|
11
|
+
require 'gdstruct/gds_007'
|
12
|
+
|
13
|
+
#===============================================================================
|
14
|
+
|
15
|
+
class GDstruct
|
16
|
+
class << self
|
17
|
+
def create( def_string )
|
18
|
+
LDLgeneratedLanguage::Gds.parse( def_string )
|
19
|
+
end
|
20
|
+
alias :c :create
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#===============================================================================
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gdstruct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Uli Ramminger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: treetop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.6.9
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.6.9
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '12'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '12'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: minitest
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.1'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '5.1'
|
61
|
+
description: "gdstruct - GDS (General Data Structure), a universal, composable data
|
62
|
+
structure, used to store any kind of data. \nTypical usage is the definition of
|
63
|
+
configurations, specifications and data sets. \nThe GDS language is a special DSL
|
64
|
+
(domain specific language) for defining general data structures. \nIt uses a succinct,
|
65
|
+
indentation-sensitive syntax which makes data representation clear and readable.
|
66
|
+
\n"
|
67
|
+
email: uli@urasepandia.de
|
68
|
+
executables: []
|
69
|
+
extensions: []
|
70
|
+
extra_rdoc_files: []
|
71
|
+
files:
|
72
|
+
- CHANGELOG
|
73
|
+
- MIT-LICENSE
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- lib/gdstruct.rb
|
77
|
+
- lib/gdstruct/gds_007.rb
|
78
|
+
- lib/gdstruct/version.rb
|
79
|
+
homepage: https://urasepandia.de/gds.html
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.6.13
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: gdstruct - GDS (General Data Structure), a universal, composable data structure,
|
103
|
+
used to store any kind of data
|
104
|
+
test_files: []
|