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.
@@ -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
@@ -0,0 +1,5 @@
1
+ # CHANGELOG
2
+
3
+ ### 0.1.0 - (2019-07-11)
4
+
5
+ * Initial release
@@ -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.
@@ -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.
@@ -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