ridl 2.8.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.rdoc +10 -7
- data/lib/ridl/backend.rb +11 -12
- data/lib/ridl/delegate.rb +166 -59
- data/lib/ridl/expression.rb +68 -28
- data/lib/ridl/genfile.rb +22 -16
- data/lib/ridl/node.rb +609 -192
- data/lib/ridl/options.rb +10 -12
- data/lib/ridl/optparse_ext.rb +32 -34
- data/lib/ridl/parser.rb +1919 -1446
- data/lib/ridl/parser.ry +66 -9
- data/lib/ridl/runner.rb +42 -28
- data/lib/ridl/scanner.rb +207 -175
- data/lib/ridl/type.rb +246 -15
- data/lib/ridl/version.rb +2 -4
- metadata +5 -6
- data/lib/ridl/parser.diff +0 -42
data/lib/ridl/scanner.rb
CHANGED
@@ -14,10 +14,12 @@ require 'delegate'
|
|
14
14
|
module IDL
|
15
15
|
class ParseError < StandardError
|
16
16
|
attr_reader :positions
|
17
|
+
|
17
18
|
def initialize(msg, positions)
|
18
19
|
super(msg)
|
19
20
|
@positions = positions
|
20
21
|
end
|
22
|
+
|
21
23
|
def inspect
|
22
24
|
puts "#{self.class.name}: #{message}"
|
23
25
|
@positions.each { |pos|
|
@@ -35,6 +37,7 @@ module IDL
|
|
35
37
|
def to_s
|
36
38
|
format('%s: line %d, column %d', name.to_s, line, column)
|
37
39
|
end
|
40
|
+
|
38
41
|
def inspect
|
39
42
|
to_s
|
40
43
|
end
|
@@ -48,15 +51,20 @@ module IDL
|
|
48
51
|
@pos = Position.new(name, line, column)
|
49
52
|
@mark = nil
|
50
53
|
end
|
54
|
+
|
51
55
|
def position
|
52
56
|
@pos
|
53
57
|
end
|
58
|
+
|
54
59
|
def column
|
55
60
|
@pos.column
|
56
61
|
end
|
62
|
+
|
57
63
|
# cursor set at last gotten character.
|
58
64
|
# ex: after initialization, position is (0,0).
|
59
|
-
def to_s
|
65
|
+
def to_s
|
66
|
+
@src.to_s
|
67
|
+
end
|
60
68
|
|
61
69
|
def lookc
|
62
70
|
@fwd
|
@@ -66,8 +74,8 @@ module IDL
|
|
66
74
|
cur = @fwd
|
67
75
|
@fwd = @src.getc unless @src.nil?
|
68
76
|
@mark << cur unless @mark.nil?
|
69
|
-
if [nil,
|
70
|
-
if @bwd ==
|
77
|
+
if [nil, "\n", "\r"].include? @bwd
|
78
|
+
if @bwd == "\r" and cur == "\n"
|
71
79
|
else
|
72
80
|
@pos.line += 1
|
73
81
|
@pos.column = 1
|
@@ -75,13 +83,6 @@ module IDL
|
|
75
83
|
else
|
76
84
|
@pos.column += 1
|
77
85
|
end
|
78
|
-
|
79
|
-
if false
|
80
|
-
if not @bwd.nil? or cur.nil? or @fwd.nil?
|
81
|
-
printf("%c(%02x), %c(%02x), %c(%02x) @(l:%d,c:%d)\n",
|
82
|
-
@bwd, @bwd, cur, cur, @fwd, @fwd, @pos.line, @pos.column)
|
83
|
-
end
|
84
|
-
end
|
85
86
|
@bwd = cur
|
86
87
|
end
|
87
88
|
|
@@ -89,28 +90,30 @@ module IDL
|
|
89
90
|
return nil if @fwd.nil?
|
90
91
|
|
91
92
|
s = ''
|
92
|
-
s << getc until [nil,
|
93
|
-
s << getc while [
|
93
|
+
s << getc until [nil, "\n", "\r"].include? lookc
|
94
|
+
s << getc while ["\n", "\r"].include? lookc
|
94
95
|
|
95
96
|
@mark << s unless @mark.nil?
|
96
97
|
s
|
97
98
|
end
|
98
99
|
alias skipc getc
|
99
100
|
|
100
|
-
def skipwhile(*
|
101
|
+
def skipwhile(*_chars, &block)
|
101
102
|
if block
|
102
103
|
until (ch = lookc).nil?
|
103
104
|
return ch unless block.call(ch)
|
105
|
+
|
104
106
|
skipc
|
105
107
|
end
|
106
108
|
end
|
107
109
|
nil
|
108
110
|
end
|
109
111
|
|
110
|
-
def skipuntil(*
|
112
|
+
def skipuntil(*_chars, &block)
|
111
113
|
if block
|
112
114
|
until (ch = lookc).nil?
|
113
115
|
return ch if block.call(ch)
|
116
|
+
|
114
117
|
skipc
|
115
118
|
end
|
116
119
|
end
|
@@ -148,14 +151,17 @@ module IDL
|
|
148
151
|
@src = src
|
149
152
|
@ix = 0
|
150
153
|
end
|
154
|
+
|
151
155
|
def to_s
|
152
156
|
@src
|
153
157
|
end
|
158
|
+
|
154
159
|
def getc
|
155
160
|
ch = @src[@ix]
|
156
161
|
@ix += 1
|
157
162
|
ch
|
158
163
|
end
|
164
|
+
|
159
165
|
def close
|
160
166
|
@ix = 0
|
161
167
|
end
|
@@ -165,15 +171,19 @@ module IDL
|
|
165
171
|
def [](key)
|
166
172
|
super(::Symbol === key ? key : key.to_s.to_sym)
|
167
173
|
end
|
174
|
+
|
168
175
|
def []=(key, val)
|
169
176
|
super(::Symbol === key ? key : key.to_s.to_sym, val.to_s)
|
170
177
|
end
|
178
|
+
|
171
179
|
def has_key?(key)
|
172
180
|
super(::Symbol === key ? key : key.to_s.to_sym)
|
173
181
|
end
|
182
|
+
|
174
183
|
def delete(key)
|
175
184
|
super(::Symbol === key ? key : key.to_s.to_sym)
|
176
185
|
end
|
186
|
+
|
177
187
|
def assoc(key)
|
178
188
|
k_ = (::Symbol === key ? key : key.to_s.to_sym)
|
179
189
|
self.has_key?(k_) ? [k_, self[k_]] : nil
|
@@ -184,6 +194,7 @@ module IDL
|
|
184
194
|
def initialize(table_)
|
185
195
|
@table = table_
|
186
196
|
end
|
197
|
+
|
187
198
|
def [](key)
|
188
199
|
key = (::Integer === key) ? key.chr.to_sym : key.to_sym
|
189
200
|
@table[key]
|
@@ -194,8 +205,8 @@ module IDL
|
|
194
205
|
# to carry both 'raw' IDL name as well as language mapped
|
195
206
|
# name
|
196
207
|
class Identifier < DelegateClass(::String)
|
197
|
-
attr_reader :checked_name
|
198
|
-
|
208
|
+
attr_reader :checked_name, :unescaped_name
|
209
|
+
|
199
210
|
def initialize(idl_id, checked_id, unescaped_idl_id = nil)
|
200
211
|
super(idl_id)
|
201
212
|
@checked_name = checked_id
|
@@ -203,10 +214,67 @@ module IDL
|
|
203
214
|
end
|
204
215
|
end
|
205
216
|
|
217
|
+
LFCR = [ ("\n"), ("\r") ]
|
218
|
+
SPACES = [ ("\ "), ("\t") ]
|
219
|
+
WHITESPACE = SPACES + LFCR
|
220
|
+
|
221
|
+
ANNOTATION = '@'
|
222
|
+
ANNOTATION_STR = '@'
|
223
|
+
|
224
|
+
BREAKCHARS = [
|
225
|
+
'(', ')', '[', ']', '{', '}',
|
226
|
+
'^', '~',
|
227
|
+
'*', '%', '&', '|',
|
228
|
+
'<', '=', '>',
|
229
|
+
',', ';' ]
|
230
|
+
|
231
|
+
SHIFTCHARS = [ '<', '>' ]
|
232
|
+
|
233
|
+
DIGITS = ('0'..'9').to_a
|
234
|
+
ALPHA_LC = ('a'..'z').to_a
|
235
|
+
ALPHA_UC = ('A'..'Z').to_a
|
236
|
+
OCTALS = ('0'..'7').to_a
|
237
|
+
HEXCHARS = DIGITS + ('a'..'f').to_a + ('A'..'F').to_a
|
238
|
+
SIGNS = ['-', '+']
|
239
|
+
DOT = '.'
|
240
|
+
|
241
|
+
IDCHARS = ['_' ] + ALPHA_LC + ALPHA_UC
|
242
|
+
FULL_IDCHARS = IDCHARS + DIGITS
|
243
|
+
|
244
|
+
ESCTBL = CharRegistry.new({
|
245
|
+
n: "\n", t: "\t", v: "\v", b: "\b",
|
246
|
+
r: "\r", f: "\f", a: "\a"
|
247
|
+
})
|
248
|
+
|
249
|
+
KEYWORDS = %w(
|
250
|
+
abstract alias any attribute boolean case char component connector const consumes context custom default double
|
251
|
+
exception emits enum eventtype factory FALSE finder fixed float getraises home import in inout interface local
|
252
|
+
long manages mirrorport module multiple native Object octet oneway out port porttype primarykey private provides
|
253
|
+
public publishes raises readonly setraises sequence short string struct supports switch TRUE truncatable typedef
|
254
|
+
typeid typename typeprefix unsigned union uses ValueBase valuetype void wchar wstring
|
255
|
+
).inject(TokenRegistry.new) { |h, a| h[a.downcase.to_sym] = a
|
256
|
+
h }
|
257
|
+
|
258
|
+
LITERALS = [
|
259
|
+
:integer_literal,
|
260
|
+
:string_literal,
|
261
|
+
# :wide_string_literal,
|
262
|
+
:character_literal,
|
263
|
+
# :wide_character_literal,
|
264
|
+
:fixed_pt_literal,
|
265
|
+
:floating_pt_literal,
|
266
|
+
:boolean_literal]
|
267
|
+
|
268
|
+
BOOL_LITERALS = {
|
269
|
+
false: false,
|
270
|
+
true: true
|
271
|
+
}
|
272
|
+
|
206
273
|
# Scanner
|
207
274
|
def initialize(src, directiver, params = {})
|
208
275
|
@includepaths = params[:includepaths] || []
|
209
276
|
@xincludepaths = params[:xincludepaths] || []
|
277
|
+
@idlversion = params[:idlversion]
|
210
278
|
@stack = []
|
211
279
|
@expansions = []
|
212
280
|
@prefix = nil
|
@@ -219,7 +287,7 @@ module IDL
|
|
219
287
|
@defined[name] = value
|
220
288
|
end
|
221
289
|
end
|
222
|
-
@ifdef =
|
290
|
+
@ifdef = []
|
223
291
|
@ifskip = false
|
224
292
|
@ifnest = 0
|
225
293
|
i = nil
|
@@ -240,7 +308,15 @@ module IDL
|
|
240
308
|
@in = In.new(i, nm)
|
241
309
|
@scan_comment = false # true if parsing commented annotation
|
242
310
|
@in_annotation = false # true if parsing annotation
|
311
|
+
|
312
|
+
# Extend the IDL keywords with IDL4 when enabled
|
313
|
+
if @idlversion >= 4
|
314
|
+
%w(bitfield bitmask bitset map int8 int16 int32 int64 uint8 uint16 uint32 uint64
|
315
|
+
).inject(KEYWORDS) { |h, a| h[a.downcase.to_sym] = a
|
316
|
+
h }
|
317
|
+
end
|
243
318
|
end
|
319
|
+
|
244
320
|
def find_include(fname, all = true)
|
245
321
|
if File.file?(fname) && File.readable?(fname)
|
246
322
|
File.expand_path(fname)
|
@@ -261,6 +337,7 @@ module IDL
|
|
261
337
|
fp
|
262
338
|
end
|
263
339
|
end
|
340
|
+
|
264
341
|
def check_include(path, fname)
|
265
342
|
fp = path + fname
|
266
343
|
File.file?(fp) && File.readable?(fp)
|
@@ -282,32 +359,37 @@ module IDL
|
|
282
359
|
# record file dir as new searchpath
|
283
360
|
@xincludepaths << (File.dirname(fpath) + '/')
|
284
361
|
@prefix = nil
|
285
|
-
@ifdef =
|
362
|
+
@ifdef = []
|
286
363
|
@in = In.new(File.open(fpath, 'r'), fpath)
|
287
364
|
@directiver.enter_include(src, fpath)
|
288
365
|
@directiver.pragma_prefix(nil)
|
289
366
|
end
|
290
367
|
end
|
368
|
+
|
291
369
|
def enter_expansion(src, define)
|
292
370
|
IDL.log(2, "** RIDL - enter_expansion > #{define} = #{src}")
|
293
371
|
@stack << [:define, nil, nil, @in, nil]
|
294
372
|
@expansions << define
|
295
373
|
@in = In.new(StrIStream.new(src), @in.position.name, @in.position.line, @in.position.column)
|
296
374
|
end
|
375
|
+
|
297
376
|
def is_expanded?(define)
|
298
377
|
@expansions.include?(define)
|
299
378
|
end
|
379
|
+
|
300
380
|
def more_source?
|
301
|
-
|
381
|
+
!@stack.empty?
|
302
382
|
end
|
383
|
+
|
303
384
|
def in_expansion?
|
304
385
|
more_source? and @stack.last[0] == :define
|
305
386
|
end
|
387
|
+
|
306
388
|
def leave_source
|
307
389
|
# make sure to close the input source
|
308
390
|
@in.close
|
309
391
|
# check if we have any previous source still stacked up
|
310
|
-
|
392
|
+
unless @stack.empty?
|
311
393
|
if @stack.last[0] == :include
|
312
394
|
@xincludepaths.pop # remove directory of finished include
|
313
395
|
@directiver.leave_include
|
@@ -319,73 +401,21 @@ module IDL
|
|
319
401
|
end
|
320
402
|
end
|
321
403
|
end
|
404
|
+
|
322
405
|
def do_parse?
|
323
406
|
@ifdef.empty? || @ifdef.last
|
324
407
|
end
|
408
|
+
|
325
409
|
def positions
|
326
|
-
@stack.reverse.inject(@in.nil? ? [] : [@in.position]) {|pos_arr, (_, _, _, in_, _)| pos_arr << in_.position }
|
410
|
+
@stack.reverse.inject(@in.nil? ? [] : [@in.position]) { |pos_arr, (_, _, _, in_, _)| pos_arr << in_.position }
|
327
411
|
end
|
412
|
+
|
328
413
|
def parse_error(msg, ex = nil)
|
329
414
|
e = IDL::ParseError.new(msg, positions)
|
330
415
|
e.set_backtrace(ex.backtrace) unless ex.nil?
|
331
416
|
raise e
|
332
417
|
end
|
333
418
|
|
334
|
-
LFCR = [ (?\n), (?\r) ]
|
335
|
-
SPACES = [ (?\ ), (?\t) ]
|
336
|
-
WHITESPACE = SPACES + LFCR
|
337
|
-
|
338
|
-
ANNOTATION = ?@
|
339
|
-
ANNOTATION_STR = '@'
|
340
|
-
|
341
|
-
BREAKCHARS = [
|
342
|
-
?(, ?), ?[, ?], ?{, ?},
|
343
|
-
?^, ?~,
|
344
|
-
?*, ?%, ?&, ?|,
|
345
|
-
?<, ?=, ?>,
|
346
|
-
?,, ?; ]
|
347
|
-
|
348
|
-
SHIFTCHARS = [ ?<, ?> ]
|
349
|
-
|
350
|
-
DIGITS = (?0..?9).to_a
|
351
|
-
ALPHA_LC = (?a..?z).to_a
|
352
|
-
ALPHA_UC = (?A..?Z).to_a
|
353
|
-
OCTALS = (?0..?7).to_a
|
354
|
-
HEXCHARS = DIGITS + (?a..?f).to_a + (?A..?F).to_a
|
355
|
-
SIGNS = [?-, ?+]
|
356
|
-
DOT = ?.
|
357
|
-
|
358
|
-
IDCHARS = [?_ ] + ALPHA_LC + ALPHA_UC
|
359
|
-
FULL_IDCHARS = IDCHARS + DIGITS
|
360
|
-
|
361
|
-
ESCTBL = CharRegistry.new({
|
362
|
-
:n => ?\n, :t => ?\t, :v => ?\v, :b => ?\b,
|
363
|
-
:r => ?\r, :f => ?\f, :a => ?\a
|
364
|
-
})
|
365
|
-
|
366
|
-
KEYWORDS = %w(
|
367
|
-
abstract alias any attribute boolean case char component connector const consumes context custom default double
|
368
|
-
exception emits enum eventtype factory FALSE finder fixed float getraises home import in inout interface local
|
369
|
-
long manages mirrorport module multiple native Object octet oneway out port porttype primarykey private provides
|
370
|
-
public publishes raises readonly setraises sequence short string struct supports switch TRUE truncatable typedef
|
371
|
-
typeid typename typeprefix unsigned union uses ValueBase valuetype void wchar wstring
|
372
|
-
).inject(TokenRegistry.new) { |h, a| h[a.downcase.to_sym] = a; h }
|
373
|
-
|
374
|
-
LITERALS = [
|
375
|
-
:integer_literal,
|
376
|
-
:string_literal,
|
377
|
-
# :wide_string_literal,
|
378
|
-
:character_literal,
|
379
|
-
# :wide_character_literal,
|
380
|
-
:fixed_pt_literal,
|
381
|
-
:floating_pt_literal,
|
382
|
-
:boolean_literal ]
|
383
|
-
|
384
|
-
BOOL_LITERALS = {
|
385
|
-
:false => false,
|
386
|
-
:true => true
|
387
|
-
}
|
388
|
-
|
389
419
|
def is_literal?(o)
|
390
420
|
LITERALS.include?(o)
|
391
421
|
end
|
@@ -408,7 +438,7 @@ module IDL
|
|
408
438
|
# determin vaue type; if it has a body it is an annotation instance
|
409
439
|
annotation_value = if member_annotation_body
|
410
440
|
{ member_annotation_id => member_annotation_body }
|
411
|
-
else
|
441
|
+
else # otherwise it is a symbolic value
|
412
442
|
member_annotation_id.to_sym
|
413
443
|
end
|
414
444
|
# get next token if needed
|
@@ -439,7 +469,7 @@ module IDL
|
|
439
469
|
token = next_token # ')' (in case of single value annotation) or '='
|
440
470
|
if token.first == ')'
|
441
471
|
parse_error 'invalid annotation member' if annotation_body
|
442
|
-
annotation_body = { :
|
472
|
+
annotation_body = { value: s1 }
|
443
473
|
else
|
444
474
|
parse_error 'invalid annotation member' unless token.first == '='
|
445
475
|
token, annotation_value = extract_annotation_value
|
@@ -479,9 +509,9 @@ module IDL
|
|
479
509
|
if token&.first == :identifier
|
480
510
|
# keyword check
|
481
511
|
if (a = KEYWORDS.assoc(token.last.to_s)).nil?
|
482
|
-
token = [
|
512
|
+
token = [:identifier, Identifier.new(token.last.to_s, chk_identifier(token.last.to_s), token.last.unescaped_name)]
|
483
513
|
elsif token.last == a[1]
|
484
|
-
token = [
|
514
|
+
token = [a[1], nil]
|
485
515
|
else
|
486
516
|
parse_error "'#{token.last}' collides with a keyword '#{a[1]}'"
|
487
517
|
end
|
@@ -494,7 +524,7 @@ module IDL
|
|
494
524
|
end
|
495
525
|
|
496
526
|
def skip_spaces
|
497
|
-
@in.skipwhile {|c| SPACES.include?(c) }
|
527
|
+
@in.skipwhile { |c| SPACES.include?(c) }
|
498
528
|
end
|
499
529
|
|
500
530
|
def next_identifier(first = nil)
|
@@ -511,10 +541,10 @@ module IDL
|
|
511
541
|
s2 = s0.dup # (to be) unescaped id
|
512
542
|
|
513
543
|
# simple check
|
514
|
-
if s2.
|
544
|
+
if s2.empty?
|
515
545
|
parse_error 'identifier expected!'
|
516
546
|
else
|
517
|
-
if s2[0] ==
|
547
|
+
if s2[0] == '_'
|
518
548
|
s2.slice!(0) ## if starts with CORBA IDL escape => remove
|
519
549
|
end
|
520
550
|
parse_error "identifier must begin with alphabet character: #{s2}" unless ALPHA_LC.include?(s2[0]) || ALPHA_UC.include?(s2[0])
|
@@ -529,15 +559,15 @@ module IDL
|
|
529
559
|
# keyword check
|
530
560
|
elsif @in_annotation
|
531
561
|
if BOOL_LITERALS.has_key?(s1)
|
532
|
-
[
|
562
|
+
[:boolean_literal, BOOL_LITERALS[s1]]
|
533
563
|
else
|
534
|
-
[
|
564
|
+
[:identifier, Identifier.new(s2, s2, s0)]
|
535
565
|
end
|
536
566
|
elsif (a = KEYWORDS.assoc(s1)).nil?
|
537
567
|
# check for language mapping keyword
|
538
|
-
[
|
568
|
+
[:identifier, Identifier.new(s2, chk_identifier(s2), s0)]
|
539
569
|
elsif s0 == a[1]
|
540
|
-
[
|
570
|
+
[a[1], nil]
|
541
571
|
else
|
542
572
|
parse_error "'#{s0}' collides with IDL keyword '#{a[1]}'"
|
543
573
|
end
|
@@ -548,12 +578,12 @@ module IDL
|
|
548
578
|
case (ch = @in.getc)
|
549
579
|
when nil
|
550
580
|
parse_error 'illegal escape sequence'
|
551
|
-
when
|
581
|
+
when '0'..'7'
|
552
582
|
ret = ''
|
553
583
|
ret << ch
|
554
584
|
1.upto(2) {
|
555
585
|
ch = @in.lookc
|
556
|
-
if (
|
586
|
+
if ('0'..'7').include? ch
|
557
587
|
ret << ch
|
558
588
|
else
|
559
589
|
break
|
@@ -561,7 +591,7 @@ module IDL
|
|
561
591
|
@in.skipc
|
562
592
|
}
|
563
593
|
ret = ret.oct
|
564
|
-
when
|
594
|
+
when 'x' # i'm not sure '\x' should be 0 or 'x'. currently returns 0.
|
565
595
|
ret = ''
|
566
596
|
1.upto(2) {
|
567
597
|
ch = @in.lookc
|
@@ -573,7 +603,7 @@ module IDL
|
|
573
603
|
@in.skipc
|
574
604
|
}
|
575
605
|
ret = ret.hex
|
576
|
-
when
|
606
|
+
when 'u'
|
577
607
|
ret = ''
|
578
608
|
1.upto(4) {
|
579
609
|
ch = @in.lookc
|
@@ -585,7 +615,7 @@ module IDL
|
|
585
615
|
@in.skipc
|
586
616
|
}
|
587
617
|
ret = ret.hex
|
588
|
-
when
|
618
|
+
when 'n', 't', 'v', 'b', 'r', 'f', 'a'
|
589
619
|
ret = ESCTBL[ch]
|
590
620
|
else
|
591
621
|
ret = ('' << ch).unpack('C').first
|
@@ -598,12 +628,12 @@ module IDL
|
|
598
628
|
case (ch = @in.getc)
|
599
629
|
when nil
|
600
630
|
parse_error 'illegal escape sequence'
|
601
|
-
when
|
631
|
+
when '0'..'7'
|
602
632
|
ret = ''
|
603
633
|
ret << ch
|
604
634
|
1.upto(2) {
|
605
635
|
ch = @in.lookc
|
606
|
-
if (
|
636
|
+
if ('0'..'7').include? ch
|
607
637
|
ret << ch
|
608
638
|
else
|
609
639
|
break
|
@@ -611,7 +641,7 @@ module IDL
|
|
611
641
|
@in.skipc
|
612
642
|
}
|
613
643
|
ret = [ :oct, ret ]
|
614
|
-
when
|
644
|
+
when 'x' # i'm not sure '\x' should be 0 or 'x'. currently returns 0.
|
615
645
|
ret = ''
|
616
646
|
ret << ch if keep_type_ch
|
617
647
|
1.upto(2) {
|
@@ -624,7 +654,7 @@ module IDL
|
|
624
654
|
@in.skipc
|
625
655
|
}
|
626
656
|
ret = [ :hex2, ret ]
|
627
|
-
when
|
657
|
+
when 'u'
|
628
658
|
ret = ''
|
629
659
|
ret << ch if keep_type_ch
|
630
660
|
1.upto(4) {
|
@@ -637,14 +667,14 @@ module IDL
|
|
637
667
|
@in.skipc
|
638
668
|
}
|
639
669
|
ret = [ :hex4, ret ]
|
640
|
-
when
|
670
|
+
when 'n', 't', 'v', 'b', 'r', 'f', 'a'
|
641
671
|
ret = ''
|
642
672
|
ret << ch
|
643
|
-
ret = [
|
673
|
+
ret = [:esc, ret]
|
644
674
|
else
|
645
675
|
ret = ''
|
646
676
|
ret << ch
|
647
|
-
ret = [
|
677
|
+
ret = [:esc_ch, ch]
|
648
678
|
end
|
649
679
|
ret
|
650
680
|
end
|
@@ -652,17 +682,17 @@ module IDL
|
|
652
682
|
def skipfloat_or_fixed
|
653
683
|
if @in.lookc == DOT
|
654
684
|
@in.skipc
|
655
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
685
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
656
686
|
end
|
657
|
-
if [
|
687
|
+
if ['e', 'E'].include? @in.lookc
|
658
688
|
@in.skipc
|
659
689
|
@in.skipc if SIGNS.include? @in.lookc
|
660
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
690
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
661
691
|
return :floating_pt_literal
|
662
|
-
elsif [
|
692
|
+
elsif ['d', 'D'].include? @in.lookc
|
663
693
|
@in.skipc
|
664
694
|
@in.skipc if SIGNS.include? @in.lookc
|
665
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
695
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
666
696
|
return :fixed_pt_literal
|
667
697
|
end
|
668
698
|
:floating_pt_literal
|
@@ -672,7 +702,7 @@ module IDL
|
|
672
702
|
while true
|
673
703
|
s = @in.gets
|
674
704
|
until s.chomp!.nil?; end
|
675
|
-
break unless s[s.length - 1] ==
|
705
|
+
break unless s[s.length - 1] == "\\"
|
676
706
|
end
|
677
707
|
end
|
678
708
|
|
@@ -681,16 +711,17 @@ module IDL
|
|
681
711
|
while true
|
682
712
|
ch = @in.lookc
|
683
713
|
break if ch.nil?
|
714
|
+
|
684
715
|
case
|
685
|
-
when (ch ==
|
716
|
+
when (ch == "\"") # "
|
686
717
|
s << @in.getc # opening quote
|
687
718
|
while true
|
688
|
-
if @in.lookc ==
|
719
|
+
if @in.lookc == "\\"
|
689
720
|
# escape sequence
|
690
721
|
s << @in.getc
|
691
722
|
_, escstr = next_escape_str(true)
|
692
723
|
s << escstr
|
693
|
-
elsif @in.lookc ==
|
724
|
+
elsif @in.lookc == "\"" # "
|
694
725
|
break
|
695
726
|
elsif @in.lookc
|
696
727
|
# normal character
|
@@ -700,36 +731,36 @@ module IDL
|
|
700
731
|
end
|
701
732
|
end
|
702
733
|
s << @in.getc # closing quote
|
703
|
-
when (ch ==
|
734
|
+
when (ch == "\'") # ' # quoted character
|
704
735
|
s << @in.getc # opening quote
|
705
|
-
if @in.lookc ==
|
736
|
+
if @in.lookc == "\\"
|
706
737
|
# escape sequence
|
707
738
|
s << @in.getc
|
708
739
|
_, escstr = next_escape_str(true)
|
709
740
|
s << escstr
|
710
|
-
elsif @in.lookc && @in.lookc !=
|
741
|
+
elsif @in.lookc && @in.lookc != "\'" # '
|
711
742
|
# normal character
|
712
743
|
s << @in.getc
|
713
744
|
end
|
714
|
-
if @in.lookc !=
|
745
|
+
if @in.lookc != "\'" # '
|
715
746
|
parse_error "character literal must be single character enclosed in \"'\""
|
716
747
|
end
|
717
748
|
s << @in.getc # closing quote
|
718
749
|
when LFCR.include?(ch)
|
719
750
|
@in.skipwhile { |ch_| LFCR.include? ch_ }
|
720
751
|
break
|
721
|
-
when ch ==
|
752
|
+
when ch == '/'
|
722
753
|
@in.skipc
|
723
|
-
if @in.lookc ==
|
754
|
+
if @in.lookc == '/'
|
724
755
|
# //-style comment; skip till eol
|
725
756
|
@in.gets
|
726
757
|
break
|
727
|
-
elsif @in.lookc ==
|
758
|
+
elsif @in.lookc == '*'
|
728
759
|
# /*...*/ style comment; skip comment
|
729
760
|
ch1 = nil
|
730
761
|
@in.skipuntil { |ch_|
|
731
762
|
ch0 = ch1; ch1 = ch_
|
732
|
-
ch0 ==
|
763
|
+
ch0 == '*' and ch1 == '/' #
|
733
764
|
}
|
734
765
|
if @in.lookc.nil?
|
735
766
|
parse_error "cannot find comment closing brace (\'*/\'). "
|
@@ -738,7 +769,7 @@ module IDL
|
|
738
769
|
else
|
739
770
|
s << ch
|
740
771
|
end
|
741
|
-
when ch ==
|
772
|
+
when ch == "\\"
|
742
773
|
@in.skipc
|
743
774
|
if LFCR.include?(@in.lookc)
|
744
775
|
# line continuation
|
@@ -759,6 +790,7 @@ module IDL
|
|
759
790
|
|
760
791
|
def resolve_define(id, stack = [])
|
761
792
|
return id if %w(true false).include?(id)
|
793
|
+
|
762
794
|
IDL.log(3, "*** RIDL - resolve_define(#{id})")
|
763
795
|
if @defined.has_key?(id)
|
764
796
|
define_ = @defined[id]
|
@@ -785,10 +817,11 @@ module IDL
|
|
785
817
|
end
|
786
818
|
|
787
819
|
def parse_directive
|
788
|
-
@in.skipwhile {|c| SPACES.include?(c) }
|
820
|
+
@in.skipwhile { |c| SPACES.include?(c) }
|
789
821
|
s = getline
|
790
822
|
/^(\w*)\s*/ === s
|
791
|
-
s1
|
823
|
+
s1 = $1
|
824
|
+
s2 = $' # '
|
792
825
|
|
793
826
|
if /(else|endif|elif)/ === s1
|
794
827
|
|
@@ -797,7 +830,7 @@ module IDL
|
|
797
830
|
end
|
798
831
|
case s1
|
799
832
|
when 'else'
|
800
|
-
if @ifnest
|
833
|
+
if @ifnest.zero?
|
801
834
|
if @ifskip # true branch has already been parsed
|
802
835
|
@ifdef[@ifdef.size - 1] = false
|
803
836
|
else
|
@@ -806,14 +839,14 @@ module IDL
|
|
806
839
|
end
|
807
840
|
end
|
808
841
|
when 'endif'
|
809
|
-
if @ifnest
|
842
|
+
if @ifnest.zero?
|
810
843
|
@ifdef.pop
|
811
844
|
@ifskip = @ifdef.last
|
812
845
|
else
|
813
846
|
@ifnest -= 1
|
814
847
|
end
|
815
848
|
else
|
816
|
-
if @ifnest
|
849
|
+
if @ifnest.zero?
|
817
850
|
if @ifskip || @ifdef[@ifdef.size - 1]
|
818
851
|
# true branch has already been parsed so skip from now on
|
819
852
|
@ifdef[@ifdef.size - 1] = false
|
@@ -829,9 +862,9 @@ module IDL
|
|
829
862
|
@ifskip = @ifdef[@ifdef.size - 1]
|
830
863
|
rescue IDL::ParseError
|
831
864
|
raise
|
832
|
-
rescue =>
|
833
|
-
p
|
834
|
-
puts
|
865
|
+
rescue => e
|
866
|
+
p e
|
867
|
+
puts e.backtrace.join("\n")
|
835
868
|
parse_error 'error evaluating #elif'
|
836
869
|
end
|
837
870
|
end
|
@@ -865,9 +898,9 @@ module IDL
|
|
865
898
|
@ifskip = @ifdef.last
|
866
899
|
rescue IDL::ParseError
|
867
900
|
raise
|
868
|
-
rescue =>
|
869
|
-
p
|
870
|
-
puts
|
901
|
+
rescue => e
|
902
|
+
p e
|
903
|
+
puts e.backtrace.join("\n")
|
871
904
|
parse_error 'error evaluating #if'
|
872
905
|
end
|
873
906
|
else
|
@@ -930,17 +963,17 @@ module IDL
|
|
930
963
|
end
|
931
964
|
|
932
965
|
def next_token_before_eol
|
933
|
-
@in.skipwhile {|c| SPACES.include?(c)}
|
966
|
+
@in.skipwhile { |c| SPACES.include?(c) }
|
934
967
|
LFCR.include?(@in.lookc) ? nil : next_token
|
935
968
|
end
|
936
969
|
|
937
970
|
def next_token
|
938
971
|
sign = nil
|
939
|
-
str = '' #initialize empty string
|
972
|
+
str = '' # initialize empty string
|
940
973
|
while true
|
941
974
|
ch = @in.getc
|
942
975
|
if ch.nil?
|
943
|
-
if
|
976
|
+
if !@ifdef.empty? and !in_expansion?
|
944
977
|
parse_error 'mismatched #if/#endif'
|
945
978
|
end
|
946
979
|
if more_source?
|
@@ -952,11 +985,11 @@ module IDL
|
|
952
985
|
end
|
953
986
|
|
954
987
|
if WHITESPACE.include? ch
|
955
|
-
@in.skipwhile {|c| WHITESPACE.include?(c) }
|
988
|
+
@in.skipwhile { |c| WHITESPACE.include?(c) }
|
956
989
|
next
|
957
990
|
end
|
958
991
|
|
959
|
-
if str.empty? && ch ==
|
992
|
+
if str.empty? && ch == "\#"
|
960
993
|
parse_directive
|
961
994
|
next
|
962
995
|
end
|
@@ -982,50 +1015,50 @@ module IDL
|
|
982
1015
|
return parse_annotation || next_token
|
983
1016
|
end
|
984
1017
|
|
985
|
-
when ch ==
|
986
|
-
if @in.lookc ==
|
1018
|
+
when ch == ':' #
|
1019
|
+
if @in.lookc == ':' #
|
987
1020
|
@in.skipc
|
988
1021
|
return %w(:: ::)
|
989
1022
|
else
|
990
1023
|
return %w(: :)
|
991
1024
|
end
|
992
1025
|
|
993
|
-
when ch ==
|
1026
|
+
when ch == 'L'
|
994
1027
|
_nxtc = @in.lookc
|
995
|
-
if _nxtc ==
|
1028
|
+
if _nxtc == "\'" # ' #single quote, for a character literal.
|
996
1029
|
@in.skipc # skip 'L'
|
997
1030
|
_nxtc = @in.lookc
|
998
|
-
ret = if _nxtc ==
|
1031
|
+
ret = if _nxtc == "\\"
|
999
1032
|
@in.skipc
|
1000
1033
|
next_escape_str
|
1001
|
-
elsif _nxtc ==
|
1034
|
+
elsif _nxtc == "\'" # '
|
1002
1035
|
[ nil, nil ]
|
1003
1036
|
else
|
1004
|
-
[
|
1037
|
+
[:char, '' << @in.getc]
|
1005
1038
|
end
|
1006
1039
|
|
1007
|
-
if @in.lookc !=
|
1040
|
+
if @in.lookc != "\'" # '
|
1008
1041
|
parse_error "wide character literal must be single wide character enclosed in \"'\""
|
1009
1042
|
end
|
1010
1043
|
|
1011
1044
|
@in.skipc
|
1012
|
-
return [
|
1045
|
+
return [:wide_character_literal, ret]
|
1013
1046
|
|
1014
|
-
elsif _nxtc ==
|
1047
|
+
elsif _nxtc == "\"" # " #double quote, for a string literal.
|
1015
1048
|
ret = []
|
1016
1049
|
chs = ''
|
1017
1050
|
@in.skipc # skip 'L'
|
1018
1051
|
while true
|
1019
1052
|
_nxtc = @in.lookc
|
1020
|
-
if _nxtc ==
|
1053
|
+
if _nxtc == "\\"
|
1021
1054
|
@in.skipc
|
1022
1055
|
ret << [:char, chs] unless chs.empty?
|
1023
1056
|
chs = ''
|
1024
1057
|
ret << next_escape_str
|
1025
|
-
elsif _nxtc ==
|
1058
|
+
elsif _nxtc == "\"" # "
|
1026
1059
|
@in.skipc
|
1027
1060
|
ret << [:char, chs] unless chs.empty?
|
1028
|
-
return [
|
1061
|
+
return [:wide_string_literal, ret]
|
1029
1062
|
else
|
1030
1063
|
chs << @in.getc
|
1031
1064
|
end
|
@@ -1038,15 +1071,15 @@ module IDL
|
|
1038
1071
|
when IDCHARS.include?(ch)
|
1039
1072
|
return next_identifier(ch)
|
1040
1073
|
|
1041
|
-
when ch ==
|
1074
|
+
when ch == '/' #
|
1042
1075
|
_nxtc = @in.lookc
|
1043
|
-
if _nxtc ==
|
1076
|
+
if _nxtc == '*'
|
1044
1077
|
# skip comment like a `/* ... */'
|
1045
1078
|
@in.skipc # forward stream beyond `/*'
|
1046
1079
|
ch1 = nil
|
1047
1080
|
@in.skipuntil { |ch_|
|
1048
1081
|
ch0 = ch1; ch1 = ch_
|
1049
|
-
ch0 ==
|
1082
|
+
ch0 == '*' and ch1 == '/' #
|
1050
1083
|
}
|
1051
1084
|
if @in.lookc.nil?
|
1052
1085
|
parse_error "cannot find comment closing brace (\'*/\'). "
|
@@ -1055,17 +1088,17 @@ module IDL
|
|
1055
1088
|
str = '' # reset
|
1056
1089
|
next
|
1057
1090
|
|
1058
|
-
elsif _nxtc ==
|
1091
|
+
elsif _nxtc == '/'
|
1059
1092
|
# skip comment like a `// ...\n'
|
1060
1093
|
@in.skipc
|
1061
|
-
unless @scan_comment
|
1094
|
+
unless @scan_comment # scan_comment will be true when parsing commented annotations
|
1062
1095
|
_nxtc = @in.lookc
|
1063
1096
|
if _nxtc == ANNOTATION
|
1064
1097
|
@in.skipc
|
1065
1098
|
# return token returned by parse_annotation or parse next token recursively
|
1066
1099
|
return parse_annotation(true) || next_token
|
1067
1100
|
else
|
1068
|
-
@in.skipuntil {|c| LFCR.include?(c) }
|
1101
|
+
@in.skipuntil { |c| LFCR.include?(c) }
|
1069
1102
|
end
|
1070
1103
|
end
|
1071
1104
|
str = '' # reset
|
@@ -1085,10 +1118,10 @@ module IDL
|
|
1085
1118
|
return [str, str]
|
1086
1119
|
end
|
1087
1120
|
|
1088
|
-
when (
|
1121
|
+
when ('1'..'9').include?(ch)
|
1089
1122
|
@in.mark(sign, ch)
|
1090
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
1091
|
-
num_type = ([
|
1123
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
1124
|
+
num_type = (['.', 'e', 'E', 'd', 'D'].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
|
1092
1125
|
|
1093
1126
|
r = @in.getregion
|
1094
1127
|
|
@@ -1102,7 +1135,7 @@ module IDL
|
|
1102
1135
|
|
1103
1136
|
when ch == DOT #
|
1104
1137
|
@in.mark(ch)
|
1105
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
1138
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
1106
1139
|
num_type = (DOT != @in.lookc) ? skipfloat_or_fixed : nil
|
1107
1140
|
s = @in.getregion
|
1108
1141
|
if s == '.'
|
@@ -1116,24 +1149,24 @@ module IDL
|
|
1116
1149
|
parse_error 'invalid floating point constant.'
|
1117
1150
|
end
|
1118
1151
|
|
1119
|
-
when ch ==
|
1152
|
+
when ch == '0'
|
1120
1153
|
@in.mark(sign, ch)
|
1121
1154
|
|
1122
1155
|
_nxtc = @in.lookc
|
1123
|
-
if _nxtc ==
|
1156
|
+
if _nxtc == 'x' || _nxtc == 'X'
|
1124
1157
|
@in.skipc
|
1125
1158
|
@in.skipwhile { |ch_| HEXCHARS.include? ch_ }
|
1126
1159
|
s = @in.getregion
|
1127
1160
|
return [:integer_literal, s.hex]
|
1128
1161
|
else
|
1129
1162
|
dec = false
|
1130
|
-
@in.skipwhile {|c| OCTALS.include?(c) }
|
1131
|
-
if (
|
1163
|
+
@in.skipwhile { |c| OCTALS.include?(c) }
|
1164
|
+
if ('8'..'9').include? @in.lookc
|
1132
1165
|
dec = TRUE
|
1133
|
-
@in.skipwhile {|c| DIGITS.include?(c) }
|
1166
|
+
@in.skipwhile { |c| DIGITS.include?(c) }
|
1134
1167
|
end
|
1135
1168
|
|
1136
|
-
num_type = ([
|
1169
|
+
num_type = (['.', 'e', 'E', 'd', 'D'].include?(@in.lookc)) ? skipfloat_or_fixed : :integer_literal
|
1137
1170
|
|
1138
1171
|
s = @in.getregion
|
1139
1172
|
ret = if num_type == :floating_pt_literal
|
@@ -1148,34 +1181,34 @@ module IDL
|
|
1148
1181
|
return ret
|
1149
1182
|
end
|
1150
1183
|
|
1151
|
-
when ch ==
|
1184
|
+
when ch == "\'" # ' #single quote, for a character literal.
|
1152
1185
|
_nxtc = @in.lookc
|
1153
|
-
ret = if _nxtc ==
|
1186
|
+
ret = if _nxtc == "\\"
|
1154
1187
|
@in.skipc
|
1155
1188
|
next_escape
|
1156
|
-
elsif _nxtc ==
|
1189
|
+
elsif _nxtc == "\'" # '
|
1157
1190
|
0
|
1158
1191
|
elsif _nxtc
|
1159
1192
|
('' << @in.getc).unpack('C').first
|
1160
1193
|
end
|
1161
1194
|
|
1162
|
-
if @in.lookc !=
|
1195
|
+
if @in.lookc != "\'" # '
|
1163
1196
|
parse_error "character literal must be single character enclosed in \"'\""
|
1164
1197
|
end
|
1165
1198
|
|
1166
1199
|
@in.skipc
|
1167
|
-
return [
|
1200
|
+
return [:character_literal, ret]
|
1168
1201
|
|
1169
|
-
when ch ==
|
1202
|
+
when ch == "\"" # " #double quote, for a string literal.
|
1170
1203
|
ret = ''
|
1171
1204
|
while true
|
1172
1205
|
_nxtc = @in.lookc
|
1173
|
-
if _nxtc ==
|
1206
|
+
if _nxtc == "\\"
|
1174
1207
|
@in.skipc
|
1175
1208
|
ret << next_escape
|
1176
|
-
elsif _nxtc ==
|
1209
|
+
elsif _nxtc == "\"" # "
|
1177
1210
|
@in.skipc
|
1178
|
-
return [
|
1211
|
+
return [:string_literal, ret]
|
1179
1212
|
elsif _nxtc
|
1180
1213
|
ret << @in.getc
|
1181
1214
|
else
|
@@ -1186,11 +1219,10 @@ module IDL
|
|
1186
1219
|
else
|
1187
1220
|
parse_error 'illegal character [' << ch << ']'
|
1188
1221
|
|
1189
|
-
end #of case
|
1222
|
+
end # of case
|
1190
1223
|
|
1191
|
-
end #of while
|
1224
|
+
end # of while
|
1192
1225
|
parse_error 'unexcepted error'
|
1193
|
-
end #of method next_token
|
1226
|
+
end # of method next_token
|
1194
1227
|
end
|
1195
|
-
|
1196
1228
|
end
|