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

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

commit from Pittsburgh

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