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

Last change on this file since 26 was 26, checked in by Tatsukawa, Akimichi, 16 years ago

fixed parser.y

File size: 62.2 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::Constraint_Model::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 adl_version = val[0][:arch_head][:arch_meta_data][:adl_version]
43 concept = val[2]
44 language = val[3][:arch_language]
45 archetype = OpenEHR::AM::Archetype::ARCHETYPE.create(
46 :archetype_id => archetype_id,
47 :adl_version => adl_version,
48 :concept => concept,
49 :description => val[4],
50 :definition => val[5],
51 :ontology => val[7]
52 ) do |archetype|
53 archetype.original_language = language
54 end
55 @@log.info("#{__FILE__}:#{__LINE__}: archetype = #{archetype} at #{@filename}:#{@lineno}")
56 result = archetype
57 }
58
59
60arch_identification: arch_head V_ARCHETYPE_ID
61 {
62 result = {:arch_head => val[0], :archetype_id => val[1] }
63 }
64 | SYM_ARCHETYPE error
65 {
66 raise
67 }
68
69arch_head: SYM_ARCHETYPE
70 {
71 result = {:arch_meta_data => nil }
72 }
73 | SYM_ARCHETYPE arch_meta_data
74 {
75 result = val[1]
76 }
77
78arch_meta_data: Left_parenthesis_code arch_meta_data_items Right_parenthesis_code
79 {
80 result = {:arch_meta_data => val[1] }
81 }
82
83arch_meta_data_items: arch_meta_data_item
84 {
85 result = val[0]
86 }
87 | arch_meta_data_items Semicolon_code arch_meta_data_item
88 {
89 result = val[0].merge(val[2])
90 }
91
92
93arch_meta_data_item: SYM_ADL_VERSION SYM_EQ V_VERSION_STRING
94 {
95 result = {:adl_version => val[2], :is_controlled => false }
96 }
97 | SYM_IS_CONTROLLED
98 {
99 result = {:is_controlled => true }
100 }
101
102# Define specialization in which its constraints are narrower than those of the parent.
103# Any data created via the use of the specialized archetype shall be conformant both to it and its parent.
104arch_specialisation: #-- empty is ok
105 | SYM_SPECIALIZE V_ARCHETYPE_ID
106 | SYM_SPECIALIZE error
107
108arch_concept: SYM_CONCEPT V_LOCAL_TERM_CODE_REF
109 {
110 result = {:arch_concept => val[1] }
111 }
112 | SYM_CONCEPT error
113
114#arch_language: #-- empty is ok for ADL 1.4 tools
115# | SYM_LANGUAGE V_DADL_TEXT
116# | SYM_LANGUAGE error
117
118arch_language: #-- empty is ok for ADL 1.4 tools
119 {
120 result = {:arch_language => nil}
121 }
122 | SYM_LANGUAGE dadl_section
123 {
124 result = {:arch_language => val[1]}
125 }
126 | SYM_LANGUAGE error
127
128#arch_description: #-- no meta-data ok
129# | SYM_DESCRIPTION V_DADL_TEXT
130# | SYM_DESCRIPTION error
131
132arch_description: #-- no meta-data ok
133 | SYM_DESCRIPTION dadl_section
134 {
135 result = OpenEHR::AM::Archetype::Archetype_Description::ARCHETYPE_DESCRIPTION.new(:details => val[1])
136 }
137 | SYM_DESCRIPTION error
138
139#arch_definition: SYM_DEFINITION V_CADL_TEXT
140# | SYM_DEFINITION error
141arch_definition: SYM_DEFINITION cadl_section
142 {
143 result = val[1]
144 }
145 | SYM_DEFINITION error
146
147
148### cADL section
149cadl_section: c_complex_object
150 {
151 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEHR::AM::Archetype::Constraint_Model::C_COMPLEX_OBJECT)}
152 @@log.info("#{__FILE__}:#{__LINE__}: c_complex_object = #{val[0]} at #{@filename}:#{@lineno}")
153 result = val[0]
154 }
155 | assertions
156 {
157 result = val[0]
158 }
159# | error
160
161#c_complex_object: c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body SYM_END_CBLOCK
162c_complex_object: c_complex_object_head SYM_MATCHES START_REGEXP_BLOCK REGEXP_BODY END_REGEXP_BLOCK # added by akimichi
163 {
164 result = OpenEHR::AM::Archetype::Constraint_Model::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
165 c_complex_object.node_id = val[0][:c_complex_object_id][:local_term_code_ref]
166 c_complex_object.rm_type_name = val[0][:c_complex_object_id][:type_identifier]
167 c_complex_object.occurrences = val[0][:c_occurrences]
168 end
169 }
170 | c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body SYM_END_CBLOCK
171 {
172 result = OpenEHR::AM::Archetype::Constraint_Model::C_COMPLEX_OBJECT.create(:attributes => val[3]) do |c_complex_object|
173 c_complex_object.node_id = val[0][:c_complex_object_id][:local_term_code_ref]
174 c_complex_object.rm_type_name = val[0][:c_complex_object_id][:type_identifier]
175 c_complex_object.occurrences = val[0][:c_occurrences]
176 end
177 }
178# | c_complex_object_head error SYM_END_CBLOCK
179# | c_complex_object_head SYM_MATCHES SYM_START_CBLOCK c_complex_object_body c_invariants SYM_END_CBLOCK
180
181c_complex_object_head: c_complex_object_id c_occurrences
182 {
183 result = {:c_complex_object_id => val[0], :c_occurrences => val[1]}
184 }
185
186c_complex_object_id: type_identifier
187 {
188 result = {:type_identifier => val[0]}
189 }
190 | type_identifier V_LOCAL_TERM_CODE_REF
191 {
192 result = {:type_identifier => val[0], :local_term_code_ref => val[1]}
193 }
194
195c_complex_object_body: c_any #-- used to indicate that any value of a type is ok
196 | c_attributes
197 {
198 result = OpenEHR::AM::Archetype::Constraint_Model::C_COMPLEX_OBJECT.new(:attributes => val[0])
199 }
200
201
202#------------------------- node types -----------------------
203
204c_object: v_c_domain_type
205 {
206 result = val[0]
207 }
208 | c_complex_object
209 {
210 result = OpenEHR::AM::Archetype::Constraint_Model::C_COMPLEX_OBJECT.new
211 }
212 | archetype_internal_ref
213 {
214 result = OpenEHR::AM::Archetype::Constraint_Model::ARCHETYPE_INTERNAL_REF.new
215 }
216 | archetype_slot
217 {
218 result = OpenEHR::AM::Archetype::Constraint_Model::ARCHETYPE_SLOT.new
219 }
220 | constraint_ref
221 {
222 result = OpenEHR::AM::Archetype::Constraint_Model::CONSTRAINT_REF.new
223 }
224 | c_code_phrase
225 {
226 result = val[0]
227 }
228 | c_ordinal
229 {
230 result = val[0]
231 }
232 | c_primitive_object
233 {
234 result = val[0]
235 }
236# | v_c_domain_type
237# | V_C_DOMAIN_TYPE
238 # this is an attempt to match a dADL section inside cADL. It will
239 # probably never work 100% properly since there can be '>' inside "||"
240 # ranges, and also strings containing any character, e.g. units string
241 # contining "{}" chars. The real solution is to use the dADL parser on
242 # the buffer from the current point on and be able to fast-forward the
243 # cursor to the last character matched by the dADL scanner
244 | ERR_C_DOMAIN_TYPE
245 | error
246
247v_c_domain_type: START_V_C_DOMAIN_TYPE_BLOCK dadl_section END_V_C_DOMAIN_TYPE_BLOCK
248 {
249 result = val[1]
250 }
251
252# 'archetype_internal_ref' is a node that refers to a previously defined object node in the same archetype.
253archetype_internal_ref: SYM_USE_NODE type_identifier c_occurrences absolute_path
254 | SYM_USE_NODE type_identifier error
255
256# 'archetype_slot' is a node whose statements define a constraint that determines which other archetypes may appear at that point in the current archetype.
257archetype_slot: c_archetype_slot_head SYM_MATCHES SYM_START_CBLOCK c_includes c_excludes SYM_END_CBLOCK
258
259c_archetype_slot_head: c_archetype_slot_id c_occurrences
260
261c_archetype_slot_id: SYM_ALLOW_ARCHETYPE type_identifier
262 | SYM_ALLOW_ARCHETYPE type_identifier V_LOCAL_TERM_CODE_REF
263 | SYM_ALLOW_ARCHETYPE error
264
265# 'c_primitive_object' is an node representing a constraint on a primitive object type.
266c_primitive_object: c_primitive
267 {
268 assert_at(__FILE__,__LINE__){val[0].kind_of?(OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_PRIMITIVE)}
269 result = OpenEHR::AM::Archetype::Constraint_Model::C_PRIMITIVE_OBJECT.new(:item => val[0])
270 }
271
272c_primitive: c_integer
273 {
274 @@log.info("#{__FILE__}:#{__LINE__}: c_integer = #{val[0]} at #{@filename}:#{@lineno}")
275 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_INTEGER.new
276 }
277 | c_real
278 {
279 @@log.info("#{__FILE__}:#{__LINE__}: c_real = #{val[0]} at #{@filename}:#{@lineno}")
280 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_REAL.new
281 }
282 | c_date
283 {
284 @@log.info("#{__FILE__}:#{__LINE__}: c_date = #{val[0]} at #{@filename}:#{@lineno}")
285 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_DATE.new
286 }
287 | c_time
288 {
289 @@log.info("#{__FILE__}:#{__LINE__}: c_time = #{val[0]} at #{@filename}:#{@lineno}")
290 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_TIME.new
291 }
292 | c_date_time
293 {
294 @@log.info("#{__FILE__}:#{__LINE__}: c_date_time = #{val[0]} at #{@filename}:#{@lineno}")
295 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_DATE_TIME.new
296 }
297 | c_duration
298 {
299 @@log.info("#{__FILE__}:#{__LINE__}: c_duration = #{val[0]} at #{@filename}:#{@lineno}")
300 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_DURATION.new
301 }
302 | c_string
303 {
304 @@log.info("#{__FILE__}:#{__LINE__}: c_string = #{val[0]} at #{@filename}:#{@lineno}")
305 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_STRING.new
306 }
307 | c_boolean
308 {
309 assert_at(__FILE__,__LINE__){val[0].instance_of?(OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_BOOLEAN)}
310 @@log.info("#{__FILE__}:#{__LINE__}: c_boolean = #{val[0]} at #{@filename}:#{@lineno}")
311 result = val[0]
312 }
313
314c_any: Star_code
315#c_any: '*'
316
317#---------------- BODY - relationships ----------------
318
319c_attributes: c_attribute
320 {
321 result = [val[0]]
322 }
323 | c_attributes c_attribute
324 {
325 result = (val[0] << val[1])
326 }
327
328# 'c_attribute' is a node representing a constraint on an attribute in an object model.
329c_attribute: c_attr_head SYM_MATCHES SYM_START_CBLOCK c_attr_values SYM_END_CBLOCK
330 {
331 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEHR::AM::Archetype::Constraint_Model::C_ATTRIBUTE)}
332 c_attribute = val[0]
333 c_attribute.children = val[3]
334 result = c_attribute
335 }
336 | c_attr_head SYM_MATCHES START_REGEXP_BLOCK REGEXP_BODY END_REGEXP_BLOCK # added by akimichi
337 {
338 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEHR::AM::Archetype::Constraint_Model::C_ATTRIBUTE)}
339 result = val[0]
340 }
341 | c_attr_head SYM_MATCHES SYM_START_CBLOCK error SYM_END_CBLOCK
342 {
343 assert_at(__FILE__,__LINE__){ val[0].kind_of?(OpenEHR::AM::Archetype::Constraint_Model::C_ATTRIBUTE)}
344 result = val[0]
345 }
346
347
348c_attr_head: V_ATTRIBUTE_IDENTIFIER c_existence
349 {
350 @@log.info("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]}, c_existence = #{val[1]} at #{@filename}")
351 result = OpenEHR::AM::Archetype::Constraint_Model::C_SINGLE_ATTRIBUTE.new(
352 :rm_attribute_name => val[0],
353 :existence => val[1]
354 )
355
356 }
357 | V_ATTRIBUTE_IDENTIFIER c_existence c_cardinality
358 {
359 assert_at(__FILE__,__LINE__){ val[2].instance_of?(OpenEHR::AM::Archetype::Constraint_Model::CARDINALITY) }
360 @@log.info("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER: #{val[0]}, c_existence = #{val[1]}, c_cardinality = #{val[2]} at #{@filename}")
361 result = OpenEHR::AM::Archetype::Constraint_Model::C_MULTIPLE_ATTRIBUTE.new(
362 :rm_attribute_name => val[0],
363 :existence => val[1],
364 :cardinality => val[2]
365 )
366 }
367
368c_attr_values: c_object
369 {
370 result = Array[val[0]]
371 }
372 | c_attr_values c_object
373 {
374 result = (val[0] << val[1])
375 }
376 | c_any # -- to allow a property to have any value
377 {
378 result = Array[val[0]]
379 }
380
381### c_includes: #-- Empty
382### | SYM_INCLUDE assertions
383c_includes: #-- Empty
384 | SYM_INCLUDE invariants
385
386### c_excludes: #-- Empty
387### | SYM_EXCLUDE assertions
388c_excludes: #-- Empty
389 | SYM_EXCLUDE invariants
390
391invariants: invariant
392 | invariants invariant
393
394invariant: any_identifier ':' boolean_expression
395 | boolean_expression
396 | any_identifier ':' error
397
398arch_invariant: #-- no invariant ok
399 | SYM_INVARIANT V_ASSERTION_TEXT
400 | SYM_INVARIANT error
401
402# define all linguistic entries in this part as dADL.
403#arch_ontology: SYM_ONTOLOGY V_DADL_TEXT
404# | SYM_ONTOLOGY error
405
406arch_ontology: SYM_ONTOLOGY dadl_section
407 {
408 dadl_section = val[1]
409 result = OpenEHR::AM::Archetype::Ontology::ARCHETYPE_ONTOLOGY.new
410 }
411 | SYM_ONTOLOGY error
412
413
414### dADL section
415dadl_section: dadl_input
416
417dadl_input: attr_vals
418 | complex_object_block
419# | error
420
421attr_vals: attr_val
422 {
423 result = Array[val[0]]
424 }
425 | attr_vals attr_val
426 {
427 result = (val[0] << val[1])
428 }
429 | attr_vals Semicolon_code attr_val
430 {
431 result = (val[0] << val[2])
432 }
433
434attr_val: attr_id SYM_EQ object_block
435 {
436 @@log.info("#{__FILE__}:#{__LINE__}: attr_id = #{val[0]}, object_block = #{val[2]} at #{@filename}:#{@lineno}")
437 result = {:attr_id => val[0], :object_block => val[2]}
438 }
439
440attr_id: V_ATTRIBUTE_IDENTIFIER
441 {
442 @@log.info("#{__FILE__}:#{__LINE__}: V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}:#{@lineno}")
443 result = val[0]
444 }
445 | V_ATTRIBUTE_IDENTIFIER error
446
447object_block: complex_object_block
448 {
449 result = val[0]
450 }
451 | primitive_object_block
452 {
453 result = val[0]
454 }
455
456complex_object_block: single_attr_object_block
457 {
458 result = val[0]
459 }
460 | multiple_attr_object_block
461 {
462 result = val[0]
463 }
464
465multiple_attr_object_block: untyped_multiple_attr_object_block
466 {
467 result = {:untyped_multiple_attr_object_block => val[0]}
468 }
469 | type_identifier untyped_multiple_attr_object_block
470 {
471 result = {:type_identifier => val[0], :untyped_multiple_attr_object_block => val[1]}
472 }
473
474untyped_multiple_attr_object_block: multiple_attr_object_block_head keyed_objects SYM_END_DBLOCK
475 {
476 result = {:multiple_attr_object_block_head => val[0], :keyed_objects => val[1]}
477 }
478
479multiple_attr_object_block_head: SYM_START_DBLOCK
480 {
481 @@log.info("SYM_START_DBLOCK: #{val[0]} at #{@filename}:#{@lineno}")
482 result = val[0]
483 }
484
485keyed_objects: keyed_object
486 {
487 result = Array[val[0]]
488 }
489 | keyed_objects keyed_object
490 {
491 result = (val[0] << val[1])
492 }
493
494keyed_object: object_key SYM_EQ object_block
495 {
496 @@log.info("#{__FILE__}:#{__LINE__}: keyed_object = #{val[0]}, object_block = #{val[2]} at #{@filename}:#{@lineno}")
497 result = {:object_key => val[0], :object_block => val[1]}
498 }
499
500object_key: Left_bracket_code simple_value Right_bracket_code
501 {
502 @@log.info("object_key: [#{val[1]}] at #{@filename}:#{@lineno}")
503 result = val[1]
504 }
505
506single_attr_object_block: untyped_single_attr_object_block
507 {
508 result = {:untyped_single_attr_object_block => val[0]}
509 }
510 | type_identifier untyped_single_attr_object_block
511 {
512 result = {:type_identifier => val[0], :untyped_single_attr_object_block => val[1]}
513 }
514
515untyped_single_attr_object_block: single_attr_object_complex_head SYM_END_DBLOCK # <>
516 {
517 @@log.info("#{__FILE__}:#{__LINE__}: single_attr_object_complex_head = #{val[0]} at #{@filename}:#{@lineno}")
518 result = {:single_attr_object_complex_head => val[0]}
519 }
520 | single_attr_object_complex_head attr_vals SYM_END_DBLOCK
521 {
522 @@log.info("#{__FILE__}:#{__LINE__}: single_attr_object_complex_head = #{val[0]}, attr_vals = #{val[1]} at #{@filename}:#{@lineno}")
523 result = {:single_attr_object_complex_head => val[0], :attr_vals => val[1]}
524 }
525single_attr_object_complex_head: SYM_START_DBLOCK
526primitive_object_block: untyped_primitive_object_block
527 {
528 @@log.info("#{__FILE__}:#{__LINE__}: untyped_primitive_object_block = #{val[0]} at #{@filename}:#{@lineno}")
529 result = {:untyped_primitive_object_block => val[0]}
530 }
531 | type_identifier untyped_primitive_object_block
532 {
533 @@log.info("#{__FILE__}:#{__LINE__}: type_identifier = #{val[0]}, untyped_primitive_object_block = #{val[1]} at #{@filename}:#{@lineno}")
534 result = {:type_identifier => val[0], :untyped_primitive_object_block => val[1]}
535 }
536untyped_primitive_object_block: SYM_START_DBLOCK primitive_object_value SYM_END_DBLOCK
537 {
538 @@log.info("#{__FILE__}:#{__LINE__}: primitive_object_block = <#{val[1]}> at #{@filename}:#{@lineno}")
539 result = val[1]
540 }
541primitive_object_value: simple_value
542 {
543 result = val[0]
544 }
545 | simple_list_value
546 {
547 result = val[0]
548 }
549 | simple_interval_value
550 {
551 result = val[0]
552 }
553 | term_code
554 {
555 result = val[0]
556 }
557 | term_code_list_value
558 {
559 result = val[0]
560 }
561simple_value: string_value
562 {
563 @@log.info("string_value: #{val[0]} at #{@filename}:#{@lineno}")
564 result = val[0]
565 }
566 | integer_value
567 {
568 @@log.info("integer_value: #{val[0]} at #{@filename}:#{@lineno}")
569 result = val[0]
570 }
571 | real_value
572 {
573 @@log.info("real_value: #{val[0]} at #{@filename}:#{@lineno}")
574 result = val[0]
575 }
576 | boolean_value
577 {
578 @@log.info("boolean_value: #{val[0]} at #{@filename}:#{@lineno}")
579 result = val[0]
580 }
581 | character_value
582 {
583 @@log.info("character_value: #{val[0]} at #{@filename}:#{@lineno}")
584 result = val[0]
585 }
586 | date_value
587 {
588 @@log.info("date_value: #{val[0]} at #{@filename}:#{@lineno}")
589 result = val[0]
590 }
591 | time_value
592 {
593 @@log.info("time_value: #{val[0]} at #{@filename}:#{@lineno}")
594 result = val[0]
595 }
596 | date_time_value
597 {
598 @@log.info("date_time_value: #{val[0]} at #{@filename}:#{@lineno}")
599 result = val[0]
600 }
601 | duration_value
602 {
603 @@log.info("duration_value: #{val[0]} at #{@filename}:#{@lineno}")
604 result = val[0]
605 }
606 | uri_value
607 {
608 @@log.info("uri_value: #{val[0]} at #{@filename}:#{@lineno}")
609 result = val[0]
610 }
611
612simple_list_value: string_list_value
613 | integer_list_value
614 | real_list_value
615 | boolean_list_value
616 | character_list_value
617 | date_list_value
618 | time_list_value
619 | date_time_list_value
620 | duration_list_value
621
622simple_interval_value: integer_interval_value
623 | real_interval_value
624 | date_interval_value
625 | time_interval_value
626 | date_time_interval_value
627 | duration_interval_value
628
629type_identifier: V_TYPE_IDENTIFIER
630 {
631 @@log.info("V_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
632 result = val[0]
633 }
634 | V_GENERIC_TYPE_IDENTIFIER
635 {
636 @@log.info("V_GENERIC_TYPE_IDENTIFIER: #{val[0]} at #{@filename}:#{@lineno}")
637 result = val[0]
638 }
639
640string_value: V_STRING
641 {
642 @@log.info("V_STRING: #{val[0]} at #{@filename}:#{@lineno}")
643 result = val[0]
644 }
645
646string_list_value: V_STRING Comma_code V_STRING
647 | string_list_value Comma_code V_STRING
648 | V_STRING Comma_code SYM_LIST_CONTINUE
649
650integer_value: V_INTEGER
651 {
652 begin
653 integer = Integer(val[0])
654 rescue
655 raise
656 end
657 result = integer
658 }
659 | Plus_code V_INTEGER
660 {
661 begin
662 integer = Integer(val[0])
663 rescue
664 raise
665 end
666 result = integer
667 }
668 | Minus_code V_INTEGER
669 {
670 begin
671 integer = Integer(val[0])
672 rescue
673 raise
674 end
675 result = - integer
676 }
677### | '+' V_INTEGER
678### | '-' V_INTEGER
679
680integer_list_value: integer_value Comma_code integer_value
681 | integer_list_value Comma_code integer_value
682 | integer_value Comma_code SYM_LIST_CONTINUE
683
684integer_interval_value: SYM_INTERVAL_DELIM integer_value SYM_ELLIPSIS integer_value SYM_INTERVAL_DELIM
685 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_ELLIPSIS integer_value SYM_INTERVAL_DELIM
686 | SYM_INTERVAL_DELIM integer_value SYM_ELLIPSIS SYM_LT integer_value SYM_INTERVAL_DELIM
687 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_ELLIPSIS SYM_LT integer_value SYM_INTERVAL_DELIM
688 | SYM_INTERVAL_DELIM SYM_LT integer_value SYM_INTERVAL_DELIM
689 | SYM_INTERVAL_DELIM SYM_LE integer_value SYM_INTERVAL_DELIM
690 | SYM_INTERVAL_DELIM SYM_GT integer_value SYM_INTERVAL_DELIM
691 | SYM_INTERVAL_DELIM SYM_GE integer_value SYM_INTERVAL_DELIM
692 | SYM_INTERVAL_DELIM integer_value SYM_INTERVAL_DELIM
693
694real_value: V_REAL
695 {
696 begin
697 real = Float(val[0])
698 rescue
699 raise
700 end
701 result = real
702 }
703 | Plus_code V_REAL
704 {
705 begin
706 real = Float(val[1])
707 rescue
708 raise
709 end
710 result = real
711 }
712 | Minus_code V_REAL
713 {
714 begin
715 real = Float(val[1])
716 rescue
717 raise
718 end
719 result = - real
720 }
721
722real_list_value: real_value Comma_code real_value
723 | real_list_value Comma_code real_value
724 | real_value Comma_code SYM_LIST_CONTINUE
725
726real_interval_value: SYM_INTERVAL_DELIM real_value SYM_ELLIPSIS real_value SYM_INTERVAL_DELIM
727 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_ELLIPSIS real_value SYM_INTERVAL_DELIM
728 | SYM_INTERVAL_DELIM real_value SYM_ELLIPSIS SYM_LT real_value SYM_INTERVAL_DELIM
729 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_ELLIPSIS SYM_LT real_value SYM_INTERVAL_DELIM
730 | SYM_INTERVAL_DELIM SYM_LT real_value SYM_INTERVAL_DELIM
731 | SYM_INTERVAL_DELIM SYM_LE real_value SYM_INTERVAL_DELIM
732 | SYM_INTERVAL_DELIM SYM_GT real_value SYM_INTERVAL_DELIM
733 | SYM_INTERVAL_DELIM SYM_GE real_value SYM_INTERVAL_DELIM
734 | SYM_INTERVAL_DELIM real_value SYM_INTERVAL_DELIM
735
736
737boolean_value: SYM_TRUE
738 {
739 result = true
740 }
741 | SYM_FALSE
742 {
743 result = false
744 }
745
746boolean_list_value: boolean_value Comma_code boolean_value
747 | boolean_list_value Comma_code boolean_value
748 | boolean_value Comma_code SYM_LIST_CONTINUE
749
750character_value: V_CHARACTER
751
752character_list_value: character_value Comma_code character_value
753 | character_list_value Comma_code character_value
754 | character_value Comma_code SYM_LIST_CONTINUE
755
756date_value: V_ISO8601_EXTENDED_DATE
757
758date_list_value: date_value Comma_code date_value
759 | date_list_value Comma_code date_value
760 | date_value Comma_code SYM_LIST_CONTINUE
761
762date_interval_value: SYM_INTERVAL_DELIM date_value SYM_ELLIPSIS date_value SYM_INTERVAL_DELIM
763 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_ELLIPSIS date_value SYM_INTERVAL_DELIM
764 | SYM_INTERVAL_DELIM date_value SYM_ELLIPSIS SYM_LT date_value SYM_INTERVAL_DELIM
765 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_ELLIPSIS SYM_LT date_value SYM_INTERVAL_DELIM
766 | SYM_INTERVAL_DELIM SYM_LT date_value SYM_INTERVAL_DELIM
767 | SYM_INTERVAL_DELIM SYM_LE date_value SYM_INTERVAL_DELIM
768 | SYM_INTERVAL_DELIM SYM_GT date_value SYM_INTERVAL_DELIM
769 | SYM_INTERVAL_DELIM SYM_GE date_value SYM_INTERVAL_DELIM
770 | SYM_INTERVAL_DELIM date_value SYM_INTERVAL_DELIM
771
772time_value: V_ISO8601_EXTENDED_TIME
773
774time_list_value: time_value Comma_code time_value
775 | time_list_value Comma_code time_value
776 | time_value Comma_code SYM_LIST_CONTINUE
777
778time_interval_value: SYM_INTERVAL_DELIM time_value SYM_ELLIPSIS time_value SYM_INTERVAL_DELIM
779 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_ELLIPSIS time_value SYM_INTERVAL_DELIM
780 | SYM_INTERVAL_DELIM time_value SYM_ELLIPSIS SYM_LT time_value SYM_INTERVAL_DELIM
781 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_ELLIPSIS SYM_LT time_value SYM_INTERVAL_DELIM
782 | SYM_INTERVAL_DELIM SYM_LT time_value SYM_INTERVAL_DELIM
783 | SYM_INTERVAL_DELIM SYM_LE time_value SYM_INTERVAL_DELIM
784 | SYM_INTERVAL_DELIM SYM_GT time_value SYM_INTERVAL_DELIM
785 | SYM_INTERVAL_DELIM SYM_GE time_value SYM_INTERVAL_DELIM
786 | SYM_INTERVAL_DELIM time_value SYM_INTERVAL_DELIM
787
788date_time_value: V_ISO8601_EXTENDED_DATE_TIME
789
790date_time_list_value: date_time_value Comma_code date_time_value
791 | date_time_list_value Comma_code date_time_value
792 | date_time_value Comma_code SYM_LIST_CONTINUE
793
794date_time_interval_value: SYM_INTERVAL_DELIM date_time_value SYM_ELLIPSIS date_time_value SYM_INTERVAL_DELIM
795 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_ELLIPSIS date_time_value SYM_INTERVAL_DELIM
796 | SYM_INTERVAL_DELIM date_time_value SYM_ELLIPSIS SYM_LT date_time_value SYM_INTERVAL_DELIM
797 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_ELLIPSIS SYM_LT date_time_value SYM_INTERVAL_DELIM
798 | SYM_INTERVAL_DELIM SYM_LT date_time_value SYM_INTERVAL_DELIM
799 | SYM_INTERVAL_DELIM SYM_LE date_time_value SYM_INTERVAL_DELIM
800 | SYM_INTERVAL_DELIM SYM_GT date_time_value SYM_INTERVAL_DELIM
801 | SYM_INTERVAL_DELIM SYM_GE date_time_value SYM_INTERVAL_DELIM
802 | SYM_INTERVAL_DELIM date_time_value SYM_INTERVAL_DELIM
803
804duration_value: V_ISO8601_DURATION
805 {
806 @@log.info("V_ISO8601_DURATION: #{val[0]} at #{@filename}:#{@lineno}")
807 result = val[0]
808 }
809
810duration_list_value: duration_value Comma_code duration_value
811 | duration_list_value Comma_code duration_value
812 | duration_value Comma_code SYM_LIST_CONTINUE
813
814duration_interval_value: SYM_INTERVAL_DELIM duration_value SYM_ELLIPSIS duration_value SYM_INTERVAL_DELIM
815 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_ELLIPSIS duration_value SYM_INTERVAL_DELIM
816 | SYM_INTERVAL_DELIM duration_value SYM_ELLIPSIS SYM_LT duration_value SYM_INTERVAL_DELIM
817 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_ELLIPSIS SYM_LT duration_value SYM_INTERVAL_DELIM
818 | SYM_INTERVAL_DELIM SYM_LT duration_value SYM_INTERVAL_DELIM
819 | SYM_INTERVAL_DELIM SYM_LE duration_value SYM_INTERVAL_DELIM
820 | SYM_INTERVAL_DELIM SYM_GT duration_value SYM_INTERVAL_DELIM
821 | SYM_INTERVAL_DELIM SYM_GE duration_value SYM_INTERVAL_DELIM
822 | SYM_INTERVAL_DELIM duration_value SYM_INTERVAL_DELIM
823
824term_code: V_QUALIFIED_TERM_CODE_REF
825 {
826 @@log.info("#{__FILE__}:#{__LINE__}: V_QUALIFIED_TERM_CODE_REF = #{val[0]} at #{@filename}:#{@lineno}")
827 result = val[0]
828 }
829
830term_code_list_value: term_code Comma_code term_code
831 | term_code_list_value Comma_code term_code
832 | term_code Comma_code SYM_LIST_CONTINUE
833
834uri_value: V_URI
835 {
836 @@log.info("#{__FILE__}:#{__LINE__}: V_URI = #{val[0]} at #{@filename}:#{@lineno}")
837 result = val[0]
838 }
839
840
841#---------------------- ASSERTIONS ------------------------
842
843assertions: assertion
844 | assertions assertion
845
846assertion: any_identifier ':' boolean_expression
847 | boolean_expression
848 | any_identifier ':' error
849
850#---------------------- expressions ---------------------
851
852boolean_expression: boolean_leaf
853 | boolean_node
854
855boolean_node: SYM_EXISTS absolute_path
856# | absolute_path
857 | SYM_EXISTS error
858 | relative_path SYM_MATCHES SYM_START_CBLOCK c_primitive SYM_END_CBLOCK
859 | relative_path SYM_MATCHES START_REGEXP_BLOCK REGEXP_BODY END_REGEXP_BLOCK # added by akimichi
860 | SYM_NOT boolean_leaf
861 | arithmetic_expression '=' arithmetic_expression
862 | arithmetic_expression SYM_NE arithmetic_expression
863 | arithmetic_expression SYM_LT arithmetic_expression
864 | arithmetic_expression SYM_GT arithmetic_expression
865 | arithmetic_expression SYM_LE arithmetic_expression
866 | arithmetic_expression SYM_GE arithmetic_expression
867 | boolean_expression SYM_AND boolean_expression
868 | boolean_expression SYM_OR boolean_expression
869 | boolean_expression SYM_XOR boolean_expression
870 | boolean_expression SYM_IMPLIES boolean_expression
871
872boolean_leaf: Left_parenthesis_code boolean_expression Right_parenthesis_code
873 | SYM_TRUE
874 | SYM_FALSE
875
876arithmetic_expression: arithmetic_leaf
877 | arithmetic_node
878
879arithmetic_node: arithmetic_expression '+' arithmetic_leaf
880 | arithmetic_expression '-' arithmetic_leaf
881 | arithmetic_expression Star_code arithmetic_leaf
882 | arithmetic_expression Slash_code arithmetic_leaf
883 | arithmetic_expression '^' arithmetic_leaf
884
885arithmetic_leaf: Left_parenthesis_code arithmetic_expression Right_parenthesis_code
886 | integer_value
887 | real_value
888 | absolute_path
889
890
891#--------------- THE FOLLOWING SOURCE TAKEN FROM OG_PATH_VALIDATOR.Y -------------
892#--------------- except to remove movable_path ----------------------------------------------------
893
894
895absolute_path: Slash_code
896 | Slash_code relative_path
897# | absolute_path Slash_code relative_path
898
899
900
901relative_path: path_segment
902 | relative_path Slash_code path_segment
903
904path_segment: V_ATTRIBUTE_IDENTIFIER V_LOCAL_TERM_CODE_REF
905 {
906 @@log.info("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
907 }
908 | V_ATTRIBUTE_IDENTIFIER
909 {
910 @@log.info("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{val[0]} at #{@filename}")
911 }
912
913
914#-------------------------------- END SOURCE TAKEN FROM OG_PATH_VALIDATOR.Y ----------------------
915
916
917#---------------- existence, occurrences, cardinality ----------------
918
919c_existence: #-- default to 1..1
920 {
921 result = Range.new(1,1)
922 }
923 | SYM_EXISTENCE SYM_MATCHES SYM_START_CBLOCK existence_spec SYM_END_CBLOCK
924 {
925 result = val[3]
926 }
927
928existence_spec: V_INTEGER #-- can only be 0 or 1
929 {
930 begin
931 integer = Integer(val[0])
932 rescue
933 raise
934 end
935 result = integer
936 }
937 | V_INTEGER SYM_ELLIPSIS V_INTEGER #-- can only be 0..0, 0..1, 1..1
938 {
939 begin
940 from_integer = Integer(val[0])
941 to_integer = Integer(val[2])
942 rescue
943 raise
944 end
945 result = Range.new(from_integer,to_integer)
946 }
947
948c_cardinality: SYM_CARDINALITY SYM_MATCHES SYM_START_CBLOCK cardinality_spec SYM_END_CBLOCK
949 {
950 result = OpenEHR::AM::Archetype::Constraint_Model::CARDINALITY.new
951 }
952
953cardinality_spec: occurrence_spec
954 | occurrence_spec Semicolon_code SYM_ORDERED
955 | occurrence_spec Semicolon_code SYM_UNORDERED
956 | occurrence_spec Semicolon_code SYM_UNIQUE
957 | occurrence_spec Semicolon_code SYM_ORDERED Semicolon_code SYM_UNIQUE
958 | occurrence_spec Semicolon_code SYM_UNORDERED Semicolon_code SYM_UNIQUE
959 | occurrence_spec Semicolon_code SYM_UNIQUE Semicolon_code SYM_ORDERED
960 | occurrence_spec Semicolon_code SYM_UNIQUE Semicolon_code SYM_UNORDERED
961
962cardinality_limit_value: integer_value
963 | Star_code
964# | '*'
965
966c_occurrences: #-- default to 1..1
967 | SYM_OCCURRENCES SYM_MATCHES SYM_START_CBLOCK occurrence_spec SYM_END_CBLOCK
968 {
969 result = val[3]
970 }
971 | SYM_OCCURRENCES error
972
973occurrence_spec: cardinality_limit_value #-- single integer or '*'
974 | V_INTEGER SYM_ELLIPSIS cardinality_limit_value
975
976#---------------------- leaf constraint types -----------------------
977
978c_integer_spec: integer_value
979 | integer_list_value
980 | integer_interval_value
981
982c_integer: c_integer_spec
983 | c_integer_spec Semicolon_code integer_value
984 | c_integer_spec Semicolon_code error
985
986c_real_spec: real_value
987 | real_list_value
988 | real_interval_value
989
990c_real: c_real_spec
991 | c_real_spec Semicolon_code real_value
992 | c_real_spec Semicolon_code error
993
994c_date_constraint: V_ISO8601_DATE_CONSTRAINT_PATTERN
995 | date_value
996 | date_interval_value
997
998c_date: c_date_constraint
999 | c_date_constraint Semicolon_code date_value
1000 | c_date_constraint Semicolon_code error
1001
1002c_time_constraint: V_ISO8601_TIME_CONSTRAINT_PATTERN
1003 | time_value
1004 | time_interval_value
1005
1006c_time: c_time_constraint
1007 | c_time_constraint Semicolon_code time_value
1008 | c_time_constraint Semicolon_code error
1009
1010c_date_time_constraint: V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN
1011 | date_time_value
1012 | date_time_interval_value
1013
1014c_date_time: c_date_time_constraint
1015 | c_date_time_constraint Semicolon_code date_time_value
1016 | c_date_time_constraint Semicolon_code error
1017
1018c_duration_constraint: duration_pattern
1019 | duration_pattern Slash_code duration_interval_value
1020 | duration_value
1021 | duration_interval_value
1022
1023c_duration: c_duration_constraint
1024 | c_duration_constraint Semicolon_code duration_value
1025 | c_duration_constraint Semicolon_code error
1026
1027c_string_spec: V_STRING #-- single value, generates closed list
1028 | string_list_value #-- closed list
1029 | string_list_value Comma_code SYM_LIST_CONTINUE #-- open list
1030# | string_list_value ',' SYM_LIST_CONTINUE #-- open list
1031# | V_REGEXP #-- regular expression with "//" or "^^" delimiters
1032
1033c_string: c_string_spec
1034 | c_string_spec Semicolon_code string_value
1035 | c_string_spec Semicolon_code error
1036
1037c_boolean_spec: SYM_TRUE
1038 {
1039 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_BOOLEAN.new(:true_valid => true)
1040 }
1041 | SYM_FALSE
1042 {
1043 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_BOOLEAN.new(:true_valid => false)
1044 }
1045 | SYM_TRUE Comma_code SYM_FALSE
1046 {
1047 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_BOOLEAN.new(:true_valid => true,:false_valid => false)
1048 }
1049 | SYM_FALSE Comma_code SYM_TRUE
1050 {
1051 result = OpenEHR::AM::Archetype::Constraint_Model::Primitive::C_BOOLEAN.new(:true_valid => false,:false_valid => true)
1052 }
1053
1054c_boolean: c_boolean_spec
1055 {
1056 result = val[0]
1057 }
1058 | c_boolean_spec Semicolon_code boolean_value
1059 {
1060 raise 'Not implemented yet'
1061 }
1062 | c_boolean_spec Semicolon_code error
1063 {
1064 raise 'Not implemented yet'
1065 }
1066
1067c_ordinal: c_ordinal_spec
1068 | c_ordinal_spec Semicolon_code integer_value
1069 | c_ordinal_spec Semicolon_code error
1070
1071c_ordinal_spec: ordinal
1072 | c_ordinal_spec Comma_code ordinal
1073
1074ordinal: integer_value SYM_INTERVAL_DELIM V_QUALIFIED_TERM_CODE_REF
1075 {
1076 @in_interval = false
1077 @@log.info("#{__FILE__}:#{__LINE__}, #{val[0]}|#{val[2]} at #{@filename}")
1078 }
1079
1080#c_code_phrase: V_TERM_CODE_CONSTRAINT #-- e.g. "[local::at0040, at0041; at0040]"
1081c_code_phrase: term_code_constraint_section #-- e.g. "[local::at0040, at0041; at0040]"
1082 | V_QUALIFIED_TERM_CODE_REF
1083
1084#term_code_constraint_section: START_TERM_CODE_CONSTRAINT term_code_body Right_bracket_code
1085term_code_constraint_section: START_TERM_CODE_CONSTRAINT term_code_body END_TERM_CODE_CONSTRAINT
1086term_code_body: # empty
1087 | TERM_CODE
1088 | term_code_body TERM_CODE
1089### term_code_constraint_section: START_TERM_CODE_CONSTRAINT term_code_body END_TERM_CODE_CONSTRAINT
1090### term_code_body: TERM_CODE
1091### | term_code_body TERM_CODE
1092
1093# A Constraint_Ref is a proxy for a set of constraints on an object.
1094constraint_ref: V_LOCAL_TERM_CODE_REF #-- e.g. "ac0003"
1095
1096any_identifier: type_identifier
1097 | V_ATTRIBUTE_IDENTIFIER
1098 {
1099 @@log.info("#{__FILE__}:#{__LINE__}, V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}")
1100 }
1101
1102
1103#----------------- TAKEN FROM DADL_VALIDATOR.Y -------------------
1104#----------------- DO NOT MODIFY -------------------
1105#---------------------- BASIC DATA VALUES -----------------------
1106
1107duration_pattern: V_ISO8601_DURATION_CONSTRAINT_PATTERN
1108 {
1109 result = val[0]
1110 }
1111
1112
1113
1114---- header
1115
1116$:.unshift File.join(File.dirname(__FILE__))
1117require 'logger'
1118require 'lib/util.rb'
1119require 'lib/scanner.rb'
1120require 'rubygems'
1121require 'am.rb'
1122$DEBUG = true
1123
1124
1125
1126---- inner
1127
1128def assert_at(file,line, message = "")
1129 unless yield
1130 raise "Assertion failed !: #{file}, #{line}: #{message}"
1131 end
1132end
1133
1134@@log = Logger.new('log/parser.log','daily')
1135@@dadl_scanner = OpenEHR::ADL::Scanner::DADL::RootScanner.new
1136@@cadl_scanner = OpenEHR::ADL::Scanner::CADL::RootScanner.new
1137
1138###----------/* keywords */ ---------------------------------------------
1139@@adl_reserved = {
1140 'archetype' => :SYM_ARCHETYPE,
1141 'adl_version' => :SYM_ADL_VERSION,
1142 'controlled' => :SYM_IS_CONTROLLED,
1143 'specialize' => :SYM_SPECIALIZE,
1144 'concept' => :SYM_CONCEPT,
1145 'language' => :SYM_LANGUAGE,
1146 'description' => :SYM_DESCRIPTION,
1147 'definition' => :SYM_DEFINITION,
1148 'invariant' => :SYM_INVARIANT,
1149 'ontology' => :SYM_ONTOLOGY,
1150 'matches' => :SYM_MATCHES,
1151 'is_in' => :SYM_MATCHES,
1152 'occurrences' => :SYM_OCCURRENCES,
1153 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
1154 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
1155 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
1156}
1157
1158@@dadl_reserved = {
1159 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
1160 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
1161 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
1162}
1163
1164@@cadl_reserved = {
1165 'then' => :SYM_THEN, # [Tt][Hh][Ee][Nn]
1166 'else' => :SYM_ELSE, # [Ee][Ll][Ss][Ee]
1167 'and' => :SYM_AND, # [Aa][Nn][Dd]
1168 'or' => :SYM_OR, # [Oo][Rr]
1169 'xor' => :SYM_XOR, # [Xx][Oo][Rr]
1170 'not' => :SYM_NOT, # [Nn][Oo][Tt]
1171 'implies' => :SYM_IMPLIES, # [Ii][Mm][Pp][Ll][Ii][Ee][Ss]
1172 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
1173 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
1174 'forall' => :SYM_FORALL, # [Ff][Oo][Rr][_][Aa][Ll][Ll]
1175 'exists' => :SYM_EXISTS, # [Ee][Xx][Ii][Ss][Tt][Ss]
1176 'existence' => :SYM_EXISTENCE, # [Ee][Xx][Iu][Ss][Tt][Ee][Nn][Cc][Ee]
1177 'occurrences' => :SYM_OCCURRENCES, # [Oo][Cc][Cc][Uu][Rr][Rr][Ee][Nn][Cc][Ee][Ss]
1178 'cardinality' => :SYM_CARDINALITY, # [Cc][Aa][Rr][Dd][Ii][Nn][Aa][Ll][Ii][Tt][Yy]
1179 'ordered' => :SYM_ORDERED, # [Oo][Rr][Dd][Ee][Rr][Ee][Dd]
1180 'unordered' => :SYM_UNORDERED, # [Uu][Nn][Oo][Rr][Dd][Ee][Rr][Ee][Dd]
1181 'unique' => :SYM_UNIQUE, # [Uu][Nn][Ii][Qq][Uu][Ee]
1182 'matches' => :SYM_MATCHES, # [Mm][Aa][Tt][Cc][Hh][Ee][Ss]
1183 'is_in' => :SYM_MATCHES, # [Ii][Ss][_][Ii][Nn]
1184 'invariant' => :SYM_INVARIANT, # [Ii][Nn][Vv][Aa][Rr][Ii][Aa][Nn][Tt]
1185 'infinity' => :SYM_INFINITY, # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
1186 'use_node' => :SYM_USE_NODE, # [Uu][Ss][Ee][_][Nn][Oo][Dd][Ee]
1187 'use_archetype' => :SYM_ALLOW_ARCHETYPE, # [Uu][Ss][Ee][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1188 'allow_archetype' => :SYM_ALLOW_ARCHETYPE, # [Aa][Ll][Ll][Oo][Ww][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1189 'include' => :SYM_INCLUDE, # [Ii][Nn][Cc][Ll][Uu][Dd][Ee]
1190 'exclude' => :SYM_EXCLUDE # [Ee][Xx][Cc][Ll][Uu][Dd][Ee]
1191}
1192
1193
1194###----------/* Scanner */ -----------------------------------------------
1195
1196def scan
1197 until @data.nil? do
1198 case @adl_type.last
1199 when :adl
1200 @data = scan_adl(@data) do |sym, val|
1201 yield sym, val
1202 end
1203 when :dadl
1204 @data = scan_dadl(@data) do |sym, val|
1205 yield sym, val
1206 end
1207 when :cadl
1208 @data = scan_cadl(@data) do |sym, val|
1209 yield sym, val
1210 end
1211 when :regexp
1212 @data = scan_regexp(@data) do |sym, val|
1213 yield sym, val
1214 end
1215 else
1216 raise
1217 end
1218 @data = $' # variable $' receives the string after the match
1219 end
1220 yield :EOF, nil
1221 yield false, '$'
1222end # of scan
1223
1224def scan_adl(data)
1225 until data.nil? do
1226 case @adl_type.last
1227 when :adl
1228# puts "Entering scan_adl"
1229 case data
1230 when /\A\n/ # carriage return
1231 @lineno += 1
1232 ;
1233 when /\A[ \t\r\f]+/ #just drop it
1234 ;
1235 when /\A--.*\n/ # single line comment
1236 @lineno += 1
1237 @@log.info("#{__FILE__}:#{__LINE__}: scan_adl: COMMENT = #{$&} at #{@filename}:#{@lineno}")
1238 ;
1239 when /\Adescription/ # description
1240 yield :SYM_DESCRIPTION, :SYM_DESCRIPTION
1241 when /\Adefinition/ # definition
1242 yield :SYM_DEFINITION, :SYM_DEFINITION
1243# @adl_type.push(:cadl)
1244 ###----------/* symbols */ -------------------------------------------------
1245 when /\A[A-Z][a-zA-Z0-9_]*/
1246 yield :V_TYPE_IDENTIFIER, $&
1247 when /\A[a-zA-Z][a-zA-Z0-9_-]+\.[a-zA-Z][a-zA-Z0-9_-]+\.[a-zA-Z0-9]+/ #V_ARCHETYPE_ID
1248 yield :V_ARCHETYPE_ID, $&
1249 when /\A[a-z][a-zA-Z0-9_]*/
1250# word = $&.downcase
1251 word = $&
1252 if @@adl_reserved[word]
1253 @@log.info("#{__FILE__}:#{__LINE__}: scan_adl: @@adl_reserved = #{@@adl_reserved[word]} at #{@filename}:#{@lineno}")
1254 yield @@adl_reserved[word], @@adl_reserved[word]
1255 elsif #/\A[A-Z][a-zA-Z0-9_]*/
1256 @@log.info("#{__FILE__}:#{__LINE__}: scan_adl: V_ATTRIBUTE_IDENTIFIER = #{$&} at #{@filename}:#{@lineno}")
1257 yield :V_ATTRIBUTE_IDENTIFIER, $&
1258 end
1259 when /\A\=/ # =
1260 yield :SYM_EQ, :SYM_EQ
1261 when /\A\>=/ # >=
1262 yield :SYM_GE, :SYM_GE
1263 when /\A\<=/ # <=
1264 yield :SYM_LE, :SYM_LE
1265 when /\A\</ # <
1266 if @in_interval
1267# @start_block_received = false
1268 yield :SYM_LT, :SYM_LT
1269 else
1270# @start_block_received = true
1271 @adl_type.push(:dadl)
1272 yield :SYM_START_DBLOCK, $&
1273 end
1274 when /\A\>/ # >
1275 if @in_interval
1276 yield :SYM_GT, :SYM_GT
1277 else
1278 adl_type = @adl_type.pop
1279# puts "Escaping #{adl_type}"
1280 assert_at(__FILE__,__LINE__){adl_type == :dadl}
1281 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
1282 end
1283 when /\A\{/ # {
1284 @adl_type.push(:cadl)
1285 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: entering cADL at #{@filename}:#{@lineno}")
1286 yield :SYM_START_CBLOCK, :SYM_START_CBLOCK
1287 when /\A\}/ # }
1288 adl_type = @adl_type.pop
1289# puts "Escaping #{adl_type}"
1290 assert_at(__FILE__,__LINE__){adl_type == :cadl}
1291 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: exiting cADL at #{@filename}:#{@lineno}")
1292 yield :SYM_END_CBLOCK, $&
1293 when /\A\-/ # -
1294 yield :Minus_code, :Minus_code
1295 when /\A\+/ # +
1296 yield :Plus_code, :Plus_code
1297 when /\A\*/ # *
1298 yield :Star_code, :Star_code
1299 when /\A\// # /
1300 yield :Slash_code, :Slash_code
1301 when /\A\^/ # ^
1302 yield :Caret_code, :Caret_code
1303 when /\A\=/ # =
1304 yield :Equal_code, :Equal_code
1305 when /\A\.\.\./ # ...
1306 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
1307 when /\A\.\./ # ..
1308 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
1309 when /\A\./ # .
1310 yield :Dot_code, :Dot_code
1311 when /\A\;/ # ;
1312 yield :Semicolon_code, :Semicolon_code
1313 when /\A\,/ # ,
1314 yield :Comma_code, :Comma_code
1315 when /\A\:/ # :
1316 yield :Colon_code, :Colon_code
1317 when /\A\!/ # !
1318 yield :Exclamation_code, :Exclamation_code
1319 when /\A\(/ # (
1320 yield :Left_parenthesis_code, :Left_parenthesis_code
1321 when /\A\)/ # )
1322 yield :Right_parenthesis_code, :Right_parenthesis_code
1323 when /\A\$/ # $
1324 yield :Dollar_code, :Dollar_code
1325 when /\A\?\?/ # ??
1326 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
1327 when /\A\?/ # ?
1328 yield :Question_mark_code, :Question_mark_code
1329 when /\A[0-9]+\.[0-9]+(\.[0-9]+)*/ # ?
1330 yield :V_VERSION_STRING, :V_VERSION_STRING
1331 when /\A\|/ # |
1332 if @in_interval
1333 @in_interval = false
1334 else
1335 @in_interval = true
1336 end
1337 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
1338 when /\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/
1339# when /\A\[[a-zA-Z0-9()\._-]+\:\:[a-zA-Z0-9\._-]+\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
1340 yield :V_QUALIFIED_TERM_CODE_REF, $&
1341 when /\A\[[a-zA-Z0-9][a-zA-Z0-9._\-]*\]/ #V_LOCAL_TERM_CODE_REF
1342 yield :V_LOCAL_TERM_CODE_REF, $&
1343 when /\A\[/ # [
1344 yield :Left_bracket_code, :Left_bracket_code
1345 when /\A\]/ # ]
1346 yield :Right_bracket_code, :Right_bracket_code
1347
1348 when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
1349 yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
1350 when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
1351 yield :V_LOCAL_CODE, $&
1352 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9](Z|[+-][0-9]{4})?/ #V_ISO8601_EXTENDED_DATE_TIME YYYY-MM-DDThh:mm:ss[,sss][Z|+/- -n-n-n-n-]-
1353 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
1354 when /\A[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})? / #V_ISO8601_EXTENDED_TIME hh:mm:ss[,sss][Z|+/-nnnn]
1355 yield :V_ISO8601_EXTENDED_TIME, $&
1356 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]|[0-9]{4}-[0-1][0-9]/ #V_ISO8601_EXTENDED_DATE YYYY-MM-DD
1357 yield :V_ISO8601_EXTENDED_DATE, $&
1358 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
1359 yield :V_GENERIC_TYPE_IDENTIFIER, $&
1360 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
1361 yield :V_INTEGER, $&
1362 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
1363 yield :V_REAL, $&
1364 # when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
1365 when /\A"([^"]*)"/m #V_STRING
1366 yield :V_STRING, $1
1367 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
1368 yield :V_URI, $&
1369 when /\AP([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?T([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?|P([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?/ #V_ISO8601_DURATION PnYnMnWnDTnnHnnMnnS
1370 yield :V_ISO8601_DURATION, $&
1371 when /\A\S/ #UTF8CHAR
1372 yield :UTF8CHAR, $&
1373 end
1374 data = $' # variable $' receives the string after the match
1375 when :dadl
1376# puts "Entering scan_dadl"
1377 data = scan_dadl(data) do |sym, val|
1378 yield sym, val
1379 end
1380 when :cadl
1381# puts "Entering scan_cadl"
1382 data = scan_cadl(data) do |sym, val|
1383 yield sym, val
1384 end
1385 when :regexp
1386# puts "Entering scan_regexp"
1387 data = scan_regexp(data) do |sym, val|
1388 yield sym, val
1389 end
1390 when :term_constraint
1391# puts "Entering scan_term_constraint"
1392 data = scan_term_constraint(data) do |sym, val|
1393 yield sym, val
1394 end
1395 else
1396 raise
1397 end
1398 end
1399end # scan_adl
1400
1401
1402def scan_cadl(data)
1403 until data.nil? do
1404 case @adl_type.last
1405 when :cadl
1406# puts "Entering scan_cadl"
1407 case scanned = @@cadl_scanner.parse(data)
1408 when Yaparc::Result::OK
1409 if scanned.value[0] == :START_V_C_DOMAIN_TYPE_BLOCK
1410 @in_c_domain_type = true
1411 @adl_type.push(:dadl)
1412 yield scanned.value
1413 else
1414 yield scanned.value
1415 end
1416 data = scanned.input
1417 end
1418
1419 case data
1420 when /\A\n/ # carriage return
1421 @lineno += 1
1422 ;
1423 when /\A[ \t\r\f]+/ #just drop it
1424 ;
1425 when /\A--.*\n/ # single line comment
1426 @lineno += 1
1427 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: COMMENT = #{$&} at #{@filename}:#{@lineno}")
1428 ;
1429 ###----------/* symbols */ -------------------------------------------------
1430 when /\A\=/ # =
1431 yield :SYM_EQ, :SYM_EQ
1432 when /\A\>=/ # >=
1433 yield :SYM_GE, :SYM_GE
1434 when /\A\<=/ # <=
1435 yield :SYM_LE, :SYM_LE
1436### when /\A[A-Z][a-zA-Z0-9_]*[ \n]*\</ # V_C_DOMAIN_TYPE
1437### @in_c_domain_type = true
1438### @adl_type.push(:dadl)
1439### yield :START_V_C_DOMAIN_TYPE_BLOCK, $&
1440 when /\A\</ # <
1441 if @in_interval
1442 yield :SYM_LT, :SYM_LT
1443 else
1444 @adl_type.push(:dadl)
1445 yield :SYM_START_DBLOCK, $&
1446 end
1447 when /\A\>/ # >
1448 if @in_interval
1449 yield :SYM_GT, :SYM_GT
1450 else
1451 adl_type = @adl_type.pop
1452# puts "Escaping #{adl_type}"
1453 assert_at(__FILE__,__LINE__){adl_type == :dadl}
1454 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
1455 end
1456 when /\A\-/ # -
1457 yield :Minus_code, :Minus_code
1458 when /\A\+/ # +
1459 yield :Plus_code, :Plus_code
1460 when /\A\*/ # *
1461 yield :Star_code, :Star_code
1462 when /\A\// # /
1463 yield :Slash_code, :Slash_code
1464 when /\A\^/ # ^
1465 yield :Caret_code, :Caret_code
1466 when /\A\.\.\./ # ...
1467 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
1468 when /\A\.\./ # ..
1469 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
1470 when /\A\./ # .
1471 yield :Dot_code, :Dot_code
1472 when /\A\;/ # ;
1473 yield :Semicolon_code, :Semicolon_code
1474 when /\A\,/ # ,
1475 yield :Comma_code, :Comma_code
1476 when /\A\:/ # :
1477 yield :Colon_code, :Colon_code
1478 when /\A\!/ # !
1479 yield :Exclamation_code, :Exclamation_code
1480 when /\A\(/ # (
1481 yield :Left_parenthesis_code, :Left_parenthesis_code
1482 when /\A\)/ # )
1483 yield :Right_parenthesis_code, :Right_parenthesis_code
1484 when /\A\{\// #V_REGEXP
1485 if @adl_type.last != :regexp
1486 @in_regexp = true
1487 @adl_type.push(:regexp)
1488 yield :START_REGEXP_BLOCK, :START_REGEXP_BLOCK
1489 else
1490 raise
1491 end
1492# yield :V_REGEXP, :V_REGEXP
1493 when /\A\{/ # {
1494 @adl_type.push(:cadl)
1495 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: entering cADL at #{@filename}:#{@lineno}")
1496 yield :SYM_START_CBLOCK, :SYM_START_CBLOCK
1497 when /\A\}/ # }
1498 adl_type = @adl_type.pop
1499# puts "Escaping #{adl_type}"
1500 assert_at(__FILE__,__LINE__){adl_type == :cadl}
1501 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: exiting cADL at #{@filename}:#{@lineno}")
1502 yield :SYM_END_CBLOCK, :SYM_END_CBLOCK
1503 when /\A\$/ # $
1504 yield :Dollar_code, :Dollar_code
1505 when /\A\?\?/ # ??
1506 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
1507 when /\A\?/ # ?
1508 yield :Question_mark_code, :Question_mark_code
1509 when /\A\|/ # |
1510 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
1511 if @in_interval
1512 @in_interval = false
1513 else
1514# @in_interval = false
1515 @in_interval = true
1516 end
1517 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
1518 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
1519
1520 when /\A\[[a-zA-Z0-9._\-]+::[a-zA-Z0-9._\-]+\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
1521 yield :V_QUALIFIED_TERM_CODE_REF, $&
1522 when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
1523 yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
1524 when /\A\[([a-zA-Z0-9()._\-]+::[a-zA-Z0-9._\_-]+)\]/
1525 yield :V_TERM_CODE_CONSTRAINT, :V_TERM_CODE_CONSTRAINT
1526 when /\A\[[a-zA-Z0-9\(\)\._\-]+::[ \t\n]*/
1527 @adl_type.push(:term_constraint)
1528 yield :START_TERM_CODE_CONSTRAINT, $&
1529 when /\A\[[a-zA-Z0-9][a-zA-Z0-9._\-]*\]/ #V_LOCAL_TERM_CODE_REF
1530 yield :V_LOCAL_TERM_CODE_REF, $&
1531 when /\A\[/ # [
1532 yield :Left_bracket_code, :Left_bracket_code
1533 when /\A\]/ # ]
1534 yield :Right_bracket_code, :Right_bracket_code
1535 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
1536 yield :V_GENERIC_TYPE_IDENTIFIER, $&
1537 when /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X][T\t][hH?X][hH?X]:[mM?X][mM?X]:[sS?X][sS?X]/
1538 yield :V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, $&
1539 when /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/
1540 yield :V_ISO8601_DATE_CONSTRAINT_PATTERN, $&
1541 when /\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/
1542 yield :V_ISO8601_TIME_CONSTRAINT_PATTERN, $&
1543 when /\A[a-z][a-zA-Z0-9_]*/
1544 word = $&.dup
1545 if @@cadl_reserved[word.downcase]
1546 yield @@cadl_reserved[word.downcase], @@cadl_reserved[word.downcase]
1547 else
1548 @@log.info("#{__FILE__}:#{__LINE__}: scan_cadl: V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}:#{@lineno}")
1549 yield :V_ATTRIBUTE_IDENTIFIER, word #V_ATTRIBUTE_IDENTIFIER /\A[a-z][a-zA-Z0-9_]*/
1550 end
1551 when /\A[A-Z][a-zA-Z0-9_]*/
1552 word = $&.dup
1553 if @@cadl_reserved[word.downcase]
1554 yield @@cadl_reserved[word.downcase], @@cadl_reserved[word.downcase]
1555 else
1556 yield :V_TYPE_IDENTIFIER, $&
1557 end
1558 when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
1559 yield :V_LOCAL_CODE, $&
1560 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9](Z|[+-][0-9]{4})?/ #V_ISO8601_EXTENDED_DATE_TIME YYYY-MM-DDThh:mm:ss[,sss][Z|+/- -n-n-n-n-]-
1561 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
1562 when /\A[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})? / #V_ISO8601_EXTENDED_TIME hh:mm:ss[,sss][Z|+/-nnnn]
1563 yield :V_ISO8601_EXTENDED_TIME, $&
1564 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]|[0-9]{4}-[0-1][0-9]/ #V_ISO8601_EXTENDED_DATE YYYY-MM-DD
1565 yield :V_ISO8601_EXTENDED_DATE, $&
1566 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
1567 yield :V_INTEGER, $&
1568 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
1569 yield :V_REAL, $&
1570 when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
1571 when /\A"([^"]*)"/m #V_STRING
1572 yield :V_STRING, $1
1573 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
1574 yield :V_URI, $&
1575### when /\AP([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?T([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?|P([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?/ #V_ISO8601_DURATION PnYnMnWnDTnnHnnMnnS
1576### yield :V_ISO8601_DURATION, $&
1577 when /\A\S/ #UTF8CHAR
1578 yield :UTF8CHAR, $&
1579 else
1580 raise
1581 end
1582 data = $' # variable $' receives the string after the match
1583 when :adl
1584# puts "Entering scan_adl"
1585 data = scan_adl(data) do |sym, val|
1586 yield sym, val
1587 end
1588 when :dadl
1589# puts "Entering scan_dadl"
1590 data = scan_dadl(data) do |sym, val|
1591 yield sym, val
1592 end
1593 when :regexp
1594# puts "Entering scan_regexp"
1595 data = scan_regexp(data) do |sym, val|
1596 yield sym, val
1597 end
1598 when :term_constraint
1599# puts "Entering scan_term_constraint"
1600 data = scan_term_constraint(data) do |sym, val|
1601 yield sym, val
1602 end
1603 else
1604 raise
1605 end
1606 end # of until
1607end # of scan_cadl
1608
1609def scan_dadl(data)
1610 until data.nil? do
1611 case @adl_type.last
1612 when :dadl
1613# puts "Entering scan_dadl"
1614 case scanned = @@dadl_scanner.parse(data)
1615 when Yaparc::Result::OK
1616 yield scanned.value
1617 data = scanned.input
1618 else
1619 end
1620
1621 case data
1622 when /\A\n/ # carriage return
1623 @lineno += 1
1624 ;
1625 when /\A[ \t\r\f]+/ #just drop it
1626 ;
1627 when /\A--.*\n/ # single line comment
1628 @lineno += 1
1629 @@log.info("#{__FILE__}:#{__LINE__}: scan_dadl: COMMENT = #{$&} at #{@filename}:#{@lineno}")
1630 ;
1631 ###----------/* symbols */ -------------------------------------------------
1632 when /\A\=/ # =
1633 yield :SYM_EQ, :SYM_EQ
1634 when /\A\>\=/ # >=
1635 yield :SYM_GE, :SYM_GE
1636 when /\A\<\=/ # <=
1637 yield :SYM_LE, :SYM_LE
1638 when /\A\</ # <
1639 if @in_interval
1640 yield :SYM_LT, :SYM_LT
1641 else
1642 @adl_type.push(:dadl)
1643 yield :SYM_START_DBLOCK, :SYM_START_DBLOCK
1644 end
1645 when /\A\>/ # >
1646 if @in_interval
1647# @in_interval = false
1648 yield :SYM_GT, :SYM_GT
1649 elsif @in_c_domain_type == true
1650 assert_at(__FILE__,__LINE__){@adl_type.last == :dadl}
1651 adl_type = @adl_type.pop
1652 if @adl_type.last == :cadl
1653 @in_c_domain_type = false
1654 yield :END_V_C_DOMAIN_TYPE_BLOCK, $&
1655 else
1656 yield :SYM_END_DBLOCK, $&
1657 end
1658 elsif @in_c_domain_type == false
1659 adl_type = @adl_type.pop
1660# puts "Escaping #{adl_type}"
1661 assert_at(__FILE__,__LINE__){adl_type == :dadl}
1662 yield :SYM_END_DBLOCK, $&
1663 else
1664 raise
1665 end
1666 when /\A\-/ # -
1667 yield :Minus_code, :Minus_code
1668 when /\A\+/ # +
1669 yield :Plus_code, :Plus_code
1670 when /\A\*/ # *
1671 yield :Star_code, :Star_code
1672 when /\A\// # /
1673 yield :Slash_code, :Slash_code
1674 when /\A\^/ # ^
1675 yield :Caret_code, :Caret_code
1676 when /\A\.\.\./ # ...
1677 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
1678 when /\A\.\./ # ..
1679 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
1680 when /\A\./ # .
1681 yield :Dot_code, :Dot_code
1682 when /\A\;/ # ;
1683 yield :Semicolon_code, :Semicolon_code
1684 when /\A\,/ # ,
1685 yield :Comma_code, :Comma_code
1686 when /\A\:/ # :
1687 yield :Colon_code, :Colon_code
1688 when /\A\!/ # !
1689 yield :Exclamation_code, :Exclamation_code
1690 when /\A\(/ # (
1691 yield :Left_parenthesis_code, :Left_parenthesis_code
1692 when /\A\)/ # )
1693 yield :Right_parenthesis_code, :Right_parenthesis_code
1694 when /\A\$/ # $
1695 yield :Dollar_code, :Dollar_code
1696 when /\A\?\?/ # ??
1697 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
1698 when /\A\?/ # ?
1699 yield :Question_mark_code, :Question_mark_code
1700 when /\A\|/ # |
1701 @@log.info("#{__FILE__}:#{__LINE__}: scan_dadl: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
1702 if @in_interval
1703 @in_interval = false
1704 else
1705# @in_interval = false
1706 @in_interval = true
1707 end
1708 @@log.info("#{__FILE__}:#{__LINE__}: scan_dadl: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
1709 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
1710### when /\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
1711### yield :V_QUALIFIED_TERM_CODE_REF, $&
1712### when /\A\[[a-zA-Z0-9][a-zA-Z0-9._\-]*\]/ #V_LOCAL_TERM_CODE_REF
1713### yield :V_LOCAL_TERM_CODE_REF, $&
1714### when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
1715### yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
1716 when /\A\[/ # [
1717 yield :Left_bracket_code, :Left_bracket_code
1718 when /\A\]/ # ]
1719 yield :Right_bracket_code, :Right_bracket_code
1720### when /\A[A-Z][a-zA-Z0-9_-]*/
1721### yield :V_TYPE_IDENTIFIER, $&
1722### when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
1723### yield :V_GENERIC_TYPE_IDENTIFIER, $&
1724### when /\A[a-z][a-zA-Z0-9_]*/
1725### word = $&.downcase
1726### if @@dadl_reserved[word]
1727### yield @@dadl_reserved[word], @@dadl_reserved[word]
1728### else
1729### yield :V_ATTRIBUTE_IDENTIFIER, $&
1730### end
1731### when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
1732### yield :V_LOCAL_CODE, $&
1733 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})?|[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9](Z|[+-][0-9]{4})?/ #V_ISO8601_EXTENDED_DATE_TIME YYYY-MM-DDThh:mm:ss[,sss][Z|+/- -n-n-n-n-]-
1734 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
1735 when /\A[0-2][0-9]:[0-6][0-9]:[0-6][0-9](,[0-9]+)?(Z|[+-][0-9]{4})?|[0-2][0-9]:[0-6][0-9](Z|[+-][0-9]{4})? / #V_ISO8601_EXTENDED_TIME hh:mm:ss[,sss][Z|+/-nnnn]
1736 yield :V_ISO8601_EXTENDED_TIME, $&
1737 when /\A[0-9]{4}-[0-1][0-9]-[0-3][0-9]|[0-9]{4}-[0-1][0-9]/ #V_ISO8601_EXTENDED_DATE YYYY-MM-DD
1738 yield :V_ISO8601_EXTENDED_DATE, $&
1739 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
1740 yield :V_GENERIC_TYPE_IDENTIFIER, $&
1741 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
1742 yield :V_INTEGER, $&
1743### when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
1744### yield :V_REAL, $&
1745 # when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
1746### when /\A"([^"]*)"/m #V_STRING
1747### yield :V_STRING, $1
1748 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
1749 yield :V_URI, $&
1750### when /\AP([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?T([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?|P([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?/ #V_ISO8601_DURATION PnYnMnWnDTnnHnnMnnS
1751### yield :V_ISO8601_DURATION, $&
1752 when /\A\S/ #UTF8CHAR
1753 yield :UTF8CHAR, $&
1754 end
1755 data = $' # variable $' receives the string after the match
1756 when :adl
1757# puts "Entering scan_adl"
1758 data = scan_adl(data) do |sym, val|
1759 yield sym, val
1760 end
1761 when :cadl
1762# puts "Entering scan_cadl"
1763 data = scan_cadl(data) do |sym, val|
1764 yield sym, val
1765 end
1766 when :regexp
1767# puts "Entering scan_regexp"
1768 data = scan_regexp(data) do |sym, val|
1769 yield sym, val
1770 end
1771 when :term_constraint
1772# puts "Entering scan_term_constraint"
1773 data = scan_term_constraint(data) do |sym, val|
1774 yield sym, val
1775 end
1776 else
1777 raise
1778 end
1779 end
1780end # of scan_dadl
1781
1782def scan_regexp(data)
1783 until data.nil? do
1784 case @adl_type.last
1785 when :regexp
1786# puts "Entering scan_regexp"
1787 case data
1788 when /\A\/\}/ #V_REGEXP
1789 if @adl_type.last == :regexp
1790 @in_regexp = false
1791 @adl_type.pop
1792 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
1793 else
1794 raise
1795 end
1796 when /\A(.*)(\/\})/ #V_REGEXP
1797 yield :REGEXP_BODY, $1
1798 if @adl_type.last == :regexp
1799 @in_regexp = false
1800 @adl_type.pop
1801 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
1802 else
1803 raise
1804 end
1805 else
1806 raise data
1807 end
1808 data = $' # variable $' receives the string after the match
1809 when :adl
1810# puts "Entering scan_adl"
1811 data = scan_adl(data) do |sym, val|
1812 yield sym, val
1813 end
1814 when :dadl
1815# puts "Entering scan_dadl"
1816 data = scan_dadl(data) do |sym, val|
1817 yield sym, val
1818 end
1819 when :cadl
1820# puts "Entering scan_cadl"
1821 data = scan_cadl(data) do |sym, val|
1822 yield sym, val
1823 end
1824 when :term_constraint
1825# puts "Entering scan_term_constraint"
1826 data = scan_term_constraint(data) do |sym, val|
1827 yield sym, val
1828 end
1829 else
1830 raise
1831 end
1832 end
1833end # of scan_regexp
1834
1835def scan_term_constraint(data)
1836 until data.nil? do
1837 case @adl_type.last
1838 when :term_constraint
1839# puts "Entering scan_term_constraint"
1840 case data
1841 when /\A\n/ # carriage return
1842 @lineno += 1
1843 ;
1844 when /\A[ \t\r\f]+/ #just drop it
1845 ;
1846 when /\A--.*$/ # single line comment
1847 @lineno += 1
1848 @@log.info("#{__FILE__}:#{__LINE__}: scan_term_constraint: COMMENT = #{$&} at #{@filename}:#{@lineno}")
1849 ;
1850 when /\A[a-zA-Z0-9\._\-]+[ \t]*,/ # match any line, with ',' termination
1851 yield :TERM_CODE, $&
1852 when /\A[a-zA-Z0-9\._\-]+[ \t]*;/ #match second last line with ';' termination (assumed value)
1853 yield :TERM_CODE, $&
1854# when /\A[a-zA-Z0-9\._\-]+[ \t]*\]/ # match final line, terminating in ']'
1855 when /\A[a-zA-Z0-9\._\-]*[ \t]*\]/ # match final line, terminating in ']'
1856 adl_type = @adl_type.pop
1857 assert_at(__FILE__,__LINE__){adl_type == :term_constraint}
1858 yield :END_TERM_CODE_CONSTRAINT, $&
1859 else
1860 raise "data = #{data}"
1861 end
1862 data = $' # variable $' receives the string after the match
1863 when :adl
1864# puts "Entering scan_adl"
1865 data = scan_adl(data) do |sym, val|
1866 yield sym, val
1867 end
1868 when :dadl
1869# puts "Entering scan_dadl"
1870 data = scan_dadl(data) do |sym, val|
1871 yield sym, val
1872 end
1873 when :cadl
1874# puts "Entering scan_cadl"
1875 data = scan_cadl(data) do |sym, val|
1876 yield sym, val
1877 end
1878 else
1879 raise
1880 end
1881 end
1882end # of scan_term_constraint
1883
1884
1885def parse(data, filename, lineno = 1, debug = false)
1886 @yydebug = true
1887 @parsestring = data
1888 @data = data
1889 @lineno = lineno
1890 @filename = filename
1891 @adl_type = [:adl] # {:adl, :cadl, :dadl}
1892 @in_regexp = false
1893 @in_interval = false
1894 @in_c_domain_type = false
1895 yyparse self, :scan
1896end
1897
1898def on_error( t, v, values)
1899 raise Racc::ParseError, "#{@filename}:#{@lineno}: Inline syntax error on #{v.inspect}"
1900end
1901
1902
1903
1904
1905
1906
1907
1908### Local Variables:
1909### mode:ruby
1910### mode:font-lock
1911### comment-column:0
1912### comment-start: "### "
1913### comment-end:""
1914### End:
1915
1916
1917
1918
Note: See TracBrowser for help on using the repository browser.