source: ruby/trunk/lib/adl_parser/lib/adl_scanner.rb@ 315

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

adl_scanner should properly change cADL or dADL scanners

File size: 51.8 KB
Line 
1require 'rubygems'
2require 'logger'
3require 'adl_parser.rb'
4require 'open_ehr'
5#require 'am.rb'
6#require 'rm.rb'
7require 'util.rb'
8
9
10module OpenEhr
11 module ADL
12 module Scanner
13# LOGGER = Logger.new('log/scanner.log')
14 LOGGER = Logger.new('log/parser.log')
15 LOGGER.level = Logger::DEBUG
16
17 class Base
18 attr_accessor :adl_type, :lineno
19 def initialize(adl_type, filename, lineno = 1)
20 @adl_type = adl_type
21 @filename = filename
22 @lineno = lineno
23 end
24
25 def scan(data)
26 raise
27 end
28 end
29
30 #
31 # ADLScanner
32 #
33 class ADLScanner < Base
34 attr_accessor :adl_type, :lineno, :cadl_scanner, :dadl_scanner, :regex_scanner, :term_constraint_scanner
35
36 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log')
37 RESERVED = {
38 'archetype' => :SYM_ARCHETYPE,
39 'adl_version' => :SYM_ADL_VERSION,
40 'controlled' => :SYM_IS_CONTROLLED,
41 'specialize' => :SYM_SPECIALIZE,
42 'concept' => :SYM_CONCEPT,
43 'language' => :SYM_LANGUAGE,
44 'description' => :SYM_DESCRIPTION,
45 'definition' => :SYM_DEFINITION,
46 'invariant' => :SYM_INVARIANT,
47 'ontology' => :SYM_ONTOLOGY,
48 'matches' => :SYM_MATCHES,
49 'is_in' => :SYM_MATCHES,
50 'occurrences' => :SYM_OCCURRENCES,
51 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
52 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
53 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
54 }
55
56 def initialize(adl_type, filename, lineno = 1)
57 super(adl_type, filename, lineno)
58 @in_interval = false
59 end
60
61 #
62 # ADLScanner#scan
63 #
64 def scan(data)
65 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering ADLScanner#scan at #{@filename}:#{@lineno}: data = #{data.inspect}")
66 until data.nil? do
67 case @adl_type.last
68 when :adl
69 case data
70 when /\A\n/ # carriage return
71 @lineno += 1
72 ;
73 when /\A[ \t\r\f]+/ #just drop it
74 ;
75 when /\A--.*/ # single line comment
76 @lineno += 1
77 @@logger.debug("ADLScanner#scan: COMMENT = #{$&} at #{@filename}:#{@lineno}")
78 ;
79 when /\Adescription/ # description
80 yield :SYM_DESCRIPTION, :SYM_DESCRIPTION
81 when /\Adefinition/ # definition
82 yield :SYM_DEFINITION, :SYM_DEFINITION
83 ###----------/* symbols */ -------------------------------------------------
84 when /\A[A-Z][a-zA-Z0-9_]*/
85 yield :V_TYPE_IDENTIFIER, $&
86 when /\A(\w+)-(\w+)-(\w+)\.(\w+)((?:-\w+)*)\.(v\w+)/ #V_ARCHETYPE_ID
87 object_id, rm_originator, rm_name, rm_entity, concept_name, specialisation, version_id = $&, $1, $2, $3, $4, $5, $6
88 #archetype_id = OpenEhr::RM::Support::Identification::ArchetypeID.new(object_id, concept_name, rm_name, rm_entity, rm_originator, specialisation, version_id)
89 archetype_id = OpenEhr::RM::Support::Identification::ArchetypeID.new(:concept_name => concept_name, :rm_name => rm_name, :rm_entity => rm_entity, :rm_originator => :rm_originator, :specialisation => specialisation, :version_id => version_id)
90 yield :V_ARCHETYPE_ID, archetype_id
91 when /\A[a-z][a-zA-Z0-9_]*/
92 word = $&
93 if RESERVED[word]
94 @@logger.debug("ADLScanner#scan: RESERVED = #{RESERVED[word]} at #{@filename}:#{@lineno}")
95 yield RESERVED[word], RESERVED[word]
96 elsif #/\A[A-Z][a-zA-Z0-9_]*/
97 @@logger.debug("ADLScanner#scan: V_ATTRIBUTE_IDENTIFIER = #{$&} at #{@filename}:#{@lineno}")
98 yield :V_ATTRIBUTE_IDENTIFIER, $&
99 end
100 when /\A\=/ # =
101 yield :SYM_EQ, :SYM_EQ
102 when /\A\>=/ # >=
103 yield :SYM_GE, :SYM_GE
104 when /\A\<=/ # <=
105 yield :SYM_LE, :SYM_LE
106 when /\A\</ # <
107 if @in_interval
108 yield :SYM_LT, :SYM_LT
109 else
110 @adl_type.push(:dadl)
111 yield :SYM_START_DBLOCK, $&
112 end
113 when /\A\>/ # >
114 if @in_interval
115 yield :SYM_GT, :SYM_GT
116 else
117 adl_type = @adl_type.pop
118 assert_at(__FILE__,__LINE__){adl_type == :dadl}
119 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
120 end
121 when /\A\{/ # {
122 @adl_type.push(:cadl)
123 @@logger.debug("ADLScanner#scan: SYM_START_CBLOCK")
124 yield :SYM_START_CBLOCK, :SYM_START_CBLOCK
125 when /\A\}/ # }
126 adl_type = @adl_type.pop
127 assert_at(__FILE__,__LINE__){adl_type == :cadl}
128 @@logger.debug("ADLScanner#scan: SYM_END_CBLOCK")
129 yield :SYM_END_CBLOCK, $&
130 when /\A\-/ # -
131 yield :Minus_code, :Minus_code
132 when /\A\+/ # +
133 yield :Plus_code, :Plus_code
134 when /\A\*/ # *
135 yield :Star_code, :Star_code
136 when /\A\// # /
137 yield :Slash_code, :Slash_code
138 when /\A\^/ # ^
139 yield :Caret_code, :Caret_code
140 when /\A\=/ # =
141 yield :Equal_code, :Equal_code
142 when /\A\.\.\./ # ...
143 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
144 when /\A\.\./ # ..
145 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
146 when /\A\./ # .
147 yield :Dot_code, :Dot_code
148 when /\A\;/ # ;
149 yield :Semicolon_code, :Semicolon_code
150 when /\A\,/ # ,
151 yield :Comma_code, :Comma_code
152 when /\A\:/ # :
153 yield :Colon_code, :Colon_code
154 when /\A\!/ # !
155 yield :Exclamation_code, :Exclamation_code
156 when /\A\(/ # (
157 yield :Left_parenthesis_code, :Left_parenthesis_code
158 when /\A\)/ # )
159 yield :Right_parenthesis_code, :Right_parenthesis_code
160 when /\A\$/ # $
161 yield :Dollar_code, :Dollar_code
162 when /\A\?\?/ # ??
163 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
164 when /\A\?/ # ?
165 yield :Question_mark_code, :Question_mark_code
166 when /\A[0-9]+\.[0-9]+(\.[0-9]+)*/ # ?
167 yield :V_VERSION_STRING, $&
168 when /\A\|/ # |
169 if @in_interval
170 @in_interval = false
171 else
172 @in_interval = true
173 end
174 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
175 when /\A\[([a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+)\]/ #V_QUALIFIED_TERM_CODE_REF form such as [ICD10AM(1998)::F23]
176 yield :V_QUALIFIED_TERM_CODE_REF, $1
177 when /\A\[([a-zA-Z0-9][a-zA-Z0-9._\-]*)\]/ #V_LOCAL_TERM_CODE_REF
178 yield :V_LOCAL_TERM_CODE_REF, $1
179 when /\A\[/ # [
180 yield :Left_bracket_code, :Left_bracket_code
181 when /\A\]/ # ]
182 yield :Right_bracket_code, :Right_bracket_code
183 when /\A"([^"]*)"/m #V_STRING
184 yield :V_STRING, $1
185 when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
186 yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
187 when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
188 yield :V_LOCAL_CODE, $&
189 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-]-
190 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
191 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]
192 yield :V_ISO8601_EXTENDED_TIME, $&
193 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
194 yield :V_ISO8601_EXTENDED_DATE, $&
195 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
196 yield :V_GENERIC_TYPE_IDENTIFIER, $&
197 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
198 @@logger.debug("ADLScanner#scan: V_INTEGER = #{$&}")
199 yield :V_INTEGER, $&
200 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
201 yield :V_REAL, $&
202 # when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
203 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
204 yield :V_URI, $&
205 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
206 yield :V_ISO8601_DURATION, $&
207 when /\A\S/ #UTF8CHAR
208 yield :UTF8CHAR, $&
209 end
210 data = $' # variable $' receives the string after the match
211 when :dadl
212 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
213 data = dadl_scanner.scan(data) do |sym, val|
214 yield sym, val
215 end
216 when :cadl
217 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
218 data = cadl_scanner.scan(data) do |sym, val|
219 yield sym, val
220 end
221 when :regexp
222 regex_scanner = OpenEhr::ADL::Scanner::RegexScanner.new(@adl_type, @filename, @lineno)
223 data = regex_scanner.scan(data) do |sym, val|
224 yield sym, val
225 end
226 when :term_constraint
227 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
228 data = term_constraint_scanner.scan(data) do |sym, val|
229 yield sym, val
230 end
231 else
232 raise
233 end
234 end
235 end
236 end # of ADLScanner
237
238 #
239 # DADLScanner
240 #
241 class DADLScanner < Base
242 attr_accessor :in_interval, :in_c_domain_type, :dblock_depth
243 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log')
244 RESERVED = {
245 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
246 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
247 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
248 }
249
250 def initialize(adl_type, filename, lineno = 1)
251 super(adl_type, filename, lineno)
252 @in_interval = false
253 @in_c_domain_type = false
254 @dblock_depth = 0
255 end
256
257 #
258 # DADLScanner#scan
259 #
260 def scan(data)
261 @@logger.debug("Entering DADLScanner#scan at #{@filename}:#{@lineno}: @adl_type = #{@adl_type.inspect}, data = #{data.inspect}")
262 until data.nil? do
263 @@logger.debug("#{@filename}:#{@lineno}: DADLScanner#scan:loop data = #{data.inspect}")
264 @@logger.debug("#{@filename}:#{@lineno}: DADLScanner#scan:loop self = \n#{self.to_yaml}")
265 case @adl_type.last
266 when :dadl
267 case data
268 when /\A\n/ # carriage return
269 #@@logger.debug("DADLScanner#scan: carriage return, data = #{data.inspect}")
270 @lineno += 1
271 ;
272 when /\A[ \t\r\f]+/ #just drop it
273 ##@@logger.debug("DADLScanner#scan: white space, data = #{data.inspect}")
274 ;
275 when /\A--.*/ # single line comment
276 @@logger.debug("DADLScanner#scan: COMMENT = #{$&} at #{@filename}:#{@lineno}")
277 ;
278 when /\A[a-z][a-zA-Z0-9_]*/
279 word = $&.dup
280 if RESERVED[word.downcase]
281 yield RESERVED[word.downcase], RESERVED[word.downcase]
282 else
283 @@logger.debug("DADLScanner#scan: V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}:#{@lineno}")
284 yield :V_ATTRIBUTE_IDENTIFIER, word #V_ATTRIBUTE_IDENTIFIER /\A[a-z][a-zA-Z0-9_]*/
285 end
286 ###----------/* symbols */ -------------------------------------------------
287 when /\A\=/ # =
288 yield :SYM_EQ, :SYM_EQ
289 when /\A\>\=/ # >=
290 yield :SYM_GE, :SYM_GE
291 when /\A\<\=/ # <=
292 yield :SYM_LE, :SYM_LE
293 when /\A\</ # <
294 if @in_interval
295 yield :SYM_LT, :SYM_LT
296 else
297 unless @in_c_domain_type
298 @adl_type.push(:dadl)
299 else
300 @dblock_depth += 1
301 end
302 yield :SYM_START_DBLOCK, :SYM_START_DBLOCK
303 end
304 when /\A\>/ # >
305 if @in_interval
306 yield :SYM_GT, :SYM_GT
307 else
308 if @in_c_domain_type
309 assert_at(__FILE__,__LINE__){@adl_type.last == :dadl}
310 @dblock_depth -= 1
311 if @dblock_depth < 0
312 @adl_type.pop
313 @in_c_domain_type = false
314 yield :END_V_C_DOMAIN_TYPE_BLOCK, :END_V_C_DOMAIN_TYPE_BLOCK
315 else
316 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
317 end
318# adl_type = @adl_type.pop
319# if adl_type == :dadl
320# yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
321# else
322# @in_c_domain_type = false
323# yield :END_V_C_DOMAIN_TYPE_BLOCK, :END_V_C_DOMAIN_TYPE_BLOCK
324# end
325 else
326 adl_type = @adl_type.pop
327 assert_at(__FILE__,__LINE__){adl_type == :dadl}
328 yield :SYM_END_DBLOCK, $&
329 end
330 end
331 when /\A\-/ # -
332 yield :Minus_code, :Minus_code
333 when /\A\+/ # +
334 yield :Plus_code, :Plus_code
335 when /\A\*/ # *
336 yield :Star_code, :Star_code
337 when /\A\// # /
338 yield :Slash_code, :Slash_code
339 when /\A\^/ # ^
340 yield :Caret_code, :Caret_code
341 when /\A\.\.\./ # ...
342 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
343 when /\A\.\./ # ..
344 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
345 when /\A\./ # .
346 yield :Dot_code, :Dot_code
347 when /\A\;/ # ;
348 yield :Semicolon_code, :Semicolon_code
349 when /\A\,/ # ,
350 yield :Comma_code, :Comma_code
351 when /\A\:/ # :
352 yield :Colon_code, :Colon_code
353 when /\A\!/ # !
354 yield :Exclamation_code, :Exclamation_code
355 when /\A\(/ # (
356 yield :Left_parenthesis_code, :Left_parenthesis_code
357 when /\A\)/ # )
358 yield :Right_parenthesis_code, :Right_parenthesis_code
359 when /\A\$/ # $
360 yield :Dollar_code, :Dollar_code
361 when /\A\?\?/ # ??
362 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
363 when /\A\?/ # ?
364 yield :Question_mark_code, :Question_mark_code
365 when /\A\|/ # |
366 @@logger.debug("DADLScanner#scan: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
367 if @in_interval
368 @in_interval = false
369 else
370 # @in_interval = false
371 @in_interval = true
372 end
373 @@logger.debug("DADLScanner#scan: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
374 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
375 when /\A\[([a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+)\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
376 yield :V_QUALIFIED_TERM_CODE_REF, $1
377 when /\A\[/ # [
378 @@logger.debug("DADLScanner#scan: Left_bracket_code at #{@filename}:#{@lineno}")
379 yield :Left_bracket_code, :Left_bracket_code
380 when /\A\]/ # ]
381 @@logger.debug("DADLScanner#scan: Right_bracket_code at #{@filename}:#{@lineno}")
382 yield :Right_bracket_code, :Right_bracket_code
383 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-]-
384 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_DATE_TIME")
385 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
386 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]
387 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_TIME")
388 yield :V_ISO8601_EXTENDED_TIME, $&
389 when /\A\d{4}-[0-1][0-9]-[0-3][0-9]|[0-9]{4}-[0-1][0-9]/ #V_ISO8601_EXTENDED_DATE YYYY-MM-DD
390 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_DATE, #{$&}")
391 yield :V_ISO8601_EXTENDED_DATE, $&
392 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
393 yield :V_GENERIC_TYPE_IDENTIFIER, $&
394 when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
395 @@logger.debug("DADLScanner#scan: V_STRING, #{$1}")
396 yield :V_STRING, $1
397 when /\A"([^"]*)"/m #V_STRING
398 @@logger.debug("DADLScanner#scan: V_STRING, #{$1}")
399 yield :V_STRING, $1
400 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
401 yield :V_REAL, $&
402 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
403 @@logger.debug("DADLScanner#scan: V_INTEGER = #{$&}")
404 yield :V_INTEGER, $&
405 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
406 yield :V_URI, $&
407 when /\A\S/ #UTF8CHAR
408 yield :UTF8CHAR, $&
409 end
410 data = $' # variable $' receives the string after the match
411 when :adl
412 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
413 data = adl_scanner.scan(data) do |sym, val|
414 yield sym, val
415 end
416 when :cadl
417 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
418 data = cadl_scanner.scan(data) do |sym, val|
419 yield sym, val
420 end
421 when :regexp
422 regex_scanner = OpenEhr::ADL::Scanner::RegexScanner.new(@adl_type, @filename, @lineno)
423 data = regex_scanner.scan(data) do |sym, val|
424 yield sym, val
425 end
426 when :term_constraint
427 @@logger.debug("#{__FILE__}:#{__LINE__}: scan_dadl: Entering scan_term_constraint at #{@filename}:#{@lineno}: data = #{data.inspect}")
428 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
429 data = term_constraint_scanner.scan(data) do |sym, val|
430 yield sym, val
431 end
432 else
433 raise
434 end
435 end
436 end
437 end # of DADLScanner
438
439
440
441 class CADLScanner < Base
442
443 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
444 RESERVED = {
445 'then' => :SYM_THEN, # [Tt][Hh][Ee][Nn]
446 'else' => :SYM_ELSE, # [Ee][Ll][Ss][Ee]
447 'and' => :SYM_AND, # [Aa][Nn][Dd]
448 'or' => :SYM_OR, # [Oo][Rr]
449 'xor' => :SYM_XOR, # [Xx][Oo][Rr]
450 'not' => :SYM_NOT, # [Nn][Oo][Tt]
451 'implies' => :SYM_IMPLIES, # [Ii][Mm][Pp][Ll][Ii][Ee][Ss]
452 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
453 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
454 'forall' => :SYM_FORALL, # [Ff][Oo][Rr][_][Aa][Ll][Ll]
455 'exists' => :SYM_EXISTS, # [Ee][Xx][Ii][Ss][Tt][Ss]
456 'existence' => :SYM_EXISTENCE, # [Ee][Xx][Iu][Ss][Tt][Ee][Nn][Cc][Ee]
457 'occurrences' => :SYM_OCCURRENCES, # [Oo][Cc][Cc][Uu][Rr][Rr][Ee][Nn][Cc][Ee][Ss]
458 'cardinality' => :SYM_CARDINALITY, # [Cc][Aa][Rr][Dd][Ii][Nn][Aa][Ll][Ii][Tt][Yy]
459 'ordered' => :SYM_ORDERED, # [Oo][Rr][Dd][Ee][Rr][Ee][Dd]
460 'unordered' => :SYM_UNORDERED, # [Uu][Nn][Oo][Rr][Dd][Ee][Rr][Ee][Dd]
461 'unique' => :SYM_UNIQUE, # [Uu][Nn][Ii][Qq][Uu][Ee]
462 'matches' => :SYM_MATCHES, # [Mm][Aa][Tt][Cc][Hh][Ee][Ss]
463 'is_in' => :SYM_MATCHES, # [Ii][Ss][_][Ii][Nn]
464 'invariant' => :SYM_INVARIANT, # [Ii][Nn][Vv][Aa][Rr][Ii][Aa][Nn][Tt]
465 'infinity' => :SYM_INFINITY, # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
466 'use_node' => :SYM_USE_NODE, # [Uu][Ss][Ee][_][Nn][Oo][Dd][Ee]
467 'use_archetype' => :SYM_ALLOW_ARCHETYPE, # [Uu][Ss][Ee][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
468 'allow_archetype' => :SYM_ALLOW_ARCHETYPE, # [Aa][Ll][Ll][Oo][Ww][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
469 'include' => :SYM_INCLUDE, # [Ii][Nn][Cc][Ll][Uu][Dd][Ee]
470 'exclude' => :SYM_EXCLUDE # [Ee][Xx][Cc][Ll][Uu][Dd][Ee]
471 }
472
473 def initialize(adl_type, filename, lineno = 1)
474 super(adl_type, filename, lineno)
475 @in_interval = false
476 end
477
478 #
479 # CADLScanner#scan
480 #
481 def scan(data)
482 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering CADLScanner#scan at #{@filename}:#{@lineno}: data = #{data.inspect}")
483 until data.nil? do
484 @@logger.debug("CADLScanner#scan: loop data = #{data.inspect}")
485 case @adl_type.last
486 when :cadl
487 case data
488 when /\A\n/ # carriage return
489 @lineno += 1
490 ;
491 #yield :CR, :CR
492 when /\A[ \t\r\f]+/ #just drop it
493 ;
494 when /\A--.*\n/ # single line comment
495 @lineno += 1
496 ;
497 ###----------/* symbols */ -------------------------------------------------
498 when /\A\=/ # =
499 yield :SYM_EQ, :SYM_EQ
500 when /\A\>=/ # >=
501 yield :SYM_GE, :SYM_GE
502 when /\A\<=/ # <=
503 yield :SYM_LE, :SYM_LE
504 when /\A\</ # <
505 if @in_interval
506 yield :SYM_LT, :SYM_LT
507 else
508 @adl_type.push(:dadl)
509 yield :SYM_START_DBLOCK, $&
510 end
511 when /\A\>/ # >
512 if @in_interval
513 yield :SYM_GT, :SYM_GT
514 else
515 adl_type = @adl_type.pop
516 assert_at(__FILE__,__LINE__){adl_type == :dadl}
517 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
518 end
519 when /\A\-/ # -
520 yield :Minus_code, :Minus_code
521 when /\A\+/ # +
522 yield :Plus_code, :Plus_code
523 when /\A\*/ # *
524 yield :Star_code, :Star_code
525 when /\A\// # /
526 yield :Slash_code, :Slash_code
527 when /\A\^/ # ^
528 yield :Caret_code, :Caret_code
529 when /\A\.\.\./ # ...
530 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
531 when /\A\.\./ # ..
532 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
533 when /\A\./ # .
534 yield :Dot_code, :Dot_code
535 when /\A\;/ # ;
536 yield :Semicolon_code, :Semicolon_code
537 when /\A\,/ # ,
538 yield :Comma_code, :Comma_code
539 when /\A\:/ # :
540 yield :Colon_code, :Colon_code
541 when /\A\!/ # !
542 yield :Exclamation_code, :Exclamation_code
543 when /\A\(/ # (
544 yield :Left_parenthesis_code, :Left_parenthesis_code
545 when /\A\)/ # )
546 yield :Right_parenthesis_code, :Right_parenthesis_code
547 when /\A\{\// #V_REGEXP
548 if @adl_type.last != :regexp
549 @in_regexp = true
550 @adl_type.push(:regexp)
551 yield :START_REGEXP_BLOCK, :START_REGEXP_BLOCK
552 else
553 raise
554 end
555 when /\A\{/ # {
556 @adl_type.push(:cadl)
557 @@logger.debug("CADLScanner#scan: entering cADL at #{@filename}:#{@lineno}")
558 yield :SYM_START_CBLOCK, :SYM_START_CBLOCK
559 when /\A\}/ # }
560 adl_type = @adl_type.pop
561 assert_at(__FILE__,__LINE__){adl_type == :cadl}
562 @@logger.debug("CADLScanner#scan: exiting cADL at #{@filename}:#{@lineno}")
563 yield :SYM_END_CBLOCK, :SYM_END_CBLOCK
564 when /\A\$/ # $
565 yield :Dollar_code, :Dollar_code
566 when /\A\?\?/ # ??
567 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
568 when /\A\?/ # ?
569 yield :Question_mark_code, :Question_mark_code
570 when /\A\|/ # |
571 @@logger.debug("CADLScanner#scan: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
572 if @in_interval
573 @in_interval = false
574 else
575 # @in_interval = false
576 @in_interval = true
577 end
578 @@logger.debug("CADLScanner#scan: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
579 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
580
581 when /\A\[([a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+)\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
582 yield :V_QUALIFIED_TERM_CODE_REF, $1
583 when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
584 yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
585 when /\A\[([a-zA-Z0-9\(\)\._\-]+)::[ \t\n]*/
586 @adl_type.push(:term_constraint)
587 yield :START_TERM_CODE_CONSTRAINT, $1
588 when /\A\[([a-zA-Z0-9][a-zA-Z0-9._\-]*)\]/ #V_LOCAL_TERM_CODE_REF
589 yield :V_LOCAL_TERM_CODE_REF, $1
590 when /\A\[/ # [
591 yield :Left_bracket_code, :Left_bracket_code
592 when /\A\]/ # ]
593 yield :Right_bracket_code, :Right_bracket_code
594 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
595 yield :V_GENERIC_TYPE_IDENTIFIER, $&
596 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]/
597 yield :V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, $&
598 when /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/
599 yield :V_ISO8601_DATE_CONSTRAINT_PATTERN, $&
600 when /\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/
601 yield :V_ISO8601_TIME_CONSTRAINT_PATTERN, $&
602 #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 such as PnYnMnWnDTnnHnnMnnS
603 when /\AP([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?T([0-9]+[hH])?([0-9]+[mM])?([0-9]+[sS])?/ #V_ISO8601_DURATION such as PnYnMnWnDTnnHnnMnnS
604 yield :V_ISO8601_DURATION, $&
605 when /\AP[yY]?[mM]?[wW]?[dD]?T[hH]?[mM]?[sS]?/ #V_ISO8601_DURATION_CONSTRAINT_PATTERNo
606 yield :V_ISO8601_DURATION_CONSTRAINT_PATTERN, $&
607 when /\A[a-z][a-zA-Z0-9_]*/
608 word = $&.dup
609 if RESERVED[word.downcase]
610 yield RESERVED[word.downcase], RESERVED[word.downcase]
611 else
612 @@logger.debug("CADLScanner#scan: V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}:#{@lineno}")
613 yield :V_ATTRIBUTE_IDENTIFIER, word #V_ATTRIBUTE_IDENTIFIER /\A[a-z][a-zA-Z0-9_]*/
614 end
615 when /\A([A-Z][a-zA-Z0-9_]*)[ \n]*\</ # V_C_DOMAIN_TYPE
616 @in_c_domain_type = true
617 @adl_type.push(:dadl)
618 yield :START_V_C_DOMAIN_TYPE_BLOCK, $1
619 when /\A[A-Z][a-zA-Z0-9_]*/
620 word = $&.dup
621 if RESERVED[word.downcase]
622 yield RESERVED[word.downcase], RESERVED[word.downcase]
623 else
624 yield :V_TYPE_IDENTIFIER, $&
625 end
626 when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
627 yield :V_LOCAL_CODE, $&
628 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-]-
629 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
630 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]
631 yield :V_ISO8601_EXTENDED_TIME, $&
632 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
633 yield :V_ISO8601_EXTENDED_DATE, $&
634 when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
635 yield :V_STRING, $1
636 when /\A"([^"]*)"/m #V_STRING
637 yield :V_STRING, $1
638 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
639 yield :V_REAL, $&
640 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
641 @@logger.debug("CADLScanner#scan: V_INTEGER = #{$&}")
642 yield :V_INTEGER, $&
643 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
644 yield :V_URI, $&
645 when /\A\S/ #UTF8CHAR
646 yield :UTF8CHAR, $&
647 when /\A.+/ #
648 raise OpenEhr::ADL::Exception::CADLScanner::Base.new, "can't handle #{data.inspect}"
649 end
650 data = $' # variable $' receives the string after the match
651 when :adl
652 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
653 data = adl_scanner.scan(data) do |sym, val|
654 yield sym, val
655 end
656 when :dadl
657 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
658 dadl_scanner.in_c_domain_type = @in_c_domain_type
659 data = dadl_scanner.scan(data) do |sym, val|
660 yield sym, val
661 end
662 when :regexp
663 regex_scanner = OpenEhr::ADL::Scanner::RegexScanner.new(@adl_type, @filename, @lineno)
664 data = regex_scanner.scan(data) do |sym, val|
665 yield sym, val
666 end
667 when :term_constraint
668 @@logger.debug("Entering scan_term_constraint at #{@filename}:#{@lineno}: data = #{data.inspect}")
669 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
670 data = term_constraint_scanner.scan(data) do |sym, val|
671 yield sym, val
672 end
673 else
674 raise OpenEhr::ADL::Exception::CADLScanner.new, "unexpected adl_type: #{@adl_type.last}"
675 end
676 end # of until
677 end
678 end # of CADLScanner
679
680
681 #
682 # RegexScanner
683 #
684 class RegexScanner < Base
685
686 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
687
688 def initialize(adl_type, filename, lineno = 1)
689 super(adl_type, filename, lineno)
690 end
691
692 def scan(data)
693 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan_regexp at #{@filename}:#{@lineno}: data = #{data.inspect}")
694 until data.nil? do
695 case @adl_type.last
696 when :regexp
697 case data
698 when /\A\/\}/ #V_REGEXP
699 if @adl_type.last == :regexp
700 @in_regexp = false
701 @adl_type.pop
702 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
703 else
704 raise
705 end
706 when /\A(.*)(\/\})/ #V_REGEXP
707 yield :REGEXP_BODY, $1
708 if @adl_type.last == :regexp
709 @in_regexp = false
710 @adl_type.pop
711 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
712 else
713 raise
714 end
715 else
716 raise data
717 end
718 data = $' # variable $' receives the string after the match
719 when :adl
720 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
721 data = adl_scanner.scan(data) do |sym, val|
722 yield sym, val
723 end
724 when :dadl
725 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
726 data = dadl_scanner.scan(data) do |sym, val|
727 yield sym, val
728 end
729 when :cadl
730 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
731 data = cadl_scanner.scan(data) do |sym, val|
732 yield sym, val
733 end
734 when :term_constraint
735 #@@logger.debug("#{__FILE__}:#{__LINE__}: scan_regexp: Entering scan_term_constraint at #{@filename}:#{@lineno}")
736 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
737 data = term_constraint_scanner.scan(data) do |sym, val|
738 yield sym, val
739 end
740 else
741 raise
742 end
743 end
744 end
745 end # of RegexScanner
746
747 #
748 # TermConstraintScanner
749 #
750 class TermConstraintScanner < Base
751 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
752 def initialize(adl_type, filename, lineno = 1)
753 super(adl_type, filename, lineno)
754 end
755
756 def scan(data)
757 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan_term_constraint")
758 until data.nil? do
759 case @adl_type.last
760 when :term_constraint
761 case data
762 when /\A\n/ # carriage return
763 @lineno += 1
764 ;
765 when /\A[ \t\r\f]+/ #just drop it
766 ;
767 when /\A--.*$/ # single line comment
768 @lineno += 1
769 @@logger.debug("#{__FILE__}:#{__LINE__}: scan_term_constraint: COMMENT = #{$&} at #{@filename}:#{@lineno}")
770 ;
771 when /\A([a-zA-Z0-9\._\-])+[ \t]*,/ # match any line, with ',' termination
772 yield :TERM_CODE, $1
773 when /\A([a-zA-Z0-9\._\-])+[ \t]*;/ # match second last line with ';' termination (assumed value)
774 yield :TERM_CODE, $1
775 when /\A([a-zA-Z0-9\._\-])*[ \t]*\]/ # match final line, terminating in ']'
776 adl_type = @adl_type.pop
777 assert_at(__FILE__,__LINE__){adl_type == :term_constraint}
778 yield :END_TERM_CODE_CONSTRAINT, $1
779 else
780 raise "data = #{data}"
781 end
782 data = $' # variable $' receives the string after the match
783 when :adl
784 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
785 data = adl_scanner.scan(data) do |sym, val|
786 yield sym, val
787 end
788 when :dadl
789 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
790 data = dadl_scanner.scan(data) do |sym, val|
791 yield sym, val
792 end
793 when :cadl
794 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
795 data = cadl_scanner.scan(data) do |sym, val|
796 yield sym, val
797 end
798 else
799 raise
800 end
801 end
802 end
803 end # of TermConstraintScanner
804
805 end
806 end
807end
808
809__END__
810
811
812
813# module Common
814# class START_TERM_CODE_CONSTRAINT
815# include Yaparc::Parsable
816# def initialize
817# @parser = lambda do |input|
818# Yaparc::Apply.new(Yaparc::Regex.new(/[ \t\n]*\[([a-zA-Z0-9\(\)\._\-]+)::[ \t\n]*/)) do |match|
819# OpenEhr::LOG.info("START_TERM_CODE_CONSTRAINT: #{match}")
820# [:START_TERM_CODE_CONSTRAINT, match]
821# end
822# end
823# end
824# end
825
826# # /\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
827# class V_QUALIFIED_TERM_CODE_REF
828# include Yaparc::Parsable
829# def initialize
830# @parser = lambda do |input|
831# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/)) do |match|
832# OpenEhr::LOG.info("V_QUALIFIED_TERM_CODE_REF: #{match}")
833# [:V_QUALIFIED_TERM_CODE_REF, match]
834# end
835# end
836# end
837# end
838
839# class V_LOCAL_TERM_CODE_REF
840# include Yaparc::Parsable
841# def initialize
842# @parser = lambda do |input|
843# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9][a-zA-Z0-9._\-]*\]/)) do |match|
844# OpenEhr::LOG.info("V_TERM_CODE_REF: #{match}")
845# [:V_LOCAL_TERM_CODE_REF, match]
846# end
847# end
848# end
849# end
850
851# class ERR_V_QUALIFIED_TERM_CODE_REF
852# include Yaparc::Parsable
853# def initialize
854# @parser = lambda do |input|
855# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/)) do |match|
856# OpenEhr::LOG.info("ERR_V_QUALIFIED_TERM_CODE_REF: #{match}")
857# [:ERR_V_QUALIFIED_TERM_CODE_REF, match]
858# end
859# end
860# end
861# end
862
863# class V_TYPE_IDENTIFIER
864# include Yaparc::Parsable
865# def initialize
866# @parser = lambda do |input|
867# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*/)) do |match|
868# OpenEhr::LOG.info("V_TYPE_IDENTIFIER: #{match}")
869# [:V_TYPE_IDENTIFIER, match]
870# end
871# end
872# end
873# end
874
875# class V_GENERIC_TYPE_IDENTIFIER
876# include Yaparc::Parsable
877# def initialize
878# @parser = lambda do |input|
879# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/)) do |match|
880# OpenEhr::LOG.info("V_GENERIC_TYPE_IDENTIFIER: #{match}")
881# [:V_GENERIC_TYPE_IDENTIFIER, match]
882# end
883# end
884# end
885# end
886
887
888# class V_LOCAL_CODE
889# include Yaparc::Parsable
890# def initialize
891# @parser = lambda do |input|
892# Yaparc::Apply.new(Yaparc::Regex.new(/\Aa[ct][0-9.]+/)) do |match|
893# OpenEhr::LOG.info("V_LOCAL_CODE: #{match}")
894# [:V_LOCAL_CODE, match]
895# end
896# end
897# end
898# end
899
900# class V_STRING
901# include Yaparc::Parsable
902# def initialize
903# @parser = lambda do |input|
904# Yaparc::Apply.new(Yaparc::Regex.new(/\A"([^"]*)"/m)) do |match|
905# OpenEhr::LOG.info("V_STRING: #{match}")
906# [:V_STRING, match]
907# end
908# end
909# end
910# end
911
912# class V_REAL
913# include Yaparc::Parsable
914# def initialize
915# @parser = lambda do |input|
916# Yaparc::Apply.new(Yaparc::Regex.new(/\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+/)) do |match|
917# OpenEhr::LOG.info("V_REAL: #{match}")
918# [:V_REAL, match]
919# end
920# end
921# end
922# end
923
924# #V_ISO8601_DURATION PnYnMnWnDTnnHnnMnnS
925# class V_ISO8601_DURATION
926# include Yaparc::Parsable
927# def initialize
928# @parser = lambda do |input|
929# Yaparc::Apply.new(
930# Yaparc::Alt.new(Yaparc::Regex.new(/\AP([0-9]+|[yY])?([0-9]+|[mM])?([0-9]+|[wW])?([0-9]+|[dD])?T([0-9]+|[hH])?([0-9]+|[mM])?([0-9]+|[sS])?/),
931# Yaparc::Regex.new(/\AP([0-9]+|[yY])?([0-9]+|[mM])?([0-9]+|[wW])?([0-9]+|[dD])?/))) do |match|
932# OpenEhr::LOG.info("V_ISO8601_DURATION: #{match}")
933# [:V_ISO8601_DURATION, match]
934# end
935# end
936# end
937# end
938
939# end # of Common
940
941# module DADL
942# # c.f. http://www.openehr.org/svn/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/adl/parser/adl_scanner.l
943# RESERVED = {
944# 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
945# 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
946# 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
947# }
948# #
949# # DADL::RootScanner
950# #
951# class RootScanner
952# include Yaparc::Parsable
953# def initialize
954# @parser = lambda do |input|
955# Yaparc::Alt.new(Reserved.new,
956# OpenEhr::ADL::Scanner::Common::V_QUALIFIED_TERM_CODE_REF.new,
957# OpenEhr::ADL::Scanner::Common::V_LOCAL_TERM_CODE_REF.new,
958# OpenEhr::ADL::Scanner::Common::ERR_V_QUALIFIED_TERM_CODE_REF.new,
959# OpenEhr::ADL::Scanner::Common::V_TYPE_IDENTIFIER.new,
960# OpenEhr::ADL::Scanner::Common::V_GENERIC_TYPE_IDENTIFIER.new,
961# OpenEhr::ADL::Scanner::Common::V_STRING.new,
962# OpenEhr::ADL::Scanner::Common::V_LOCAL_CODE.new,
963# OpenEhr::ADL::Scanner::Common::V_REAL.new,
964# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new#,
965# #OpenEhr::ADL::Scanner::Common::START_TERM_CODE_CONSTRAINT.new
966# )
967# end
968# end
969# end
970
971# # <DADL::Reserved class>
972# class Reserved
973# include Yaparc::Parsable
974
975# def initialize
976# @parser = lambda do |input|
977# reserved_parsers = OpenEhr::ADL::Scanner::DADL::RESERVED.map do |keyword|
978# Yaparc::Tokenize.new(
979# Yaparc::Literal.new(keyword[0],false)
980# )
981# end
982# Yaparc::Alt.new(Yaparc::Apply.new(Yaparc::Alt.new(*reserved_parsers)) do |match|
983# OpenEhr::LOG.info("Reserved: #{match}")
984# [OpenEhr::ADL::Scanner::DADL::RESERVED[match], OpenEhr::ADL::Scanner::DADL::RESERVED[match]]
985# end,
986# Yaparc::Apply.new(Yaparc::Regex.new(/\A[a-z][a-zA-Z0-9_]*/)) do |match|
987# OpenEhr::LOG.info("V_ATTRIBUTE_IDENTIFIER: #{match}")
988# [:V_ATTRIBUTE_IDENTIFIER, match]
989# end)
990# end
991# end
992# end
993# end # of DADL
994
995# module CADL
996# # c.f. http://www.openehr.org/svn/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/cadl/parser/cadl_scanner.l
997# RESERVED = {
998# 'ordered' => :SYM_ORDERED, # [Oo][Rr][Dd][Ee][Rr][Ee][Dd]
999# 'unordered' => :SYM_UNORDERED, # [Uu][Nn][Oo][Rr][Dd][Ee][Rr][Ee][Dd]
1000# 'then' => :SYM_THEN, # [Tt][Hh][Ee][Nn]
1001# 'else' => :SYM_ELSE, # [Ee][Ll][Ss][Ee]
1002# 'and' => :SYM_AND, # [Aa][Nn][Dd]
1003# 'or' => :SYM_OR, # [Oo][Rr]
1004# 'xor' => :SYM_XOR, # [Xx][Oo][Rr]
1005# 'not' => :SYM_NOT, # [Nn][Oo][Tt]
1006# 'implies' => :SYM_IMPLIES, # [Ii][Mm][Pp][Ll][Ii][Ee][Ss]
1007# 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
1008# 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
1009# 'forall' => :SYM_FORALL, # [Ff][Oo][Rr][_][Aa][Ll][Ll]
1010# 'exists' => :SYM_EXISTS, # [Ee][Xx][Ii][Ss][Tt][Ss]
1011# 'existence' => :SYM_EXISTENCE, # [Ee][Xx][Iu][Ss][Tt][Ee][Nn][Cc][Ee]
1012# 'occurrences' => :SYM_OCCURRENCES, # [Oo][Cc][Cc][Uu][Rr][Rr][Ee][Nn][Cc][Ee][Ss]
1013# 'cardinality' => :SYM_CARDINALITY, # [Cc][Aa][Rr][Dd][Ii][Nn][Aa][Ll][Ii][Tt][Yy]
1014# 'unique' => :SYM_UNIQUE, # [Uu][Nn][Ii][Qq][Uu][Ee]
1015# 'matches' => :SYM_MATCHES, # [Mm][Aa][Tt][Cc][Hh][Ee][Ss]
1016# 'is_in' => :SYM_MATCHES, # [Ii][Ss][_][Ii][Nn]
1017# 'invariant' => :SYM_INVARIANT, # [Ii][Nn][Vv][Aa][Rr][Ii][Aa][Nn][Tt]
1018# 'infinity' => :SYM_INFINITY, # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
1019# 'use_node' => :SYM_USE_NODE, # [Uu][Ss][Ee][_][Nn][Oo][Dd][Ee]
1020# 'use_archetype' => :SYM_ALLOW_ARCHETYPE, # [Uu][Ss][Ee][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1021# 'allow_archetype' => :SYM_ALLOW_ARCHETYPE, # [Aa][Ll][Ll][Oo][Ww][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1022# 'include' => :SYM_INCLUDE, # [Ii][Nn][Cc][Ll][Uu][Dd][Ee]
1023# 'exclude' => :SYM_EXCLUDE # [Ee][Xx][Cc][Ll][Uu][Dd][Ee]
1024# }
1025
1026# #V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, /\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]/
1027# class V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN
1028# include Yaparc::Parsable
1029# def initialize
1030# @parser = lambda do |input|
1031# Yaparc::Apply.new(Yaparc::Regex.new(/\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]/)) do |match|
1032# OpenEhr::LOG.info("V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN: #{match}")
1033# [:V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, match]
1034# end
1035# end
1036# end
1037# end
1038
1039# #V_ISO8601_DATE_CONSTRAINT_PATTERN /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/
1040# class V_ISO8601_DATE_CONSTRAINT_PATTERN
1041# include Yaparc::Parsable
1042# def initialize
1043# @parser = lambda do |input|
1044# Yaparc::Apply.new(Yaparc::Regex.new(/\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/)) do |match|
1045# OpenEhr::LOG.info("V_ISO8601_DATE_CONSTRAINT_PATTERN: #{match}")
1046# [:V_ISO8601_DATE_CONSTRAINT_PATTERN, match]
1047# end
1048# end
1049# end
1050# end
1051
1052# #V_ISO8601_TIME_CONSTRAINT_PATTERN /\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/
1053# class V_ISO8601_TIME_CONSTRAINT_PATTERN
1054# include Yaparc::Parsable
1055# def initialize
1056# @parser = lambda do |input|
1057# Yaparc::Apply.new(Yaparc::Regex.new(/\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/)) do |match|
1058# OpenEhr::LOG.info("V_ISO8601_TIME_CONSTRAINT_PATTERN: #{match}")
1059# [:V_ISO8601_TIME_CONSTRAINT_PATTERN, match]
1060# end
1061# end
1062# end
1063# end
1064
1065# #V_ISO8601_DURATION_CONSTRAINT_PATTERN
1066# class V_ISO8601_DURATION_CONSTRAINT_PATTERN
1067# include Yaparc::Parsable
1068# def initialize
1069# @parser = lambda do |input|
1070# Yaparc::Apply.new(Yaparc::Alt.new(Yaparc::Regex.new(/\AP[yY]?[mM]?[wW]?[dD]?T[hH]?[mM]?[sS]?/),
1071# Yaparc::Regex.new(/\AP[yY]?[mM]?[wW]?[dD]?/))) do |match|
1072# OpenEhr::LOG.info("V_ISO8601_DURATION_CONSTRAINT_PATTERN: #{match}")
1073# [:V_ISO8601_DURATION_CONSTRAINT_PATTERN, match]
1074# end
1075# end
1076# end
1077# end
1078
1079# #V_C_DOMAIN_TYPE /\A[A-Z][a-zA-Z0-9_]*[ \n]*\</
1080# class V_C_DOMAIN_TYPE
1081# include Yaparc::Parsable
1082# def initialize
1083# @parser = lambda do |input|
1084# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*[ \n]*\</)) do |match|
1085# OpenEhr::LOG.info("V_C_DOMAIN_TYPE: #{match}")
1086# [:START_V_C_DOMAIN_TYPE_BLOCK, match]
1087# end
1088# end
1089# end
1090# end
1091
1092# #
1093# # CADL::RootScanner
1094# #
1095# class RootScanner
1096# include Yaparc::Parsable
1097# def initialize
1098# @parser = lambda do |input|
1099# Yaparc::Alt.new(V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN.new,
1100# V_ISO8601_DATE_CONSTRAINT_PATTERN.new,
1101# V_ISO8601_TIME_CONSTRAINT_PATTERN.new,
1102# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new,
1103# V_C_DOMAIN_TYPE.new,
1104# V_ISO8601_DURATION_CONSTRAINT_PATTERN.new,
1105# Reserved.new,
1106# OpenEhr::ADL::Scanner::Common::V_QUALIFIED_TERM_CODE_REF.new,
1107# OpenEhr::ADL::Scanner::Common::V_LOCAL_TERM_CODE_REF.new,
1108# OpenEhr::ADL::Scanner::Common::ERR_V_QUALIFIED_TERM_CODE_REF.new,
1109# OpenEhr::ADL::Scanner::Common::V_TYPE_IDENTIFIER.new,
1110# OpenEhr::ADL::Scanner::Common::V_GENERIC_TYPE_IDENTIFIER.new,
1111# OpenEhr::ADL::Scanner::Common::V_STRING.new,
1112# OpenEhr::ADL::Scanner::Common::V_LOCAL_CODE.new,
1113# OpenEhr::ADL::Scanner::Common::V_REAL.new,
1114# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new#,
1115# #OpenEhr::ADL::Scanner::Common::START_TERM_CODE_CONSTRAINT.new
1116# )
1117# end
1118# end
1119# end
1120
1121# # <CADL::Reserved class>
1122# class Reserved
1123# include Yaparc::Parsable
1124
1125# def initialize
1126# @parser = lambda do |input|
1127# orderd_reserved = RESERVED.keys.sort{|x,y| y.length <=> x.length }
1128# reserved_parsers = orderd_reserved.map do |keyword|
1129# Yaparc::Literal.new(keyword,false)
1130# end
1131# Yaparc::Alt.new(Yaparc::Apply.new(Yaparc::Alt.new(*reserved_parsers)) do |match|
1132# OpenEhr::LOG.info("Reserved: #{match}")
1133# [OpenEhr::ADL::Scanner::CADL::RESERVED[match], OpenEhr::ADL::Scanner::CADL::RESERVED[match]]
1134# end,
1135# Yaparc::Apply.new(Yaparc::Regex.new(/\A[a-z][a-zA-Z0-9_]*/)) do |match|
1136# OpenEhr::LOG.info("V_ATTRIBUTE_IDENTIFIER: #{match}")
1137# [:V_ATTRIBUTE_IDENTIFIER, match]
1138# end)
1139# end
1140# end
1141# end
1142
1143# end
1144
1145
Note: See TracBrowser for help on using the repository browser.