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