gds-data-validation 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/CHANGELOG.md +5 -0
- data/MIT-LICENSE +18 -0
- data/README.md +85 -0
- data/Rakefile +15 -0
- data/lib/gds-data-validation.rb +45 -0
- data/lib/gds-data-validation/lng_gds_check.rb +40 -0
- data/lib/gds-data-validation/validation_generator.rb +1420 -0
- data/lib/gds-data-validation/version.rb +5 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0f56c000f3ef005f609da4a062006914e0e851ba
|
4
|
+
data.tar.gz: e3fe4d0e6c382a06f3a859bd7b3d00d49e08285e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1ec8377a3978dd16fedc947ea370c7402a182338c3e0d997063ee071935b150727f058377280eb0cb95cc4e770f82bb5f4686023217b102af3bf3a110a2743c3
|
7
|
+
data.tar.gz: 20d7ffb1c4087fba7306f0c1ca2491ef7a7d975e9fca7c78b6b2dae97e28bb50bbf2078389e65afd2fc4a568ec0122a514b58338582e4f54f63b65a0dcb10a3d
|
data/CHANGELOG.md
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2019 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,85 @@
|
|
1
|
+
gds-data-validation
|
2
|
+
===================
|
3
|
+
|
4
|
+
A data validation library providing a rule-based schema definition language.
|
5
|
+
For checking (incoming) data against a specified schema definition.
|
6
|
+
GDS stands for General Data Structure.
|
7
|
+
|
8
|
+
Installation
|
9
|
+
============
|
10
|
+
|
11
|
+
~~~
|
12
|
+
gem install gds-data-validation
|
13
|
+
~~~
|
14
|
+
|
15
|
+
An Example
|
16
|
+
==========
|
17
|
+
|
18
|
+
~~~ruby
|
19
|
+
require "gds-data-validation"
|
20
|
+
|
21
|
+
dataValidation = GdsDataValidation.create( <<-EOS )
|
22
|
+
company = :name : @t_string,
|
23
|
+
:address : address,
|
24
|
+
:ceo : person,
|
25
|
+
:employees : person*
|
26
|
+
person = :firstname : @t_string,
|
27
|
+
:lastname : @t_string,
|
28
|
+
:yearOfBirth : @t_int,
|
29
|
+
:address : address
|
30
|
+
address = :street : @t_string,
|
31
|
+
:zipcode : @t_int,
|
32
|
+
:city : @t_string
|
33
|
+
EOS
|
34
|
+
|
35
|
+
dataValidation.check( nil ) # => false
|
36
|
+
dataValidation.check(
|
37
|
+
{ name: 'My Company', address: { street: 'Broadway 300', zipcode: 22222, city: 'New York' },
|
38
|
+
ceo: { firstname: 'John', lastname: 'McArthur', yearOfBirth: 1959,
|
39
|
+
address: { street: 'Rosedale Dr. 40', zipcode: 34003, city: 'Los Angeles' } },
|
40
|
+
employees: [
|
41
|
+
{ firstname: 'Berry', lastname: 'Miller', yearOfBirth: 1989,
|
42
|
+
address: { street: 'South St. 12', zipcode: 48333, city: 'Chicago' } },
|
43
|
+
{ firstname: 'Jane', lastname: 'Smith', yearOfBirth: 1993,
|
44
|
+
address: { street: 'Mainstreet 4', zipcode: 62883, city: 'Seattle' } } ] }
|
45
|
+
) # => true
|
46
|
+
~~~
|
47
|
+
|
48
|
+
Introduction
|
49
|
+
============
|
50
|
+
|
51
|
+
The original idea was to create a library for the validation of data structures which have been created
|
52
|
+
by the [GDS (General Data Structure)](https://urasepandia.de/gds.html) language.
|
53
|
+
|
54
|
+
Synonyms and related terms are data validation, validation checker, schema validation, schema validator, schema checker.
|
55
|
+
|
56
|
+
Ruby Gem
|
57
|
+
========
|
58
|
+
|
59
|
+
You can find it on RubyGems.org:
|
60
|
+
|
61
|
+
[rubygems.org/gems/gds-data-validation](https://rubygems.org/gems/gds-data-validation)
|
62
|
+
|
63
|
+
Source Code
|
64
|
+
===========
|
65
|
+
|
66
|
+
You can find the source code on GitHub:
|
67
|
+
|
68
|
+
[github.com/uliramminger/gds-data-validation](https://github.com/uliramminger/gds-data-validation)
|
69
|
+
|
70
|
+
Further Information
|
71
|
+
===================
|
72
|
+
|
73
|
+
You will find detailed information here: [urasepandia.de/gds-data-validation.html](https://urasepandia.de/gds-data-validation.html)
|
74
|
+
|
75
|
+
Maintainer
|
76
|
+
==========
|
77
|
+
|
78
|
+
Uli Ramminger <uli@urasepandia.de>
|
79
|
+
|
80
|
+
Copyright
|
81
|
+
=========
|
82
|
+
|
83
|
+
Copyright (c) 2019 Ulrich Ramminger
|
84
|
+
|
85
|
+
See MIT-LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
Rake::TestTask.new do |t|
|
4
|
+
t.libs = [ 'test' ]
|
5
|
+
t.test_files = FileList['test/test*.rb']
|
6
|
+
t.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Gem build"
|
10
|
+
task :gembuild do
|
11
|
+
puts `gem build gds-data-validation.gemspec`
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run tests"
|
15
|
+
task :default => :test
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# gds-data-validation.rb
|
2
|
+
|
3
|
+
# You will find further information here: https://urasepandia.de/gds-data-validation.html
|
4
|
+
|
5
|
+
require_relative 'gds-data-validation/version.rb'
|
6
|
+
require_relative 'gds-data-validation/lng_gds_check.rb'
|
7
|
+
require_relative 'gds-data-validation/validation_generator.rb'
|
8
|
+
|
9
|
+
class GdsDataValidation
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
# create an data validation class which is checking incoming data against a specified schema definition
|
14
|
+
#
|
15
|
+
# @param schema_definition [String] the schema definition to be used for data validation
|
16
|
+
#
|
17
|
+
# @return [Class] anonymous class for data validation
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# require 'gds-data-validaion'
|
21
|
+
#
|
22
|
+
# dataValidation = GdsDataValidation.create( <<-EOS )
|
23
|
+
# schema = @t_int
|
24
|
+
# EOS
|
25
|
+
#
|
26
|
+
# dataValidation.check( 10 ) # => true
|
27
|
+
# dataValidation.check( "a" ) # => false
|
28
|
+
def create( schema_definition )
|
29
|
+
vcg = ValidationCheckerGenerator.new
|
30
|
+
vcg.generate( LDLgeneratedLanguage::Language_gds_check.parse( schema_definition ) )
|
31
|
+
end
|
32
|
+
|
33
|
+
# create an data validation class which is checking incoming data against a specified schema definition stored in a file
|
34
|
+
#
|
35
|
+
# @param file_name [String] file name, this file contains the schema definition
|
36
|
+
#
|
37
|
+
# @return [Class] anonymous class for data validation
|
38
|
+
def create_from_file( file_name )
|
39
|
+
vcg = ValidationCheckerGenerator.new
|
40
|
+
vcg.generate( LDLgeneratedLanguage::Language_gds_check.parse( File.read( file_name ) ) )
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# lng_gds_check.rb
|
2
|
+
|
3
|
+
module LDLgeneratedLanguage
|
4
|
+
|
5
|
+
class Language_gds_check
|
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( 'Language_gds_check_05Parser' )
|
15
|
+
end
|
16
|
+
parser = @parserClass.new
|
17
|
+
|
18
|
+
parseTree = parser.parse( s + "\n" )
|
19
|
+
|
20
|
+
unless parseTree
|
21
|
+
lineOfFailure = parser.failure_line
|
22
|
+
columnOfFailure = parser.failure_column
|
23
|
+
|
24
|
+
s = "LANGUAGE_GDS_CHECK: Error happend, while parsing the definition: line #{lineOfFailure}, column #{columnOfFailure}" + "\n"
|
25
|
+
s += parser.failure_reason + "\n" if parser.failure_reason
|
26
|
+
s += "--->" + "\n"
|
27
|
+
s += parser.input.lines[((lineOfFailure-1-5)>0 ? (lineOfFailure-1-5) : 0)..(lineOfFailure-1)].join.chomp + "\n"
|
28
|
+
s += ' '*((parser.failure_column) -1) + '^' + "\n"
|
29
|
+
s += "<---" + "\n"
|
30
|
+
|
31
|
+
raise SyntaxError, s
|
32
|
+
end
|
33
|
+
|
34
|
+
parseTree.ast
|
35
|
+
end
|
36
|
+
|
37
|
+
GrammarDef = "grammar Language_gds_check_05\n\n rule top\n defs ''\n {\n def ast\n defs.ast\n end\n }\n end\n\n rule defs\n wscommnl2 productionrule_l:(productionrule*) wscommnl2\n {\n def ast\n r = []\n productionrule_l.elements.each do |e|\n r << e.ast\n end\n r\n end\n }\n end\n\n rule productionrule\n rulename wscommnl2 '=' wscommnl2 ruledefinition \n {\n def ast\n r = {}\n r.merge!( Hash[ :name, rulename.ast ] )\n r.merge!( Hash[ :ruledefinition, ruledefinition.ast ] )\n r\n end\n }\n end\n\n rule rulename\n identifier ''\n {\n def ast\n identifier.ast\n end\n }\n end\n\n rule ruledefinition\n alternatives ''\n {\n def ast\n alternatives.ast\n end\n }\n end\n\n rule alternatives\n alternative_mb wscommnl2 '/' wscommnl2 alternatives \n {\n def ast\n r = []\n r << alternative_mb.ast\n r2 = alternatives.ast\n if r2.is_a?(Array); r.concat( r2 ); else r << r2; end\n r\n end\n }\n /\n alternative_mb '' \n {\n def ast\n r = []\n r << alternative_mb.ast\n r\n end\n }\n end\n\n rule alternative_mb\n mb:maybe? wscommnl2 alternative \n {\n def ast\n r = {}\n r.merge!( alternative.ast )\n r.merge!( Hash[ :maybe, mb.ast ] ) unless mb.empty?\n r\n end\n }\n end\n\n rule alternative\n hashdef wscommnl2 \n {\n def ast\n hashdef.ast\n end\n }\n /\n structuraldef wscommnl2 \n {\n def ast\n structuraldef.ast\n end\n }\n end\n\n rule hashdef\n sk:strictkeys? wscommnl2 keyvaluedefs \n {\n def ast\n r = {}\n r.merge!( Hash[ :hashdef, keyvaluedefs.ast ] )\n r.merge!( Hash[ :strict, sk.ast ] ) unless sk.empty?\n r\n end\n }\n end\n\n rule arraydef\n rulename sizespec \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :rulename, rulename.ast ] )\n r1.merge!( Hash[ :sizespec, sizespec.ast ] )\n r.merge!( Hash[ :arraydef, r1 ] )\n r\n end\n }\n end\n\n rule subruledef\n rulename '' \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :rulename, rulename.ast ] )\n r.merge!( Hash[ :subruledef, r1 ] )\n r\n end\n }\n end\n\n rule strictkeys\n '@strict' \n {\n def ast\n :strict\n end\n }\n end\n\n rule keyvaluedefs\n keyvaluedef wscommnl2 ',' wscommnl2 keyvaluedefs \n {\n def ast\n r = []\n r << keyvaluedef.ast\n r2 = keyvaluedefs.ast\n if r2.is_a?(Array); r.concat( r2 ); else r << r2; end\n r\n end\n }\n /\n keyvaluedef '' \n {\n def ast\n r = []\n r << keyvaluedef.ast\n r\n end\n }\n end\n\n rule keyvaluedef\n keydef wscommnl2 ':?' wscommnl2 structuraldef_mb \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :key, keydef.ast ] )\n r1.merge!( Hash[ :value, structuraldef_mb.ast ] )\n r1.merge!( Hash[ :optional, :optional ] )\n r.merge!( Hash[ :keyvaluedef, r1 ] )\n r\n end\n }\n /\n keydef wscommnl2 ':' wscommnl2 structuraldef_mb \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :key, keydef.ast ] )\n r1.merge!( Hash[ :value, structuraldef_mb.ast ] )\n r.merge!( Hash[ :keyvaluedef, r1 ] )\n r\n end\n }\n end\n\n rule keydef\n wscommnl2 ':' identifier \n {\n def ast\n identifier.ast\n end\n }\n end\n\n rule structuraldef_mb\n mb:maybe? wscommnl2 structuraldef \n {\n def ast\n r = {}\n r.merge!( structuraldef.ast )\n r.merge!( Hash[ :maybe, mb.ast ] ) unless mb.empty?\n r\n end\n }\n end\n\n rule structuraldef\n no:notop? wscommnl2 '(' wscommnl2 typevaldef_disjunction wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valdefdisjunct, typevaldef_disjunction.ast ] )\n r.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r\n end\n }\n /\n typevaldef_disjunction '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valdefdisjunct, typevaldef_disjunction.ast ] )\n r\n end\n }\n /\n no:notop? wscommnl2 typedef \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( typedef.ast )\n r1.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( Hash[ :typedef, r1 ] )\n r\n end\n }\n /\n basicvaldef '' \n {\n def ast\n basicvaldef.ast\n end\n }\n /\n arraydef '' \n {\n def ast\n r = {}\n r.merge!( arraydef.ast )\n r\n end\n }\n /\n subruledef '' \n {\n def ast\n r = {}\n r.merge!( subruledef.ast )\n r\n end\n }\n end\n\n rule basicvaldef\n rubysymbol '' \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :type, :t_symbol ] )\n r1.merge!( Hash[ :value, rubysymbol.ast ] )\n r.merge!( Hash[ :basicvaluedef, r1 ] )\n r\n end\n }\n /\n string '' \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :type, :t_string ] )\n r1.merge!( Hash[ :value, string.ast ] )\n r.merge!( Hash[ :basicvaluedef, r1 ] )\n r\n end\n }\n /\n number_float '' \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :type, :t_float ] )\n r1.merge!( Hash[ :value, number_float.ast ] )\n r.merge!( Hash[ :basicvaluedef, r1 ] )\n r\n end\n }\n /\n number_int '' \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( Hash[ :type, :t_int ] )\n r1.merge!( Hash[ :value, number_int.ast ] )\n r.merge!( Hash[ :basicvaluedef, r1 ] )\n r\n end\n }\n /\n keyword_literal '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :basicvaluedef, keyword_literal.ast ] )\n r\n end\n }\n end\n\n rule typevaldef_disjunction\n tvclause wscommnl2 '|' wscommnl2 tvclauses \n {\n def ast\n r = []\n r << tvclause.ast\n r2 = tvclauses.ast\n if r2.is_a?(Array); r.concat( r2 ); else r << r2; end\n r\n end\n }\n end\n\n rule tvclauses\n tvclause wscommnl2 '|' wscommnl2 tvclauses \n {\n def ast\n r = []\n r << tvclause.ast\n r2 = tvclauses.ast\n if r2.is_a?(Array); r.concat( r2 ); else r << r2; end\n r\n end\n }\n /\n tvclause '' \n {\n def ast\n r = []\n r << tvclause.ast\n r\n end\n }\n end\n\n rule tvclause\n no:notop? wscommnl2 typedef \n {\n def ast\n r = {}\n r1 = {}\n r1.merge!( typedef.ast )\n r1.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( Hash[ :typedef, r1 ] )\n r\n end\n }\n /\n basicvaldef '' \n {\n def ast\n basicvaldef.ast\n end\n }\n end\n\n rule sizespec\n '+'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n '*'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n '(' wscommnl2 '..' wscommnl2 number_int wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :max, number_int.ast ] )\n r\n end\n }\n /\n '(' wscommnl2 a:number_int wscommnl2 '..' wscommnl2 b:number_int wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, a.ast ] )\n r.merge!( Hash[ :max, b.ast ] )\n r\n end\n }\n /\n '(' wscommnl2 number_int wscommnl2 '..' wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, number_int.ast ] )\n r\n end\n }\n /\n '(' wscommnl2 number_int wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, number_int.ast ] )\n r.merge!( Hash[ :max, number_int.ast ] )\n r\n end\n }\n end\n\n rule typedef\n typedef_string ''\n {\n def ast\n typedef_string.ast\n end\n }\n /\n typedef_int ''\n {\n def ast\n typedef_int.ast\n end\n }\n /\n typedef_float ''\n {\n def ast\n typedef_float.ast\n end\n }\n /\n '@t_numeric' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_numeric ] )\n r\n end\n }\n /\n '@t_nil' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_nil ] )\n r\n end\n }\n /\n '@t_bool' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_bool ] )\n r\n end\n }\n /\n '@t_true' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_true ] )\n r\n end\n }\n /\n '@t_false' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_false ] )\n r\n end\n }\n /\n typedef_symbol ''\n {\n def ast\n typedef_symbol.ast\n end\n }\n /\n '@t_any' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_any ] )\n r\n end\n }\n end\n\n rule typedef_int\n wscommnl2 '@t_int' wscommnl2 ivs:intvaluespecs? \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_int ] )\n r.merge!( Hash[ :valuespecs, ivs.ast ] ) unless ivs.empty?\n r\n end\n }\n end\n\n rule maybe\n '@maybe' \n {\n def ast\n :maybe\n end\n }\n end\n\n rule intvaluespecs\n intvaluespec_with_not* \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 intvaluespec_with_not\n no:notop? wscommnl2 intvaluespec wscommnl2 \n {\n def ast\n r = {}\n r.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( intvaluespec.ast )\n r\n end\n }\n end\n\n rule intvaluespec\n wscommnl2 '!=' wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :neql ] )\n r.merge!( Hash[ :val, number_int.ast ] )\n r\n end\n }\n /\n wscommnl2 '==' wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :eql ] )\n r.merge!( Hash[ :val, number_int.ast ] )\n r\n end\n }\n /\n intvaluespec_keywords '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, intvaluespec_keywords.ast ] )\n r\n end\n }\n /\n intminmaxspec ''\n {\n def ast\n intminmaxspec.ast\n end\n }\n /\n intvaluelist '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valuelist, intvaluelist.ast ] )\n r\n end\n }\n end\n\n rule intvaluespec_keywords\n 'odd'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n 'even'\n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule intvaluelist\n wscommnl2 '[' wscommnl2 intvalues_comma wscommnl2 ']'\n {\n def ast\n intvalues_comma.ast\n end\n }\n /\n wscommnl2 '%(' wscommnl2 intvalues_nocomma wscommnl2 ')'\n {\n def ast\n intvalues_nocomma.ast\n end\n }\n end\n\n rule intvalues_comma\n number_int wscommnl2 onemorenumint_comma_l:(onemorenumint_comma*) \n {\n def ast\n r = []\n r << number_int.ast\n r1 = []\n onemorenumint_comma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorenumint_comma\n wscommnl2 ',' wscommnl2 number_int\n {\n def ast\n number_int.ast\n end\n }\n end\n\n rule intvalues_nocomma\n number_int wscommnl2 onemorenumint_nocomma_l:(onemorenumint_nocomma*) \n {\n def ast\n r = []\n r << number_int.ast\n r1 = []\n onemorenumint_nocomma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorenumint_nocomma\n ws number_int\n {\n def ast\n number_int.ast\n end\n }\n end\n\n rule typedef_string\n wscommnl2 '@t_string' wscommnl2 svs:stringvaluespecs? \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_string ] )\n r.merge!( Hash[ :valuespecs, svs.ast ] ) unless svs.empty?\n r\n end\n }\n end\n\n rule stringvaluespecs\n stringvaluespec_with_not* \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 stringvaluespec_with_not\n no:notop? wscommnl2 stringvaluespec wscommnl2 \n {\n def ast\n r = {}\n r.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( stringvaluespec.ast )\n r\n end\n }\n end\n\n rule stringvaluespec\n wscommnl2 '!=' wscommnl2 string \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :neql ] )\n r.merge!( Hash[ :val, string.ast ] )\n r\n end\n }\n /\n wscommnl2 '==' wscommnl2 string \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :eql ] )\n r.merge!( Hash[ :val, string.ast ] )\n r\n end\n }\n /\n stringvaluespec_keywords '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, stringvaluespec_keywords.ast ] )\n r\n end\n }\n /\n lengthspec ''\n {\n def ast\n lengthspec.ast\n end\n }\n /\n stringvaluelist '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valuelist, stringvaluelist.ast ] )\n r\n end\n }\n /\n regexp '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :regexp ] )\n r.merge!( regexp.ast )\n r\n end\n }\n end\n\n rule stringvaluespec_keywords\n 'blank'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n 'empty'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n 'present'\n {\n def ast\n text_value.to_sym\n end\n }\n /\n 'something'\n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule stringvaluelist\n wscommnl2 '[' wscommnl2 stringvalues_comma wscommnl2 ']'\n {\n def ast\n stringvalues_comma.ast\n end\n }\n /\n wscommnl2 '%(' wscommnl2 stringvalues_nocomma wscommnl2 ')'\n {\n def ast\n stringvalues_nocomma.ast\n end\n }\n end\n\n rule stringvalues_comma\n string wscommnl2 onemorestring_comma_l:(onemorestring_comma*) \n {\n def ast\n r = []\n r << string.ast\n r1 = []\n onemorestring_comma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorestring_comma\n wscommnl2 ',' wscommnl2 string\n {\n def ast\n string.ast\n end\n }\n end\n\n rule stringvalues_nocomma\n stringnoblank wscommnl2 onemorestring_nocomma_l:(onemorestring_nocomma*) \n {\n def ast\n r = []\n r << stringnoblank.ast\n r1 = []\n onemorestring_nocomma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorestring_nocomma\n ws stringnoblank\n {\n def ast\n stringnoblank.ast\n end\n }\n end\n\n rule typedef_float\n wscommnl2 '@t_float' wscommnl2 vs:floatvaluespecs? \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_float ] )\n r.merge!( Hash[ :valuespecs, vs.ast ] ) unless vs.empty?\n r\n end\n }\n end\n\n rule floatvaluespecs\n floatvaluespec_with_not* \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 floatvaluespec_with_not\n no:notop? wscommnl2 floatvaluespec wscommnl2 \n {\n def ast\n r = {}\n r.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( floatvaluespec.ast )\n r\n end\n }\n end\n\n rule floatvaluespec\n wscommnl2 '!=' wscommnl2 number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :neql ] )\n r.merge!( Hash[ :val, number_float.ast ] )\n r\n end\n }\n /\n wscommnl2 '==' wscommnl2 number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :eql ] )\n r.merge!( Hash[ :val, number_float.ast ] )\n r\n end\n }\n /\n floatminmaxspec ''\n {\n def ast\n floatminmaxspec.ast\n end\n }\n /\n floatvaluelist '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valuelist, floatvaluelist.ast ] )\n r\n end\n }\n end\n\n rule floatminmaxspec\n min wscommnl2 a:number_float wscommnl2 max wscommnl2 b:number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, a.ast ] )\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, b.ast ] )\n r\n end\n }\n /\n max wscommnl2 a:number_float wscommnl2 min wscommnl2 b:number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, a.ast ] )\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, b.ast ] )\n r\n end\n }\n /\n min wscommnl2 number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, number_float.ast ] )\n r\n end\n }\n /\n max wscommnl2 number_float \n {\n def ast\n r = {}\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, number_float.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 a:number_float wscommnl2 '..' wscommnl2 b:number_float wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, a.ast ] )\n r.merge!( Hash[ :max, b.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 number_float wscommnl2 '..' wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, number_float.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 '..' wscommnl2 number_float wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :max, number_float.ast ] )\n r\n end\n }\n end\n\n rule floatvaluelist\n wscommnl2 '[' wscommnl2 floatvalues_comma wscommnl2 ']'\n {\n def ast\n floatvalues_comma.ast\n end\n }\n /\n wscommnl2 '%(' wscommnl2 floatvalues_nocomma wscommnl2 ')'\n {\n def ast\n floatvalues_nocomma.ast\n end\n }\n end\n\n rule floatvalues_comma\n number_float wscommnl2 onemorenumfloat_comma_l:(onemorenumfloat_comma*) \n {\n def ast\n r = []\n r << number_float.ast\n r1 = []\n onemorenumfloat_comma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorenumfloat_comma\n wscommnl2 ',' wscommnl2 number_float\n {\n def ast\n number_float.ast\n end\n }\n end\n\n rule floatvalues_nocomma\n number_float wscommnl2 onemorenumfloat_nocomma_l:(onemorenumfloat_nocomma*) \n {\n def ast\n r = []\n r << number_float.ast\n r1 = []\n onemorenumfloat_nocomma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemorenumfloat_nocomma\n ws number_float\n {\n def ast\n number_float.ast\n end\n }\n end\n\n rule typedef_symbol\n wscommnl2 '@t_symbol' wscommnl2 vs:symbolvaluespecs? \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_symbol ] )\n r.merge!( Hash[ :valuespecs, vs.ast ] ) unless vs.empty?\n r\n end\n }\n end\n\n rule symbolvaluespecs\n symbolvaluespec_with_not* \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 symbolvaluespec_with_not\n no:notop? wscommnl2 symbolvaluespec wscommnl2 \n {\n def ast\n r = {}\n r.merge!( Hash[ :notop, no.ast ] ) unless no.empty?\n r.merge!( symbolvaluespec.ast )\n r\n end\n }\n end\n\n rule symbolvaluespec\n wscommnl2 '!=' wscommnl2 rubysymbol \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :neql ] )\n r.merge!( Hash[ :val, rubysymbol.ast ] )\n r\n end\n }\n /\n wscommnl2 '==' wscommnl2 rubysymbol \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :eql ] )\n r.merge!( Hash[ :val, rubysymbol.ast ] )\n r\n end\n }\n /\n lengthspec ''\n {\n def ast\n lengthspec.ast\n end\n }\n /\n symbolvaluelist '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :valuelist, symbolvaluelist.ast ] )\n r\n end\n }\n /\n regexp '' \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :regexp ] )\n r.merge!( regexp.ast )\n r\n end\n }\n end\n\n rule symbolvaluelist\n wscommnl2 '[' wscommnl2 symbolvalues_comma wscommnl2 ']'\n {\n def ast\n symbolvalues_comma.ast\n end\n }\n /\n wscommnl2 '%(' wscommnl2 symbolvalues_nocomma wscommnl2 ')'\n {\n def ast\n symbolvalues_nocomma.ast\n end\n }\n end\n\n rule symbolvalues_comma\n rubysymbol wscommnl2 onemoresymbol_comma_l:(onemoresymbol_comma*) \n {\n def ast\n r = []\n r << rubysymbol.ast\n r1 = []\n onemoresymbol_comma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemoresymbol_comma\n wscommnl2 ',' wscommnl2 rubysymbol\n {\n def ast\n rubysymbol.ast\n end\n }\n end\n\n rule symbolvalues_nocomma\n rubysymbolcontent wscommnl2 onemoresymbol_nocomma_l:(onemoresymbol_nocomma*) \n {\n def ast\n r = []\n r << rubysymbolcontent.ast\n r1 = []\n onemoresymbol_nocomma_l.elements.each do |e|\n r1 << e.ast\n end\n r.concat( r1 )\n r\n end\n }\n end\n\n rule onemoresymbol_nocomma\n ws rubysymbolcontent\n {\n def ast\n rubysymbolcontent.ast\n end\n }\n end\n\n rule notop\n !'!=' '!' \n {\n def ast\n :notop\n end\n }\n end\n\n rule intminmaxspec\n min wscommnl2 a:number_int wscommnl2 max wscommnl2 b:number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, a.ast ] )\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, b.ast ] )\n r\n end\n }\n /\n max wscommnl2 a:number_int wscommnl2 min wscommnl2 b:number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, a.ast ] )\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, b.ast ] )\n r\n end\n }\n /\n min wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :minspec, min.ast ] )\n r.merge!( Hash[ :min, number_int.ast ] )\n r\n end\n }\n /\n max wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :maxspec, max.ast ] )\n r.merge!( Hash[ :max, number_int.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 a:number_int wscommnl2 '..' wscommnl2 b:number_int wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, a.ast ] )\n r.merge!( Hash[ :max, b.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 number_int wscommnl2 '..' wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :min, number_int.ast ] )\n r\n end\n }\n /\n wscommnl2 '(' wscommnl2 '..' wscommnl2 number_int wscommnl2 ')' \n {\n def ast\n r = {}\n r.merge!( Hash[ :max, number_int.ast ] )\n r\n end\n }\n end\n\n rule min\n '>=' \n {\n def ast\n :gte\n end\n }\n /\n '>' \n {\n def ast\n :gt\n end\n }\n end\n\n rule max\n '<=' \n {\n def ast\n :lte\n end\n }\n /\n '<' \n {\n def ast\n :lt\n end\n }\n end\n\n rule lengthspec\n wscommnl2 'length' wscommnl2 '==' wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :length ] )\n r.merge!( Hash[ :relop, :eql ] )\n r.merge!( Hash[ :val, number_int.ast ] )\n r\n end\n }\n /\n wscommnl2 'length' wscommnl2 '!=' wscommnl2 number_int \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :length ] )\n r.merge!( Hash[ :relop, :neql ] )\n r.merge!( Hash[ :val, number_int.ast ] )\n r\n end\n }\n /\n wscommnl2 'length' wscommnl2 intminmaxspec \n {\n def ast\n r = {}\n r.merge!( Hash[ :spec, :length ] )\n r.merge!( intminmaxspec.ast )\n r\n end\n }\n end\n\n rule keyword_literal\n 'true' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_true ] )\n r.merge!( Hash[ :value, :true ] )\n r\n end\n }\n /\n 'false' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_false ] )\n r.merge!( Hash[ :value, :false ] )\n r\n end\n }\n /\n 'nil' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_nil ] )\n r.merge!( Hash[ :value, :nil ] )\n r\n end\n }\n /\n 'null' \n {\n def ast\n r = {}\n r.merge!( Hash[ :type, :t_nil ] )\n r.merge!( Hash[ :value, :nil ] )\n r\n end\n }\n end\n\n rule rubysymbol\n wscommnl2 ':' rubysymbolcontent \n {\n def ast\n rubysymbolcontent.ast\n end\n }\n end\n\n rule rubysymbolcontent\n wscommnl2 '\"' rubysymbol_in_double_quotes '\"' \n {\n def ast\n rubysymbol_in_double_quotes.ast\n end\n }\n /\n wscommnl2 '\\'' rubysymbol_in_single_quotes '\\'' \n {\n def ast\n rubysymbol_in_single_quotes.ast\n end\n }\n /\n ( !'(' !')' !'}' !' ' !',' !']' !'#' !'/*' !'*/' !\"\\n\" .)+ \n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule rubysymbol_in_double_quotes\n ('\\\"' / !'\"' !\"\\n\" .)+ \n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule rubysymbol_in_single_quotes\n ('\\\\\\'' / !'\\'' !\"\\n\" .)+ \n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule string\n string_with_doublequotes ''\n {\n def ast\n string_with_doublequotes.ast\n end\n }\n end\n\n rule string_with_doublequotes\n wscommnl2 '\"' string_double_q '\"'\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 \n text_value.gsub(/(\\\\\\\\)|(\\\\n)|(\\\\\")/, '\\\\\\\\'=>'\\\\', \"\\\\n\"=>\"\\n\", '\\\\\"'=>'\"')\n \n end\n }\n end\n\n rule stringnoblank\n (!' ' !'(' !')' .)+ \n {\n def ast\n text_value \n end\n }\n end\n\n rule regexp\n wscommnl2 '/' wscommnl2 regexp_inner wscommnl2 '/' regexp_options \n {\n def ast\n r = {}\n r.merge!( Hash[ :regexp, regexp_inner.ast ] )\n r.merge!( Hash[ :options, regexp_options.ast ] )\n r\n end\n }\n end\n\n rule regexp_options\n regexp_option* \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 regexp_option\n 'i'\n {\n def ast\n text_value.to_sym\n end\n }\n end\n\n rule regexp_inner\n ('\\\\\\\\' / '\\/' / !'/' .)* \n {\n def ast\n \n #text_value.gsub(/(\\\\\\\\)|(\\\\n)|(\\\\\")/, '\\\\\\\\'=>'\\\\', \"\\\\n\"=>\"\\n\", '\\\\\"'=>'\"')\n text_value # .gsub(/(\\\\\\\\)|(\\\\n)|(\\\\\")/, '\\\\\\\\'=>'\\\\', \"\\\\n\"=>\"\\n\", '\\\\\"'=>'\"')\n \n end\n }\n end\n\n rule number_int\n ('-'/'+')? ([1-9]) ([0-9])* \n {\n def ast\n text_value.to_i\n end\n }\n /\n [0] \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 wsc\n [ \\t] \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"
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,1420 @@
|
|
1
|
+
# validation_generator.rb
|
2
|
+
|
3
|
+
# ATTENTION: this file is generated
|
4
|
+
|
5
|
+
require 'forwardable'
|
6
|
+
|
7
|
+
class GdsDataValidation
|
8
|
+
|
9
|
+
class ValidationCheckerGenerator
|
10
|
+
|
11
|
+
class SourceGenerator
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@resultString = ""
|
15
|
+
@indentLevel = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def indent
|
19
|
+
@indentLevel += 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def unindent
|
23
|
+
@indentLevel -= 1 if @indentLevel > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def add( str )
|
27
|
+
@resultString << str
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_line( str )
|
31
|
+
@resultString << " "*(@indentLevel * 2) + str << "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
def begin_line( str )
|
35
|
+
@resultString << " "*(@indentLevel * 2) + str
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_line( str )
|
39
|
+
@resultString << str << "\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
def new_line
|
43
|
+
@resultString << "\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
def result
|
47
|
+
@resultString
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset
|
51
|
+
@resultString = ""
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
extend Forwardable
|
57
|
+
def_delegators :@scgen, :add, :add_line, :begin_line, :end_line, :new_line, :indent, :unindent, :result, :reset
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@scgen = SourceGenerator.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def generate( appliedGrammar )
|
64
|
+
reset
|
65
|
+
_gen_main( appliedGrammar )
|
66
|
+
|
67
|
+
create_class
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def create_class
|
73
|
+
Class.new.tap{ |x| x.class_eval( result ) }
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def _gen_main( struct, label = nil, params = nil )
|
78
|
+
if struct.is_a?( Array )
|
79
|
+
if label
|
80
|
+
case label
|
81
|
+
when "before"
|
82
|
+
indent
|
83
|
+
add_line "class << self"
|
84
|
+
new_line
|
85
|
+
indent
|
86
|
+
when "after"
|
87
|
+
unindent
|
88
|
+
new_line
|
89
|
+
add_line "end"
|
90
|
+
unindent
|
91
|
+
when "check_method"
|
92
|
+
add_line "def check( value )"
|
93
|
+
indent
|
94
|
+
_gen_ruledefinition( struct.first, "callfirstrule" )
|
95
|
+
unindent
|
96
|
+
add_line "end"
|
97
|
+
end
|
98
|
+
else
|
99
|
+
unless label || params
|
100
|
+
_gen_main( struct, "before" )
|
101
|
+
_gen_main( struct, "check_method" )
|
102
|
+
struct.each do |subval|
|
103
|
+
_gen_ruledefinition( subval, nil, nil )
|
104
|
+
end
|
105
|
+
_gen_main( struct, "after" )
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def _gen_ruledefinition( struct, label = nil, params = nil )
|
112
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :name ) && struct.has_key?( :ruledefinition ) )
|
113
|
+
if label
|
114
|
+
case label
|
115
|
+
when "callfirstrule"
|
116
|
+
add_line "check_#{struct[:name]}( value )"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
unless label || params
|
120
|
+
new_line
|
121
|
+
add_line "def check_#{struct[:name]}( value )"
|
122
|
+
indent
|
123
|
+
_gen_alternatives( struct[:ruledefinition], nil, nil )
|
124
|
+
unindent
|
125
|
+
add_line "end"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def _gen_alternatives( struct, label = nil, params = nil )
|
132
|
+
if struct.is_a?( Array ) && struct.length() == 1
|
133
|
+
unless label || params
|
134
|
+
struct.each do |subval|
|
135
|
+
_gen_alternative( subval, nil, nil )
|
136
|
+
end
|
137
|
+
end
|
138
|
+
elsif struct.is_a?( Array ) && struct.length() >= 2
|
139
|
+
unless label || params
|
140
|
+
add_line "clauseRule = false"
|
141
|
+
struct.each do |subval|
|
142
|
+
_gen_alternative_clause( subval, nil, nil )
|
143
|
+
end
|
144
|
+
begin_line ""
|
145
|
+
add "unless"
|
146
|
+
end_line( " clauseRule" )
|
147
|
+
indent
|
148
|
+
add_line "return false"
|
149
|
+
unindent
|
150
|
+
add_line "end"
|
151
|
+
add_line "return true"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def _gen_alternative_clause( struct, label = nil, params = nil )
|
157
|
+
if true # :name
|
158
|
+
unless label || params
|
159
|
+
add_line "unless clauseRule"
|
160
|
+
indent
|
161
|
+
add_line "clauseRule = lambda do"
|
162
|
+
indent
|
163
|
+
_gen_alternative( struct, nil, nil )
|
164
|
+
unindent
|
165
|
+
add_line "end.()"
|
166
|
+
unindent
|
167
|
+
add_line "end"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def _gen_alternative( struct, label = nil, params = nil )
|
173
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :hashdef ) && struct.has_key?( :strict ) && struct[:strict] == :strict )
|
174
|
+
unless label || params
|
175
|
+
_gen_maybe3( struct, nil, ["value"] )
|
176
|
+
add_line "unless ( value.is_a?( Hash ) )"
|
177
|
+
indent
|
178
|
+
add_line "return false"
|
179
|
+
unindent
|
180
|
+
add_line "end"
|
181
|
+
begin_line "unless ( value.keys - %i( "
|
182
|
+
struct[:hashdef].each do |subval|
|
183
|
+
_gen_keyvaluedef( subval, "output_key" )
|
184
|
+
end
|
185
|
+
end_line( ") ).empty?" )
|
186
|
+
indent
|
187
|
+
add_line "return false"
|
188
|
+
unindent
|
189
|
+
add_line "end"
|
190
|
+
struct[:hashdef].each do |subval|
|
191
|
+
_gen_keyvaluedef( subval, nil, nil )
|
192
|
+
end
|
193
|
+
add_line "return true"
|
194
|
+
end
|
195
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :hashdef ) )
|
196
|
+
unless label || params
|
197
|
+
_gen_maybe3( struct, nil, ["value"] )
|
198
|
+
add_line "unless ( value.is_a?( Hash ) )"
|
199
|
+
indent
|
200
|
+
add_line "return false"
|
201
|
+
unindent
|
202
|
+
add_line "end"
|
203
|
+
struct[:hashdef].each do |subval|
|
204
|
+
_gen_keyvaluedef( subval, nil, nil )
|
205
|
+
end
|
206
|
+
add_line "return true"
|
207
|
+
end
|
208
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :arraydef ) )
|
209
|
+
unless label || params
|
210
|
+
_gen_maybe3( struct, nil, ["value"] )
|
211
|
+
add_line "unless value.is_a?( Array )"
|
212
|
+
indent
|
213
|
+
add_line "return false"
|
214
|
+
unindent
|
215
|
+
add_line "end"
|
216
|
+
_gen_arraydef( struct[:arraydef], nil, ["value"] )
|
217
|
+
add_line "return true"
|
218
|
+
end
|
219
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :subruledef ) )
|
220
|
+
unless label || params
|
221
|
+
_gen_maybe3( struct, nil, ["value"] )
|
222
|
+
begin_line "unless check_"
|
223
|
+
_gen_subruledef( struct[:subruledef], "therulename", nil )
|
224
|
+
end_line( "( value )" )
|
225
|
+
indent
|
226
|
+
add_line "return false"
|
227
|
+
unindent
|
228
|
+
add_line "end"
|
229
|
+
add_line "return true"
|
230
|
+
end
|
231
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :typedef ) )
|
232
|
+
unless label || params
|
233
|
+
_gen_maybe3( struct, nil, ["value"] )
|
234
|
+
begin_line ""
|
235
|
+
_gen_notop( struct[:typedef], nil, nil )
|
236
|
+
add " ( "
|
237
|
+
_gen_typedef( struct[:typedef], "typecheck", ["value"] )
|
238
|
+
end_line( " )" )
|
239
|
+
indent
|
240
|
+
add_line "return false"
|
241
|
+
unindent
|
242
|
+
add_line "end"
|
243
|
+
_gen_maybe2( struct[:typedef], nil, ["value"] )
|
244
|
+
add_line "return true"
|
245
|
+
end
|
246
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :basicvaluedef ) )
|
247
|
+
unless label || params
|
248
|
+
_gen_maybe3( struct, nil, ["value"] )
|
249
|
+
_gen_basicvaluedef( struct[:basicvaluedef], nil, ["value"] )
|
250
|
+
end
|
251
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valdefdisjunct ) )
|
252
|
+
unless label || params
|
253
|
+
_gen_maybe3( struct, nil, ["value"] )
|
254
|
+
add_line "clause = false"
|
255
|
+
struct[:valdefdisjunct].each do |subval|
|
256
|
+
_gen_disjunction( subval, nil, ["value"] )
|
257
|
+
end
|
258
|
+
begin_line ""
|
259
|
+
_gen_notop( struct, nil, nil )
|
260
|
+
end_line( " clause" )
|
261
|
+
indent
|
262
|
+
add_line "return false"
|
263
|
+
unindent
|
264
|
+
add_line "end"
|
265
|
+
add_line "return true"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def _gen_basicvaluedef( struct, label = nil, params = nil )
|
271
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_true && struct.has_key?( :value ) )
|
272
|
+
if label
|
273
|
+
case label
|
274
|
+
when "thevalue"
|
275
|
+
add "true"
|
276
|
+
end
|
277
|
+
elsif params
|
278
|
+
if params.length == 1
|
279
|
+
add_line "unless #{params[0]} == true"
|
280
|
+
indent
|
281
|
+
add_line "return false"
|
282
|
+
unindent
|
283
|
+
add_line "end"
|
284
|
+
add_line "return true"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_false && struct.has_key?( :value ) )
|
288
|
+
if label
|
289
|
+
case label
|
290
|
+
when "thevalue"
|
291
|
+
add "false"
|
292
|
+
end
|
293
|
+
elsif params
|
294
|
+
if params.length == 1
|
295
|
+
add_line "unless #{params[0]} == false"
|
296
|
+
indent
|
297
|
+
add_line "return false"
|
298
|
+
unindent
|
299
|
+
add_line "end"
|
300
|
+
add_line "return true"
|
301
|
+
end
|
302
|
+
end
|
303
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_nil && struct.has_key?( :value ) )
|
304
|
+
if label
|
305
|
+
case label
|
306
|
+
when "thevalue"
|
307
|
+
add "nil"
|
308
|
+
end
|
309
|
+
elsif params
|
310
|
+
if params.length == 1
|
311
|
+
add_line "unless #{params[0]} == nil"
|
312
|
+
indent
|
313
|
+
add_line "return false"
|
314
|
+
unindent
|
315
|
+
add_line "end"
|
316
|
+
add_line "return true"
|
317
|
+
end
|
318
|
+
end
|
319
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :value ) )
|
320
|
+
if label
|
321
|
+
case label
|
322
|
+
when "thevalue"
|
323
|
+
add "#{struct[:value].inspect}"
|
324
|
+
end
|
325
|
+
elsif params
|
326
|
+
if params.length == 1
|
327
|
+
add_line "unless #{params[0]} == #{struct[:value].inspect}"
|
328
|
+
indent
|
329
|
+
add_line "return false"
|
330
|
+
unindent
|
331
|
+
add_line "end"
|
332
|
+
add_line "return true"
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def _gen_maybe( struct, label = nil, params = nil )
|
339
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :maybe ) && struct[:maybe] == :maybe )
|
340
|
+
if params
|
341
|
+
if params.length == 1
|
342
|
+
add "#{params[0]}.nil? || "
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def _gen_maybe2( struct, label = nil, params = nil )
|
349
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :maybe ) && struct[:maybe] == :maybe )
|
350
|
+
if params
|
351
|
+
if params.length == 1
|
352
|
+
add_line "unless #{params[0]}.nil?"
|
353
|
+
indent
|
354
|
+
_gen_typedef( struct, nil, ["value"] )
|
355
|
+
unindent
|
356
|
+
add_line "end"
|
357
|
+
end
|
358
|
+
end
|
359
|
+
elsif true
|
360
|
+
if params
|
361
|
+
if params.length == 1
|
362
|
+
_gen_typedef( struct, nil, ["value"] )
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def _gen_maybe3( struct, label = nil, params = nil )
|
369
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :maybe ) && struct[:maybe] == :maybe )
|
370
|
+
if label
|
371
|
+
case label
|
372
|
+
when "condition"
|
373
|
+
if params
|
374
|
+
if params.length == 1
|
375
|
+
add "#{params[0]}.nil? || "
|
376
|
+
end
|
377
|
+
end
|
378
|
+
when "only_begin"
|
379
|
+
if params
|
380
|
+
if params.length == 1
|
381
|
+
add_line "unless #{params[0]}.nil?"
|
382
|
+
indent
|
383
|
+
end
|
384
|
+
end
|
385
|
+
when "only_end"
|
386
|
+
unindent
|
387
|
+
add_line "end"
|
388
|
+
when "disjunct"
|
389
|
+
if params
|
390
|
+
if params.length == 1
|
391
|
+
add_line "clause = #{params[0]}.nil?"
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
elsif params
|
396
|
+
if params.length == 1
|
397
|
+
add_line "if #{params[0]}.nil?"
|
398
|
+
indent
|
399
|
+
add_line "return true"
|
400
|
+
unindent
|
401
|
+
add_line "end"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
def _gen_disjunction( struct, label = nil, params = nil )
|
408
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :typedef ) )
|
409
|
+
if params
|
410
|
+
if params.length == 1
|
411
|
+
add_line "unless clause"
|
412
|
+
indent
|
413
|
+
add_line "clause = lambda do"
|
414
|
+
indent
|
415
|
+
begin_line ""
|
416
|
+
_gen_notop( struct[:typedef], nil, nil )
|
417
|
+
add " ( "
|
418
|
+
_gen_typedef( struct[:typedef], "typecheck", ["#{params[0]}"] )
|
419
|
+
end_line( " )" )
|
420
|
+
indent
|
421
|
+
add_line "return false"
|
422
|
+
unindent
|
423
|
+
add_line "end"
|
424
|
+
_gen_typedef( struct[:typedef], nil, ["#{params[0]}"] )
|
425
|
+
add_line "return true"
|
426
|
+
unindent
|
427
|
+
add_line "end.()"
|
428
|
+
unindent
|
429
|
+
add_line "end"
|
430
|
+
end
|
431
|
+
end
|
432
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :basicvaluedef ) )
|
433
|
+
if params
|
434
|
+
if params.length == 1
|
435
|
+
add_line "unless clause"
|
436
|
+
indent
|
437
|
+
add_line "clause = lambda do"
|
438
|
+
indent
|
439
|
+
_gen_maybe3( struct, nil, ["#{params[0]}"] )
|
440
|
+
_gen_basicvaluedef( struct[:basicvaluedef], nil, ["#{params[0]}"] )
|
441
|
+
unindent
|
442
|
+
add_line "end.()"
|
443
|
+
unindent
|
444
|
+
add_line "end"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def _gen_keyvaluedef( struct, label = nil, params = nil )
|
451
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :keyvaluedef ) )
|
452
|
+
if label
|
453
|
+
case label
|
454
|
+
when "output_key"
|
455
|
+
_gen_keyvaluedef1( struct[:keyvaluedef], "output_key", nil )
|
456
|
+
end
|
457
|
+
else
|
458
|
+
unless label || params
|
459
|
+
_gen_keyvaluedef1( struct[:keyvaluedef], nil, nil )
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
def _gen_arraydef( struct, label = nil, params = nil )
|
466
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :rulename ) && struct.has_key?( :sizespec ) )
|
467
|
+
if params
|
468
|
+
if params.length == 1
|
469
|
+
_gen_sizespec( struct[:sizespec], nil, ["#{params[0]}"] )
|
470
|
+
add_line "unless #{params[0]}.all? { |e| check_#{struct[:rulename]}( e ) }"
|
471
|
+
indent
|
472
|
+
add_line "return false"
|
473
|
+
unindent
|
474
|
+
add_line "end"
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def _gen_keyvaluedef1( struct, label = nil, params = nil )
|
481
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :key ) && struct.has_key?( :value ) && struct.has_key?( :optional ) && struct[:optional] == :optional )
|
482
|
+
if label
|
483
|
+
case label
|
484
|
+
when "output_key"
|
485
|
+
add "#{struct[:key]} "
|
486
|
+
end
|
487
|
+
else
|
488
|
+
unless label || params
|
489
|
+
add_line "if value.has_key?( #{struct[:key].inspect} )"
|
490
|
+
indent
|
491
|
+
add_line "v = value.fetch( #{struct[:key].inspect} )"
|
492
|
+
_gen_valuedef( struct[:value], nil, nil )
|
493
|
+
unindent
|
494
|
+
add_line "end"
|
495
|
+
end
|
496
|
+
end
|
497
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :key ) && struct.has_key?( :value ) )
|
498
|
+
if label
|
499
|
+
case label
|
500
|
+
when "output_key"
|
501
|
+
add "#{struct[:key]} "
|
502
|
+
end
|
503
|
+
else
|
504
|
+
unless label || params
|
505
|
+
add_line "unless value.has_key?( #{struct[:key].inspect} )"
|
506
|
+
indent
|
507
|
+
add_line "return false"
|
508
|
+
unindent
|
509
|
+
add_line "end"
|
510
|
+
add_line "v = value.fetch( #{struct[:key].inspect} )"
|
511
|
+
_gen_valuedef( struct[:value], nil, nil )
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def _gen_valuedef( struct, label = nil, params = nil )
|
518
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :basicvaluedef ) )
|
519
|
+
unless label || params
|
520
|
+
begin_line "unless "
|
521
|
+
_gen_maybe3( struct, "condition", ["v"] )
|
522
|
+
add "v == "
|
523
|
+
_gen_basicvaluedef( struct[:basicvaluedef], "thevalue", nil )
|
524
|
+
end_line( "" )
|
525
|
+
indent
|
526
|
+
add_line "return false"
|
527
|
+
unindent
|
528
|
+
add_line "end"
|
529
|
+
end
|
530
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :typedef ) )
|
531
|
+
unless label || params
|
532
|
+
begin_line "unless "
|
533
|
+
_gen_maybe3( struct, "condition", ["v"] )
|
534
|
+
_gen_notop( struct[:typedef], "boolop", nil )
|
535
|
+
add "( "
|
536
|
+
_gen_typedef( struct[:typedef], "typecheck", ["v"] )
|
537
|
+
end_line( " )" )
|
538
|
+
indent
|
539
|
+
add_line "return false"
|
540
|
+
unindent
|
541
|
+
add_line "end"
|
542
|
+
_gen_maybe3( struct, "only_begin", ["v"] )
|
543
|
+
_gen_typedef( struct[:typedef], nil, ["v"] )
|
544
|
+
_gen_maybe3( struct, "only_end", nil )
|
545
|
+
end
|
546
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :arraydef ) )
|
547
|
+
unless label || params
|
548
|
+
begin_line "unless "
|
549
|
+
_gen_maybe3( struct, "condition", ["v"] )
|
550
|
+
end_line( "v.is_a?( Array )" )
|
551
|
+
indent
|
552
|
+
add_line "return false"
|
553
|
+
unindent
|
554
|
+
add_line "end"
|
555
|
+
_gen_maybe3( struct, "only_begin", ["v"] )
|
556
|
+
_gen_arraydef( struct[:arraydef], nil, ["v"] )
|
557
|
+
_gen_maybe3( struct, "only_end", nil )
|
558
|
+
end
|
559
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :subruledef ) )
|
560
|
+
unless label || params
|
561
|
+
begin_line "unless "
|
562
|
+
_gen_maybe3( struct, "condition", ["v"] )
|
563
|
+
add "check_"
|
564
|
+
_gen_subruledef( struct[:subruledef], "therulename", nil )
|
565
|
+
end_line( "( v )" )
|
566
|
+
indent
|
567
|
+
add_line "return false"
|
568
|
+
unindent
|
569
|
+
add_line "end"
|
570
|
+
end
|
571
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valdefdisjunct ) )
|
572
|
+
unless label || params
|
573
|
+
add_line "clause = false"
|
574
|
+
_gen_maybe3( struct, "disjunct", ["v"] )
|
575
|
+
struct[:valdefdisjunct].each do |subval|
|
576
|
+
_gen_disjunction( subval, nil, ["v"] )
|
577
|
+
end
|
578
|
+
_gen_maybe3( struct, "only_begin", ["v"] )
|
579
|
+
begin_line ""
|
580
|
+
_gen_notop( struct, nil, nil )
|
581
|
+
end_line( " clause" )
|
582
|
+
indent
|
583
|
+
add_line "return false"
|
584
|
+
unindent
|
585
|
+
add_line "end"
|
586
|
+
_gen_maybe3( struct, "only_end", nil )
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
def _gen_sizespec( struct, label = nil, params = nil )
|
592
|
+
if ( struct.is_a?( Symbol ) && struct == :* )
|
593
|
+
if params
|
594
|
+
if params.length == 1
|
595
|
+
end
|
596
|
+
end
|
597
|
+
elsif ( struct.is_a?( Symbol ) && struct == :+ )
|
598
|
+
if params
|
599
|
+
if params.length == 1
|
600
|
+
add_line "unless #{params[0]}.size() >= 1"
|
601
|
+
indent
|
602
|
+
add_line "return false"
|
603
|
+
unindent
|
604
|
+
add_line "end"
|
605
|
+
end
|
606
|
+
end
|
607
|
+
elsif true
|
608
|
+
if params
|
609
|
+
if params.length == 1
|
610
|
+
_gen_minmaxspec( struct, nil, ["#{params[0]}"".size()"] )
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
def _gen_subruledef( struct, label = nil, params = nil )
|
617
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :rulename ) )
|
618
|
+
if label
|
619
|
+
case label
|
620
|
+
when "therulename"
|
621
|
+
add "#{struct[:rulename]}"
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
def _gen_typedef( struct, label = nil, params = nil )
|
628
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_string && struct.has_key?( :valuespecs ) )
|
629
|
+
if label
|
630
|
+
case label
|
631
|
+
when "thetype"
|
632
|
+
unless params
|
633
|
+
add "String"
|
634
|
+
end
|
635
|
+
if params
|
636
|
+
if params.length == 1
|
637
|
+
add "String # #{params[0]}"
|
638
|
+
end
|
639
|
+
if params.length == 2
|
640
|
+
add "String # #{params[0]} and #{params[1]}"
|
641
|
+
end
|
642
|
+
end
|
643
|
+
when "typecheck"
|
644
|
+
if params
|
645
|
+
if params.length == 1
|
646
|
+
add "#{params[0]}.is_a?( "
|
647
|
+
_gen_typedef( struct, "thetype" )
|
648
|
+
add " )"
|
649
|
+
end
|
650
|
+
end
|
651
|
+
end
|
652
|
+
elsif params
|
653
|
+
if params.length == 1
|
654
|
+
struct[:valuespecs].each do |subval|
|
655
|
+
_gen_stringvaluespec( subval, nil, ["#{params[0]}"] )
|
656
|
+
end
|
657
|
+
end
|
658
|
+
if params.length == 2
|
659
|
+
struct[:valuespecs].each do |subval|
|
660
|
+
_gen_stringvaluespec( subval, nil, ["#{params[1]}"" - ""#{params[0]}"] )
|
661
|
+
end
|
662
|
+
end
|
663
|
+
end
|
664
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_string )
|
665
|
+
if label
|
666
|
+
case label
|
667
|
+
when "thetype"
|
668
|
+
add "String"
|
669
|
+
when "typecheck"
|
670
|
+
if params
|
671
|
+
if params.length == 1
|
672
|
+
add "#{params[0]}.is_a?( "
|
673
|
+
_gen_typedef( struct, "thetype" )
|
674
|
+
add " )"
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
678
|
+
else
|
679
|
+
unless label || params
|
680
|
+
add ""
|
681
|
+
end
|
682
|
+
end
|
683
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_int && struct.has_key?( :valuespecs ) )
|
684
|
+
if label
|
685
|
+
case label
|
686
|
+
when "thetype"
|
687
|
+
add "Integer"
|
688
|
+
when "typecheck"
|
689
|
+
if params
|
690
|
+
if params.length == 1
|
691
|
+
add "#{params[0]}.is_a?( "
|
692
|
+
_gen_typedef( struct, "thetype" )
|
693
|
+
add " )"
|
694
|
+
end
|
695
|
+
end
|
696
|
+
end
|
697
|
+
elsif params
|
698
|
+
if params.length == 1
|
699
|
+
_gen_intvaluespecs( struct[:valuespecs], nil, ["#{params[0]}"] )
|
700
|
+
end
|
701
|
+
end
|
702
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_int )
|
703
|
+
if label
|
704
|
+
case label
|
705
|
+
when "thetype"
|
706
|
+
add "Integer"
|
707
|
+
when "typecheck"
|
708
|
+
if params
|
709
|
+
if params.length == 1
|
710
|
+
add "#{params[0]}.is_a?( "
|
711
|
+
_gen_typedef( struct, "thetype" )
|
712
|
+
add " )"
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
else
|
717
|
+
unless label || params
|
718
|
+
add ""
|
719
|
+
end
|
720
|
+
end
|
721
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_float && struct.has_key?( :valuespecs ) )
|
722
|
+
if label
|
723
|
+
case label
|
724
|
+
when "thetype"
|
725
|
+
add "Float"
|
726
|
+
when "typecheck"
|
727
|
+
if params
|
728
|
+
if params.length == 1
|
729
|
+
add "#{params[0]}.is_a?( "
|
730
|
+
_gen_typedef( struct, "thetype" )
|
731
|
+
add " )"
|
732
|
+
end
|
733
|
+
end
|
734
|
+
end
|
735
|
+
elsif params
|
736
|
+
if params.length == 1
|
737
|
+
_gen_floatvaluespecs( struct[:valuespecs], nil, ["#{params[0]}"] )
|
738
|
+
end
|
739
|
+
end
|
740
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_float )
|
741
|
+
if label
|
742
|
+
case label
|
743
|
+
when "thetype"
|
744
|
+
add "Float"
|
745
|
+
when "typecheck"
|
746
|
+
if params
|
747
|
+
if params.length == 1
|
748
|
+
add "#{params[0]}.is_a?( "
|
749
|
+
_gen_typedef( struct, "thetype" )
|
750
|
+
add " )"
|
751
|
+
end
|
752
|
+
end
|
753
|
+
end
|
754
|
+
else
|
755
|
+
unless label || params
|
756
|
+
add ""
|
757
|
+
end
|
758
|
+
end
|
759
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_nil )
|
760
|
+
if label
|
761
|
+
case label
|
762
|
+
when "thetype"
|
763
|
+
add "NilClass"
|
764
|
+
when "typecheck"
|
765
|
+
if params
|
766
|
+
if params.length == 1
|
767
|
+
add "#{params[0]}.is_a?( "
|
768
|
+
_gen_typedef( struct, "thetype" )
|
769
|
+
add " )"
|
770
|
+
end
|
771
|
+
end
|
772
|
+
end
|
773
|
+
else
|
774
|
+
unless label || params
|
775
|
+
add ""
|
776
|
+
end
|
777
|
+
end
|
778
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_numeric )
|
779
|
+
if label
|
780
|
+
case label
|
781
|
+
when "thetype"
|
782
|
+
add "Numeric"
|
783
|
+
when "typecheck"
|
784
|
+
if params
|
785
|
+
if params.length == 1
|
786
|
+
add "#{params[0]}.is_a?( "
|
787
|
+
_gen_typedef( struct, "thetype" )
|
788
|
+
add " )"
|
789
|
+
end
|
790
|
+
end
|
791
|
+
end
|
792
|
+
else
|
793
|
+
unless label || params
|
794
|
+
add ""
|
795
|
+
end
|
796
|
+
end
|
797
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_symbol && struct.has_key?( :valuespecs ) )
|
798
|
+
if label
|
799
|
+
case label
|
800
|
+
when "thetype"
|
801
|
+
add "Symbol"
|
802
|
+
when "typecheck"
|
803
|
+
if params
|
804
|
+
if params.length == 1
|
805
|
+
add "#{params[0]}.is_a?( "
|
806
|
+
_gen_typedef( struct, "thetype" )
|
807
|
+
add " )"
|
808
|
+
end
|
809
|
+
end
|
810
|
+
end
|
811
|
+
elsif params
|
812
|
+
if params.length == 1
|
813
|
+
_gen_symbolvaluespecs( struct[:valuespecs], nil, ["#{params[0]}"] )
|
814
|
+
end
|
815
|
+
end
|
816
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_symbol )
|
817
|
+
if label
|
818
|
+
case label
|
819
|
+
when "thetype"
|
820
|
+
add "Symbol"
|
821
|
+
when "typecheck"
|
822
|
+
if params
|
823
|
+
if params.length == 1
|
824
|
+
add "#{params[0]}.is_a?( "
|
825
|
+
_gen_typedef( struct, "thetype" )
|
826
|
+
add " )"
|
827
|
+
end
|
828
|
+
end
|
829
|
+
end
|
830
|
+
else
|
831
|
+
unless label || params
|
832
|
+
add ""
|
833
|
+
end
|
834
|
+
end
|
835
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_true )
|
836
|
+
if label
|
837
|
+
case label
|
838
|
+
when "thetype"
|
839
|
+
add "TrueClass"
|
840
|
+
when "typecheck"
|
841
|
+
if params
|
842
|
+
if params.length == 1
|
843
|
+
add "#{params[0]}.is_a?( "
|
844
|
+
_gen_typedef( struct, "thetype" )
|
845
|
+
add " )"
|
846
|
+
end
|
847
|
+
end
|
848
|
+
end
|
849
|
+
else
|
850
|
+
unless label || params
|
851
|
+
add ""
|
852
|
+
end
|
853
|
+
end
|
854
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_false )
|
855
|
+
if label
|
856
|
+
case label
|
857
|
+
when "thetype"
|
858
|
+
add "FalseClass"
|
859
|
+
when "typecheck"
|
860
|
+
if params
|
861
|
+
if params.length == 1
|
862
|
+
add "#{params[0]}.is_a?( "
|
863
|
+
_gen_typedef( struct, "thetype" )
|
864
|
+
add " )"
|
865
|
+
end
|
866
|
+
end
|
867
|
+
end
|
868
|
+
else
|
869
|
+
unless label || params
|
870
|
+
add ""
|
871
|
+
end
|
872
|
+
end
|
873
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_bool )
|
874
|
+
if label
|
875
|
+
case label
|
876
|
+
when "typecheck"
|
877
|
+
if params
|
878
|
+
if params.length == 1
|
879
|
+
add "#{params[0]}.is_a?( TrueClass ) || #{params[0]}.is_a?( FalseClass )"
|
880
|
+
end
|
881
|
+
end
|
882
|
+
end
|
883
|
+
else
|
884
|
+
unless label || params
|
885
|
+
add ""
|
886
|
+
end
|
887
|
+
end
|
888
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :type ) && struct[:type] == :t_any )
|
889
|
+
if label
|
890
|
+
case label
|
891
|
+
when "thetype"
|
892
|
+
add "Object"
|
893
|
+
when "typecheck"
|
894
|
+
if params
|
895
|
+
if params.length == 1
|
896
|
+
add "#{params[0]}.is_a?( "
|
897
|
+
_gen_typedef( struct, "thetype" )
|
898
|
+
add " )"
|
899
|
+
end
|
900
|
+
end
|
901
|
+
end
|
902
|
+
else
|
903
|
+
unless label || params
|
904
|
+
add ""
|
905
|
+
end
|
906
|
+
end
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
def _gen_intvaluespecs( struct, label = nil, params = nil )
|
911
|
+
if struct.is_a?( Array )
|
912
|
+
if params
|
913
|
+
if params.length == 1
|
914
|
+
struct.each do |subval|
|
915
|
+
_gen_intvaluespec( subval, nil, ["#{params[0]}"] )
|
916
|
+
end
|
917
|
+
end
|
918
|
+
end
|
919
|
+
end
|
920
|
+
end
|
921
|
+
|
922
|
+
def _gen_intvaluespec( struct, label = nil, params = nil )
|
923
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :even )
|
924
|
+
if params
|
925
|
+
if params.length == 1
|
926
|
+
begin_line ""
|
927
|
+
_gen_notop( struct, nil, nil )
|
928
|
+
end_line( " #{params[0]}.even?" )
|
929
|
+
indent
|
930
|
+
add_line "return false"
|
931
|
+
unindent
|
932
|
+
add_line "end"
|
933
|
+
_gen_minmaxspec( struct, nil, ["#{params[0]}"] )
|
934
|
+
end
|
935
|
+
end
|
936
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :odd )
|
937
|
+
if params
|
938
|
+
if params.length == 1
|
939
|
+
begin_line ""
|
940
|
+
_gen_notop( struct, nil, nil )
|
941
|
+
end_line( " #{params[0]}.odd?" )
|
942
|
+
indent
|
943
|
+
add_line "return false"
|
944
|
+
unindent
|
945
|
+
add_line "end"
|
946
|
+
_gen_minmaxspec( struct, nil, ["#{params[0]}"] )
|
947
|
+
end
|
948
|
+
end
|
949
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :eql && struct.has_key?( :val ) )
|
950
|
+
if params
|
951
|
+
if params.length == 1
|
952
|
+
begin_line ""
|
953
|
+
_gen_notop( struct, nil, nil )
|
954
|
+
end_line( " #{params[0]} == #{struct[:val]}" )
|
955
|
+
indent
|
956
|
+
add_line "return false"
|
957
|
+
unindent
|
958
|
+
add_line "end"
|
959
|
+
end
|
960
|
+
end
|
961
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :neql && struct.has_key?( :val ) )
|
962
|
+
if params
|
963
|
+
if params.length == 1
|
964
|
+
begin_line ""
|
965
|
+
_gen_notop( struct, nil, nil )
|
966
|
+
end_line( " #{params[0]} != #{struct[:val]}" )
|
967
|
+
indent
|
968
|
+
add_line "return false"
|
969
|
+
unindent
|
970
|
+
add_line "end"
|
971
|
+
end
|
972
|
+
end
|
973
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valuelist ) )
|
974
|
+
if params
|
975
|
+
if params.length == 1
|
976
|
+
begin_line ""
|
977
|
+
_gen_notop( struct, nil, nil )
|
978
|
+
end_line( " #{struct[:valuelist].inspect}.include?( #{params[0]} )" )
|
979
|
+
indent
|
980
|
+
add_line "return false"
|
981
|
+
unindent
|
982
|
+
add_line "end"
|
983
|
+
end
|
984
|
+
end
|
985
|
+
elsif true
|
986
|
+
if params
|
987
|
+
if params.length == 1
|
988
|
+
_gen_minmaxspec( struct, nil, ["#{params[0]}"] )
|
989
|
+
end
|
990
|
+
end
|
991
|
+
end
|
992
|
+
end
|
993
|
+
|
994
|
+
def _gen_stringvaluespecs( struct, label = nil, params = nil )
|
995
|
+
if struct.is_a?( Array )
|
996
|
+
if params
|
997
|
+
if params.length == 1
|
998
|
+
struct.each do |subval|
|
999
|
+
_gen_stringvaluespec( subval, nil, ["#{params[0]}"] )
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def _gen_stringvaluespec( struct, label = nil, params = nil )
|
1007
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :eql && struct.has_key?( :val ) )
|
1008
|
+
if params
|
1009
|
+
if params.length == 1
|
1010
|
+
begin_line ""
|
1011
|
+
_gen_notop( struct, nil, nil )
|
1012
|
+
end_line( " #{params[0]} == #{struct[:val].inspect}" )
|
1013
|
+
indent
|
1014
|
+
add_line "return false"
|
1015
|
+
unindent
|
1016
|
+
add_line "end"
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :neql && struct.has_key?( :val ) )
|
1020
|
+
if params
|
1021
|
+
if params.length == 1
|
1022
|
+
begin_line ""
|
1023
|
+
_gen_notop( struct, nil, nil )
|
1024
|
+
end_line( " #{params[0]} != #{struct[:val].inspect}" )
|
1025
|
+
indent
|
1026
|
+
add_line "return false"
|
1027
|
+
unindent
|
1028
|
+
add_line "end"
|
1029
|
+
end
|
1030
|
+
end
|
1031
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valuelist ) )
|
1032
|
+
if params
|
1033
|
+
if params.length == 1
|
1034
|
+
begin_line ""
|
1035
|
+
_gen_notop( struct, nil, nil )
|
1036
|
+
end_line( " #{struct[:valuelist].inspect}.include?( #{params[0]} )" )
|
1037
|
+
indent
|
1038
|
+
add_line "return false"
|
1039
|
+
unindent
|
1040
|
+
add_line "end"
|
1041
|
+
end
|
1042
|
+
end
|
1043
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :empty )
|
1044
|
+
if params
|
1045
|
+
if params.length == 1
|
1046
|
+
begin_line ""
|
1047
|
+
_gen_notop( struct, nil, nil )
|
1048
|
+
end_line( " #{params[0]}.empty?" )
|
1049
|
+
indent
|
1050
|
+
add_line "return false"
|
1051
|
+
unindent
|
1052
|
+
add_line "end"
|
1053
|
+
end
|
1054
|
+
end
|
1055
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :something )
|
1056
|
+
if params
|
1057
|
+
if params.length == 1
|
1058
|
+
begin_line ""
|
1059
|
+
_gen_notop( struct, nil, nil )
|
1060
|
+
end_line( " ! #{params[0]}.empty?" )
|
1061
|
+
indent
|
1062
|
+
add_line "return false"
|
1063
|
+
unindent
|
1064
|
+
add_line "end"
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :blank )
|
1068
|
+
if params
|
1069
|
+
if params.length == 1
|
1070
|
+
begin_line ""
|
1071
|
+
_gen_notop( struct, nil, nil )
|
1072
|
+
end_line( " #{params[0]}.empty? || #{params[0]}.match( /\\A[[:space:]]*\\z/ )" )
|
1073
|
+
indent
|
1074
|
+
add_line "return false"
|
1075
|
+
unindent
|
1076
|
+
add_line "end"
|
1077
|
+
end
|
1078
|
+
end
|
1079
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :present )
|
1080
|
+
if params
|
1081
|
+
if params.length == 1
|
1082
|
+
begin_line ""
|
1083
|
+
_gen_notop( struct, nil, nil )
|
1084
|
+
end_line( " ! ( #{params[0]}.empty? || #{params[0]}.match( /\\A[[:space:]]*\\z/ ) )" )
|
1085
|
+
indent
|
1086
|
+
add_line "return false"
|
1087
|
+
unindent
|
1088
|
+
add_line "end"
|
1089
|
+
end
|
1090
|
+
end
|
1091
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :length )
|
1092
|
+
if params
|
1093
|
+
if params.length == 1
|
1094
|
+
add_line "l = #{params[0]}.length"
|
1095
|
+
_gen_minmaxspec( struct, nil, ["l"] )
|
1096
|
+
end
|
1097
|
+
end
|
1098
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :regexp && struct.has_key?( :regexp ) && struct.has_key?( :options ) )
|
1099
|
+
if params
|
1100
|
+
if params.length == 1
|
1101
|
+
begin_line ""
|
1102
|
+
_gen_notop( struct, nil, nil )
|
1103
|
+
add " #{params[0]}.match( /#{struct[:regexp]}/"
|
1104
|
+
_gen_regexp_options( struct[:options], nil, nil )
|
1105
|
+
end_line( " )" )
|
1106
|
+
indent
|
1107
|
+
add_line "return false"
|
1108
|
+
unindent
|
1109
|
+
add_line "end"
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
end
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
def _gen_regexp_options( struct, label = nil, params = nil )
|
1116
|
+
if struct.is_a?( Array )
|
1117
|
+
unless label || params
|
1118
|
+
struct.each do |subval|
|
1119
|
+
_gen_regexp_option( subval, nil, nil )
|
1120
|
+
end
|
1121
|
+
end
|
1122
|
+
end
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
def _gen_regexp_option( struct, label = nil, params = nil )
|
1126
|
+
if ( struct.is_a?( Symbol ) && struct == :i )
|
1127
|
+
unless label || params
|
1128
|
+
add "i"
|
1129
|
+
end
|
1130
|
+
end
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def _gen_floatvaluespecs( struct, label = nil, params = nil )
|
1134
|
+
if struct.is_a?( Array )
|
1135
|
+
if params
|
1136
|
+
if params.length == 1
|
1137
|
+
struct.each do |subval|
|
1138
|
+
_gen_floatvaluespec( subval, nil, ["#{params[0]}"] )
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
def _gen_floatvaluespec( struct, label = nil, params = nil )
|
1146
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :eql && struct.has_key?( :val ) )
|
1147
|
+
if params
|
1148
|
+
if params.length == 1
|
1149
|
+
begin_line ""
|
1150
|
+
_gen_notop( struct, nil, nil )
|
1151
|
+
end_line( " #{params[0]} == #{struct[:val]}" )
|
1152
|
+
indent
|
1153
|
+
add_line "return false"
|
1154
|
+
unindent
|
1155
|
+
add_line "end"
|
1156
|
+
end
|
1157
|
+
end
|
1158
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :neql && struct.has_key?( :val ) )
|
1159
|
+
if params
|
1160
|
+
if params.length == 1
|
1161
|
+
begin_line ""
|
1162
|
+
_gen_notop( struct, nil, nil )
|
1163
|
+
end_line( " #{params[0]} != #{struct[:val]}" )
|
1164
|
+
indent
|
1165
|
+
add_line "return false"
|
1166
|
+
unindent
|
1167
|
+
add_line "end"
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valuelist ) )
|
1171
|
+
if params
|
1172
|
+
if params.length == 1
|
1173
|
+
begin_line ""
|
1174
|
+
_gen_notop( struct, nil, nil )
|
1175
|
+
end_line( " #{struct[:valuelist].inspect}.include?( #{params[0]} )" )
|
1176
|
+
indent
|
1177
|
+
add_line "return false"
|
1178
|
+
unindent
|
1179
|
+
add_line "end"
|
1180
|
+
end
|
1181
|
+
end
|
1182
|
+
elsif true
|
1183
|
+
if params
|
1184
|
+
if params.length == 1
|
1185
|
+
_gen_minmaxspec( struct, nil, ["#{params[0]}"] )
|
1186
|
+
end
|
1187
|
+
end
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
def _gen_symbolvaluespecs( struct, label = nil, params = nil )
|
1192
|
+
if struct.is_a?( Array )
|
1193
|
+
if params
|
1194
|
+
if params.length == 1
|
1195
|
+
struct.each do |subval|
|
1196
|
+
_gen_symbolvaluespec( subval, nil, ["#{params[0]}"] )
|
1197
|
+
end
|
1198
|
+
end
|
1199
|
+
end
|
1200
|
+
end
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def _gen_symbolvaluespec( struct, label = nil, params = nil )
|
1204
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :eql && struct.has_key?( :val ) )
|
1205
|
+
if params
|
1206
|
+
if params.length == 1
|
1207
|
+
begin_line ""
|
1208
|
+
_gen_notop( struct, nil, nil )
|
1209
|
+
end_line( " #{params[0]} == #{struct[:val].inspect}" )
|
1210
|
+
indent
|
1211
|
+
add_line "return false"
|
1212
|
+
unindent
|
1213
|
+
add_line "end"
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :neql && struct.has_key?( :val ) )
|
1217
|
+
if params
|
1218
|
+
if params.length == 1
|
1219
|
+
begin_line ""
|
1220
|
+
_gen_notop( struct, nil, nil )
|
1221
|
+
end_line( " #{params[0]} != #{struct[:val].inspect}" )
|
1222
|
+
indent
|
1223
|
+
add_line "return false"
|
1224
|
+
unindent
|
1225
|
+
add_line "end"
|
1226
|
+
end
|
1227
|
+
end
|
1228
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :valuelist ) )
|
1229
|
+
if params
|
1230
|
+
if params.length == 1
|
1231
|
+
begin_line ""
|
1232
|
+
_gen_notop( struct, nil, nil )
|
1233
|
+
end_line( " #{struct[:valuelist].inspect}.include?( #{params[0]} )" )
|
1234
|
+
indent
|
1235
|
+
add_line "return false"
|
1236
|
+
unindent
|
1237
|
+
add_line "end"
|
1238
|
+
end
|
1239
|
+
end
|
1240
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :length )
|
1241
|
+
if params
|
1242
|
+
if params.length == 1
|
1243
|
+
add_line "l = #{params[0]}.length"
|
1244
|
+
_gen_minmaxspec( struct, nil, ["l"] )
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :spec ) && struct[:spec] == :regexp && struct.has_key?( :regexp ) && struct.has_key?( :options ) )
|
1248
|
+
if params
|
1249
|
+
if params.length == 1
|
1250
|
+
begin_line ""
|
1251
|
+
_gen_notop( struct, nil, nil )
|
1252
|
+
add " #{params[0]}.match( /#{struct[:regexp]}/"
|
1253
|
+
_gen_regexp_options( struct[:options], nil, nil )
|
1254
|
+
end_line( " )" )
|
1255
|
+
indent
|
1256
|
+
add_line "return false"
|
1257
|
+
unindent
|
1258
|
+
add_line "end"
|
1259
|
+
end
|
1260
|
+
end
|
1261
|
+
end
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
def _gen_minmaxspec( struct, label = nil, params = nil )
|
1265
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :relop ) && struct[:relop] == :eql && struct.has_key?( :val ) )
|
1266
|
+
if params
|
1267
|
+
if params.length == 1
|
1268
|
+
begin_line ""
|
1269
|
+
_gen_notop( struct, nil, nil )
|
1270
|
+
end_line( " #{params[0]} == #{struct[:val]}" )
|
1271
|
+
indent
|
1272
|
+
add_line "return false"
|
1273
|
+
unindent
|
1274
|
+
add_line "end"
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :relop ) && struct[:relop] == :neql && struct.has_key?( :val ) )
|
1278
|
+
if params
|
1279
|
+
if params.length == 1
|
1280
|
+
begin_line ""
|
1281
|
+
_gen_notop( struct, nil, nil )
|
1282
|
+
end_line( " #{params[0]} != #{struct[:val]}" )
|
1283
|
+
indent
|
1284
|
+
add_line "return false"
|
1285
|
+
unindent
|
1286
|
+
add_line "end"
|
1287
|
+
end
|
1288
|
+
end
|
1289
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :minspec ) && struct.has_key?( :maxspec ) && struct.has_key?( :min ) && struct.has_key?( :max ) )
|
1290
|
+
if params
|
1291
|
+
if params.length == 1
|
1292
|
+
begin_line ""
|
1293
|
+
_gen_notop( struct, nil, nil )
|
1294
|
+
add " #{params[0]} "
|
1295
|
+
_gen_relationalop( struct[:minspec], nil, nil )
|
1296
|
+
add " #{struct[:min]} && #{params[0]} "
|
1297
|
+
_gen_relationalop( struct[:maxspec], nil, nil )
|
1298
|
+
end_line( " #{struct[:max]}" )
|
1299
|
+
indent
|
1300
|
+
add_line "return false"
|
1301
|
+
unindent
|
1302
|
+
add_line "end"
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :minspec ) && struct.has_key?( :min ) )
|
1306
|
+
if params
|
1307
|
+
if params.length == 1
|
1308
|
+
begin_line ""
|
1309
|
+
_gen_notop( struct, nil, nil )
|
1310
|
+
add " #{params[0]} "
|
1311
|
+
_gen_relationalop( struct[:minspec], nil, nil )
|
1312
|
+
end_line( " #{struct[:min]}" )
|
1313
|
+
indent
|
1314
|
+
add_line "return false"
|
1315
|
+
unindent
|
1316
|
+
add_line "end"
|
1317
|
+
end
|
1318
|
+
end
|
1319
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :maxspec ) && struct.has_key?( :max ) )
|
1320
|
+
if params
|
1321
|
+
if params.length == 1
|
1322
|
+
begin_line ""
|
1323
|
+
_gen_notop( struct, nil, nil )
|
1324
|
+
add " #{params[0]} "
|
1325
|
+
_gen_relationalop( struct[:maxspec], nil, nil )
|
1326
|
+
end_line( " #{struct[:max]}" )
|
1327
|
+
indent
|
1328
|
+
add_line "return false"
|
1329
|
+
unindent
|
1330
|
+
add_line "end"
|
1331
|
+
end
|
1332
|
+
end
|
1333
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :min ) && struct.has_key?( :max ) )
|
1334
|
+
if params
|
1335
|
+
if params.length == 1
|
1336
|
+
begin_line ""
|
1337
|
+
_gen_notop( struct, nil, nil )
|
1338
|
+
end_line( " #{params[0]} >= #{struct[:min]} && #{params[0]} <= #{struct[:max]}" )
|
1339
|
+
indent
|
1340
|
+
add_line "return false"
|
1341
|
+
unindent
|
1342
|
+
add_line "end"
|
1343
|
+
end
|
1344
|
+
end
|
1345
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :min ) )
|
1346
|
+
if params
|
1347
|
+
if params.length == 1
|
1348
|
+
begin_line ""
|
1349
|
+
_gen_notop( struct, nil, nil )
|
1350
|
+
end_line( " #{params[0]} >= #{struct[:min]}" )
|
1351
|
+
indent
|
1352
|
+
add_line "return false"
|
1353
|
+
unindent
|
1354
|
+
add_line "end"
|
1355
|
+
end
|
1356
|
+
end
|
1357
|
+
elsif ( struct.is_a?( Hash ) && struct.has_key?( :max ) )
|
1358
|
+
if params
|
1359
|
+
if params.length == 1
|
1360
|
+
begin_line ""
|
1361
|
+
_gen_notop( struct, nil, nil )
|
1362
|
+
end_line( " #{params[0]} <= #{struct[:max]}" )
|
1363
|
+
indent
|
1364
|
+
add_line "return false"
|
1365
|
+
unindent
|
1366
|
+
add_line "end"
|
1367
|
+
end
|
1368
|
+
end
|
1369
|
+
end
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
def _gen_notop( struct, label = nil, params = nil )
|
1373
|
+
if ( struct.is_a?( Hash ) && struct.has_key?( :notop ) && struct[:notop] == :notop )
|
1374
|
+
if label
|
1375
|
+
case label
|
1376
|
+
when "boolop"
|
1377
|
+
add "! "
|
1378
|
+
end
|
1379
|
+
else
|
1380
|
+
unless label || params
|
1381
|
+
add "if"
|
1382
|
+
end
|
1383
|
+
end
|
1384
|
+
elsif true
|
1385
|
+
if label
|
1386
|
+
case label
|
1387
|
+
when "boolop"
|
1388
|
+
add ""
|
1389
|
+
end
|
1390
|
+
else
|
1391
|
+
unless label || params
|
1392
|
+
add "unless"
|
1393
|
+
end
|
1394
|
+
end
|
1395
|
+
end
|
1396
|
+
end
|
1397
|
+
|
1398
|
+
def _gen_relationalop( struct, label = nil, params = nil )
|
1399
|
+
if ( struct.is_a?( Symbol ) && struct == :gt )
|
1400
|
+
unless label || params
|
1401
|
+
add ">"
|
1402
|
+
end
|
1403
|
+
elsif ( struct.is_a?( Symbol ) && struct == :gte )
|
1404
|
+
unless label || params
|
1405
|
+
add ">="
|
1406
|
+
end
|
1407
|
+
elsif ( struct.is_a?( Symbol ) && struct == :lt )
|
1408
|
+
unless label || params
|
1409
|
+
add "<"
|
1410
|
+
end
|
1411
|
+
elsif ( struct.is_a?( Symbol ) && struct == :lte )
|
1412
|
+
unless label || params
|
1413
|
+
add "<="
|
1414
|
+
end
|
1415
|
+
end
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
end
|