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

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

successfully parsing all the adl files under http://www.openehr.org/svn/knowledge/archetypes/dev/adl/openehr/ehr directory

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