cast 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/CHANGELOG +12 -0
- data/Rakefile +2 -0
- data/ext/cast.h +1 -0
- data/ext/parser.c +2 -0
- data/ext/yylex.c +4346 -5767
- data/ext/yylex.re +3 -0
- data/lib/cast/c.tab.rb +2070 -1415
- data/lib/cast/c.y +12 -3
- data/lib/cast/node.rb +0 -14
- data/lib/cast/node_list.rb +0 -33
- data/lib/cast/preprocessor.rb +4 -2
- data/lib/cast/version.rb +1 -1
- data/lib/cast.rb +1 -0
- data/test/c_nodes_test.rb +2 -2
- data/test/node_list_test.rb +1 -1
- data/test/parse_test.rb +3 -1
- data/test/parser_test.rb +60 -0
- data/test/preprocessor_test.rb +2 -2
- data/test/test_helper.rb +0 -6
- metadata +7 -8
data/lib/cast/c.y
CHANGED
@@ -12,8 +12,11 @@ translation_unit
|
|
12
12
|
|
13
13
|
# Returns Declaration|FunctionDef
|
14
14
|
external_declaration
|
15
|
-
: function_definition
|
16
|
-
| declaration
|
15
|
+
: function_definition {result = val[0]}
|
16
|
+
| declaration {result = val[0]}
|
17
|
+
# GCC EXTENSION: __extension__ can go before any external declaration
|
18
|
+
# this has no effect aside from suppressing certain warnings
|
19
|
+
| EXTENSION external_declaration {result = val[1]}
|
17
20
|
|
18
21
|
# Returns FunctionDef
|
19
22
|
function_definition
|
@@ -172,7 +175,11 @@ struct_declaration_list
|
|
172
175
|
|
173
176
|
# Returns Declaration
|
174
177
|
struct_declaration
|
175
|
-
: specifier_qualifier_list struct_declarator_list SEMICOLON
|
178
|
+
: specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
|
179
|
+
| specifier_qualifier_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
|
180
|
+
# GCC EXTENSION: __extension__ can go before any struct_declaration
|
181
|
+
| EXTENSION specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[1][0], val[1][1], val[2])}
|
182
|
+
| EXTENSION specifier_qualifier_list SEMICOLON {result = make_declaration(val[1][0], val[1][1], NodeArray[])}
|
176
183
|
|
177
184
|
# Returns {Pos, [Symbol]}
|
178
185
|
specifier_qualifier_list
|
@@ -381,6 +388,8 @@ unary_expression
|
|
381
388
|
| unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
|
382
389
|
| SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
|
383
390
|
| SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
|
391
|
+
# GCC extension: __extension__
|
392
|
+
| EXTENSION cast_expression {result = val[1]}
|
384
393
|
|
385
394
|
# Returns [Class, Pos]
|
386
395
|
unary_operator
|
data/lib/cast/node.rb
CHANGED
@@ -9,20 +9,6 @@ module C
|
|
9
9
|
# Abstract base class for all AST nodes.
|
10
10
|
#
|
11
11
|
class Node
|
12
|
-
#
|
13
|
-
# Called by the test suite to ensure all invariants are true.
|
14
|
-
#
|
15
|
-
def assert_invariants(testcase)
|
16
|
-
fields.each do |field|
|
17
|
-
if val = send(field.reader)
|
18
|
-
assert_same(self, node.parent, "field.reader is #{field.reader}")
|
19
|
-
if field.child?
|
20
|
-
assert_same(field, val.instance_variable_get(:@parent_field), "field.reader is #{field.reader}")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
12
|
#
|
27
13
|
# Like self.new, but the first argument is taken as the position
|
28
14
|
# of the Node.
|
data/lib/cast/node_list.rb
CHANGED
@@ -148,14 +148,6 @@ module C
|
|
148
148
|
end
|
149
149
|
|
150
150
|
class NodeArray
|
151
|
-
def assert_invariants(testcase)
|
152
|
-
super
|
153
|
-
testcase.assert_same(::Array, @array)
|
154
|
-
@array.each_with_index do |node, i|
|
155
|
-
assert_same(i, node.instance_variable_get(:@parent_index))
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
151
|
def initialize
|
160
152
|
super
|
161
153
|
@array = []
|
@@ -177,31 +169,6 @@ module C
|
|
177
169
|
end
|
178
170
|
|
179
171
|
class NodeChain
|
180
|
-
def assert_invariants(testcase)
|
181
|
-
super
|
182
|
-
assert_same(@length.zero?, @first.nil?)
|
183
|
-
assert_same(@length.zero?, @last.nil?)
|
184
|
-
unless @length.zero?
|
185
|
-
assert_same(@first, self[0])
|
186
|
-
assert_same(@last, self[@length-1])
|
187
|
-
(0...@length.times).each do |i|
|
188
|
-
nodeprev = self[i].instance_variable_get(:@prev)
|
189
|
-
nodenext = self[i].instance_variable_get(:@next)
|
190
|
-
if i == 0
|
191
|
-
assert_nil(nodeprev)
|
192
|
-
else
|
193
|
-
assert_same(self[i-1], nodeprev)
|
194
|
-
end
|
195
|
-
|
196
|
-
if i == @length-1
|
197
|
-
assert_nil(nodenext)
|
198
|
-
else
|
199
|
-
assert_same(self[i+1], nodenext)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
172
|
def initialize
|
206
173
|
super
|
207
174
|
@first = nil
|
data/lib/cast/preprocessor.rb
CHANGED
@@ -29,11 +29,13 @@ module C
|
|
29
29
|
end
|
30
30
|
def preprocess(text)
|
31
31
|
filename = nil
|
32
|
-
|
32
|
+
output = nil
|
33
|
+
Tempfile.open(['cast-preprocessor-input.', '.c']) do |file|
|
33
34
|
filename = file.path
|
34
35
|
file.puts text
|
36
|
+
file.flush
|
37
|
+
output = `#{full_command(filename)} #{'2> /dev/null' if @quiet}`
|
35
38
|
end
|
36
|
-
output = `#{full_command(filename)} #{'2> /dev/null' if @quiet}`
|
37
39
|
if $? == 0
|
38
40
|
return output
|
39
41
|
else
|
data/lib/cast/version.rb
CHANGED
data/lib/cast.rb
CHANGED
data/test/c_nodes_test.rb
CHANGED
@@ -194,7 +194,7 @@ EOS
|
|
194
194
|
|
195
195
|
c.wide = false
|
196
196
|
assert(!c.wide?)
|
197
|
-
|
197
|
+
assert_nil(c.prefix)
|
198
198
|
end
|
199
199
|
def test_string_literal_wide
|
200
200
|
s = C::StringLiteral.new('abc', 'L')
|
@@ -219,6 +219,6 @@ EOS
|
|
219
219
|
|
220
220
|
s.wide = false
|
221
221
|
assert(!s.wide?)
|
222
|
-
|
222
|
+
assert_nil(s.prefix)
|
223
223
|
end
|
224
224
|
end
|
data/test/node_list_test.rb
CHANGED
@@ -1298,7 +1298,7 @@ module NodeListArrayQueryTests
|
|
1298
1298
|
assert_equal(0, list.index(a))
|
1299
1299
|
assert_equal(1, list.index(l1))
|
1300
1300
|
assert_equal(1, list.index(_List[C::Int.new(2)]))
|
1301
|
-
|
1301
|
+
assert_nil(list.index([b]))
|
1302
1302
|
assert_nil(list.index([a]))
|
1303
1303
|
assert_nil(list.index(C::Int.new))
|
1304
1304
|
assert_nil(list.index(nil))
|
data/test/parse_test.rb
CHANGED
@@ -1761,10 +1761,12 @@ Struct
|
|
1761
1761
|
name: "s"
|
1762
1762
|
EOS
|
1763
1763
|
check C::Struct, <<EOS
|
1764
|
-
const struct {int i, j : 4;}
|
1764
|
+
const struct {float; int i, j : 4;}
|
1765
1765
|
----
|
1766
1766
|
Struct (const)
|
1767
1767
|
members:
|
1768
|
+
- Declaration
|
1769
|
+
type: Float
|
1768
1770
|
- Declaration
|
1769
1771
|
type: Int
|
1770
1772
|
declarators:
|
data/test/parser_test.rb
CHANGED
@@ -118,6 +118,66 @@ TranslationUnit
|
|
118
118
|
EOS
|
119
119
|
end
|
120
120
|
|
121
|
+
def test_external_declaration_with_extension_kw
|
122
|
+
check <<EOS
|
123
|
+
__extension__ typedef int blah;
|
124
|
+
----
|
125
|
+
TranslationUnit
|
126
|
+
entities:
|
127
|
+
- Declaration
|
128
|
+
storage: typedef
|
129
|
+
type: Int
|
130
|
+
declarators:
|
131
|
+
- Declarator
|
132
|
+
name: "blah"
|
133
|
+
EOS
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_struct_member_declaration_with_extension_kw
|
137
|
+
check <<EOS
|
138
|
+
struct { __extension__ int; __extension__ int i; int j; } blah;
|
139
|
+
----
|
140
|
+
TranslationUnit
|
141
|
+
entities:
|
142
|
+
- Declaration
|
143
|
+
type: Struct
|
144
|
+
members:
|
145
|
+
- Declaration
|
146
|
+
type: Int
|
147
|
+
- Declaration
|
148
|
+
type: Int
|
149
|
+
declarators:
|
150
|
+
- Declarator
|
151
|
+
name: "i"
|
152
|
+
- Declaration
|
153
|
+
type: Int
|
154
|
+
declarators:
|
155
|
+
- Declarator
|
156
|
+
name: "j"
|
157
|
+
declarators:
|
158
|
+
- Declarator
|
159
|
+
name: "blah"
|
160
|
+
EOS
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_unary_extension_kw
|
164
|
+
check <<EOS
|
165
|
+
void f() { __extension__ 0; }
|
166
|
+
----
|
167
|
+
TranslationUnit
|
168
|
+
entities:
|
169
|
+
- FunctionDef
|
170
|
+
type: Function
|
171
|
+
type: Void
|
172
|
+
name: "f"
|
173
|
+
def: Block
|
174
|
+
stmts:
|
175
|
+
- ExpressionStatement
|
176
|
+
expr: IntLiteral
|
177
|
+
val: 0
|
178
|
+
EOS
|
179
|
+
end
|
180
|
+
|
121
181
|
def test_function_def
|
122
182
|
check <<EOS
|
123
183
|
int main(int, char **) {}
|
data/test/preprocessor_test.rb
CHANGED
@@ -14,7 +14,7 @@ class PreprocessorTest < Minitest::Test
|
|
14
14
|
attr_accessor :cpp
|
15
15
|
def setup
|
16
16
|
@cpp = C::Preprocessor.new(quiet: true)
|
17
|
-
@cpp.include_path <<
|
17
|
+
@cpp.include_path << TEST_DIR << 'dir 2'
|
18
18
|
@cpp.macros['V'] = nil
|
19
19
|
@cpp.macros['I'] = 5
|
20
20
|
@cpp.macros['S'] = '"blah"'
|
@@ -30,7 +30,7 @@ class PreprocessorTest < Minitest::Test
|
|
30
30
|
C::Preprocessor.command = 'COMMAND'
|
31
31
|
assert_equal([
|
32
32
|
'COMMAND',
|
33
|
-
|
33
|
+
"-I#{TEST_DIR}", '-Idir 2',
|
34
34
|
'-DI=5', '-DS="blah"', '-DSWAP(a,b)=a ^= b ^= a ^= b', '-DV',
|
35
35
|
'a file.c',
|
36
36
|
], cpp.full_command('a file.c').shellsplit)
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Ogata
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description:
|
14
14
|
email:
|
15
15
|
- george.ogata@gmail.com
|
16
16
|
executables: []
|
@@ -56,7 +56,7 @@ homepage: http://github.com/oggy/cast
|
|
56
56
|
licenses:
|
57
57
|
- MIT
|
58
58
|
metadata: {}
|
59
|
-
post_install_message:
|
59
|
+
post_install_message:
|
60
60
|
rdoc_options: []
|
61
61
|
require_paths:
|
62
62
|
- lib
|
@@ -71,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
73
|
requirements: []
|
74
|
-
|
75
|
-
|
76
|
-
signing_key:
|
74
|
+
rubygems_version: 3.5.9
|
75
|
+
signing_key:
|
77
76
|
specification_version: 4
|
78
77
|
summary: C parser and AST constructor.
|
79
78
|
test_files:
|