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

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

created remote_adl_test.rb

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 @@logger.debug("DADLScanner#scan: Comma_code")
351 yield :Comma_code, :Comma_code
352 when /\A\:/ # :
353 yield :Colon_code, :Colon_code
354 when /\A\!/ # !
355 yield :Exclamation_code, :Exclamation_code
356 when /\A\(/ # (
357 yield :Left_parenthesis_code, :Left_parenthesis_code
358 when /\A\)/ # )
359 yield :Right_parenthesis_code, :Right_parenthesis_code
360 when /\A\$/ # $
361 yield :Dollar_code, :Dollar_code
362 when /\A\?\?/ # ??
363 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
364 when /\A\?/ # ?
365 yield :Question_mark_code, :Question_mark_code
366 when /\A\|/ # |
367 @@logger.debug("DADLScanner#scan: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
368 if @in_interval
369 @in_interval = false
370 else
371 # @in_interval = false
372 @in_interval = true
373 end
374 @@logger.debug("DADLScanner#scan: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
375 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
376 when /\A\[([a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+)\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
377 yield :V_QUALIFIED_TERM_CODE_REF, $1
378 when /\A\[/ # [
379 @@logger.debug("DADLScanner#scan: Left_bracket_code at #{@filename}:#{@lineno}")
380 yield :Left_bracket_code, :Left_bracket_code
381 when /\A\]/ # ]
382 @@logger.debug("DADLScanner#scan: Right_bracket_code at #{@filename}:#{@lineno}")
383 yield :Right_bracket_code, :Right_bracket_code
384 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-]-
385 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_DATE_TIME")
386 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
387 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]
388 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_TIME")
389 yield :V_ISO8601_EXTENDED_TIME, $&
390 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
391 @@logger.debug("DADLScanner#scan: V_ISO8601_EXTENDED_DATE, #{$&}")
392 yield :V_ISO8601_EXTENDED_DATE, $&
393 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
394 yield :V_GENERIC_TYPE_IDENTIFIER, $&
395 when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
396 @@logger.debug("DADLScanner#scan: V_STRING, #{$1}")
397 yield :V_STRING, $1
398 when /\A"([^"]*)"/m #V_STRING
399 @@logger.debug("DADLScanner#scan: V_STRING, #{$1}")
400 yield :V_STRING, $1
401 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
402 yield :V_REAL, $&
403 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
404 @@logger.debug("DADLScanner#scan: V_INTEGER = #{$&}")
405 yield :V_INTEGER, $&
406 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
407 yield :V_URI, $&
408 when /\A\S/ #UTF8CHAR
409 yield :UTF8CHAR, $&
410 end
411 data = $' # variable $' receives the string after the match
412 when :adl
413 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
414 data = adl_scanner.scan(data) do |sym, val|
415 yield sym, val
416 end
417 when :cadl
418 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
419 data = cadl_scanner.scan(data) do |sym, val|
420 yield sym, val
421 end
422 when :regexp
423 regex_scanner = OpenEhr::ADL::Scanner::RegexScanner.new(@adl_type, @filename, @lineno)
424 data = regex_scanner.scan(data) do |sym, val|
425 yield sym, val
426 end
427 when :term_constraint
428 @@logger.debug("#{__FILE__}:#{__LINE__}: scan_dadl: Entering scan_term_constraint at #{@filename}:#{@lineno}: data = #{data.inspect}")
429 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
430 data = term_constraint_scanner.scan(data) do |sym, val|
431 yield sym, val
432 end
433 else
434 raise
435 end
436 end
437 end
438 end # of DADLScanner
439
440
441
442 class CADLScanner < Base
443
444 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
445 RESERVED = {
446 'then' => :SYM_THEN, # [Tt][Hh][Ee][Nn]
447 'else' => :SYM_ELSE, # [Ee][Ll][Ss][Ee]
448 'and' => :SYM_AND, # [Aa][Nn][Dd]
449 'or' => :SYM_OR, # [Oo][Rr]
450 'xor' => :SYM_XOR, # [Xx][Oo][Rr]
451 'not' => :SYM_NOT, # [Nn][Oo][Tt]
452 'implies' => :SYM_IMPLIES, # [Ii][Mm][Pp][Ll][Ii][Ee][Ss]
453 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
454 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
455 'forall' => :SYM_FORALL, # [Ff][Oo][Rr][_][Aa][Ll][Ll]
456 'exists' => :SYM_EXISTS, # [Ee][Xx][Ii][Ss][Tt][Ss]
457 'existence' => :SYM_EXISTENCE, # [Ee][Xx][Iu][Ss][Tt][Ee][Nn][Cc][Ee]
458 'occurrences' => :SYM_OCCURRENCES, # [Oo][Cc][Cc][Uu][Rr][Rr][Ee][Nn][Cc][Ee][Ss]
459 'cardinality' => :SYM_CARDINALITY, # [Cc][Aa][Rr][Dd][Ii][Nn][Aa][Ll][Ii][Tt][Yy]
460 'ordered' => :SYM_ORDERED, # [Oo][Rr][Dd][Ee][Rr][Ee][Dd]
461 'unordered' => :SYM_UNORDERED, # [Uu][Nn][Oo][Rr][Dd][Ee][Rr][Ee][Dd]
462 'unique' => :SYM_UNIQUE, # [Uu][Nn][Ii][Qq][Uu][Ee]
463 'matches' => :SYM_MATCHES, # [Mm][Aa][Tt][Cc][Hh][Ee][Ss]
464 'is_in' => :SYM_MATCHES, # [Ii][Ss][_][Ii][Nn]
465 'invariant' => :SYM_INVARIANT, # [Ii][Nn][Vv][Aa][Rr][Ii][Aa][Nn][Tt]
466 'infinity' => :SYM_INFINITY, # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
467 'use_node' => :SYM_USE_NODE, # [Uu][Ss][Ee][_][Nn][Oo][Dd][Ee]
468 'use_archetype' => :SYM_ALLOW_ARCHETYPE, # [Uu][Ss][Ee][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
469 'allow_archetype' => :SYM_ALLOW_ARCHETYPE, # [Aa][Ll][Ll][Oo][Ww][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
470 'include' => :SYM_INCLUDE, # [Ii][Nn][Cc][Ll][Uu][Dd][Ee]
471 'exclude' => :SYM_EXCLUDE # [Ee][Xx][Cc][Ll][Uu][Dd][Ee]
472 }
473
474 def initialize(adl_type, filename, lineno = 1)
475 super(adl_type, filename, lineno)
476 @in_interval = false
477 end
478
479 #
480 # CADLScanner#scan
481 #
482 def scan(data)
483 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering CADLScanner#scan at #{@filename}:#{@lineno}: data = #{data.inspect}")
484 until data.nil? do
485 @@logger.debug("CADLScanner#scan: loop data = #{data.inspect}")
486 case @adl_type.last
487 when :cadl
488 case data
489 when /\A\n/ # carriage return
490 @lineno += 1
491 ;
492 #yield :CR, :CR
493 when /\A[ \t\r\f]+/ #just drop it
494 ;
495 when /\A--.*\n/ # single line comment
496 @lineno += 1
497 ;
498 ###----------/* symbols */ -------------------------------------------------
499 when /\A\=/ # =
500 yield :SYM_EQ, :SYM_EQ
501 when /\A\>=/ # >=
502 yield :SYM_GE, :SYM_GE
503 when /\A\<=/ # <=
504 yield :SYM_LE, :SYM_LE
505 when /\A\</ # <
506 if @in_interval
507 yield :SYM_LT, :SYM_LT
508 else
509 @adl_type.push(:dadl)
510 yield :SYM_START_DBLOCK, $&
511 end
512 when /\A\>/ # >
513 if @in_interval
514 yield :SYM_GT, :SYM_GT
515 else
516 adl_type = @adl_type.pop
517 assert_at(__FILE__,__LINE__){adl_type == :dadl}
518 yield :SYM_END_DBLOCK, :SYM_END_DBLOCK
519 end
520 when /\A\-/ # -
521 yield :Minus_code, :Minus_code
522 when /\A\+/ # +
523 yield :Plus_code, :Plus_code
524 when /\A\*/ # *
525 yield :Star_code, :Star_code
526 when /\A\// # /
527 yield :Slash_code, :Slash_code
528 when /\A\^/ # ^
529 yield :Caret_code, :Caret_code
530 when /\A\.\.\./ # ...
531 yield :SYM_LIST_CONTINUE, :SYM_LIST_CONTINUE
532 when /\A\.\./ # ..
533 yield :SYM_ELLIPSIS, :SYM_ELLIPSIS
534 when /\A\./ # .
535 yield :Dot_code, :Dot_code
536 when /\A\;/ # ;
537 yield :Semicolon_code, :Semicolon_code
538 when /\A\,/ # ,
539 yield :Comma_code, :Comma_code
540 when /\A\:/ # :
541 yield :Colon_code, :Colon_code
542 when /\A\!/ # !
543 yield :Exclamation_code, :Exclamation_code
544 when /\A\(/ # (
545 yield :Left_parenthesis_code, :Left_parenthesis_code
546 when /\A\)/ # )
547 yield :Right_parenthesis_code, :Right_parenthesis_code
548 when /\A\{\// #V_REGEXP
549 if @adl_type.last != :regexp
550 @in_regexp = true
551 @adl_type.push(:regexp)
552 yield :START_REGEXP_BLOCK, :START_REGEXP_BLOCK
553 else
554 raise
555 end
556 when /\A\{/ # {
557 @adl_type.push(:cadl)
558 @@logger.debug("CADLScanner#scan: entering cADL at #{@filename}:#{@lineno}")
559 yield :SYM_START_CBLOCK, :SYM_START_CBLOCK
560 when /\A\}/ # }
561 adl_type = @adl_type.pop
562 assert_at(__FILE__,__LINE__){adl_type == :cadl}
563 @@logger.debug("CADLScanner#scan: exiting cADL at #{@filename}:#{@lineno}")
564 yield :SYM_END_CBLOCK, :SYM_END_CBLOCK
565 when /\A\$/ # $
566 yield :Dollar_code, :Dollar_code
567 when /\A\?\?/ # ??
568 yield :SYM_DT_UNKNOWN, :SYM_DT_UNKNOWN
569 when /\A\?/ # ?
570 yield :Question_mark_code, :Question_mark_code
571 when /\A\|/ # |
572 @@logger.debug("CADLScanner#scan: @in_interval = #{@in_interval} at #{@filename}:#{@lineno}")
573 if @in_interval
574 @in_interval = false
575 else
576 # @in_interval = false
577 @in_interval = true
578 end
579 @@logger.debug("CADLScanner#scan: SYM_INTERVAL_DELIM at #{@filename}:#{@lineno}")
580 yield :SYM_INTERVAL_DELIM, :SYM_INTERVAL_DELIM
581
582 when /\A\[([a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+)\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
583 yield :V_QUALIFIED_TERM_CODE_REF, $1
584 when /\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/ #ERR_V_QUALIFIED_TERM_CODE_REF
585 yield :ERR_V_QUALIFIED_TERM_CODE_REF, $&
586 when /\A\[([a-zA-Z0-9\(\)\._\-]+)::[ \t\n]*/
587 @adl_type.push(:term_constraint)
588 yield :START_TERM_CODE_CONSTRAINT, $1
589 when /\A\[([a-zA-Z0-9][a-zA-Z0-9._\-]*)\]/ #V_LOCAL_TERM_CODE_REF
590 yield :V_LOCAL_TERM_CODE_REF, $1
591 when /\A\[/ # [
592 yield :Left_bracket_code, :Left_bracket_code
593 when /\A\]/ # ]
594 yield :Right_bracket_code, :Right_bracket_code
595 when /\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/ #V_GENERIC_TYPE_IDENTIFIER
596 yield :V_GENERIC_TYPE_IDENTIFIER, $&
597 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]/
598 yield :V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, $&
599 when /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/
600 yield :V_ISO8601_DATE_CONSTRAINT_PATTERN, $&
601 when /\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/
602 yield :V_ISO8601_TIME_CONSTRAINT_PATTERN, $&
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])?|P([0-9]+[yY])?([0-9]+[mM])?([0-9]+[wW])?([0-9]+[dD])?/ #V_ISO8601_DURATION such as PnYnMnWnDTnnHnnMnnS
604 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
605 yield :V_ISO8601_DURATION, $&
606 when /\AP[yY]?[mM]?[wW]?[dD]?T[hH]?[mM]?[sS]?/ #V_ISO8601_DURATION_CONSTRAINT_PATTERNo
607 yield :V_ISO8601_DURATION_CONSTRAINT_PATTERN, $&
608 when /\A[a-z][a-zA-Z0-9_]*/
609 word = $&.dup
610 if RESERVED[word.downcase]
611 yield RESERVED[word.downcase], RESERVED[word.downcase]
612 else
613 @@logger.debug("CADLScanner#scan: V_ATTRIBUTE_IDENTIFIER = #{word} at #{@filename}:#{@lineno}")
614 yield :V_ATTRIBUTE_IDENTIFIER, word #V_ATTRIBUTE_IDENTIFIER /\A[a-z][a-zA-Z0-9_]*/
615 end
616 when /\A([A-Z][a-zA-Z0-9_]*)[ \n]*\</ # V_C_DOMAIN_TYPE
617 @in_c_domain_type = true
618 @adl_type.push(:dadl)
619 yield :START_V_C_DOMAIN_TYPE_BLOCK, $1
620 when /\A[A-Z][a-zA-Z0-9_]*/
621 word = $&.dup
622 if RESERVED[word.downcase]
623 yield RESERVED[word.downcase], RESERVED[word.downcase]
624 else
625 yield :V_TYPE_IDENTIFIER, $&
626 end
627 when /\Aa[ct][0-9.]+/ #V_LOCAL_CODE
628 yield :V_LOCAL_CODE, $&
629 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-]-
630 yield :V_ISO8601_EXTENDED_DATE_TIME, $&
631 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]
632 yield :V_ISO8601_EXTENDED_TIME, $&
633 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
634 yield :V_ISO8601_EXTENDED_DATE, $&
635 when /\A"((?:[^"\\]+|\\.)*)"/ #V_STRING
636 yield :V_STRING, $1
637 when /\A"([^"]*)"/m #V_STRING
638 yield :V_STRING, $1
639 when /\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+ / #V_REAL
640 yield :V_REAL, $&
641 when /\A[0-9]+|[0-9]+[eE][+-]?[0-9]+/ #V_INTEGER
642 @@logger.debug("CADLScanner#scan: V_INTEGER = #{$&}")
643 yield :V_INTEGER, $&
644 when /\A[a-z]+:\/\/[^<>|\\{}^~"\[\] ]*/ #V_URI
645 yield :V_URI, $&
646 when /\A\S/ #UTF8CHAR
647 yield :UTF8CHAR, $&
648 when /\A.+/ #
649 raise OpenEhr::ADL::Exception::CADLScanner::Base.new, "can't handle #{data.inspect}"
650 end
651 data = $' # variable $' receives the string after the match
652 when :adl
653 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
654 data = adl_scanner.scan(data) do |sym, val|
655 yield sym, val
656 end
657 when :dadl
658 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
659 dadl_scanner.in_c_domain_type = @in_c_domain_type
660 data = dadl_scanner.scan(data) do |sym, val|
661 yield sym, val
662 end
663 when :regexp
664 regex_scanner = OpenEhr::ADL::Scanner::RegexScanner.new(@adl_type, @filename, @lineno)
665 data = regex_scanner.scan(data) do |sym, val|
666 yield sym, val
667 end
668 when :term_constraint
669 @@logger.debug("Entering scan_term_constraint at #{@filename}:#{@lineno}: data = #{data.inspect}")
670 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
671 data = term_constraint_scanner.scan(data) do |sym, val|
672 yield sym, val
673 end
674 else
675 raise OpenEhr::ADL::Exception::CADLScanner.new, "unexpected adl_type: #{@adl_type.last}"
676 end
677 end # of until
678 end
679 end # of CADLScanner
680
681
682 #
683 # RegexScanner
684 #
685 class RegexScanner < Base
686
687 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
688
689 def initialize(adl_type, filename, lineno = 1)
690 super(adl_type, filename, lineno)
691 end
692
693 def scan(data)
694 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan_regexp at #{@filename}:#{@lineno}: data = #{data.inspect}")
695 until data.nil? do
696 case @adl_type.last
697 when :regexp
698 case data
699 when /\A\/\}/ #V_REGEXP
700 if @adl_type.last == :regexp
701 @in_regexp = false
702 @adl_type.pop
703 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
704 else
705 raise
706 end
707 when /\A(.*)(\/\})/ #V_REGEXP
708 yield :REGEXP_BODY, $1
709 if @adl_type.last == :regexp
710 @in_regexp = false
711 @adl_type.pop
712 yield :END_REGEXP_BLOCK, :END_REGEXP_BLOCK
713 else
714 raise
715 end
716 else
717 raise data
718 end
719 data = $' # variable $' receives the string after the match
720 when :adl
721 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
722 data = adl_scanner.scan(data) do |sym, val|
723 yield sym, val
724 end
725 when :dadl
726 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
727 data = dadl_scanner.scan(data) do |sym, val|
728 yield sym, val
729 end
730 when :cadl
731 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
732 data = cadl_scanner.scan(data) do |sym, val|
733 yield sym, val
734 end
735 when :term_constraint
736 #@@logger.debug("#{__FILE__}:#{__LINE__}: scan_regexp: Entering scan_term_constraint at #{@filename}:#{@lineno}")
737 term_constraint_scanner = OpenEhr::ADL::Scanner::TermConstraintScanner.new(@adl_type, @filename, @lineno)
738 data = term_constraint_scanner.scan(data) do |sym, val|
739 yield sym, val
740 end
741 else
742 raise
743 end
744 end
745 end
746 end # of RegexScanner
747
748 #
749 # TermConstraintScanner
750 #
751 class TermConstraintScanner < Base
752 @@logger = OpenEhr::ADL::Scanner::LOGGER #Logger.new('log/scanner.log') #Logger.new('log/scanner.log')
753 def initialize(adl_type, filename, lineno = 1)
754 super(adl_type, filename, lineno)
755 end
756
757 def scan(data)
758 @@logger.debug("#{__FILE__}:#{__LINE__}: Entering scan_term_constraint")
759 until data.nil? do
760 case @adl_type.last
761 when :term_constraint
762 case data
763 when /\A\n/ # carriage return
764 @lineno += 1
765 ;
766 when /\A[ \t\r\f]+/ #just drop it
767 ;
768 when /\A--.*$/ # single line comment
769 @lineno += 1
770 @@logger.debug("#{__FILE__}:#{__LINE__}: scan_term_constraint: COMMENT = #{$&} at #{@filename}:#{@lineno}")
771 ;
772 when /\A([a-zA-Z0-9\._\-])+[ \t]*,/ # match any line, with ',' termination
773 yield :TERM_CODE, $1
774 when /\A([a-zA-Z0-9\._\-])+[ \t]*;/ # match second last line with ';' termination (assumed value)
775 yield :TERM_CODE, $1
776 when /\A([a-zA-Z0-9\._\-])*[ \t]*\]/ # match final line, terminating in ']'
777 adl_type = @adl_type.pop
778 assert_at(__FILE__,__LINE__){adl_type == :term_constraint}
779 yield :END_TERM_CODE_CONSTRAINT, $1
780 else
781 raise "data = #{data}"
782 end
783 data = $' # variable $' receives the string after the match
784 when :adl
785 adl_scanner = OpenEhr::ADL::Scanner::ADLScanner.new(@adl_type, @filename, @lineno)
786 data = adl_scanner.scan(data) do |sym, val|
787 yield sym, val
788 end
789 when :dadl
790 dadl_scanner = OpenEhr::ADL::Scanner::DADLScanner.new(@adl_type, @filename, @lineno)
791 data = dadl_scanner.scan(data) do |sym, val|
792 yield sym, val
793 end
794 when :cadl
795 cadl_scanner = OpenEhr::ADL::Scanner::CADLScanner.new(@adl_type, @filename, @lineno)
796 data = cadl_scanner.scan(data) do |sym, val|
797 yield sym, val
798 end
799 else
800 raise
801 end
802 end
803 end
804 end # of TermConstraintScanner
805
806 end
807 end
808end
809
810__END__
811
812
813
814# module Common
815# class START_TERM_CODE_CONSTRAINT
816# include Yaparc::Parsable
817# def initialize
818# @parser = lambda do |input|
819# Yaparc::Apply.new(Yaparc::Regex.new(/[ \t\n]*\[([a-zA-Z0-9\(\)\._\-]+)::[ \t\n]*/)) do |match|
820# OpenEhr::LOG.info("START_TERM_CODE_CONSTRAINT: #{match}")
821# [:START_TERM_CODE_CONSTRAINT, match]
822# end
823# end
824# end
825# end
826
827# # /\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/ #V_QUALIFIED_TERM_CODE_REF form [ICD10AM(1998)::F23]
828# class V_QUALIFIED_TERM_CODE_REF
829# include Yaparc::Parsable
830# def initialize
831# @parser = lambda do |input|
832# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9()\._-]+::[a-zA-Z0-9\._-]+\]/)) do |match|
833# OpenEhr::LOG.info("V_QUALIFIED_TERM_CODE_REF: #{match}")
834# [:V_QUALIFIED_TERM_CODE_REF, match]
835# end
836# end
837# end
838# end
839
840# class V_LOCAL_TERM_CODE_REF
841# include Yaparc::Parsable
842# def initialize
843# @parser = lambda do |input|
844# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9][a-zA-Z0-9._\-]*\]/)) do |match|
845# OpenEhr::LOG.info("V_TERM_CODE_REF: #{match}")
846# [:V_LOCAL_TERM_CODE_REF, match]
847# end
848# end
849# end
850# end
851
852# class ERR_V_QUALIFIED_TERM_CODE_REF
853# include Yaparc::Parsable
854# def initialize
855# @parser = lambda do |input|
856# Yaparc::Apply.new(Yaparc::Regex.new(/\A\[[a-zA-Z0-9._\- ]+::[a-zA-Z0-9._\- ]+\]/)) do |match|
857# OpenEhr::LOG.info("ERR_V_QUALIFIED_TERM_CODE_REF: #{match}")
858# [:ERR_V_QUALIFIED_TERM_CODE_REF, match]
859# end
860# end
861# end
862# end
863
864# class V_TYPE_IDENTIFIER
865# include Yaparc::Parsable
866# def initialize
867# @parser = lambda do |input|
868# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*/)) do |match|
869# OpenEhr::LOG.info("V_TYPE_IDENTIFIER: #{match}")
870# [:V_TYPE_IDENTIFIER, match]
871# end
872# end
873# end
874# end
875
876# class V_GENERIC_TYPE_IDENTIFIER
877# include Yaparc::Parsable
878# def initialize
879# @parser = lambda do |input|
880# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*<[a-zA-Z0-9,_<>]+>/)) do |match|
881# OpenEhr::LOG.info("V_GENERIC_TYPE_IDENTIFIER: #{match}")
882# [:V_GENERIC_TYPE_IDENTIFIER, match]
883# end
884# end
885# end
886# end
887
888
889# class V_LOCAL_CODE
890# include Yaparc::Parsable
891# def initialize
892# @parser = lambda do |input|
893# Yaparc::Apply.new(Yaparc::Regex.new(/\Aa[ct][0-9.]+/)) do |match|
894# OpenEhr::LOG.info("V_LOCAL_CODE: #{match}")
895# [:V_LOCAL_CODE, match]
896# end
897# end
898# end
899# end
900
901# class V_STRING
902# include Yaparc::Parsable
903# def initialize
904# @parser = lambda do |input|
905# Yaparc::Apply.new(Yaparc::Regex.new(/\A"([^"]*)"/m)) do |match|
906# OpenEhr::LOG.info("V_STRING: #{match}")
907# [:V_STRING, match]
908# end
909# end
910# end
911# end
912
913# class V_REAL
914# include Yaparc::Parsable
915# def initialize
916# @parser = lambda do |input|
917# Yaparc::Apply.new(Yaparc::Regex.new(/\A[0-9]+\.[0-9]+|[0-9]+\.[0-9]+[eE][+-]?[0-9]+/)) do |match|
918# OpenEhr::LOG.info("V_REAL: #{match}")
919# [:V_REAL, match]
920# end
921# end
922# end
923# end
924
925# #V_ISO8601_DURATION PnYnMnWnDTnnHnnMnnS
926# class V_ISO8601_DURATION
927# include Yaparc::Parsable
928# def initialize
929# @parser = lambda do |input|
930# Yaparc::Apply.new(
931# 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])?/),
932# Yaparc::Regex.new(/\AP([0-9]+|[yY])?([0-9]+|[mM])?([0-9]+|[wW])?([0-9]+|[dD])?/))) do |match|
933# OpenEhr::LOG.info("V_ISO8601_DURATION: #{match}")
934# [:V_ISO8601_DURATION, match]
935# end
936# end
937# end
938# end
939
940# end # of Common
941
942# module DADL
943# # c.f. http://www.openehr.org/svn/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/adl/parser/adl_scanner.l
944# RESERVED = {
945# 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
946# 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
947# 'infinity' => :SYM_INFINITY # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
948# }
949# #
950# # DADL::RootScanner
951# #
952# class RootScanner
953# include Yaparc::Parsable
954# def initialize
955# @parser = lambda do |input|
956# Yaparc::Alt.new(Reserved.new,
957# OpenEhr::ADL::Scanner::Common::V_QUALIFIED_TERM_CODE_REF.new,
958# OpenEhr::ADL::Scanner::Common::V_LOCAL_TERM_CODE_REF.new,
959# OpenEhr::ADL::Scanner::Common::ERR_V_QUALIFIED_TERM_CODE_REF.new,
960# OpenEhr::ADL::Scanner::Common::V_TYPE_IDENTIFIER.new,
961# OpenEhr::ADL::Scanner::Common::V_GENERIC_TYPE_IDENTIFIER.new,
962# OpenEhr::ADL::Scanner::Common::V_STRING.new,
963# OpenEhr::ADL::Scanner::Common::V_LOCAL_CODE.new,
964# OpenEhr::ADL::Scanner::Common::V_REAL.new,
965# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new#,
966# #OpenEhr::ADL::Scanner::Common::START_TERM_CODE_CONSTRAINT.new
967# )
968# end
969# end
970# end
971
972# # <DADL::Reserved class>
973# class Reserved
974# include Yaparc::Parsable
975
976# def initialize
977# @parser = lambda do |input|
978# reserved_parsers = OpenEhr::ADL::Scanner::DADL::RESERVED.map do |keyword|
979# Yaparc::Tokenize.new(
980# Yaparc::Literal.new(keyword[0],false)
981# )
982# end
983# Yaparc::Alt.new(Yaparc::Apply.new(Yaparc::Alt.new(*reserved_parsers)) do |match|
984# OpenEhr::LOG.info("Reserved: #{match}")
985# [OpenEhr::ADL::Scanner::DADL::RESERVED[match], OpenEhr::ADL::Scanner::DADL::RESERVED[match]]
986# end,
987# Yaparc::Apply.new(Yaparc::Regex.new(/\A[a-z][a-zA-Z0-9_]*/)) do |match|
988# OpenEhr::LOG.info("V_ATTRIBUTE_IDENTIFIER: #{match}")
989# [:V_ATTRIBUTE_IDENTIFIER, match]
990# end)
991# end
992# end
993# end
994# end # of DADL
995
996# module CADL
997# # c.f. http://www.openehr.org/svn/ref_impl_eiffel/TRUNK/components/adl_parser/src/syntax/cadl/parser/cadl_scanner.l
998# RESERVED = {
999# 'ordered' => :SYM_ORDERED, # [Oo][Rr][Dd][Ee][Rr][Ee][Dd]
1000# 'unordered' => :SYM_UNORDERED, # [Uu][Nn][Oo][Rr][Dd][Ee][Rr][Ee][Dd]
1001# 'then' => :SYM_THEN, # [Tt][Hh][Ee][Nn]
1002# 'else' => :SYM_ELSE, # [Ee][Ll][Ss][Ee]
1003# 'and' => :SYM_AND, # [Aa][Nn][Dd]
1004# 'or' => :SYM_OR, # [Oo][Rr]
1005# 'xor' => :SYM_XOR, # [Xx][Oo][Rr]
1006# 'not' => :SYM_NOT, # [Nn][Oo][Tt]
1007# 'implies' => :SYM_IMPLIES, # [Ii][Mm][Pp][Ll][Ii][Ee][Ss]
1008# 'true' => :SYM_TRUE, #[Tt][Rr][Uu][Ee] -- -> SYM_TRUE
1009# 'false' => :SYM_FALSE, # [Ff][Aa][Ll][Ss][Ee] -- -> SYM_FALSE
1010# 'forall' => :SYM_FORALL, # [Ff][Oo][Rr][_][Aa][Ll][Ll]
1011# 'exists' => :SYM_EXISTS, # [Ee][Xx][Ii][Ss][Tt][Ss]
1012# 'existence' => :SYM_EXISTENCE, # [Ee][Xx][Iu][Ss][Tt][Ee][Nn][Cc][Ee]
1013# 'occurrences' => :SYM_OCCURRENCES, # [Oo][Cc][Cc][Uu][Rr][Rr][Ee][Nn][Cc][Ee][Ss]
1014# 'cardinality' => :SYM_CARDINALITY, # [Cc][Aa][Rr][Dd][Ii][Nn][Aa][Ll][Ii][Tt][Yy]
1015# 'unique' => :SYM_UNIQUE, # [Uu][Nn][Ii][Qq][Uu][Ee]
1016# 'matches' => :SYM_MATCHES, # [Mm][Aa][Tt][Cc][Hh][Ee][Ss]
1017# 'is_in' => :SYM_MATCHES, # [Ii][Ss][_][Ii][Nn]
1018# 'invariant' => :SYM_INVARIANT, # [Ii][Nn][Vv][Aa][Rr][Ii][Aa][Nn][Tt]
1019# 'infinity' => :SYM_INFINITY, # [Ii][Nn][Ff][Ii][Nn][Ii][Tt][Yy] -- -> SYM_INFINITY
1020# 'use_node' => :SYM_USE_NODE, # [Uu][Ss][Ee][_][Nn][Oo][Dd][Ee]
1021# 'use_archetype' => :SYM_ALLOW_ARCHETYPE, # [Uu][Ss][Ee][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1022# 'allow_archetype' => :SYM_ALLOW_ARCHETYPE, # [Aa][Ll][Ll][Oo][Ww][_][Aa][Rr][Cc][Hh][Ee][Tt][Yy][Pp][Ee]
1023# 'include' => :SYM_INCLUDE, # [Ii][Nn][Cc][Ll][Uu][Dd][Ee]
1024# 'exclude' => :SYM_EXCLUDE # [Ee][Xx][Cc][Ll][Uu][Dd][Ee]
1025# }
1026
1027# #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]/
1028# class V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN
1029# include Yaparc::Parsable
1030# def initialize
1031# @parser = lambda do |input|
1032# 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|
1033# OpenEhr::LOG.info("V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN: #{match}")
1034# [:V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN, match]
1035# end
1036# end
1037# end
1038# end
1039
1040# #V_ISO8601_DATE_CONSTRAINT_PATTERN /\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/
1041# class V_ISO8601_DATE_CONSTRAINT_PATTERN
1042# include Yaparc::Parsable
1043# def initialize
1044# @parser = lambda do |input|
1045# Yaparc::Apply.new(Yaparc::Regex.new(/\A[yY][yY][yY][yY]-[mM?X][mM?X]-[dD?X][dD?X]/)) do |match|
1046# OpenEhr::LOG.info("V_ISO8601_DATE_CONSTRAINT_PATTERN: #{match}")
1047# [:V_ISO8601_DATE_CONSTRAINT_PATTERN, match]
1048# end
1049# end
1050# end
1051# end
1052
1053# #V_ISO8601_TIME_CONSTRAINT_PATTERN /\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/
1054# class V_ISO8601_TIME_CONSTRAINT_PATTERN
1055# include Yaparc::Parsable
1056# def initialize
1057# @parser = lambda do |input|
1058# Yaparc::Apply.new(Yaparc::Regex.new(/\A[hH][hH]:[mM?X][mM?X]:[sS?X][sS?X]/)) do |match|
1059# OpenEhr::LOG.info("V_ISO8601_TIME_CONSTRAINT_PATTERN: #{match}")
1060# [:V_ISO8601_TIME_CONSTRAINT_PATTERN, match]
1061# end
1062# end
1063# end
1064# end
1065
1066# #V_ISO8601_DURATION_CONSTRAINT_PATTERN
1067# class V_ISO8601_DURATION_CONSTRAINT_PATTERN
1068# include Yaparc::Parsable
1069# def initialize
1070# @parser = lambda do |input|
1071# Yaparc::Apply.new(Yaparc::Alt.new(Yaparc::Regex.new(/\AP[yY]?[mM]?[wW]?[dD]?T[hH]?[mM]?[sS]?/),
1072# Yaparc::Regex.new(/\AP[yY]?[mM]?[wW]?[dD]?/))) do |match|
1073# OpenEhr::LOG.info("V_ISO8601_DURATION_CONSTRAINT_PATTERN: #{match}")
1074# [:V_ISO8601_DURATION_CONSTRAINT_PATTERN, match]
1075# end
1076# end
1077# end
1078# end
1079
1080# #V_C_DOMAIN_TYPE /\A[A-Z][a-zA-Z0-9_]*[ \n]*\</
1081# class V_C_DOMAIN_TYPE
1082# include Yaparc::Parsable
1083# def initialize
1084# @parser = lambda do |input|
1085# Yaparc::Apply.new(Yaparc::Regex.new(/\A[A-Z][a-zA-Z0-9_]*[ \n]*\</)) do |match|
1086# OpenEhr::LOG.info("V_C_DOMAIN_TYPE: #{match}")
1087# [:START_V_C_DOMAIN_TYPE_BLOCK, match]
1088# end
1089# end
1090# end
1091# end
1092
1093# #
1094# # CADL::RootScanner
1095# #
1096# class RootScanner
1097# include Yaparc::Parsable
1098# def initialize
1099# @parser = lambda do |input|
1100# Yaparc::Alt.new(V_ISO8601_DATE_TIME_CONSTRAINT_PATTERN.new,
1101# V_ISO8601_DATE_CONSTRAINT_PATTERN.new,
1102# V_ISO8601_TIME_CONSTRAINT_PATTERN.new,
1103# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new,
1104# V_C_DOMAIN_TYPE.new,
1105# V_ISO8601_DURATION_CONSTRAINT_PATTERN.new,
1106# Reserved.new,
1107# OpenEhr::ADL::Scanner::Common::V_QUALIFIED_TERM_CODE_REF.new,
1108# OpenEhr::ADL::Scanner::Common::V_LOCAL_TERM_CODE_REF.new,
1109# OpenEhr::ADL::Scanner::Common::ERR_V_QUALIFIED_TERM_CODE_REF.new,
1110# OpenEhr::ADL::Scanner::Common::V_TYPE_IDENTIFIER.new,
1111# OpenEhr::ADL::Scanner::Common::V_GENERIC_TYPE_IDENTIFIER.new,
1112# OpenEhr::ADL::Scanner::Common::V_STRING.new,
1113# OpenEhr::ADL::Scanner::Common::V_LOCAL_CODE.new,
1114# OpenEhr::ADL::Scanner::Common::V_REAL.new,
1115# OpenEhr::ADL::Scanner::Common::V_ISO8601_DURATION.new#,
1116# #OpenEhr::ADL::Scanner::Common::START_TERM_CODE_CONSTRAINT.new
1117# )
1118# end
1119# end
1120# end
1121
1122# # <CADL::Reserved class>
1123# class Reserved
1124# include Yaparc::Parsable
1125
1126# def initialize
1127# @parser = lambda do |input|
1128# orderd_reserved = RESERVED.keys.sort{|x,y| y.length <=> x.length }
1129# reserved_parsers = orderd_reserved.map do |keyword|
1130# Yaparc::Literal.new(keyword,false)
1131# end
1132# Yaparc::Alt.new(Yaparc::Apply.new(Yaparc::Alt.new(*reserved_parsers)) do |match|
1133# OpenEhr::LOG.info("Reserved: #{match}")
1134# [OpenEhr::ADL::Scanner::CADL::RESERVED[match], OpenEhr::ADL::Scanner::CADL::RESERVED[match]]
1135# end,
1136# Yaparc::Apply.new(Yaparc::Regex.new(/\A[a-z][a-zA-Z0-9_]*/)) do |match|
1137# OpenEhr::LOG.info("V_ATTRIBUTE_IDENTIFIER: #{match}")
1138# [:V_ATTRIBUTE_IDENTIFIER, match]
1139# end)
1140# end
1141# end
1142# end
1143
1144# end
1145
1146
Note: See TracBrowser for help on using the repository browser.