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

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

working on adl_parser semantic functions

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