gds-data-validation 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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