cast 0.3.1 → 0.4.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/CHANGELOG +8 -0
- data/Rakefile +2 -0
- data/ext/cast.h +1 -0
- data/ext/parser.c +2 -0
- data/ext/yylex.c +4032 -3893
- data/ext/yylex.re +3 -0
- data/lib/cast/c.tab.rb +2043 -1401
- data/lib/cast/c.y +12 -4
- 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/parser_test.rb +60 -0
- data/test/preprocessor_test.rb +2 -2
- data/test/test_helper.rb +0 -6
- metadata +7 -7
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,8 +175,11 @@ struct_declaration_list
|
|
172
175
|
|
173
176
|
# Returns Declaration
|
174
177
|
struct_declaration
|
175
|
-
: specifier_qualifier_list struct_declarator_list SEMICOLON
|
176
|
-
| specifier_qualifier_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[])}
|
177
183
|
|
178
184
|
# Returns {Pos, [Symbol]}
|
179
185
|
specifier_qualifier_list
|
@@ -382,6 +388,8 @@ unary_expression
|
|
382
388
|
| unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
|
383
389
|
| SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
|
384
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]}
|
385
393
|
|
386
394
|
# Returns [Class, Pos]
|
387
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/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,8 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '0'
|
73
73
|
requirements: []
|
74
|
-
rubygems_version: 3.
|
75
|
-
signing_key:
|
74
|
+
rubygems_version: 3.5.9
|
75
|
+
signing_key:
|
76
76
|
specification_version: 4
|
77
77
|
summary: C parser and AST constructor.
|
78
78
|
test_files:
|