source: ruby/branches/0.5/lib/adl_parser/lib/adl_scanner.rb@ 291

Last change on this file since 291 was 290, checked in by KOBAYASHI, Shinji, 15 years ago

merged latest trunc change to branches/0.5

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