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

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

edited README

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