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

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

commit after MOSS 9

File size: 48.3 KB
Line 
1
2class OpenEhr::ADL::Parser
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
30 {
31 result = val[0]
32 }
33 | error
34
35archetype: arch_identification arch_specialisation arch_concept arch_language arch_description arch_definition arch_invariant arch_ontology
36 {
37 assert_at(__FILE__,__LINE__) do
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)
39 end
40
41 archetype_id = val[0][:archetype_id]
42 parent_archtype_id = val[1][:parent_archtype_id] if val[1]
43 adl_version = val[0][:arch_head][:arch_meta_data][:adl_version]
44 concept = val[2][:arch_concept]
45 language = val[3][:arch_language]
46 archetype = OpenEhr::AM::Archetype::ARCHETYPE.create(
47 :archetype_id => archetype_id,
48 :parent_archtype_id => parent_archtype_id,
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
57 @@logger.debug("#{__FILE__}:#{__LINE__}: archetype = #{archetype.to_yaml} at #{@filename}:#{@lineno}")
58 result = archetype
59 }
60
61
62arch_identification: arch_head V_ARCHETYPE_ID
63 {
64 result = {:arch_head => val[0], :archetype_id => val[1] }
65 }
66 | SYM_ARCHETYPE error
67 {
68 raise
69 }
70
71arch_head: SYM_ARCHETYPE
72 {
73 result = {:arch_meta_data => nil }
74 }
75 | SYM_ARCHETYPE arch_meta_data
76 {
77 result = val[1]
78 }
79
80arch_meta_data: Left_parenthesis_code arch_meta_data_items Right_parenthesis_code
81 {
82 result = {:arch_meta_data => val[1] }
83 }
84
85arch_meta_data_items: arch_meta_data_item
86 {
87 result = val[0]
88 }
89 | arch_meta_data_items Semicolon_code arch_meta_data_item
90 {
91 result = val[0].merge(val[2])
92 }
93
94
95arch_meta_data_item: SYM_ADL_VERSION SYM_EQ V_VERSION_STRING
96 {
97 result = {:adl_version => val[2], :is_controlled => false }
98 }
99 | SYM_IS_CONTROLLED
100 {
101 result = {:is_controlled => true }
102 }
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
108 {
109 result = {:parent_archtype_id => val[1]}
110 }
111 | SYM_SPECIALIZE error
112
113arch_concept: SYM_CONCEPT V_LOCAL_TERM_CODE_REF
114 {
115 result = {:arch_concept => val[1] }
116 }
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
124 {
125 result = {:arch_language => ""}
126 }
127 | SYM_LANGUAGE dadl_section
128 {
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]}
138 else
139 raise OpenEhr::ADL::Exception::Parser::Error, "It should be 'original_language, but was #{dadl_section[:attr_id]}' at #{@filename}:#{@lineno} "
140 end
141 }
142 | SYM_LANGUAGE error
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
150 {
151 dadl_section = val[1]
152 args = Hash.new
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]
158 when "original_author"
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]])
163 else
164 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
165 end
166 when "details"
167# unless item[:type_identifier]
168 unless dadl_section[:type_identifier]
169# args.merge!(Hash[:details => item[:untyped_multiple_attr_object_block]])
170 #args.merge!(Hash[:details => item[:object_block]])
171 args.merge!(Hash[:details => dadl_section[:untyped_multiple_attr_object_block]])
172 else
173 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
174 end
175 when "lifecycle_state"
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]])
180 else
181 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
182 end
183 when "other_contributors"
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]])
188 else
189 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
190 end
191 when "other_details"
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]])
196 else
197 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
198 end
199 else
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} "
202 end
203# end
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)
206 }
207 | SYM_DESCRIPTION error
208
209#arch_definition: SYM_DEFINITION V_CADL_TEXT
210# | SYM_DEFINITION error
211arch_definition: SYM_DEFINITION cadl_section
212 {
213 result = val[1]
214 }
215 | SYM_DEFINITION error
216
217
218### cADL section
219cadl_section: c_complex_object
220 {
221 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT)}
222 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object = #{val[0]} at #{@filename}:#{@lineno}")
223 result = val[0]
224 }
225 | assertions
226 {
227 result = val[0]
228 }
229# | error
230
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}")
236 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
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
241 }
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
244 {
245 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
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
250 }
251
252# | c_complex_object_head error SYM_END_CBLOCK
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
256 {
257 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object_head: c_complex_object_id => #{val[0]}, c_occurrences => #{val[1]}")
258 result = {:c_complex_object_id => val[0], :c_occurrences => val[1]}
259 }
260
261c_complex_object_id: type_identifier
262 {
263 result = {:type_identifier => val[0]}
264 }
265 | type_identifier V_LOCAL_TERM_CODE_REF
266 {
267 result = {:type_identifier => val[0], :local_term_code_ref => val[1]}
268 }
269
270c_complex_object_body: c_any #-- used to indicate that any value of a type is ok
271 | c_attributes
272 {
273 result = OpenEhr::AM::Archetype::ConstraintModel::C_COMPLEX_OBJECT.new(:attributes => val[0])
274 }
275
276
277#------------------------- node types -----------------------
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
290 {
291 @@logger.debug("#{__FILE__}:#{__LINE__}: c_complex_object = #{val[0].inspect} at #{@filename}:#{@lineno}")
292 result = val[0]
293 }
294 | archetype_internal_ref
295 {
296 result = OpenEhr::AM::Archetype::ConstraintModel::ARCHETYPE_INTERNAL_REF.create do |archetype_internal_ref|
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
301 }
302 | archetype_slot
303 {
304 result = val[0]
305 }
306 | constraint_ref
307 {
308 result = OpenEhr::AM::Archetype::ConstraintModel::CONSTRAINT_REF.create do |constraint_ref|
309 constraint_ref.reference = val[0]
310 end
311 }
312 | c_code_phrase
313 {
314 result = val[0]
315 }
316 | c_ordinal
317 {
318 result = val[0]
319 }
320 | c_primitive_object
321 {
322 result = val[0]
323 }
324 | v_c_domain_type
325 {
326 result = val[0]
327 }
328# | v_c_domain_type
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
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
354 | ERR_C_DOMAIN_TYPE
355 | error
356
357v_c_domain_type: START_V_C_DOMAIN_TYPE_BLOCK dadl_section END_V_C_DOMAIN_TYPE_BLOCK
358 {
359 result = val[1]
360 }
361
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
364 {
365 result = {:type_identifier => val[1], :c_occurrences => val[2], :absolute_path => val[3] }
366 }
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
371 {
372 result = OpenEhr::AM::Archetype::ConstraintModel::ARCHETYPE_SLOT.create do |archetype_slot|
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 }
379c_archetype_slot_head: c_archetype_slot_id c_occurrences
380 {
381 result = {:c_archetype_slot_id => val[0],:c_occurrences => val[1]}
382 }
383
384c_archetype_slot_id: SYM_ALLOW_ARCHETYPE type_identifier
385 {
386 result = val[1]
387 }
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
393 {
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|
396 c_primitive_object.item = val[0]
397 end
398 }
399
400c_primitive: c_integer
401 {
402 @@logger.debug("#{__FILE__}:#{__LINE__}: c_integer = #{val[0]} at #{@filename}:#{@lineno}")
403 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_INTEGER.create do |c_integer|
404 c_integer.list
405 c_integer.range
406 c_integer.assumed_value
407 end
408 }
409 | c_real
410 {
411 @@logger.debug("#{__FILE__}:#{__LINE__}: c_real = #{val[0]} at #{@filename}:#{@lineno}")
412 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_REAL.new
413 }
414 | c_date
415 {
416 @@logger.debug("#{__FILE__}:#{__LINE__}: c_date = #{val[0]} at #{@filename}:#{@lineno}")
417 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DATE.new
418 }
419 | c_time
420 {
421 @@logger.debug("#{__FILE__}:#{__LINE__}: c_time = #{val[0]} at #{@filename}:#{@lineno}")
422 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_TIME.new
423 }
424 | c_date_time
425 {
426 @@logger.debug("#{__FILE__}:#{__LINE__}: c_date_time = #{val[0]} at #{@filename}:#{@lineno}")
427 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DATE_TIME.new
428 }
429 | c_duration
430 {
431 @@logger.debug("#{__FILE__}:#{__LINE__}: c_duration = #{val[0]} at #{@filename}:#{@lineno}")
432 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DURATION.new
433 }
434 | c_string
435 {
436 @@logger.debug("#{__FILE__}:#{__LINE__}: c_string = #{val[0]} at #{@filename}:#{@lineno}")
437 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_STRING.new
438 }
439 | c_boolean
440 {
441 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN)}
442 @@logger.debug("#{__FILE__}:#{__LINE__}: c_boolean = #{val[0]} at #{@filename}:#{@lineno}")
443 result = val[0]
444 }
445
446c_any: Star_code
447#c_any: '*'
448
449#---------------- BODY - relationships ----------------
450
451c_attributes: c_attribute
452 {
453 result = [val[0]]
454 }
455 | c_attributes c_attribute
456 {
457 result = (val[0] << val[1])
458 }
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
462 {
463 @@logger.debug("#{__FILE__}:#{__LINE__}:c_attribute: #{val[0]} matches #{val[3]}")
464 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
465 c_attribute = val[0]
466 c_attribute.children = val[3]
467 result = c_attribute
468 }
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]}}")
472 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
473 result = val[0]
474 }
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 }
482 | c_attr_head SYM_MATCHES SYM_START_CBLOCK error SYM_END_CBLOCK
483 {
484 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEhr::AM::Archetype::ConstraintModel::C_ATTRIBUTE)}
485 result = val[0]
486 }
487
488
489c_attr_head: V_ATTRIBUTE_IDENTIFIER c_existence
490 {
491 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]}, c_existence = #{val[1]} at #{@filename}")
492 result = OpenEhr::AM::Archetype::ConstraintModel::C_SINGLE_ATTRIBUTE.new(
493 :rm_attribute_name => val[0],
494 :existence => val[1]
495 )
496
497 }
498 | V_ATTRIBUTE_IDENTIFIER c_existence c_cardinality
499 {
500 assert_at(__FILE__,__LINE__){ val[2].instance_of?(OpenEhr::AM::Archetype::ConstraintModel::CARDINALITY) }
501 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER: #{val[0]}, c_existence = #{val[1]}, c_cardinality = #{val[2]} at #{@filename}")
502 result = OpenEhr::AM::Archetype::ConstraintModel::C_MULTIPLE_ATTRIBUTE.new(
503 :rm_attribute_name => val[0],
504 :existence => val[1],
505 :cardinality => val[2]
506 )
507 }
508
509c_attr_values: c_object
510 {
511 result = Array[val[0]]
512 }
513 | c_attr_values c_object
514 {
515 result = (val[0] << val[1])
516 }
517 | c_any # -- to allow a property to have any value
518 {
519 result = Array[val[0]]
520 }
521
522c_includes: #-- Empty
523 | SYM_INCLUDE assertions
524{
525 @@logger.debug("#{__FILE__}:#{__LINE__}: c_includes: assertions = #{val[1]}")
526 result = val[1]
527}
528### c_includes: #-- Empty
529### | SYM_INCLUDE invariants
530
531c_excludes: #-- Empty
532 | SYM_EXCLUDE assertions
533 {
534 @@logger.debug("#{__FILE__}:#{__LINE__}: c_excludes: assertions = #{val[1]}")
535 result = val[1]
536 }
537### c_excludes: #-- Empty
538### | SYM_EXCLUDE invariants
539
540invariants: invariant
541 | invariants invariant
542
543invariant: any_identifier Colon_code boolean_expression
544 | boolean_expression
545 | any_identifier Colon_code error
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
556 {
557 dadl_section = val[1]
558 @@logger.debug("#{__FILE__}:#{__LINE__}: arch_ontology: dadl_section = \n#{dadl_section.to_yaml}")
559 args = Hash.new
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]])
564 else
565 raise OpenEhr::ADL::Exception::Parser::Error, "Needless type_identifier at #{@filename}:#{@lineno} "
566 end
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} "
581 end
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
607
608 result = OpenEhr::AM::Archetype::Ontology::ARCHETYPE_ONTOLOGY.new(args)
609 }
610 | SYM_ONTOLOGY error
611
612
613### dADL section
614dadl_section: # no dadl section
615 | attr_vals
616 {
617 @@logger.debug("#{__FILE__}:#{__LINE__}:dadl_section::attr_vals = \n#{val[0].to_yaml}")
618 result = val[0]
619 }
620 | complex_object_block
621 {
622 #@@logger.debug("#{__FILE__}:#{__LINE__}:dadl_section::complex_object_block = \n#{val[0].to_yaml}")
623 result = val[0]
624 }
625# | error
626
627attr_vals: attr_val
628 {
629 attr_val = val[0]
630 result = Hash[attr_val[:attr_id] => attr_val[:object_block]]
631 }
632 | attr_vals attr_val
633 {
634 result = val[0].merge!(val[1])
635 }
636 | attr_vals Semicolon_code attr_val
637 {
638 result = val[0].merge!(val[2])
639 }
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### }
652
653attr_val: attr_id SYM_EQ object_block
654 {
655 @@logger.debug("#{__FILE__}:#{__LINE__}:attr_val\n attr_id = #{val[0].to_yaml},\n object_block = #{val[2].to_yaml}")
656 result = {:attr_id => val[0], :object_block => val[2]}
657 }
658
659attr_id: V_ATTRIBUTE_IDENTIFIER
660 {
661 @@logger.debug("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]}")
662 result = val[0]
663 }
664 | V_ATTRIBUTE_IDENTIFIER error
665
666object_block: complex_object_block
667 {
668 result = val[0]
669 }
670 | primitive_object_block
671 {
672 result = val[0]
673 }
674
675complex_object_block: single_attr_object_block
676 {
677 result = val[0]
678 }
679 | multiple_attr_object_block
680 {
681 result = val[0]
682 }
683
684multiple_attr_object_block: untyped_multiple_attr_object_block
685 {
686 @@logger.debug("#{__FILE__}:#{__LINE__}:multiple_attr_object_block::attr_val\n untyped_multiple_attr_object_block = #{val[0].to_yaml}")
687 result = {:untyped_multiple_attr_object_block => val[0]}
688 }
689 | type_identifier untyped_multiple_attr_object_block
690 {
691 result = {:type_identifier => val[0], :untyped_multiple_attr_object_block => val[1]}
692 }
693
694untyped_multiple_attr_object_block: multiple_attr_object_block_head keyed_objects SYM_END_DBLOCK
695 {
696 @@logger.debug("#{__FILE__}:#{__LINE__}:untyped_multiple_attr_object_block::keyed_objects\n keyed_objects = #{val[1].to_yaml}")
697 result = val[1]
698 }
699
700multiple_attr_object_block_head: SYM_START_DBLOCK
701 {
702 result = val[0]
703 }
704
705keyed_objects: keyed_object
706 {
707 result = Array[val[0]]
708 }
709 | keyed_objects keyed_object
710 {
711 result = (val[0] << val[1])
712 }
713
714keyed_object: object_key SYM_EQ object_block
715 {
716 #@@logger.debug("#{__FILE__}:#{__LINE__}: keyed_object = #{val[0]} at #{@filename}:#{@lineno}")
717 #result = {:object_key => val[0], :object_block => val[2]}
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]]
721 else
722 raise OpenEhr::ADL::Exception::Parser::Error, "Missing type_identifier at #{@filename}:#{@lineno} "
723 end
724 }
725
726object_key: Left_bracket_code simple_value Right_bracket_code
727 {
728 @@logger.debug("object_key: [#{val[1]}] at #{@filename}:#{@lineno}")
729 result = val[1]
730 }
731
732single_attr_object_block: untyped_single_attr_object_block
733 {
734 result = {:untyped_single_attr_object_block => val[0]}
735 }
736 | type_identifier untyped_single_attr_object_block
737 {
738 result = {:type_identifier => val[0], :untyped_single_attr_object_block => val[1]}
739 }
740
741untyped_single_attr_object_block: single_attr_object_complex_head SYM_END_DBLOCK # >
742 {
743 @@logger.debug("#{__FILE__}:#{__LINE__}: single_attr_object_complex_head = #{val[0]} at #{@filename}:#{@lineno}")
744 result = []
745 }
746 | single_attr_object_complex_head attr_vals SYM_END_DBLOCK
747 {
748 @@logger.debug("#{__FILE__}:#{__LINE__}: untyped_single_attr_object_block::attr_vals = \n#{val[1].to_yaml} at #{@filename}:#{@lineno}")
749 result = val[1]
750 }
751single_attr_object_complex_head: SYM_START_DBLOCK
752
753primitive_object_block: untyped_primitive_object_block
754 {
755 @@logger.debug("#{__FILE__}:#{__LINE__}: untyped_primitive_object_block = #{val[0]} at #{@filename}:#{@lineno}")
756 result = {:untyped_primitive_object_block => val[0]}
757 }
758 | type_identifier untyped_primitive_object_block
759 {
760 @@logger.debug("#{__FILE__}:#{__LINE__}: type_identifier = #{val[0]}, untyped_primitive_object_block = #{val[1]} at #{@filename}:#{@lineno}")
761 result = {:type_identifier => val[0], :untyped_primitive_object_block => val[1]}
762 }
763untyped_primitive_object_block: SYM_START_DBLOCK primitive_object_value SYM_END_DBLOCK
764 {
765 #@@logger.debug("#{__FILE__}:#{__LINE__}: primitive_object_block = <#{val[1]}> at #{@filename}:#{@lineno}")
766 result = val[1]
767 }
768primitive_object_value: simple_value
769 {
770 result = val[0]
771 }
772 | simple_list_value
773 {
774 result = val[0]
775 }
776 | simple_interval_value
777 {
778 result = val[0]
779 }
780 | term_code
781 {
782 result = val[0]
783 }
784 | term_code_list_value
785 {
786 result = val[0]
787 }
788simple_value: string_value
789 {
790 @@logger.debug("string_value: #{val[0]} at #{@filename}:#{@lineno}")
791 result = val[0]
792 }
793 | integer_value
794 {
795 @@logger.debug("integer_value: #{val[0]} at #{@filename}:#{@lineno}")
796 result = val[0]
797 }
798 | real_value
799 {
800 @@logger.debug("real_value: #{val[0]} at #{@filename}:#{@lineno}")
801 result = val[0]
802 }
803 | boolean_value
804 {
805 @@logger.debug("boolean_value: #{val[0]} at #{@filename}:#{@lineno}")
806 result = val[0]
807 }
808 | character_value
809 {
810 @@logger.debug("character_value: #{val[0]} at #{@filename}:#{@lineno}")
811 result = val[0]
812 }
813 | date_value
814 {
815 @@logger.debug("date_value: #{val[0]} at #{@filename}:#{@lineno}")
816 result = val[0]
817 }
818 | time_value
819 {
820 @@logger.debug("time_value: #{val[0]} at #{@filename}:#{@lineno}")
821 result = val[0]
822 }
823 | date_time_value
824 {
825 @@logger.debug("date_time_value: #{val[0]} at #{@filename}:#{@lineno}")
826 result = val[0]
827 }
828 | duration_value
829 {
830 @@logger.debug("duration_value: #{val[0]} at #{@filename}:#{@lineno}")
831 result = val[0]
832 }
833 | uri_value
834 {
835 @@logger.debug("uri_value: #{val[0]} at #{@filename}:#{@lineno}")
836 result = val[0]
837 }
838
839simple_list_value: string_list_value
840 {
841 @@logger.debug("string_list_value: #{val[0]} at #{@filename}:#{@lineno}")
842 result = val[0]
843 }
844 | integer_list_value
845 {
846 result = val[0]
847 }
848 | real_list_value
849 {
850 result = val[0]
851 }
852 | boolean_list_value
853 {
854 result = val[0]
855 }
856 | character_list_value
857 {
858 result = val[0]
859 }
860 | date_list_value
861 {
862 result = val[0]
863 }
864 | time_list_value
865 {
866 result = val[0]
867 }
868 | date_time_list_value
869 {
870 result = val[0]
871 }
872 | duration_list_value
873 {
874 result = val[0]
875 }
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
885 {
886 @@logger.debug("V_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
887 result = val[0]
888 }
889 | V_GENERIC_TYPE_IDENTIFIER
890 {
891 @@logger.debug("V_GENERIC_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
892 result = val[0]
893 }
894
895string_value: V_STRING
896 {
897 @@logger.debug("V_STRING: #{val[0]} at #{@filename}:#{@lineno}")
898 result = val[0]
899 }
900
901string_list_value: V_STRING Comma_code V_STRING
902 {
903 result = [val[0],val[2]]
904 }
905 | string_list_value Comma_code V_STRING
906 {
907 result = val[0] << val[2]
908 }
909 | V_STRING Comma_code SYM_LIST_CONTINUE
910 {
911 result = val[0]
912 }
913
914integer_value: V_INTEGER
915 {
916 begin
917 integer = Integer(val[0])
918 rescue
919 raise
920 end
921 result = integer
922 }
923 | Plus_code V_INTEGER
924 {
925 begin
926 integer = Integer(val[0])
927 rescue
928 raise
929 end
930 result = integer
931 }
932 | Minus_code V_INTEGER
933 {
934 begin
935 integer = Integer(val[0])
936 rescue
937 raise
938 end
939 result = - integer
940 }
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
957 {
958 begin
959 real = Float(val[0])
960 rescue
961 raise
962 end
963 result = real
964 }
965 | Plus_code V_REAL
966 {
967 begin
968 real = Float(val[1])
969 rescue
970 raise
971 end
972 result = real
973 }
974 | Minus_code V_REAL
975 {
976 begin
977 real = Float(val[1])
978 rescue
979 raise
980 end
981 result = - real
982 }
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
1000 {
1001 result = true
1002 }
1003 | SYM_FALSE
1004 {
1005 result = false
1006 }
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
1019 {
1020 result = val[0]
1021 }
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
1054 {
1055 @@logger.debug("V_ISO8601_EXTENDED_DATE_TIME: #{val[0]} at #{@filename}:#{@lineno}")
1056 result = val[0]
1057 }
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
1074 {
1075 @@logger.debug("V_ISO8601_DURATION: #{val[0]} at #{@filename}:#{@lineno}")
1076 result = val[0]
1077 }
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
1094 {
1095 @@logger.debug("#{__FILE__}:#{__LINE__}: V_QUALIFIED_TERM_CODE_REF = #{val[0]} at #{@filename}:#{@lineno}")
1096 result = val[0]
1097 }
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
1104 {
1105 @@logger.debug("#{__FILE__}:#{__LINE__}: V_URI = #{val[0]} at #{@filename}:#{@lineno}")
1106 result = val[0]
1107 }
1108
1109
1110#---------------------- ASSERTIONS ------------------------
1111
1112assertions: assertion
1113 | assertions assertion
1114
1115assertion: any_identifier Colon_code boolean_expression
1116 | boolean_expression
1117 | any_identifier Colon_code error
1118
1119#---------------------- expressions ---------------------
1120
1121boolean_expression: boolean_leaf
1122 | boolean_node
1123
1124boolean_node: SYM_EXISTS absolute_path
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 }
1131 | relative_path SYM_MATCHES SYM_START_CBLOCK c_primitive SYM_END_CBLOCK
1132# | relative_path SYM_MATCHES SYM_START_CBLOCK Slash_code REGEXP_BODY Slash_code SYM_END_CBLOCK# added by akimichi
1133 | SYM_NOT boolean_leaf
1134 | arithmetic_expression Equal_code arithmetic_expression
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
1149arithmetic_node: arithmetic_expression Plus_code arithmetic_leaf
1150 | arithmetic_expression Minus_code arithmetic_leaf
1151 | arithmetic_expression Star_code arithmetic_leaf
1152 | arithmetic_expression Slash_code arithmetic_leaf
1153 | arithmetic_expression Caret_code arithmetic_leaf
1154
1155arithmetic_leaf: Left_parenthesis_code arithmetic_expression Right_parenthesis_code
1156 | integer_value
1157 | real_value
1158 | absolute_path
1159
1160arithmetic_expression: arithmetic_leaf
1161 | arithmetic_node
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
1174 {
1175 @@logger.debug("#{__FILE__}:#{__LINE__}, relative_path = #{val[0]}")
1176 result = val[0]
1177 }
1178 | relative_path Slash_code path_segment
1179 {
1180 @@logger.debug("#{__FILE__}:#{__LINE__}, relative_path = #{val[0]}/#{val[2]}")
1181 result = [val[0],val[2]]
1182 }
1183
1184path_segment: V_ATTRIBUTE_IDENTIFIER V_LOCAL_TERM_CODE_REF
1185 {
1186 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
1187 result = [val[0],val[1]]
1188 }
1189 | V_ATTRIBUTE_IDENTIFIER
1190 {
1191 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
1192 result = val[0]
1193 }
1194
1195
1196#-------------------------------- END SOURCE TAKEN FROM OG_PATH_VALIDATOR.Y ----------------------
1197
1198
1199#---------------- existence, occurrences, cardinality ----------------
1200
1201c_existence: #-- default to 1..1
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 }
1209
1210existence_spec: V_INTEGER #-- can only be 0 or 1
1211 {
1212 begin
1213 integer = Integer(val[0])
1214 rescue
1215 raise
1216 end
1217 result = integer
1218 }
1219 | V_INTEGER SYM_ELLIPSIS V_INTEGER #-- can only be 0..0, 0..1, 1..1
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 }
1229
1230c_cardinality: SYM_CARDINALITY SYM_MATCHES SYM_START_CBLOCK cardinality_spec SYM_END_CBLOCK
1231 {
1232 result = OpenEhr::AM::Archetype::ConstraintModel::CARDINALITY.new
1233 }
1234
1235cardinality_spec: occurrence_spec
1236 {
1237 result = val[0]
1238 }
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
1248 {
1249 result = val[0]
1250 }
1251 | Star_code # '*'
1252 {
1253 result = val[0]
1254 }
1255
1256
1257c_occurrences: #-- default to 1..1
1258 | SYM_OCCURRENCES SYM_MATCHES SYM_START_CBLOCK occurrence_spec SYM_END_CBLOCK
1259 {
1260 case val[3]
1261 when OpenEhr::RM::Support::AssumedTypes::Interval
1262 result = val[3]
1263 else
1264 result = val[3]
1265 end
1266 }
1267 | SYM_OCCURRENCES error
1268
1269occurrence_spec: cardinality_limit_value #-- single integer or '*'
1270 {
1271 result = val[0]
1272 }
1273 | V_INTEGER SYM_ELLIPSIS cardinality_limit_value
1274 {
1275 result = OpenEhr::RM::Support::AssumedTypes::Interval.new(val[0], val[2])
1276 }
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
1340 {
1341 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => true)
1342 }
1343 | SYM_FALSE
1344 {
1345 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => false)
1346 }
1347 | SYM_TRUE Comma_code SYM_FALSE
1348 {
1349 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => true,:false_valid => false)
1350 }
1351 | SYM_FALSE Comma_code SYM_TRUE
1352 {
1353 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_BOOLEAN.new(:true_valid => false,:false_valid => true)
1354 }
1355
1356c_boolean: c_boolean_spec
1357 {
1358 result = val[0]
1359 }
1360 | c_boolean_spec Semicolon_code boolean_value
1361 {
1362 result = val[0]
1363 #raise 'Not implemented yet'
1364 }
1365 | c_boolean_spec Semicolon_code error
1366 {
1367 raise 'Not implemented yet'
1368 }
1369
1370c_ordinal: c_ordinal_spec
1371 | c_ordinal_spec Semicolon_code integer_value
1372 | c_ordinal_spec Semicolon_code error
1373
1374c_ordinal_spec: ordinal
1375 | c_ordinal_spec Comma_code ordinal
1376
1377ordinal: integer_value SYM_INTERVAL_DELIM V_QUALIFIED_TERM_CODE_REF
1378 {
1379 @in_interval = false
1380 @@logger.debug("#{__FILE__}:#{__LINE__}, #{val[0]}|#{val[2]} at #{@filename}")
1381 }
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]"
1385 {
1386 result = val[0]
1387 }
1388 | V_QUALIFIED_TERM_CODE_REF
1389 {
1390 result = val[0]
1391 }
1392
1393# [[a-zA-Z0-9\(\)\._\-]+::[ \t\n]* [[a-zA-Z0-9\._\-]*[ \t]*]
1394term_code_constraint_section: START_TERM_CODE_CONSTRAINT term_code_body END_TERM_CODE_CONSTRAINT
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
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"
1411 {
1412 result = val[0]
1413 }
1414
1415any_identifier: type_identifier
1416 {
1417 result = val[0]
1418 }
1419 | V_ATTRIBUTE_IDENTIFIER
1420 {
1421 @@logger.debug("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}")
1422 result = val[0]
1423 }
1424
1425
1426#----------------- TAKEN FROM DADL_VALIDATOR.Y -------------------
1427#----------------- DO NOT MODIFY -------------------
1428#---------------------- BASIC DATA VALUES -----------------------
1429
1430duration_pattern: V_ISO8601_DURATION_CONSTRAINT_PATTERN
1431 {
1432 result = OpenEhr::AM::Archetype::ConstraintModel::Primitive::C_DURATION.new #val[0]
1433 }
1434
1435
1436
1437---- header
1438
1439
1440$:.unshift File.join(File.dirname(__FILE__))
1441require 'logger'
1442require 'yaml'
1443require 'rubygems'
1444require 'open_ehr'
1445$DEBUG = true
1446
1447
1448
1449---- inner
1450
1451def assert_at(file,line, message = "")
1452 unless yield
1453 raise "Assertion failed !: #{file}, #{line}: #{message}"
1454 end
1455end
1456
1457if $DEBUG
1458 @@logger = Logger.new('log/parser.log','daily')
1459 @@logger.level = Logger::DEBUG
1460else
1461 @@logger = Logger.new(STDOUT)
1462 @@logger.level = Logger::WARN
1463end
1464
1465
1466
1467###----------/* Scanner */ -----------------------------------------------
1468
1469
1470def scan
1471 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan at #{@filename}:#{@lineno}:")
1472 scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename)
1473
1474 until @data.nil? do
1475 @data = scanner.scan(@data) do |sym, val|
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
1484
1485def parse(data, filename = "", lineno = 1, debug = false)
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
1494 @in_c_domain_type = false
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
1503__END__
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.