source: ruby/trunk/lib/adl_parser/lib/parser.y

Last change on this file was 329, checked in by Tatsukawa, Akimichi, 15 years ago

commit after MOSS 9

File size: 48.3 KB
RevLine 
[4]1
[307]2class OpenEhr::ADL::Parser
[4]3
4#options omit_action_call
5
6prechigh
7
8 nonassoc UMINUS UPLUS
9 left '*' '/'
10 left '+' '-'
11
12 nonassoc SYM_EQ
13 nonassoc SYM_NE
14 nonassoc SYM_LT
15 nonassoc SYM_START_DBLOCK
16 nonassoc SYM_START_CBLOCK
17 nonassoc SYM_GT
18 nonassoc SYM_END_CBLOCK
19 nonassoc SYM_END_DBLOCK
20 nonassoc SYM_LE
21 nonassoc SYM_GE
22
23preclow
24
25
26rule
27### http://svn.openehr.org/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/adl/parser/adl_validator.y
28
29input: archetype EOF
[21]30 {
31 result = val[0]
32 }
[4]33 | error
34
[21]35archetype: arch_identification arch_specialisation arch_concept arch_language arch_description arch_definition arch_invariant arch_ontology
36 {
[22]37 assert_at(__FILE__,__LINE__) do
[318]38 val[4].instance_of?(OpenEhr::AM::Archetype::Archetype_Description::ARCHETYPE_DESCRIPTION) and val[5].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT) and val[7].instance_of?(OpenEhr::AM::Archetype::Ontology::ARCHETYPE_ONTOLOGY)
[22]39 end
40
[26]41 archetype_id = val[0][:archetype_id]
[257]42 parent_archtype_id = val[1][:parent_archtype_id] if val[1]
[26]43 adl_version = val[0][:arch_head][:arch_meta_data][:adl_version]
[307]44 concept = val[2][:arch_concept]
[26]45 language = val[3][:arch_language]
[307]46 archetype = OpenEhr::AM::Archetype::ARCHETYPE.create(
[26]47 :archetype_id => archetype_id,
[257]48 :parent_archtype_id => parent_archtype_id,
[26]49 :adl_version => adl_version,
50 :concept => concept,
51 :description => val[4],
52 :definition => val[5],
53 :ontology => val[7]
54 ) do |archetype|
55 archetype.original_language = language
56 end
[283]57 @@logger.debug("#{__FILE__}:#{__LINE__}: archetype = #{archetype.to_yaml} at #{@filename}:#{@lineno}")
[26]58 result = archetype
[21]59 }
[4]60
61
62arch_identification: arch_head V_ARCHETYPE_ID
[24]63 {
64 result = {:arch_head => val[0], :archetype_id => val[1] }
65 }
[4]66 | SYM_ARCHETYPE error
[24]67 {
68 raise
69 }
[4]70
71arch_head: SYM_ARCHETYPE
[24]72 {
73 result = {:arch_meta_data => nil }
74 }
[4]75 | SYM_ARCHETYPE arch_meta_data
[24]76 {
[26]77 result = val[1]
[24]78 }
[4]79
80arch_meta_data: Left_parenthesis_code arch_meta_data_items Right_parenthesis_code
[24]81 {
[26]82 result = {:arch_meta_data => val[1] }
[24]83 }
[4]84
85arch_meta_data_items: arch_meta_data_item
[24]86 {
[26]87 result = val[0]
[24]88 }
[19]89 | arch_meta_data_items Semicolon_code arch_meta_data_item
[24]90 {
[26]91 result = val[0].merge(val[2])
[24]92 }
[4]93
[24]94
[4]95arch_meta_data_item: SYM_ADL_VERSION SYM_EQ V_VERSION_STRING
[24]96 {
[26]97 result = {:adl_version => val[2], :is_controlled => false }
[24]98 }
[4]99 | SYM_IS_CONTROLLED
[24]100 {
[26]101 result = {:is_controlled => true }
[24]102 }
[4]103
104# Define specialization in which its constraints are narrower than those of the parent.
105# Any data created via the use of the specialized archetype shall be conformant both to it and its parent.
106arch_specialisation: #-- empty is ok
107 | SYM_SPECIALIZE V_ARCHETYPE_ID
[257]108 {
109 result = {:parent_archtype_id => val[1]}
110 }
[4]111 | SYM_SPECIALIZE error
112
113arch_concept: SYM_CONCEPT V_LOCAL_TERM_CODE_REF
[26]114 {
115 result = {:arch_concept => val[1] }
116 }
[4]117 | SYM_CONCEPT error
118
119#arch_language: #-- empty is ok for ADL 1.4 tools
120# | SYM_LANGUAGE V_DADL_TEXT
121# | SYM_LANGUAGE error
122
123arch_language: #-- empty is ok for ADL 1.4 tools
[26]124 {
[326]125 result = {:arch_language => ""}
[26]126 }
[4]127 | SYM_LANGUAGE dadl_section
[16]128 {
[328]129 dadl_section = val[1]
130 @@logger.debug("#{__FILE__}:#{__LINE__}: arch_language::dadl_section = \n#{dadl_section.to_yaml}")
131 case dadl_section[:attr_id]
132 when "translations"
133 result = {:arch_language => dadl_section[:object_block][:untyped_primitive_object_block]}
134 when "original_language"
135 result = {:arch_language => dadl_section[:object_block][:untyped_primitive_object_block]}
136### if val[1][:attr_id] == "original_language"
137### result = {:arch_language => val[0][:object_block][:untyped_primitive_object_block]}
[326]138 else
[328]139 raise OpenEhr::ADL::Exception::Parser::Error, "It should be 'original_language, but was #{dadl_section[:attr_id]}' at #{@filename}:#{@lineno} "
[326]140 end
[16]141 }
142 | SYM_LANGUAGE error
[4]143
144#arch_description: #-- no meta-data ok
145# | SYM_DESCRIPTION V_DADL_TEXT
146# | SYM_DESCRIPTION error
147
148arch_description: #-- no meta-data ok
149 | SYM_DESCRIPTION dadl_section
[21]150 {
[329]151 dadl_section = val[1]
[326]152 args = Hash.new
[329]153 @@logger.debug("#{__FILE__}:#{__LINE__}: arch_description: val[1].class = \n#{val[1].class} at #{@filename}:#{@lineno}")
154# val[1].each do |item|
155# @@logger.debug("#{__FILE__}:#{__LINE__}: arch_description: item = \n#{item.to_yaml} at #{@filename}:#{@lineno}")
156# case item[:attr_id]
157 case dadl_section[:attr_id]
[326]158 when "original_author"
[329]159# unless item[:object_block][:type_identifier]
160 unless dadl_section[:object_block][:type_identifier]
161# args.merge!(Hash[:original_author => item[:untyped_multiple_attr_object_block]])
162 args.merge!(Hash[:original_author => dadl_section[:untyped_multiple_attr_object_block]])
[326]163 else
164 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
165 end
166 when "details"
[329]167# unless item[:type_identifier]
168 unless dadl_section[:type_identifier]
169# args.merge!(Hash[:details => item[:untyped_multiple_attr_object_block]])
[328]170 #args.merge!(Hash[:details => item[:object_block]])
[329]171 args.merge!(Hash[:details => dadl_section[:untyped_multiple_attr_object_block]])
[326]172 else
173 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
174 end
175 when "lifecycle_state"
[329]176# unless item[:type_identifier]
177 unless dadl_section[:type_identifier]
178# args.merge!(Hash[:lifecycle_state => item[:untyped_primitive_object_block]])
179 args.merge!(Hash[:lifecycle_state => dadl_section[:untyped_primitive_object_block]])
[326]180 else
181 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
182 end
183 when "other_contributors"
[329]184# unless item[:type_identifier]
185 unless dadl_section[:type_identifier]
186# args.merge!(Hash[:other_contributors => item[:untyped_multiple_attr_object_block]])
187 args.merge!(Hash[:other_contributors => dadl_section[:untyped_multiple_attr_object_block]])
[326]188 else
189 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
190 end
191 when "other_details"
[329]192# unless item[:type_identifier]
193 unless dadl_section[:type_identifier]
194# args.merge!(Hash[:other_contributors => item[:untyped_multiple_attr_object_block]])
195 args.merge!(Hash[:other_contributors => dadl_section[:untyped_multiple_attr_object_block]])
[326]196 else
197 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
198 end
199 else
[329]200# raise OpenEhr::ADL::Exception::Parser::Error, "Unknown case #{item} at #{@filename}:#{@lineno} "
201 raise OpenEhr::ADL::Exception::Parser::Error, "Unknown case #{dadl_section} at #{@filename}:#{@lineno} "
[326]202 end
[329]203# end
[326]204 @@logger.debug("#{__FILE__}:#{__LINE__}: arch_description: args = \n#{args.to_yaml} at #{@filename}:#{@lineno}")
205 result = OpenEhr::AM::Archetype::Archetype_Description::ARCHETYPE_DESCRIPTION.new(args)
[21]206 }
207 | SYM_DESCRIPTION error
208
[4]209#arch_definition: SYM_DEFINITION V_CADL_TEXT
210# | SYM_DEFINITION error
211arch_definition: SYM_DEFINITION cadl_section
[21]212 {
213 result = val[1]
214 }
[4]215 | SYM_DEFINITION error
216
217
218### cADL section
219cadl_section: c_complex_object
[35]220 {
[318]221 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT)}
[261]222 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object = #{val[0]} at #{@filename}:#{@lineno}")
[21]223 result = val[0]
224 }
[4]225 | assertions
[23]226 {
227 result = val[0]
228 }
[4]229# | error
230
[321]231### c_complex_object: c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body SYM_END_CBLOCK
232# | c_complx_object_head SYM_MATCHES Slash_code REGEXP_BODY Slash_code # added by akimichi
233c_complex_object: c_complx_object_head SYM_MATCHES REGEXP_HEAD REGEXP_BODY # added by akimichi
234 {
235 @@logger.debug("#{__FILE__}:#{__LINE__}:c_complx_object = \n c_complx_object_head = #{val[0].to_yaml}")
[318]236 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
[23]237 c_complex_object.node_id = val[0][:c_complex_object_id][:local_term_code_ref]
238 c_complex_object.rm_type_name = val[0][:c_complex_object_id][:type_identifier]
239 c_complex_object.occurrences = val[0][:c_occurrences]
240 end
[21]241 }
[321]242#c_complex_object: c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body SYM_END_CBLOCK
243 | c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body SYM_END_CBLOCK
[21]244 {
[318]245 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
[23]246 c_complex_object.node_id = val[0][:c_complex_object_id][:local_term_code_ref]
247 c_complex_object.rm_type_name = val[0][:c_complex_object_id][:type_identifier]
248 c_complex_object.occurrences = val[0][:c_occurrences]
249 end
[21]250 }
[321]251
[21]252# | c_complex_object_head error SYM_END_CBLOCK
[4]253# | c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body c_invariants SYM_END_CBLOCK
254
255c_complex_object_head: c_complex_object_id c_occurrences
[23]256 {
[321]257 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object_head: c_complex_object_id => #{val[0]}, c_occurrences => #{val[1]}")
[23]258 result = {:c_complex_object_id => val[0], :c_occurrences => val[1]}
259 }
[4]260
261c_complex_object_id: type_identifier
[16]262 {
[23]263 result = {:type_identifier => val[0]}
[16]264 }
[4]265 | type_identifier V_LOCAL_TERM_CODE_REF
[16]266 {
[23]267 result = {:type_identifier => val[0], :local_term_code_ref => val[1]}
[16]268 }
[4]269
270c_complex_object_body: c_any #-- used to indicate that any value of a type is ok
271 | c_attributes
[22]272 {
[318]273 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.new(:attributes => val[0])
[22]274 }
[4]275
276
277#------------------------- node types -----------------------
[261]278### http://www.openehr.org/svn/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/cadl/parser/cadl_validator.html
279### c_object: c_complex_object
280### | archetype_internal_ref
281### | archetype_slot
282### | constraint_ref
283### | c_code_phrase
284### | c_ordinal
285### | c_primitive_object
286### | V_C_DOMAIN_TYPE
287### | ERR_C_DOMAIN_TYPE
288### | error
289c_object: c_complex_object
[32]290 {
[261]291 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object = #{val[0].inspect} at #{@filename}:#{@lineno}")
[22]292 result = val[0]
293 }
[4]294 | archetype_internal_ref
[32]295 {
[318]296 result = OpenEhr::AM::Archetype::ConstraintModel::ARCHETYPE_INTERNAL_REF.create do |archetype_internal_ref|
[32]297 archetype_internal_ref.target_path = val[0][:absolute_path]
298 archetype_internal_ref.rm_type_name = val[0][:type_identifier]
299 archetype_internal_ref.occurrences = val[0][:c_occurrences]
300 end
[22]301 }
[4]302 | archetype_slot
[32]303 {
304 result = val[0]
[22]305 }
[4]306 | constraint_ref
[32]307 {
[318]308 result = OpenEhr::AM::Archetype::ConstraintModel::CONSTRAINT_REF.create do |constraint_ref|
[32]309 constraint_ref.reference = val[0]
310 end
[22]311 }
[4]312 | c_code_phrase
[32]313 {
[22]314 result = val[0]
315 }
[4]316 | c_ordinal
[32]317 {
[22]318 result = val[0]
319 }
[4]320 | c_primitive_object
[32]321 {
[22]322 result = val[0]
323 }
[261]324 | v_c_domain_type
325 {
326 result = val[0]
327 }
[19]328# | v_c_domain_type
[14]329# | V_C_DOMAIN_TYPE
330 # this is an attempt to match a dADL section inside cADL. It will
331 # probably never work 100% properly since there can be '>' inside "||"
332 # ranges, and also strings containing any character, e.g. units string
333 # contining "{}" chars. The real solution is to use the dADL parser on
334 # the buffer from the current point on and be able to fast-forward the
335 # cursor to the last character matched by the dADL scanner
[307]336### ----------/* V_C_DOMAIN_TYPE - sections of dADL syntax */ ------------------------------------------------- ----------/* V_C_DOMAIN_TYPE - sections of dADL syntax */ -------------------------------------------------
337
338
339### [A-Z][a-zA-Z0-9_]*[ \n]*< { -- match a pattern like 'Type_Identifier whitespace <' [A-Z][a-zA-Z0-9_]*[ \n]*< { -- match a pattern like 'Type_Identifier whitespace <'
340### set_start_condition (IN_C_DOMAIN_TYPE) set_start_condition (IN_C_DOMAIN_TYPE)
341### } }
342
343### <IN_C_DOMAIN_TYPE>[^}>]*>[ \n]*[^>}A-Z] { -- match up to next > not followed by a '}' or '>' <IN_C_DOMAIN_TYPE>[^}>]*>[ \n]*[^>}A-Z] { -- match up to next > not followed by a '}' or '>'
344### in_buffer.append_string (text) in_buffer.append_string (text)
345### } }
346
347### <IN_C_DOMAIN_TYPE>[^}>]*>+[ \n]*[}A-Z] { -- final section - '...> whitespace } or beginning of a type identifier' <IN_C_DOMAIN_TYPE>[^}>]*>+[ \n]*[}A-Z] { -- final section - '...> whitespace } or beginning of a type identifier'
348
349### <IN_C_DOMAIN_TYPE>[^}>]*[ \n]*} { -- match up to next '}' not preceded by a '>' <IN_C_DOMAIN_TYPE>[^}>]*[ \n]*} { -- match up to next '}' not preceded by a '>'
350### in_buffer.append_string (text) in_buffer.append_string (text)
351### } }
352
353
[4]354 | ERR_C_DOMAIN_TYPE
355 | error
356
[16]357v_c_domain_type: START_V_C_DOMAIN_TYPE_BLOCK dadl_section END_V_C_DOMAIN_TYPE_BLOCK
[23]358 {
359 result = val[1]
360 }
[14]361
[4]362# 'archetype_internal_ref' is a node that refers to a previously defined object node in the same archetype.
363archetype_internal_ref: SYM_USE_NODE type_identifier c_occurrences absolute_path
[32]364 {
365 result = {:type_identifier => val[1], :c_occurrences => val[2], :absolute_path => val[3] }
366 }
[4]367 | SYM_USE_NODE type_identifier error
368
369# 'archetype_slot' is a node whose statements define a constraint that determines which other archetypes may appear at that point in the current archetype.
370archetype_slot: c_archetype_slot_head SYM_MATCHES SYM_START_CBLOCK c_includes c_excludes SYM_END_CBLOCK
[32]371 {
[318]372 result = OpenEhr::AM::Archetype::ConstraintModel::ARCHETYPE_SLOT.create do |archetype_slot|
[32]373 archetype_slot.includes = val[3]
374 archetype_slot.excludes = val[4]
375 archetype_slot.rm_type_name = val[0][:c_archetype_slot_id]
376 archetype_slot.occurrences = val[0][:c_occurrences]
377 end
378 }
[4]379c_archetype_slot_head: c_archetype_slot_id c_occurrences
[32]380 {
381 result = {:c_archetype_slot_id => val[0],:c_occurrences => val[1]}
382 }
[4]383
384c_archetype_slot_id: SYM_ALLOW_ARCHETYPE type_identifier
[32]385 {
386 result = val[1]
387 }
[4]388 | SYM_ALLOW_ARCHETYPE type_identifier V_LOCAL_TERM_CODE_REF
389 | SYM_ALLOW_ARCHETYPE error
390
391# 'c_primitive_object' is an node representing a constraint on a primitive object type.
392c_primitive_object: c_primitive
[22]393 {
[318]394 assert_at(__FILE__,__LINE__){val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_PRIMITIVE)}
395 result = OpenEhr::AM::Archetype::ConstraintModel::C_PRIMITIVE_OBJECT.create do |c_primitive_object|
[32]396 c_primitive_object.item = val[0]
397 end
[22]398 }
[4]399
400c_primitive: c_integer
[21]401 {
[261]402 @@logger.debug("#{__FILE__}:#{__LINE__}: c_integer = #{val[0]} at #{@filename}:#{@lineno}")
[318]403 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_INTEGER.create do |c_integer|
[32]404 c_integer.list
405 c_integer.range
406 c_integer.assumed_value
407 end
[21]408 }
[4]409 | c_real
[22]410 {
[261]411 @@logger.debug("#{__FILE__}:#{__LINE__}: c_real = #{val[0]} at #{@filename}:#{@lineno}")
[318]412 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_REAL.new
[22]413 }
[4]414 | c_date
[22]415 {
[261]416 @@logger.debug("#{__FILE__}:#{__LINE__}: c_date = #{val[0]} at #{@filename}:#{@lineno}")
[318]417 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DATE.new
[22]418 }
[4]419 | c_time
[22]420 {
[261]421 @@logger.debug("#{__FILE__}:#{__LINE__}: c_time = #{val[0]} at #{@filename}:#{@lineno}")
[318]422 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_TIME.new
[22]423 }
[4]424 | c_date_time
[22]425 {
[261]426 @@logger.debug("#{__FILE__}:#{__LINE__}: c_date_time = #{val[0]} at #{@filename}:#{@lineno}")
[318]427 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DATE_TIME.new
[22]428 }
[4]429 | c_duration
[22]430 {
[261]431 @@logger.debug("#{__FILE__}:#{__LINE__}: c_duration = #{val[0]} at #{@filename}:#{@lineno}")
[318]432 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DURATION.new
[22]433 }
[4]434 | c_string
[22]435 {
[261]436 @@logger.debug("#{__FILE__}:#{__LINE__}: c_string = #{val[0]} at #{@filename}:#{@lineno}")
[318]437 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_STRING.new
[22]438 }
[4]439 | c_boolean
[22]440 {
[318]441 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN)}
[261]442 @@logger.debug("#{__FILE__}:#{__LINE__}: c_boolean = #{val[0]} at #{@filename}:#{@lineno}")
[22]443 result = val[0]
444 }
[4]445
446c_any: Star_code
447#c_any: '*'
448
449#---------------- BODY - relationships ----------------
450
451c_attributes: c_attribute
[22]452 {
453 result = [val[0]]
454 }
[4]455 | c_attributes c_attribute
[22]456 {
457 result = (val[0] << val[1])
458 }
[4]459
460# 'c_attribute' is a node representing a constraint on an attribute in an object model.
461c_attribute: c_attr_head SYM_MATCHES SYM_START_CBLOCK c_attr_values SYM_END_CBLOCK
[22]462 {
[321]463 @@logger.debug("#{__FILE__}:#{__LINE__}:c_attribute: #{val[0]} matches #{val[3]}")
[318]464 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
[22]465 c_attribute = val[0]
466 c_attribute.children = val[3]
467 result = c_attribute
468 }
[321]469 | c_attr_head SYM_MATCHES REGEXP_HEAD REGEXP_BODY SYM_END_CBLOCK # added by akimichi
470 {
471 @@logger.debug("c_attribute: #{val[0]} matches #{val[3]}}")
[318]472 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
[22]473 result = val[0]
474 }
[321]475 | c_attr_head SYM_MATCHES REGEXP_HEAD REGEXP_BODY Semicolon_code string_value SYM_END_CBLOCK # added by akimichi
476
477 {
478 @@logger.debug("c_attribute: #{val[0]} matches #{val[5]}}")
479 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
480 result = val[0]
481 }
[4]482 | c_attr_head SYM_MATCHES SYM_START_CBLOCK error SYM_END_CBLOCK
[22]483 {
[318]484 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
[22]485 result = val[0]
486 }
[4]487
488
489c_attr_head: V_ATTRIBUTE_IDENTIFIER c_existence
[19]490 {
[261]491 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]}, c_existence = #{val[1]} at #{@filename}")
[318]492 result = OpenEhr::AM::Archetype::ConstraintModel::C_SINGLE_ATTRIBUTE.new(
[22]493 :rm_attribute_name => val[0],
494 :existence => val[1]
495 )
496
[19]497 }
[4]498 | V_ATTRIBUTE_IDENTIFIER c_existence c_cardinality
[19]499 {
[318]500 assert_at(__FILE__,__LINE__){ val[2].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::CARDINALITY) }
[261]501 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER: #{val[0]}, c_existence = #{val[1]}, c_cardinality = #{val[2]} at #{@filename}")
[318]502 result = OpenEhr::AM::Archetype::ConstraintModel::C_MULTIPLE_ATTRIBUTE.new(
[22]503 :rm_attribute_name => val[0],
504 :existence => val[1],
505 :cardinality => val[2]
506 )
[19]507 }
[4]508
509c_attr_values: c_object
[22]510 {
511 result = Array[val[0]]
512 }
[4]513 | c_attr_values c_object
[22]514 {
515 result = (val[0] << val[1])
516 }
[4]517 | c_any # -- to allow a property to have any value
[22]518 {
519 result = Array[val[0]]
520 }
[4]521
522c_includes: #-- Empty
[321]523 | SYM_INCLUDE assertions
[32]524{
[321]525 @@logger.debug("#{__FILE__}:#{__LINE__}: c_includes: assertions = #{val[1]}")
[32]526 result = val[1]
527}
[321]528### c_includes: #-- Empty
529### | SYM_INCLUDE invariants
[4]530
531c_excludes: #-- Empty
[321]532 | SYM_EXCLUDE assertions
533 {
534 @@logger.debug("#{__FILE__}:#{__LINE__}: c_excludes: assertions = #{val[1]}")
[32]535 result = val[1]
[321]536 }
537### c_excludes: #-- Empty
538### | SYM_EXCLUDE invariants
[4]539
540invariants: invariant
541 | invariants invariant
542
[321]543invariant: any_identifier Colon_code boolean_expression
[4]544 | boolean_expression
[321]545 | any_identifier Colon_code error
[4]546
547arch_invariant: #-- no invariant ok
548 | SYM_INVARIANT V_ASSERTION_TEXT
549 | SYM_INVARIANT error
550
551# define all linguistic entries in this part as dADL.
552#arch_ontology: SYM_ONTOLOGY V_DADL_TEXT
553# | SYM_ONTOLOGY error
554
555arch_ontology: SYM_ONTOLOGY dadl_section
[22]556 {
[26]557 dadl_section = val[1]
[329]558 @@logger.debug("#{__FILE__}:#{__LINE__}: arch_ontology: dadl_section = \n#{dadl_section.to_yaml}")
[328]559 args = Hash.new
[329]560 case dadl_section[:attr_id]
561 when "terminologies_available"
562 unless dadl_section[:object_block][:type_identifier]
563 args.merge!(Hash[:terminologies_available => dadl_section[:object_block][:untyped_primitive_object_block]])
[328]564 else
[329]565 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
[328]566 end
[329]567 when "term_definitions"
568 unless dadl_section[:object_block][:type_identifier]
569 args.merge!(Hash[:term_definitions => dadl_section[:object_block][:untyped_multiple_attr_object_block]])
570 else
571 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
572 end
573 when "term_binding"
574 unless dadl_section[:object_block][:type_identifier]
575 args.merge!(Hash[:term_binding => dadl_section[:object_block][:untyped_multiple_attr_object_block]])
576 else
577 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
578 end
579 else
580 raise OpenEhr::ADL::Exception::Parser::Error, "Unknown case #{dadl_section[:attr_id]} at #{@filename}:#{@lineno} "
[328]581 end
[329]582### dadl_section.each do |item|
583### @@logger.debug("#{__FILE__}:#{__LINE__}: arch_description: item[:object_block] = #{item[:object_block].to_yaml} at #{@filename}:#{@lineno}")
584### case item[:attr_id]
585### when "terminologies_available"
586### unless item[:object_block][:type_identifier]
587### args.merge!(Hash[:terminologies_available => item[:object_block][:untyped_primitive_object_block]])
588### else
589### raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
590### end
591### when "term_definitions"
592### unless item[:object_block][:type_identifier]
593### args.merge!(Hash[:term_definitions => item[:object_block][:untyped_multiple_attr_object_block]])
594### else
595### raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
596### end
597### when "term_binding"
598### unless item[:object_block][:type_identifier]
599### args.merge!(Hash[:term_binding => item[:object_block][:untyped_multiple_attr_object_block]])
600### else
601### raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
602### end
603### else
604### raise OpenEhr::ADL::Exception::Parser::Error, "Unknown case #{item[:attr_id]} at #{@filename}:#{@lineno} "
605### end
606### end
[328]607
608 result = OpenEhr::AM::Archetype::Ontology::ARCHETYPE_ONTOLOGY.new(args)
[22]609 }
[4]610 | SYM_ONTOLOGY error
611
612
613### dADL section
[318]614dadl_section: # no dadl section
615 | attr_vals
[307]616 {
[328]617 @@logger.debug("#{__FILE__}:#{__LINE__}:dadl_section::attr_vals = \n#{val[0].to_yaml}")
[307]618 result = val[0]
619 }
[4]620 | complex_object_block
[307]621 {
[328]622 #@@logger.debug("#{__FILE__}:#{__LINE__}:dadl_section::complex_object_block = \n#{val[0].to_yaml}")
[307]623 result = val[0]
624 }
[4]625# | error
626
627attr_vals: attr_val
[23]628 {
[328]629 attr_val = val[0]
630 result = Hash[attr_val[:attr_id] => attr_val[:object_block]]
[23]631 }
[4]632 | attr_vals attr_val
[23]633 {
[328]634 result = val[0].merge!(val[1])
[23]635 }
[19]636 | attr_vals Semicolon_code attr_val
[23]637 {
[328]638 result = val[0].merge!(val[2])
[23]639 }
[328]640### attr_vals: attr_val
641### {
642### result = Array[val[0]]
643### }
644### | attr_vals attr_val
645### {
646### result = (val[0] << val[1])
647### }
648### | attr_vals Semicolon_code attr_val
649### {
650### result = (val[0] << val[2])
651### }
[4]652
653attr_val: attr_id SYM_EQ object_block
[19]654 {
[328]655 @@logger.debug("#{__FILE__}:#{__LINE__}:attr_val\n attr_id = #{val[0].to_yaml},\n object_block = #{val[2].to_yaml}")
[23]656 result = {:attr_id => val[0], :object_block => val[2]}
[19]657 }
[4]658
659attr_id: V_ATTRIBUTE_IDENTIFIER
[18]660 {
[307]661 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]}")
[22]662 result = val[0]
[18]663 }
[4]664 | V_ATTRIBUTE_IDENTIFIER error
665
666object_block: complex_object_block
[22]667 {
668 result = val[0]
669 }
[4]670 | primitive_object_block
[22]671 {
672 result = val[0]
673 }
[4]674
675complex_object_block: single_attr_object_block
[22]676 {
677 result = val[0]
678 }
[4]679 | multiple_attr_object_block
[22]680 {
681 result = val[0]
682 }
[4]683
684multiple_attr_object_block: untyped_multiple_attr_object_block
[22]685 {
[328]686 @@logger.debug("#{__FILE__}:#{__LINE__}:multiple_attr_object_block::attr_val\n untyped_multiple_attr_object_block = #{val[0].to_yaml}")
[23]687 result = {:untyped_multiple_attr_object_block => val[0]}
[22]688 }
[4]689 | type_identifier untyped_multiple_attr_object_block
[22]690 {
[23]691 result = {:type_identifier => val[0], :untyped_multiple_attr_object_block => val[1]}
[22]692 }
[4]693
694untyped_multiple_attr_object_block: multiple_attr_object_block_head keyed_objects SYM_END_DBLOCK
[22]695 {
[328]696 @@logger.debug("#{__FILE__}:#{__LINE__}:untyped_multiple_attr_object_block::keyed_objects\n keyed_objects = #{val[1].to_yaml}")
[326]697 result = val[1]
[22]698 }
[4]699
700multiple_attr_object_block_head: SYM_START_DBLOCK
[22]701 {
702 result = val[0]
[20]703 }
[4]704
705keyed_objects: keyed_object
[23]706 {
707 result = Array[val[0]]
708 }
[4]709 | keyed_objects keyed_object
[23]710 {
711 result = (val[0] << val[1])
712 }
[4]713
714keyed_object: object_key SYM_EQ object_block
[20]715 {
[326]716 #@@logger.debug("#{__FILE__}:#{__LINE__}: keyed_object = #{val[0]} at #{@filename}:#{@lineno}")
717 #result = {:object_key => val[0], :object_block => val[2]}
[328]718 object_key,object_block = val[0],val[2]
719 unless object_block[:type_identifier]
720 result = Hash[val[0] => object_block[:untyped_primitive_object_block]]
[326]721 else
722 raise OpenEhr::ADL::Exception::Parser::Error, "Missing type_identifier at #{@filename}:#{@lineno} "
723 end
[20]724 }
[4]725
726object_key: Left_bracket_code simple_value Right_bracket_code
[19]727 {
[261]728 @@logger.debug("object_key: [#{val[1]}] at #{@filename}:#{@lineno}")
[22]729 result = val[1]
[19]730 }
[4]731
732single_attr_object_block: untyped_single_attr_object_block
[23]733 {
734 result = {:untyped_single_attr_object_block => val[0]}
735 }
[4]736 | type_identifier untyped_single_attr_object_block
[23]737 {
738 result = {:type_identifier => val[0], :untyped_single_attr_object_block => val[1]}
739 }
740
[257]741untyped_single_attr_object_block: single_attr_object_complex_head SYM_END_DBLOCK # >
[22]742 {
[261]743 @@logger.debug("#{__FILE__}:#{__LINE__}: single_attr_object_complex_head = #{val[0]} at #{@filename}:#{@lineno}")
[326]744 result = []
[22]745 }
[4]746 | single_attr_object_complex_head attr_vals SYM_END_DBLOCK
[22]747 {
[328]748 @@logger.debug("#{__FILE__}:#{__LINE__}: untyped_single_attr_object_block::attr_vals = \n#{val[1].to_yaml} at #{@filename}:#{@lineno}")
[326]749 result = val[1]
[22]750 }
[4]751single_attr_object_complex_head: SYM_START_DBLOCK
[328]752
[4]753primitive_object_block: untyped_primitive_object_block
[22]754 {
[261]755 @@logger.debug("#{__FILE__}:#{__LINE__}: untyped_primitive_object_block = #{val[0]} at #{@filename}:#{@lineno}")
[23]756 result = {:untyped_primitive_object_block => val[0]}
[22]757 }
[4]758 | type_identifier untyped_primitive_object_block
[22]759 {
[261]760 @@logger.debug("#{__FILE__}:#{__LINE__}: type_identifier = #{val[0]}, untyped_primitive_object_block = #{val[1]} at #{@filename}:#{@lineno}")
[23]761 result = {:type_identifier => val[0], :untyped_primitive_object_block => val[1]}
[22]762 }
[4]763untyped_primitive_object_block: SYM_START_DBLOCK primitive_object_value SYM_END_DBLOCK
[20]764 {
[326]765 #@@logger.debug("#{__FILE__}:#{__LINE__}: primitive_object_block = <#{val[1]}> at #{@filename}:#{@lineno}")
[22]766 result = val[1]
[20]767 }
[4]768primitive_object_value: simple_value
[22]769 {
770 result = val[0]
771 }
[4]772 | simple_list_value
[22]773 {
774 result = val[0]
775 }
[4]776 | simple_interval_value
[22]777 {
778 result = val[0]
779 }
[4]780 | term_code
[22]781 {
782 result = val[0]
783 }
[4]784 | term_code_list_value
[22]785 {
786 result = val[0]
787 }
[4]788simple_value: string_value
[19]789 {
[261]790 @@logger.debug("string_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]791 result = val[0]
[19]792 }
[4]793 | integer_value
[19]794 {
[261]795 @@logger.debug("integer_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]796 result = val[0]
[19]797 }
[4]798 | real_value
[19]799 {
[261]800 @@logger.debug("real_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]801 result = val[0]
[19]802 }
[4]803 | boolean_value
[19]804 {
[261]805 @@logger.debug("boolean_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]806 result = val[0]
[19]807 }
[4]808 | character_value
[19]809 {
[261]810 @@logger.debug("character_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]811 result = val[0]
[19]812 }
[4]813 | date_value
[19]814 {
[261]815 @@logger.debug("date_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]816 result = val[0]
[19]817 }
[4]818 | time_value
[19]819 {
[261]820 @@logger.debug("time_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]821 result = val[0]
[19]822 }
[4]823 | date_time_value
[19]824 {
[261]825 @@logger.debug("date_time_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]826 result = val[0]
[19]827 }
[4]828 | duration_value
[19]829 {
[261]830 @@logger.debug("duration_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]831 result = val[0]
[19]832 }
[4]833 | uri_value
[19]834 {
[261]835 @@logger.debug("uri_value: #{val[0]} at #{@filename}:#{@lineno}")
[22]836 result = val[0]
[19]837 }
[22]838
[4]839simple_list_value: string_list_value
[317]840 {
841 @@logger.debug("string_list_value: #{val[0]} at #{@filename}:#{@lineno}")
842 result = val[0]
843 }
[4]844 | integer_list_value
[317]845 {
846 result = val[0]
847 }
[4]848 | real_list_value
[317]849 {
850 result = val[0]
851 }
[4]852 | boolean_list_value
[317]853 {
854 result = val[0]
855 }
[4]856 | character_list_value
[317]857 {
858 result = val[0]
859 }
[4]860 | date_list_value
[317]861 {
862 result = val[0]
863 }
[4]864 | time_list_value
[317]865 {
866 result = val[0]
867 }
[4]868 | date_time_list_value
[317]869 {
870 result = val[0]
871 }
[4]872 | duration_list_value
[317]873 {
874 result = val[0]
875 }
[4]876
877simple_interval_value: integer_interval_value
878 | real_interval_value
879 | date_interval_value
880 | time_interval_value
881 | date_time_interval_value
882 | duration_interval_value
883
884type_identifier: V_TYPE_IDENTIFIER
[19]885 {
[261]886 @@logger.debug("V_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
[22]887 result = val[0]
[19]888 }
[4]889 | V_GENERIC_TYPE_IDENTIFIER
[19]890 {
[261]891 @@logger.debug("V_GENERIC_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
[22]892 result = val[0]
[19]893 }
[4]894
895string_value: V_STRING
[18]896 {
[261]897 @@logger.debug("V_STRING: #{val[0]} at #{@filename}:#{@lineno}")
[22]898 result = val[0]
[18]899 }
[4]900
901string_list_value: V_STRING Comma_code V_STRING
[317]902 {
903 result = [val[0],val[2]]
904 }
[4]905 | string_list_value Comma_code V_STRING
[317]906 {
907 result = val[0] << val[2]
908 }
[4]909 | V_STRING Comma_code SYM_LIST_CONTINUE
[317]910 {
911 result = val[0]
912 }
[4]913
914integer_value: V_INTEGER
[22]915 {
916 begin
917 integer = Integer(val[0])
918 rescue
919 raise
920 end
921 result = integer
922 }
[18]923 | Plus_code V_INTEGER
[22]924 {
925 begin
926 integer = Integer(val[0])
927 rescue
928 raise
929 end
930 result = integer
931 }
[18]932 | Minus_code V_INTEGER
[22]933 {
934 begin
935 integer = Integer(val[0])
936 rescue
937 raise
938 end
939 result = - integer
940 }
[4]941
942integer_list_value: integer_value Comma_code integer_value
943 | integer_list_value Comma_code integer_value
944 | integer_value Comma_code SYM_LIST_CONTINUE
945
946integer_interval_value: SYM_INTERVAL_DELIM integer_value SYM_ELLIPSIS integer_value SYM_INTERVAL_DELIM
947 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_ELLIPSIS integer_value SYM_INTERVAL_DELIM
948 | SYM_INTERVAL_DELIM integer_value SYM_ELLIPSIS SYM_LT integer_value SYM_INTERVAL_DELIM
949 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_ELLIPSIS SYM_LT integer_value SYM_INTERVAL_DELIM
950 | SYM_INTERVAL_DELIM SYM_LT integer_value SYM_INTERVAL_DELIM
951 | SYM_INTERVAL_DELIM SYM_LE integer_value SYM_INTERVAL_DELIM
952 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_INTERVAL_DELIM
953 | SYM_INTERVAL_DELIM SYM_GE integer_value SYM_INTERVAL_DELIM
954 | SYM_INTERVAL_DELIM integer_value SYM_INTERVAL_DELIM
955
956real_value: V_REAL
[23]957 {
958 begin
959 real = Float(val[0])
960 rescue
961 raise
962 end
963 result = real
964 }
[18]965 | Plus_code V_REAL
[23]966 {
967 begin
[25]968 real = Float(val[1])
[23]969 rescue
970 raise
971 end
972 result = real
973 }
[18]974 | Minus_code V_REAL
[23]975 {
976 begin
[25]977 real = Float(val[1])
[23]978 rescue
979 raise
980 end
981 result = - real
982 }
[4]983
984real_list_value: real_value Comma_code real_value
985 | real_list_value Comma_code real_value
986 | real_value Comma_code SYM_LIST_CONTINUE
987
988real_interval_value: SYM_INTERVAL_DELIM real_value SYM_ELLIPSIS real_value SYM_INTERVAL_DELIM
989 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_ELLIPSIS real_value SYM_INTERVAL_DELIM
990 | SYM_INTERVAL_DELIM real_value SYM_ELLIPSIS SYM_LT real_value SYM_INTERVAL_DELIM
991 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_ELLIPSIS SYM_LT real_value SYM_INTERVAL_DELIM
992 | SYM_INTERVAL_DELIM SYM_LT real_value SYM_INTERVAL_DELIM
993 | SYM_INTERVAL_DELIM SYM_LE real_value SYM_INTERVAL_DELIM
994 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_INTERVAL_DELIM
995 | SYM_INTERVAL_DELIM SYM_GE real_value SYM_INTERVAL_DELIM
996 | SYM_INTERVAL_DELIM real_value SYM_INTERVAL_DELIM
997
998
999boolean_value: SYM_TRUE
[23]1000 {
1001 result = true
1002 }
[4]1003 | SYM_FALSE
[23]1004 {
1005 result = false
1006 }
[4]1007
1008boolean_list_value: boolean_value Comma_code boolean_value
1009 | boolean_list_value Comma_code boolean_value
1010 | boolean_value Comma_code SYM_LIST_CONTINUE
1011
1012character_value: V_CHARACTER
1013
1014character_list_value: character_value Comma_code character_value
1015 | character_list_value Comma_code character_value
1016 | character_value Comma_code SYM_LIST_CONTINUE
1017
1018date_value: V_ISO8601_EXTENDED_DATE
[283]1019 {
1020 result = val[0]
1021 }
[4]1022
1023date_list_value: date_value Comma_code date_value
1024 | date_list_value Comma_code date_value
1025 | date_value Comma_code SYM_LIST_CONTINUE
1026
1027date_interval_value: SYM_INTERVAL_DELIM date_value SYM_ELLIPSIS date_value SYM_INTERVAL_DELIM
1028 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_ELLIPSIS date_value SYM_INTERVAL_DELIM
1029 | SYM_INTERVAL_DELIM date_value SYM_ELLIPSIS SYM_LT date_value SYM_INTERVAL_DELIM
1030 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_ELLIPSIS SYM_LT date_value SYM_INTERVAL_DELIM
1031 | SYM_INTERVAL_DELIM SYM_LT date_value SYM_INTERVAL_DELIM
1032 | SYM_INTERVAL_DELIM SYM_LE date_value SYM_INTERVAL_DELIM
1033 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_INTERVAL_DELIM
1034 | SYM_INTERVAL_DELIM SYM_GE date_value SYM_INTERVAL_DELIM
1035 | SYM_INTERVAL_DELIM date_value SYM_INTERVAL_DELIM
1036
1037time_value: V_ISO8601_EXTENDED_TIME
1038
1039time_list_value: time_value Comma_code time_value
1040 | time_list_value Comma_code time_value
1041 | time_value Comma_code SYM_LIST_CONTINUE
1042
1043time_interval_value: SYM_INTERVAL_DELIM time_value SYM_ELLIPSIS time_value SYM_INTERVAL_DELIM
1044 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_ELLIPSIS time_value SYM_INTERVAL_DELIM
1045 | SYM_INTERVAL_DELIM time_value SYM_ELLIPSIS SYM_LT time_value SYM_INTERVAL_DELIM
1046 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_ELLIPSIS SYM_LT time_value SYM_INTERVAL_DELIM
1047 | SYM_INTERVAL_DELIM SYM_LT time_value SYM_INTERVAL_DELIM
1048 | SYM_INTERVAL_DELIM SYM_LE time_value SYM_INTERVAL_DELIM
1049 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_INTERVAL_DELIM
1050 | SYM_INTERVAL_DELIM SYM_GE time_value SYM_INTERVAL_DELIM
1051 | SYM_INTERVAL_DELIM time_value SYM_INTERVAL_DELIM
1052
1053date_time_value: V_ISO8601_EXTENDED_DATE_TIME
[320]1054 {
1055 @@logger.debug("V_ISO8601_EXTENDED_DATE_TIME: #{val[0]} at #{@filename}:#{@lineno}")
1056 result = val[0]
1057 }
[4]1058
1059date_time_list_value: date_time_value Comma_code date_time_value
1060 | date_time_list_value Comma_code date_time_value
1061 | date_time_value Comma_code SYM_LIST_CONTINUE
1062
1063date_time_interval_value: SYM_INTERVAL_DELIM date_time_value SYM_ELLIPSIS date_time_value SYM_INTERVAL_DELIM
1064 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_ELLIPSIS date_time_value SYM_INTERVAL_DELIM
1065 | SYM_INTERVAL_DELIM date_time_value SYM_ELLIPSIS SYM_LT date_time_value SYM_INTERVAL_DELIM
1066 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_ELLIPSIS SYM_LT date_time_value SYM_INTERVAL_DELIM
1067 | SYM_INTERVAL_DELIM SYM_LT date_time_value SYM_INTERVAL_DELIM
1068 | SYM_INTERVAL_DELIM SYM_LE date_time_value SYM_INTERVAL_DELIM
1069 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_INTERVAL_DELIM
1070 | SYM_INTERVAL_DELIM SYM_GE date_time_value SYM_INTERVAL_DELIM
1071 | SYM_INTERVAL_DELIM date_time_value SYM_INTERVAL_DELIM
1072
1073duration_value: V_ISO8601_DURATION
[19]1074 {
[261]1075 @@logger.debug("V_ISO8601_DURATION: #{val[0]} at #{@filename}:#{@lineno}")
[22]1076 result = val[0]
[19]1077 }
[4]1078
1079duration_list_value: duration_value Comma_code duration_value
1080 | duration_list_value Comma_code duration_value
1081 | duration_value Comma_code SYM_LIST_CONTINUE
1082
1083duration_interval_value: SYM_INTERVAL_DELIM duration_value SYM_ELLIPSIS duration_value SYM_INTERVAL_DELIM
1084 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_ELLIPSIS duration_value SYM_INTERVAL_DELIM
1085 | SYM_INTERVAL_DELIM duration_value SYM_ELLIPSIS SYM_LT duration_value SYM_INTERVAL_DELIM
1086 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_ELLIPSIS SYM_LT duration_value SYM_INTERVAL_DELIM
1087 | SYM_INTERVAL_DELIM SYM_LT duration_value SYM_INTERVAL_DELIM
1088 | SYM_INTERVAL_DELIM SYM_LE duration_value SYM_INTERVAL_DELIM
1089 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_INTERVAL_DELIM
1090 | SYM_INTERVAL_DELIM SYM_GE duration_value SYM_INTERVAL_DELIM
1091 | SYM_INTERVAL_DELIM duration_value SYM_INTERVAL_DELIM
1092
1093term_code: V_QUALIFIED_TERM_CODE_REF
[20]1094 {
[261]1095 @@logger.debug("#{__FILE__}:#{__LINE__}: V_QUALIFIED_TERM_CODE_REF = #{val[0]} at #{@filename}:#{@lineno}")
[26]1096 result = val[0]
[20]1097 }
[4]1098
1099term_code_list_value: term_code Comma_code term_code
1100 | term_code_list_value Comma_code term_code
1101 | term_code Comma_code SYM_LIST_CONTINUE
1102
1103uri_value: V_URI
[20]1104 {
[261]1105 @@logger.debug("#{__FILE__}:#{__LINE__}: V_URI = #{val[0]} at #{@filename}:#{@lineno}")
[26]1106 result = val[0]
[20]1107 }
[4]1108
1109
1110#---------------------- ASSERTIONS ------------------------
1111
1112assertions: assertion
1113 | assertions assertion
1114
[321]1115assertion: any_identifier Colon_code boolean_expression
[4]1116 | boolean_expression
[321]1117 | any_identifier Colon_code error
[4]1118
1119#---------------------- expressions ---------------------
1120
1121boolean_expression: boolean_leaf
1122 | boolean_node
1123
1124boolean_node: SYM_EXISTS absolute_path
[321]1125# | SYM_EXISTS error
1126 | relative_path SYM_MATCHES REGEXP_HEAD REGEXP_BODY SYM_END_CBLOCK# added by akimichi
1127 {
1128 @@logger.debug("#{__FILE__}:#{__LINE__}, boolean_node: relative_path = #{val[0]}, regexp_body => #{val[3]} at #{@filename}")
1129 result = {:relative_path => val[0], :regexp_body => val[3]}
1130 }
[4]1131 | relative_path SYM_MATCHES SYM_START_CBLOCK c_primitive SYM_END_CBLOCK
[321]1132# | relative_path SYM_MATCHES SYM_START_CBLOCK Slash_code REGEXP_BODY Slash_code SYM_END_CBLOCK# added by akimichi
[4]1133 | SYM_NOT boolean_leaf
[321]1134 | arithmetic_expression Equal_code arithmetic_expression
[4]1135 | arithmetic_expression SYM_NE arithmetic_expression
1136 | arithmetic_expression SYM_LT arithmetic_expression
1137 | arithmetic_expression SYM_GT arithmetic_expression
1138 | arithmetic_expression SYM_LE arithmetic_expression
1139 | arithmetic_expression SYM_GE arithmetic_expression
1140 | boolean_expression SYM_AND boolean_expression
1141 | boolean_expression SYM_OR boolean_expression
1142 | boolean_expression SYM_XOR boolean_expression
1143 | boolean_expression SYM_IMPLIES boolean_expression
1144
1145boolean_leaf: Left_parenthesis_code boolean_expression Right_parenthesis_code
1146 | SYM_TRUE
1147 | SYM_FALSE
1148
[323]1149arithmetic_node: arithmetic_expression Plus_code arithmetic_leaf
[321]1150 | arithmetic_expression Minus_code arithmetic_leaf
[4]1151 | arithmetic_expression Star_code arithmetic_leaf
1152 | arithmetic_expression Slash_code arithmetic_leaf
[321]1153 | arithmetic_expression Caret_code arithmetic_leaf
[4]1154
1155arithmetic_leaf: Left_parenthesis_code arithmetic_expression Right_parenthesis_code
1156 | integer_value
1157 | real_value
1158 | absolute_path
1159
[321]1160arithmetic_expression: arithmetic_leaf
1161 | arithmetic_node
[4]1162
1163#--------------- THE FOLLOWING SOURCE TAKEN FROM OG_PATH_VALIDATOR.Y -------------
1164#--------------- except to remove movable_path ----------------------------------------------------
1165
1166
1167absolute_path: Slash_code
1168 | Slash_code relative_path
1169# | absolute_path Slash_code relative_path
1170
1171
1172
1173relative_path: path_segment
[321]1174 {
1175 @@logger.debug("#{__FILE__}:#{__LINE__}, relative_path = #{val[0]}")
1176 result = val[0]
1177 }
[4]1178 | relative_path Slash_code path_segment
[321]1179 {
1180 @@logger.debug("#{__FILE__}:#{__LINE__}, relative_path = #{val[0]}/#{val[2]}")
1181 result = [val[0],val[2]]
1182 }
[4]1183
1184path_segment: V_ATTRIBUTE_IDENTIFIER V_LOCAL_TERM_CODE_REF
[19]1185 {
[261]1186 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
[321]1187 result = [val[0],val[1]]
[19]1188 }
[4]1189 | V_ATTRIBUTE_IDENTIFIER
[19]1190 {
[261]1191 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
[321]1192 result = val[0]
[19]1193 }
[4]1194
1195
1196#-------------------------------- END SOURCE TAKEN FROM OG_PATH_VALIDATOR.Y ----------------------
1197
1198
1199#---------------- existence, occurrences, cardinality ----------------
1200
1201c_existence: #-- default to 1..1
[22]1202 {
1203 result = Range.new(1,1)
1204 }
1205 | SYM_EXISTENCE SYM_MATCHES SYM_START_CBLOCK existence_spec SYM_END_CBLOCK
1206 {
1207 result = val[3]
1208 }
[4]1209
1210existence_spec: V_INTEGER #-- can only be 0 or 1
[22]1211 {
1212 begin
1213 integer = Integer(val[0])
1214 rescue
1215 raise
1216 end
1217 result = integer
1218 }
[4]1219 | V_INTEGER SYM_ELLIPSIS V_INTEGER #-- can only be 0..0, 0..1, 1..1
[22]1220 {
1221 begin
1222 from_integer = Integer(val[0])
1223 to_integer = Integer(val[2])
1224 rescue
1225 raise
1226 end
1227 result = Range.new(from_integer,to_integer)
1228 }
[4]1229
1230c_cardinality: SYM_CARDINALITY SYM_MATCHES SYM_START_CBLOCK cardinality_spec SYM_END_CBLOCK
[22]1231 {
[318]1232 result = OpenEhr::AM::Archetype::ConstraintModel::CARDINALITY.new
[22]1233 }
[4]1234
1235cardinality_spec: occurrence_spec
[323]1236 {
1237 result = val[0]
1238 }
[4]1239 | occurrence_spec Semicolon_code SYM_ORDERED
1240 | occurrence_spec Semicolon_code SYM_UNORDERED
1241 | occurrence_spec Semicolon_code SYM_UNIQUE
1242 | occurrence_spec Semicolon_code SYM_ORDERED Semicolon_code SYM_UNIQUE
1243 | occurrence_spec Semicolon_code SYM_UNORDERED Semicolon_code SYM_UNIQUE
1244 | occurrence_spec Semicolon_code SYM_UNIQUE Semicolon_code SYM_ORDERED
1245 | occurrence_spec Semicolon_code SYM_UNIQUE Semicolon_code SYM_UNORDERED
1246
1247cardinality_limit_value: integer_value
[35]1248 {
1249 result = val[0]
1250 }
1251 | Star_code # '*'
1252 {
1253 result = val[0]
1254 }
[4]1255
[35]1256
[4]1257c_occurrences: #-- default to 1..1
1258 | SYM_OCCURRENCES SYM_MATCHES SYM_START_CBLOCK occurrence_spec SYM_END_CBLOCK
[23]1259 {
[307]1260 case val[3]
1261 when OpenEhr::RM::Support::AssumedTypes::Interval
1262 result = val[3]
1263 else
1264 result = val[3]
1265 end
[23]1266 }
[4]1267 | SYM_OCCURRENCES error
1268
1269occurrence_spec: cardinality_limit_value #-- single integer or '*'
[307]1270 {
1271 result = val[0]
1272 }
[4]1273 | V_INTEGER SYM_ELLIPSIS cardinality_limit_value
[307]1274 {
1275 result = OpenEhr::RM::Support::AssumedTypes::Interval.new(val[0], val[2])
1276 }
[4]1277
1278#---------------------- leaf constraint types -----------------------
1279
1280c_integer_spec: integer_value
1281 | integer_list_value
1282 | integer_interval_value
1283
1284c_integer: c_integer_spec
1285 | c_integer_spec Semicolon_code integer_value
1286 | c_integer_spec Semicolon_code error
1287
1288c_real_spec: real_value
1289 | real_list_value
1290 | real_interval_value
1291
1292c_real: c_real_spec
1293 | c_real_spec Semicolon_code real_value
1294 | c_real_spec Semicolon_code error
1295
1296c_date_constraint: V_ISO8601_DATE_CONSTRAINT_PATTERN
1297 | date_value
1298 | date_interval_value
1299
1300c_date: c_date_constraint
1301 | c_date_constraint Semicolon_code date_value
1302 | c_date_constraint Semicolon_code error
1303
1304c_time_constraint: V_ISO8601_TIME_CONSTRAINT_PATTERN
1305 | time_value
1306 | time_interval_value
1307
1308c_time: c_time_constraint
1309 | c_time_constraint Semicolon_code time_value
1310 | c_time_constraint Semicolon_code error
1311
1312c_date_time_constraint: V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN
1313 | date_time_value
1314 | date_time_interval_value
1315
1316c_date_time: c_date_time_constraint
1317 | c_date_time_constraint Semicolon_code date_time_value
1318 | c_date_time_constraint Semicolon_code error
1319
1320c_duration_constraint: duration_pattern
1321 | duration_pattern Slash_code duration_interval_value
1322 | duration_value
1323 | duration_interval_value
1324
1325c_duration: c_duration_constraint
1326 | c_duration_constraint Semicolon_code duration_value
1327 | c_duration_constraint Semicolon_code error
1328
1329c_string_spec: V_STRING #-- single value, generates closed list
1330 | string_list_value #-- closed list
1331 | string_list_value Comma_code SYM_LIST_CONTINUE #-- open list
1332# | string_list_value ',' SYM_LIST_CONTINUE #-- open list
1333# | V_REGEXP #-- regular expression with "//" or "^^" delimiters
1334
1335c_string: c_string_spec
1336 | c_string_spec Semicolon_code string_value
1337 | c_string_spec Semicolon_code error
1338
1339c_boolean_spec: SYM_TRUE
[22]1340 {
[318]1341 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => true)
[22]1342 }
[4]1343 | SYM_FALSE
[22]1344 {
[318]1345 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => false)
[22]1346 }
[4]1347 | SYM_TRUE Comma_code SYM_FALSE
[22]1348 {
[318]1349 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => true,:false_valid => false)
[22]1350 }
[4]1351 | SYM_FALSE Comma_code SYM_TRUE
[22]1352 {
[318]1353 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => false,:false_valid => true)
[22]1354 }
[4]1355
1356c_boolean: c_boolean_spec
[22]1357 {
1358 result = val[0]
1359 }
[4]1360 | c_boolean_spec Semicolon_code boolean_value
[22]1361 {
[321]1362 result = val[0]
1363 #raise 'Not implemented yet'
[22]1364 }
[19]1365 | c_boolean_spec Semicolon_code error
[22]1366 {
1367 raise 'Not implemented yet'
1368 }
[4]1369
1370c_ordinal: c_ordinal_spec
1371 | c_ordinal_spec Semicolon_code integer_value
[19]1372 | c_ordinal_spec Semicolon_code error
[4]1373
1374c_ordinal_spec: ordinal
1375 | c_ordinal_spec Comma_code ordinal
1376
1377ordinal: integer_value SYM_INTERVAL_DELIM V_QUALIFIED_TERM_CODE_REF
[20]1378 {
1379 @in_interval = false
[261]1380 @@logger.debug("#{__FILE__}:#{__LINE__}, #{val[0]}|#{val[2]} at #{@filename}")
[20]1381 }
[4]1382
1383#c_code_phrase: V_TERM_CODE_CONSTRAINT #-- e.g. "[local::at0040, at0041; at0040]"
1384c_code_phrase: term_code_constraint_section #-- e.g. "[local::at0040, at0041; at0040]"
[32]1385 {
1386 result = val[0]
1387 }
[4]1388 | V_QUALIFIED_TERM_CODE_REF
[32]1389 {
1390 result = val[0]
1391 }
[4]1392
[261]1393# [[a-zA-Z0-9\(\)\._\-]+::[ \t\n]* [[a-zA-Z0-9\._\-]*[ \t]*]
[4]1394term_code_constraint_section: START_TERM_CODE_CONSTRAINT term_code_body END_TERM_CODE_CONSTRAINT
[261]1395 {
1396 @@logger.debug("#{__FILE__}:#{__LINE__}, START_TERM_CODE_CONSTRAINT = #{val[0]} at #{@filename}")
1397 @@logger.debug("#{__FILE__}:#{__LINE__}, term_code_body = #{val[1]}")
1398 @@logger.debug("#{__FILE__}:#{__LINE__}, END_TERM_CODE_CONSTRAINT = #{val[2]}")
1399 result = val[1]
1400 }
1401
1402
[4]1403term_code_body: # empty
1404 | TERM_CODE
1405 | term_code_body TERM_CODE
1406### term_code_body: TERM_CODE
1407### | term_code_body TERM_CODE
1408
1409# A Constraint_Ref is a proxy for a set of constraints on an object.
1410constraint_ref: V_LOCAL_TERM_CODE_REF #-- e.g. "ac0003"
[32]1411 {
1412 result = val[0]
1413 }
[4]1414
1415any_identifier: type_identifier
[32]1416 {
1417 result = val[0]
1418 }
[4]1419 | V_ATTRIBUTE_IDENTIFIER
[19]1420 {
[261]1421 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}")
[32]1422 result = val[0]
[19]1423 }
[4]1424
1425
1426#----------------- TAKEN FROM DADL_VALIDATOR.Y -------------------
1427#----------------- DO NOT MODIFY -------------------
1428#---------------------- BASIC DATA VALUES -----------------------
1429
1430duration_pattern: V_ISO8601_DURATION_CONSTRAINT_PATTERN
[318]1431 {
1432 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DURATION.new #val[0]
[26]1433 }
[4]1434
1435
1436
1437---- header
1438
[49]1439
[4]1440$:.unshift File.join(File.dirname(__FILE__))
[17]1441require 'logger'
[283]1442require 'yaml'
[21]1443require 'rubygems'
[307]1444require 'open_ehr'
1445$DEBUG = true
[4]1446
1447
[17]1448
[4]1449---- inner
[17]1450
[22]1451def assert_at(file,line, message = "")
1452 unless yield
1453 raise "Assertion failed !: #{file}, #{line}: #{message}"
1454 end
1455end
1456
[49]1457if $DEBUG
[261]1458 @@logger = Logger.new('log/parser.log','daily')
[263]1459 @@logger.level = Logger::DEBUG
[49]1460else
[261]1461 @@logger = Logger.new(STDOUT)
1462 @@logger.level = Logger::WARN
[49]1463end
1464
[17]1465
[4]1466
1467###----------/* Scanner */ -----------------------------------------------
1468
[265]1469
[4]1470def scan
[261]1471 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan at #{@filename}:#{@lineno}:")
[307]1472 scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename)
[265]1473
[4]1474 until @data.nil? do
[283]1475 @data = scanner.scan(@data) do |sym, val|
[4]1476 yield sym, val
1477 end
1478 @data = $' # variable $' receives the string after the match
1479 end
1480 yield :EOF, nil
1481 yield false, '$'
1482end # of scan
1483
[265]1484
[328]1485def parse(data, filename = "", lineno = 1, debug = false)
[4]1486 @yydebug = true
1487 @parsestring = data
1488 @data = data
1489 @lineno = lineno
1490 @filename = filename
1491 @adl_type = [:adl] # {:adl, :cadl, :dadl}
1492 @in_regexp = false
1493 @in_interval = false
[14]1494 @in_c_domain_type = false
[4]1495 yyparse self, :scan
1496end
1497
1498def on_error( t, v, values)
1499 raise Racc::ParseError, "#{@filename}:#{@lineno}: Inline syntax error on #{v.inspect}"
1500end
1501
1502
[283]1503__END__
[4]1504
1505
1506
1507
1508### Local Variables:
1509### mode:ruby
1510### mode:font-lock
1511### comment-column:0
1512### comment-start: "### "
1513### comment-end:""
1514### End:
1515
1516
1517
1518
Note: See TracBrowser for help on using the repository browser.