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

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

ADL parser is roughly coupled with open_ehr model classes

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