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

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

Scanners for ADL parser do not need yaparc library any more

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.