adlint 1.10.0 → 1.12.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.
- data/ChangeLog +197 -4
- data/MANIFEST +17 -0
- data/NEWS +23 -4
- data/etc/mesg.d/en_US/messages.yml +14 -1
- data/etc/mesg.d/ja_JP/messages.yml +14 -1
- data/features/message_detection/W0093.feature +87 -0
- data/features/message_detection/W0687.feature +25 -0
- data/features/message_detection/W0688.feature +63 -0
- data/features/message_detection/W0689.feature +46 -0
- data/features/message_detection/W0690.feature +35 -0
- data/features/message_detection/W0698.feature +3 -2
- data/features/message_detection/W0703.feature +1 -0
- data/features/message_detection/W0723.feature +34 -0
- data/features/message_detection/W0732.feature +158 -0
- data/features/message_detection/W0733.feature +158 -0
- data/features/message_detection/W0734.feature +322 -0
- data/features/message_detection/W0735.feature +322 -0
- data/features/message_detection/W1052.feature +66 -0
- data/features/message_detection/W9001.feature +33 -0
- data/features/message_detection/W9003.feature +131 -0
- data/lib/adlint/c/ctrlexpr.rb +51 -50
- data/lib/adlint/c/domain.rb +237 -223
- data/lib/adlint/c/expr.rb +6 -8
- data/lib/adlint/c/interp.rb +8 -11
- data/lib/adlint/c/message.rb +20 -0
- data/lib/adlint/c/message_shima.rb +63 -0
- data/lib/adlint/c/object.rb +5 -4
- data/lib/adlint/c/operator.rb +99 -0
- data/lib/adlint/c/parser.rb +2 -2
- data/lib/adlint/c/parser.y +2 -2
- data/lib/adlint/c/phase.rb +6 -1
- data/lib/adlint/c/syntax.rb +442 -30
- data/lib/adlint/c/type.rb +449 -363
- data/lib/adlint/c/value.rb +96 -25
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/prelude.rb +16 -18
- data/lib/adlint/version.rb +2 -2
- data/share/doc/developers_guide_ja.html +11 -5
- data/share/doc/developers_guide_ja.texi +9 -3
- data/share/doc/users_guide_en.html +697 -131
- data/share/doc/users_guide_en.texi +491 -41
- data/share/doc/users_guide_ja.html +709 -139
- data/share/doc/users_guide_ja.texi +499 -45
- data/spec/adlint/c/ctrlexpr_spec.rb +168 -0
- data/spec/adlint/c/domain_spec.rb +835 -0
- data/spec/adlint/c/operator_spec.rb +406 -0
- data/spec/adlint/c/syntax_spec.rb +717 -0
- data/spec/adlint/c/type_spec.rb +55 -30
- metadata +19 -2
@@ -0,0 +1,717 @@
|
|
1
|
+
# Unit specification of AST of C language.
|
2
|
+
#
|
3
|
+
# Author:: Rie Shima <mailto:rkakuuchi@users.sourceforge.net>
|
4
|
+
# Copyright:: Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
|
5
|
+
# License:: GPLv3+: GNU General Public License version 3 or later
|
6
|
+
#
|
7
|
+
# Owner:: Rie Shima <mailto:rkakuuchi@users.sourceforge.net>
|
8
|
+
|
9
|
+
#--
|
10
|
+
# ___ ____ __ ___ _________
|
11
|
+
# / | / _ |/ / / / | / /__ __/ Source Code Static Analyzer
|
12
|
+
# / /| | / / / / / / / |/ / / / AdLint - Advanced Lint
|
13
|
+
# / __ |/ /_/ / /___/ / /| / / /
|
14
|
+
# /_/ |_|_____/_____/_/_/ |_/ /_/ Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
|
15
|
+
#
|
16
|
+
# This file is part of AdLint.
|
17
|
+
#
|
18
|
+
# AdLint is free software: you can redistribute it and/or modify it under the
|
19
|
+
# terms of the GNU General Public License as published by the Free Software
|
20
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
21
|
+
# version.
|
22
|
+
#
|
23
|
+
# AdLint is distributed in the hope that it will be useful, but WITHOUT ANY
|
24
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
25
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
26
|
+
#
|
27
|
+
# You should have received a copy of the GNU General Public License along with
|
28
|
+
# AdLint. If not, see <http://www.gnu.org/licenses/>.
|
29
|
+
#
|
30
|
+
#++
|
31
|
+
|
32
|
+
require "spec_helper"
|
33
|
+
|
34
|
+
module AdLint
|
35
|
+
module C
|
36
|
+
|
37
|
+
describe Expression do
|
38
|
+
before(:all) { Traits.instance.read_from($default_traits) }
|
39
|
+
|
40
|
+
let(:symbol_table) { SymbolTable.new }
|
41
|
+
|
42
|
+
context "`*'" do
|
43
|
+
subject { error_expression(operator("*")) }
|
44
|
+
|
45
|
+
it { should_not be_logical }
|
46
|
+
it { should_not be_arithmetic }
|
47
|
+
it { should_not be_bitwise }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "`foo'" do
|
51
|
+
subject { object_specifier("foo") }
|
52
|
+
|
53
|
+
it { should_not be_logical }
|
54
|
+
it { should_not be_arithmetic }
|
55
|
+
it { should_not be_bitwise }
|
56
|
+
end
|
57
|
+
|
58
|
+
context "`0x11'" do
|
59
|
+
subject { constant_specifier("0x11") }
|
60
|
+
|
61
|
+
it { should_not be_logical }
|
62
|
+
it { should_not be_arithmetic }
|
63
|
+
it { should_not be_bitwise }
|
64
|
+
end
|
65
|
+
|
66
|
+
context %(`"aiueo"') do
|
67
|
+
subject { string_literal_specifier('"aiueo"') }
|
68
|
+
|
69
|
+
it { should_not be_logical }
|
70
|
+
it { should_not be_arithmetic }
|
71
|
+
it { should_not be_bitwise }
|
72
|
+
end
|
73
|
+
|
74
|
+
context "`NULL'" do
|
75
|
+
subject { null_constant_specifier }
|
76
|
+
|
77
|
+
it { should_not be_logical }
|
78
|
+
it { should_not be_arithmetic }
|
79
|
+
it { should_not be_bitwise }
|
80
|
+
end
|
81
|
+
|
82
|
+
# NOTE: GroupedExpression encloses an arithmetic expression.
|
83
|
+
context "`(1 + 2)'" do
|
84
|
+
subject do
|
85
|
+
grouped_expression(
|
86
|
+
additive_expression(
|
87
|
+
"+", constant_specifier(1), constant_specifier(2)))
|
88
|
+
end
|
89
|
+
|
90
|
+
it { should_not be_logical }
|
91
|
+
it { should be_arithmetic }
|
92
|
+
it { should_not be_bitwise }
|
93
|
+
end
|
94
|
+
|
95
|
+
# NOTE: GroupedExpression encloses a bitwise expression.
|
96
|
+
context "`(1 << 2)'" do
|
97
|
+
subject do
|
98
|
+
grouped_expression(
|
99
|
+
shift_expression("<<", constant_specifier(1), constant_specifier(2)))
|
100
|
+
end
|
101
|
+
|
102
|
+
it { should_not be_logical }
|
103
|
+
it { should_not be_arithmetic }
|
104
|
+
it { should be_bitwise }
|
105
|
+
end
|
106
|
+
|
107
|
+
# NOTE: GroupedExpression encloses an expression which is neither
|
108
|
+
# arithmetic nor bitwise.
|
109
|
+
context "`(1 && 2)'" do
|
110
|
+
subject do
|
111
|
+
grouped_expression(
|
112
|
+
logical_and_expression(constant_specifier(1), constant_specifier(2)))
|
113
|
+
end
|
114
|
+
|
115
|
+
it { should be_logical }
|
116
|
+
it { should_not be_arithmetic }
|
117
|
+
it { should_not be_bitwise }
|
118
|
+
end
|
119
|
+
|
120
|
+
context "`i++'" do
|
121
|
+
subject { postfix_increment_expression(object_specifier("i")) }
|
122
|
+
|
123
|
+
it { should_not be_logical }
|
124
|
+
it { should be_arithmetic }
|
125
|
+
it { should_not be_bitwise }
|
126
|
+
end
|
127
|
+
|
128
|
+
context "`i--'" do
|
129
|
+
subject { postfix_decrement_expression(object_specifier("i")) }
|
130
|
+
|
131
|
+
it { should_not be_logical }
|
132
|
+
it { should be_arithmetic }
|
133
|
+
it { should_not be_bitwise }
|
134
|
+
end
|
135
|
+
|
136
|
+
context "`++i'" do
|
137
|
+
subject { prefix_increment_expression(object_specifier("i")) }
|
138
|
+
|
139
|
+
it { should_not be_logical }
|
140
|
+
it { should be_arithmetic }
|
141
|
+
it { should_not be_bitwise }
|
142
|
+
end
|
143
|
+
|
144
|
+
context "`--i'" do
|
145
|
+
subject { prefix_decrement_expression(object_specifier("i")) }
|
146
|
+
|
147
|
+
it { should_not be_logical }
|
148
|
+
it { should be_arithmetic }
|
149
|
+
it { should_not be_bitwise }
|
150
|
+
end
|
151
|
+
|
152
|
+
context "`(char) i'" do
|
153
|
+
subject { cast_expression(char_type_name, object_specifier("i")) }
|
154
|
+
|
155
|
+
it { should_not be_logical }
|
156
|
+
it { should_not be_arithmetic }
|
157
|
+
it { should_not be_bitwise }
|
158
|
+
end
|
159
|
+
|
160
|
+
context "`(char) (i + 1)'" do
|
161
|
+
subject do
|
162
|
+
cast_expression(
|
163
|
+
char_type_name, grouped_expression(
|
164
|
+
additive_expression(
|
165
|
+
"+", object_specifier("i"), constant_specifier(1))))
|
166
|
+
end
|
167
|
+
|
168
|
+
it { should_not be_logical }
|
169
|
+
it { should be_arithmetic }
|
170
|
+
it { should_not be_bitwise }
|
171
|
+
end
|
172
|
+
|
173
|
+
context "`(char) (i == 0)'" do
|
174
|
+
subject do
|
175
|
+
cast_expression(
|
176
|
+
char_type_name,
|
177
|
+
grouped_expression(
|
178
|
+
equality_expression(
|
179
|
+
"==", object_specifier("i"), constant_specifier(1))))
|
180
|
+
end
|
181
|
+
|
182
|
+
it { should be_logical }
|
183
|
+
it { should_not be_arithmetic }
|
184
|
+
it { should_not be_bitwise }
|
185
|
+
end
|
186
|
+
|
187
|
+
context "`(char) (i & 1)'" do
|
188
|
+
subject do
|
189
|
+
cast_expression(
|
190
|
+
char_type_name,
|
191
|
+
grouped_expression(
|
192
|
+
and_expression(object_specifier("i"), constant_specifier(1))))
|
193
|
+
end
|
194
|
+
|
195
|
+
it { should_not be_logical }
|
196
|
+
it { should_not be_arithmetic }
|
197
|
+
it { should be_bitwise }
|
198
|
+
end
|
199
|
+
|
200
|
+
context "`i * j'" do
|
201
|
+
subject do
|
202
|
+
multiplicative_expression(
|
203
|
+
"*", object_specifier("i"), object_specifier("j"))
|
204
|
+
end
|
205
|
+
|
206
|
+
it { should_not be_logical }
|
207
|
+
it { should be_arithmetic }
|
208
|
+
it { should_not be_bitwise }
|
209
|
+
end
|
210
|
+
|
211
|
+
context "`i + j'" do
|
212
|
+
subject do
|
213
|
+
additive_expression("+", object_specifier("i"), object_specifier("j"))
|
214
|
+
end
|
215
|
+
|
216
|
+
it { should_not be_logical }
|
217
|
+
it { should be_arithmetic }
|
218
|
+
it { should_not be_bitwise }
|
219
|
+
end
|
220
|
+
|
221
|
+
context "`i << 1'" do
|
222
|
+
subject do
|
223
|
+
shift_expression("<<", object_specifier("i"), constant_specifier(1))
|
224
|
+
end
|
225
|
+
|
226
|
+
it { should_not be_logical }
|
227
|
+
it { should_not be_arithmetic }
|
228
|
+
it { should be_bitwise }
|
229
|
+
end
|
230
|
+
|
231
|
+
context "`i < 0'" do
|
232
|
+
subject do
|
233
|
+
relational_expression(
|
234
|
+
"<", object_specifier("i"), constant_specifier(0))
|
235
|
+
end
|
236
|
+
|
237
|
+
it { should be_logical }
|
238
|
+
it { should_not be_arithmetic }
|
239
|
+
it { should_not be_bitwise }
|
240
|
+
end
|
241
|
+
|
242
|
+
context "`i == j'" do
|
243
|
+
subject do
|
244
|
+
equality_expression("==", object_specifier("i"), object_specifier("j"))
|
245
|
+
end
|
246
|
+
|
247
|
+
it { should be_logical }
|
248
|
+
it { should_not be_arithmetic }
|
249
|
+
it { should_not be_bitwise }
|
250
|
+
end
|
251
|
+
|
252
|
+
context "`i & 1'" do
|
253
|
+
subject { and_expression(object_specifier("i"), constant_specifier(1)) }
|
254
|
+
|
255
|
+
it { should_not be_logical }
|
256
|
+
it { should_not be_arithmetic }
|
257
|
+
it { should be_bitwise }
|
258
|
+
end
|
259
|
+
|
260
|
+
context "`i ^ 2'" do
|
261
|
+
subject do
|
262
|
+
exclusive_or_expression(object_specifier("i"), constant_specifier(2))
|
263
|
+
end
|
264
|
+
|
265
|
+
it { should_not be_logical }
|
266
|
+
it { should_not be_arithmetic }
|
267
|
+
it { should be_bitwise }
|
268
|
+
end
|
269
|
+
|
270
|
+
context "`i | 2'" do
|
271
|
+
subject do
|
272
|
+
inclusive_or_expression(object_specifier("i"), constant_specifier(2))
|
273
|
+
end
|
274
|
+
|
275
|
+
it { should_not be_logical }
|
276
|
+
it { should_not be_arithmetic }
|
277
|
+
it { should be_bitwise }
|
278
|
+
end
|
279
|
+
|
280
|
+
context "`i && j'" do
|
281
|
+
subject do
|
282
|
+
logical_and_expression(object_specifier("i"), object_specifier("j"))
|
283
|
+
end
|
284
|
+
|
285
|
+
it { should be_logical }
|
286
|
+
it { should_not be_arithmetic }
|
287
|
+
it { should_not be_bitwise }
|
288
|
+
end
|
289
|
+
|
290
|
+
context "`i || j'" do
|
291
|
+
subject do
|
292
|
+
logical_or_expression(object_specifier("i"), object_specifier("j"))
|
293
|
+
end
|
294
|
+
|
295
|
+
it { should be_logical }
|
296
|
+
it { should_not be_arithmetic }
|
297
|
+
it { should_not be_bitwise }
|
298
|
+
end
|
299
|
+
|
300
|
+
# NOTE: ConditionalExpression has arithmetics as 2nd and 3rd expression.
|
301
|
+
context "`i > 0 ? i + 2 : j - 4'" do
|
302
|
+
subject do
|
303
|
+
conditional_expression(
|
304
|
+
relational_expression(
|
305
|
+
">", object_specifier("i"), constant_specifier(0)),
|
306
|
+
additive_expression(
|
307
|
+
"+", object_specifier("i"), constant_specifier(2)),
|
308
|
+
additive_expression(
|
309
|
+
"-", object_specifier("j"), constant_specifier(4)))
|
310
|
+
end
|
311
|
+
|
312
|
+
it { should_not be_logical }
|
313
|
+
it { should be_arithmetic }
|
314
|
+
it { should_not be_bitwise }
|
315
|
+
end
|
316
|
+
|
317
|
+
# NOTE: ConditionalExpression has an arithmetic as 2nd expression and a
|
318
|
+
# logical as 3rd expression.
|
319
|
+
context "`i > 0 ? i + 2 : j || k'" do
|
320
|
+
subject do
|
321
|
+
conditional_expression(
|
322
|
+
relational_expression(
|
323
|
+
">", object_specifier("i"), constant_specifier(0)),
|
324
|
+
additive_expression(
|
325
|
+
"+", object_specifier("i"), constant_specifier(2)),
|
326
|
+
logical_or_expression(
|
327
|
+
object_specifier("j"), object_specifier("k")))
|
328
|
+
end
|
329
|
+
|
330
|
+
it { should be_logical }
|
331
|
+
it { should be_arithmetic }
|
332
|
+
it { should_not be_bitwise }
|
333
|
+
end
|
334
|
+
|
335
|
+
# NOTE: ConditionalExpression has an arithmetic as 2nd expression and a
|
336
|
+
# bitwise as 3rd expression.
|
337
|
+
context "`i < 10 ? i + 2 : i << 4'" do
|
338
|
+
subject do
|
339
|
+
conditional_expression(
|
340
|
+
relational_expression(
|
341
|
+
"<", object_specifier("i"), constant_specifier(10)),
|
342
|
+
additive_expression(
|
343
|
+
"+", object_specifier("i"), constant_specifier(2)),
|
344
|
+
shift_expression(
|
345
|
+
"<<", object_specifier("i"), constant_specifier(4)))
|
346
|
+
end
|
347
|
+
|
348
|
+
it { should_not be_logical }
|
349
|
+
it { should be_arithmetic }
|
350
|
+
it { should be_bitwise }
|
351
|
+
end
|
352
|
+
|
353
|
+
# NOTE: ConditionalExpression has bitwises as 2nd and 3rd expression.
|
354
|
+
context "`i < 10 ? i ^ 2 : i << 4'" do
|
355
|
+
subject do
|
356
|
+
conditional_expression(
|
357
|
+
relational_expression(
|
358
|
+
"<", object_specifier("i"), constant_specifier(10)),
|
359
|
+
exclusive_or_expression(
|
360
|
+
object_specifier("i"), constant_specifier(2)),
|
361
|
+
shift_expression(
|
362
|
+
"<<", object_specifier("i"), constant_specifier(4)))
|
363
|
+
end
|
364
|
+
|
365
|
+
it { should_not be_logical }
|
366
|
+
it { should_not be_arithmetic }
|
367
|
+
it { should be_bitwise }
|
368
|
+
end
|
369
|
+
|
370
|
+
# NOTE: ConditionalExpression has a logical as 2nd expression and a bitwise
|
371
|
+
# as 3rd expression.
|
372
|
+
context "`i < 10 ? i && j : i << 4'" do
|
373
|
+
subject do
|
374
|
+
conditional_expression(
|
375
|
+
relational_expression(
|
376
|
+
"<", object_specifier("i"), constant_specifier(10)),
|
377
|
+
logical_and_expression(
|
378
|
+
object_specifier("i"), object_specifier("j")),
|
379
|
+
shift_expression(
|
380
|
+
"<<", object_specifier("i"), constant_specifier(4)))
|
381
|
+
end
|
382
|
+
|
383
|
+
it { should be_logical }
|
384
|
+
it { should_not be_arithmetic }
|
385
|
+
it { should be_bitwise }
|
386
|
+
end
|
387
|
+
|
388
|
+
# NOTE: ConditionalExpression has logicals as 2nd and 3rd expression.
|
389
|
+
context "`i < 10 ? i && j : i || j'" do
|
390
|
+
subject do
|
391
|
+
conditional_expression(
|
392
|
+
relational_expression(
|
393
|
+
"<", object_specifier("i"), constant_specifier(10)),
|
394
|
+
logical_and_expression(
|
395
|
+
object_specifier("i"), object_specifier("j")),
|
396
|
+
logical_or_expression(
|
397
|
+
object_specifier("i"), object_specifier("j")))
|
398
|
+
end
|
399
|
+
|
400
|
+
it { should be_logical }
|
401
|
+
it { should_not be_arithmetic }
|
402
|
+
it { should_not be_bitwise }
|
403
|
+
end
|
404
|
+
|
405
|
+
context "`i = 0'" do
|
406
|
+
subject do
|
407
|
+
simple_assignment_expression(
|
408
|
+
object_specifier("i"), constant_specifier(0))
|
409
|
+
end
|
410
|
+
|
411
|
+
it { should_not be_logical }
|
412
|
+
it { should_not be_arithmetic }
|
413
|
+
it { should_not be_bitwise }
|
414
|
+
end
|
415
|
+
|
416
|
+
context "`i = j = k + 1'" do
|
417
|
+
subject do
|
418
|
+
simple_assignment_expression(
|
419
|
+
object_specifier("i"),
|
420
|
+
simple_assignment_expression(
|
421
|
+
object_specifier("j"),
|
422
|
+
additive_expression(
|
423
|
+
"+", object_specifier("k"), constant_specifier(1))))
|
424
|
+
end
|
425
|
+
|
426
|
+
it { should_not be_logical }
|
427
|
+
it { should be_arithmetic }
|
428
|
+
it { should_not be_bitwise }
|
429
|
+
end
|
430
|
+
|
431
|
+
context "`i = j = k << 1'" do
|
432
|
+
subject do
|
433
|
+
simple_assignment_expression(
|
434
|
+
object_specifier("i"),
|
435
|
+
simple_assignment_expression(
|
436
|
+
object_specifier("j"),
|
437
|
+
shift_expression(
|
438
|
+
"<<", object_specifier("k"), constant_specifier(1))))
|
439
|
+
end
|
440
|
+
|
441
|
+
it { should_not be_logical }
|
442
|
+
it { should_not be_arithmetic }
|
443
|
+
it { should be_bitwise }
|
444
|
+
end
|
445
|
+
|
446
|
+
context "`i = j = (k > 5 && k < 10)'" do
|
447
|
+
subject do
|
448
|
+
simple_assignment_expression(
|
449
|
+
object_specifier("i"),
|
450
|
+
simple_assignment_expression(
|
451
|
+
object_specifier("j"),
|
452
|
+
grouped_expression(
|
453
|
+
logical_and_expression(
|
454
|
+
relational_expression(
|
455
|
+
">", object_specifier("k"), constant_specifier(5)),
|
456
|
+
relational_expression(
|
457
|
+
"<", object_specifier("k"), constant_specifier(10))))))
|
458
|
+
end
|
459
|
+
|
460
|
+
it { should be_logical }
|
461
|
+
it { should_not be_arithmetic }
|
462
|
+
it { should_not be_bitwise }
|
463
|
+
end
|
464
|
+
|
465
|
+
context "`i += 2'" do
|
466
|
+
subject do
|
467
|
+
compound_assignment_expression(
|
468
|
+
"+=", object_specifier("i"), constant_specifier(2))
|
469
|
+
end
|
470
|
+
|
471
|
+
it { should_not be_logical }
|
472
|
+
it { should be_arithmetic }
|
473
|
+
it { should_not be_bitwise }
|
474
|
+
end
|
475
|
+
|
476
|
+
context "`i &= 2'" do
|
477
|
+
subject do
|
478
|
+
compound_assignment_expression(
|
479
|
+
"&=", object_specifier("i"), constant_specifier(2))
|
480
|
+
end
|
481
|
+
|
482
|
+
it { should_not be_logical }
|
483
|
+
it { should_not be_arithmetic }
|
484
|
+
it { should be_bitwise }
|
485
|
+
end
|
486
|
+
|
487
|
+
context "`i ^= j && k'" do
|
488
|
+
subject do
|
489
|
+
compound_assignment_expression(
|
490
|
+
"^=", object_specifier("i"),
|
491
|
+
logical_and_expression(
|
492
|
+
object_specifier("j"), object_specifier("k")))
|
493
|
+
end
|
494
|
+
|
495
|
+
it { should_not be_logical }
|
496
|
+
it { should_not be_arithmetic }
|
497
|
+
it { should be_bitwise }
|
498
|
+
end
|
499
|
+
|
500
|
+
# NOTE: CommaSeparatedExpression has two arithmetic expressions.
|
501
|
+
context "`i + 1, j + 2'" do
|
502
|
+
subject do
|
503
|
+
comma_separated_expression(
|
504
|
+
additive_expression(
|
505
|
+
"+", object_specifier("i"), constant_specifier(1)),
|
506
|
+
additive_expression(
|
507
|
+
"+", object_specifier("j"), constant_specifier(2)))
|
508
|
+
end
|
509
|
+
|
510
|
+
it { should_not be_logical }
|
511
|
+
it { should be_arithmetic }
|
512
|
+
it { should_not be_bitwise }
|
513
|
+
end
|
514
|
+
|
515
|
+
# NOTE: CommaSeparatedExpression has a logical expression followed by an
|
516
|
+
# arithmetic expression.
|
517
|
+
context "`i < 1, j + 2'" do
|
518
|
+
subject do
|
519
|
+
comma_separated_expression(
|
520
|
+
relational_expression(
|
521
|
+
"<", object_specifier("i"), constant_specifier(1)),
|
522
|
+
additive_expression(
|
523
|
+
"+", object_specifier("j"), constant_specifier(2)))
|
524
|
+
end
|
525
|
+
|
526
|
+
it { should_not be_logical }
|
527
|
+
it { should be_arithmetic }
|
528
|
+
it { should_not be_bitwise }
|
529
|
+
end
|
530
|
+
|
531
|
+
# NOTE: CommaSeparatedExpression has an arithmetic expression followed by a
|
532
|
+
# bitwise expression.
|
533
|
+
context "`i + 1, j << 2'" do
|
534
|
+
subject do
|
535
|
+
comma_separated_expression(
|
536
|
+
additive_expression(
|
537
|
+
"+", object_specifier("i"), constant_specifier(1)),
|
538
|
+
shift_expression(
|
539
|
+
"<<", object_specifier("j"), constant_specifier(2)))
|
540
|
+
end
|
541
|
+
|
542
|
+
it { should_not be_logical }
|
543
|
+
it { should_not be_arithmetic }
|
544
|
+
it { should be_bitwise }
|
545
|
+
end
|
546
|
+
|
547
|
+
# NOTE: CommaSeparatedExpression has two bitwise expressions.
|
548
|
+
context "`i << 1, j << 2'" do
|
549
|
+
subject do
|
550
|
+
comma_separated_expression(
|
551
|
+
shift_expression(
|
552
|
+
"<<", object_specifier("i"), constant_specifier(1)),
|
553
|
+
shift_expression(
|
554
|
+
"<<", object_specifier("j"), constant_specifier(2)))
|
555
|
+
end
|
556
|
+
|
557
|
+
it { should_not be_logical }
|
558
|
+
it { should_not be_arithmetic }
|
559
|
+
it { should be_bitwise }
|
560
|
+
end
|
561
|
+
|
562
|
+
# NOTE: CommaSeparatedExpression has a logical expression followed by a
|
563
|
+
# bitwise expression.
|
564
|
+
context "`i > 0, i << 1'" do
|
565
|
+
subject do
|
566
|
+
comma_separated_expression(
|
567
|
+
relational_expression(
|
568
|
+
">", object_specifier("i"), constant_specifier(0)),
|
569
|
+
shift_expression(
|
570
|
+
"<<", object_specifier("i"), constant_specifier(1)))
|
571
|
+
end
|
572
|
+
|
573
|
+
it { should_not be_logical }
|
574
|
+
it { should_not be_arithmetic }
|
575
|
+
it { should be_bitwise }
|
576
|
+
end
|
577
|
+
|
578
|
+
# NOTE: CommaSeparatedExpression has two logical expressions.
|
579
|
+
context "`i < 0, j > 0'" do
|
580
|
+
subject do
|
581
|
+
comma_separated_expression(
|
582
|
+
relational_expression(
|
583
|
+
"<", object_specifier("i"), constant_specifier(0)),
|
584
|
+
relational_expression(
|
585
|
+
">", object_specifier("j"), constant_specifier(0)))
|
586
|
+
end
|
587
|
+
|
588
|
+
it { should be_logical }
|
589
|
+
it { should_not be_arithmetic }
|
590
|
+
it { should_not be_bitwise }
|
591
|
+
end
|
592
|
+
|
593
|
+
private
|
594
|
+
def comma_separated_expression(*exprs)
|
595
|
+
CommaSeparatedExpression.new(exprs.first).tap do |obj|
|
596
|
+
exprs[1..-1].each { |expr| obj.push(expr) }
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
def compound_assignment_expression(op_str, lhs, rhs)
|
601
|
+
CompoundAssignmentExpression.new(operator(op_str), lhs, rhs)
|
602
|
+
end
|
603
|
+
|
604
|
+
def simple_assignment_expression(lhs, rhs)
|
605
|
+
SimpleAssignmentExpression.new(operator("="), lhs, rhs)
|
606
|
+
end
|
607
|
+
|
608
|
+
def conditional_expression(first, second, third)
|
609
|
+
ConditionalExpression.new(first, second, third, operator("?"))
|
610
|
+
end
|
611
|
+
|
612
|
+
def inclusive_or_expression(lhs, rhs)
|
613
|
+
InclusiveOrExpression.new(operator("|"), lhs, rhs)
|
614
|
+
end
|
615
|
+
|
616
|
+
def exclusive_or_expression(lhs, rhs)
|
617
|
+
ExclusiveOrExpression.new(operator("^"), lhs, rhs)
|
618
|
+
end
|
619
|
+
|
620
|
+
def relational_expression(op_str, lhs, rhs)
|
621
|
+
RelationalExpression.new(operator(op_str), lhs, rhs)
|
622
|
+
end
|
623
|
+
|
624
|
+
def multiplicative_expression(op_str, lhs, rhs)
|
625
|
+
MultiplicativeExpression.new(operator(op_str), lhs, rhs)
|
626
|
+
end
|
627
|
+
|
628
|
+
def and_expression(lhs, rhs)
|
629
|
+
AndExpression.new(operator("&"), lhs, rhs)
|
630
|
+
end
|
631
|
+
|
632
|
+
def equality_expression(op_str, lhs, rhs)
|
633
|
+
EqualityExpression.new(operator(op_str), lhs, rhs)
|
634
|
+
end
|
635
|
+
|
636
|
+
def cast_expression(type_name, operand)
|
637
|
+
CastExpression.new(type_name, operand)
|
638
|
+
end
|
639
|
+
|
640
|
+
def char_type_name
|
641
|
+
sq_list = SpecifierQualifierList.new.tap { |obj|
|
642
|
+
obj.type_qualifiers.push(char_type_specifier)
|
643
|
+
}
|
644
|
+
TypeName.new(sq_list, nil, symbol_table)
|
645
|
+
end
|
646
|
+
|
647
|
+
def char_type_specifier
|
648
|
+
StandardTypeSpecifier.new(Token.new(:CHAR, "char", location))
|
649
|
+
end
|
650
|
+
|
651
|
+
def prefix_decrement_expression(operand)
|
652
|
+
PrefixDecrementExpression.new(operator("--"), operand)
|
653
|
+
end
|
654
|
+
|
655
|
+
def prefix_increment_expression(operand)
|
656
|
+
PrefixIncrementExpression.new(operator("++"), operand)
|
657
|
+
end
|
658
|
+
|
659
|
+
def postfix_decrement_expression(operand)
|
660
|
+
PostfixDecrementExpression.new(operator("--"), operand)
|
661
|
+
end
|
662
|
+
|
663
|
+
def postfix_increment_expression(operand)
|
664
|
+
PostfixIncrementExpression.new(operator("++"), operand)
|
665
|
+
end
|
666
|
+
|
667
|
+
def logical_or_expression(lhs, rhs)
|
668
|
+
LogicalOrExpression.new(operator("||"), lhs, rhs)
|
669
|
+
end
|
670
|
+
|
671
|
+
def logical_and_expression(lhs, rhs)
|
672
|
+
LogicalAndExpression.new(operator("&&"), lhs, rhs)
|
673
|
+
end
|
674
|
+
|
675
|
+
def shift_expression(op_str, lhs, rhs)
|
676
|
+
ShiftExpression.new(operator(op_str), lhs, rhs)
|
677
|
+
end
|
678
|
+
|
679
|
+
def additive_expression(op_str, lhs, rhs)
|
680
|
+
AdditiveExpression.new(operator(op_str), lhs, rhs)
|
681
|
+
end
|
682
|
+
|
683
|
+
def grouped_expression(expr)
|
684
|
+
GroupedExpression.new(expr)
|
685
|
+
end
|
686
|
+
|
687
|
+
def error_expression(token)
|
688
|
+
ErrorExpression.new(token)
|
689
|
+
end
|
690
|
+
|
691
|
+
def object_specifier(str)
|
692
|
+
ObjectSpecifier.new(Token.new(:IDENTIFIER, str, location))
|
693
|
+
end
|
694
|
+
|
695
|
+
def null_constant_specifier
|
696
|
+
NullConstantSpecifier.new(Token.new(:NULL, "NULL", location))
|
697
|
+
end
|
698
|
+
|
699
|
+
def constant_specifier(str)
|
700
|
+
ConstantSpecifier.new(Token.new(:CONSTANT, str, location))
|
701
|
+
end
|
702
|
+
|
703
|
+
def string_literal_specifier(str)
|
704
|
+
StringLiteralSpecifier.new(Token.new(:STRING_LITERAL, str, location))
|
705
|
+
end
|
706
|
+
|
707
|
+
def operator(str)
|
708
|
+
Token.new(str, str, location)
|
709
|
+
end
|
710
|
+
|
711
|
+
def location
|
712
|
+
Location.new
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
end
|
717
|
+
end
|