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

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

successful parsing 25 archtypes

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