racc 1.4.14-java → 1.4.15-java

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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/Manifest.txt +50 -0
  3. data/ext/racc/com/headius/racc/Cparse.java +66 -23
  4. data/ext/racc/cparse.c +1 -1
  5. data/ext/racc/depend +1 -1
  6. data/lib/racc/cparse-jruby.jar +0 -0
  7. data/lib/racc/info.rb +2 -2
  8. data/test/assets/bibtex.y +141 -0
  9. data/test/assets/cadenza.y +170 -0
  10. data/test/assets/cast.y +926 -0
  11. data/test/assets/csspool.y +729 -0
  12. data/test/assets/edtf.y +583 -0
  13. data/test/assets/huia.y +318 -0
  14. data/test/assets/journey.y +47 -0
  15. data/test/assets/liquor.y +313 -0
  16. data/test/assets/machete.y +423 -0
  17. data/test/assets/macruby.y +2197 -0
  18. data/test/assets/mediacloth.y +599 -0
  19. data/test/assets/mof.y +649 -0
  20. data/test/assets/namae.y +302 -0
  21. data/test/assets/nasl.y +626 -0
  22. data/test/assets/nokogiri-css.y +255 -0
  23. data/test/assets/opal.y +1807 -0
  24. data/test/assets/php_serialization.y +98 -0
  25. data/test/assets/rdblockparser.y +576 -0
  26. data/test/assets/rdinlineparser.y +561 -0
  27. data/test/assets/riml.y +665 -0
  28. data/test/assets/ruby18.y +1943 -0
  29. data/test/assets/ruby19.y +2174 -0
  30. data/test/assets/ruby20.y +2350 -0
  31. data/test/assets/ruby21.y +2359 -0
  32. data/test/assets/ruby22.y +2381 -0
  33. data/test/assets/tp_plus.y +622 -0
  34. data/test/assets/twowaysql.y +278 -0
  35. data/test/helper.rb +50 -34
  36. data/test/regress/bibtex +474 -0
  37. data/test/regress/cadenza +796 -0
  38. data/test/regress/cast +3425 -0
  39. data/test/regress/csspool +2318 -0
  40. data/test/regress/edtf +1794 -0
  41. data/test/regress/huia +1392 -0
  42. data/test/regress/journey +222 -0
  43. data/test/regress/liquor +885 -0
  44. data/test/regress/machete +833 -0
  45. data/test/regress/mediacloth +1463 -0
  46. data/test/regress/mof +1368 -0
  47. data/test/regress/namae +634 -0
  48. data/test/regress/nasl +2058 -0
  49. data/test/regress/nokogiri-css +836 -0
  50. data/test/regress/opal +6429 -0
  51. data/test/regress/php_serialization +336 -0
  52. data/test/regress/rdblockparser +1061 -0
  53. data/test/regress/rdinlineparser +1243 -0
  54. data/test/regress/riml +3297 -0
  55. data/test/regress/ruby18 +6351 -0
  56. data/test/regress/ruby22 +7456 -0
  57. data/test/regress/tp_plus +1933 -0
  58. data/test/regress/twowaysql +556 -0
  59. data/test/test_racc_command.rb +177 -0
  60. metadata +80 -25
  61. data/.gemtest +0 -0
@@ -0,0 +1,170 @@
1
+ # This grammar is released under an MIT license
2
+ # Author: William Howard (http://github.com/whoward)
3
+ # Source: https://github.com/whoward/cadenza/blob/master/src/cadenza.y
4
+
5
+ class Cadenza::RaccParser
6
+
7
+ /* expect this many shift/reduce conflicts */
8
+ expect 37
9
+
10
+ rule
11
+ target
12
+ : document
13
+ | /* none */ { result = nil }
14
+ ;
15
+
16
+ parameter_list
17
+ : logical_expression { result = [val[0]] }
18
+ | parameter_list ',' logical_expression { result = val[0].push(val[2]) }
19
+ ;
20
+
21
+ /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
22
+ primary_expression
23
+ : IDENTIFIER { result = VariableNode.new(val[0].value) }
24
+ | IDENTIFIER parameter_list { result = VariableNode.new(val[0].value, val[1]) }
25
+ | INTEGER { result = ConstantNode.new(val[0].value) }
26
+ | REAL { result = ConstantNode.new(val[0].value) }
27
+ | STRING { result = ConstantNode.new(val[0].value) }
28
+ | '(' filtered_expression ')' { result = val[1] }
29
+ ;
30
+
31
+ multiplicative_expression
32
+ : primary_expression
33
+ | multiplicative_expression '*' primary_expression { result = OperationNode.new(val[0], "*", val[2]) }
34
+ | multiplicative_expression '/' primary_expression { result = OperationNode.new(val[0], "/", val[2]) }
35
+ ;
36
+
37
+ additive_expression
38
+ : multiplicative_expression
39
+ | additive_expression '+' multiplicative_expression { result = OperationNode.new(val[0], "+", val[2]) }
40
+ | additive_expression '-' multiplicative_expression { result = OperationNode.new(val[0], "-", val[2]) }
41
+ ;
42
+
43
+ boolean_expression
44
+ : additive_expression
45
+ | boolean_expression OP_EQ additive_expression { result = OperationNode.new(val[0], "==", val[2]) }
46
+ | boolean_expression OP_NEQ additive_expression { result = OperationNode.new(val[0], "!=", val[2]) }
47
+ | boolean_expression OP_LEQ additive_expression { result = OperationNode.new(val[0], "<=", val[2]) }
48
+ | boolean_expression OP_GEQ additive_expression { result = OperationNode.new(val[0], ">=", val[2]) }
49
+ | boolean_expression '>' additive_expression { result = OperationNode.new(val[0], ">", val[2]) }
50
+ | boolean_expression '<' additive_expression { result = OperationNode.new(val[0], "<", val[2]) }
51
+ ;
52
+
53
+ inverse_expression
54
+ : boolean_expression
55
+ | NOT boolean_expression { result = BooleanInverseNode.new(val[1]) }
56
+ ;
57
+
58
+ logical_expression
59
+ : inverse_expression
60
+ | logical_expression AND inverse_expression { result = OperationNode.new(val[0], "and", val[2]) }
61
+ | logical_expression OR inverse_expression { result = OperationNode.new(val[0], "or", val[2]) }
62
+ ;
63
+
64
+ filter
65
+ : IDENTIFIER { result = FilterNode.new(val[0].value) }
66
+ | IDENTIFIER ':' parameter_list { result = FilterNode.new(val[0].value, val[2]) }
67
+ ;
68
+
69
+ filter_list
70
+ : filter { result = [val[0]] }
71
+ | filter_list '|' filter { result = val[0].push(val[2]) }
72
+ ;
73
+
74
+ filtered_expression
75
+ : logical_expression
76
+ | logical_expression '|' filter_list { result = FilteredValueNode.new(val[0], val[2]) }
77
+ ;
78
+
79
+ inject_statement
80
+ : VAR_OPEN filtered_expression VAR_CLOSE { result = val[1] }
81
+ ;
82
+
83
+ if_tag
84
+ : STMT_OPEN IF logical_expression STMT_CLOSE { open_scope!; result = val[2] }
85
+ | STMT_OPEN UNLESS logical_expression STMT_CLOSE { open_scope!; result = BooleanInverseNode.new(val[2]) }
86
+ ;
87
+
88
+ else_tag
89
+ : STMT_OPEN ELSE STMT_CLOSE { result = close_scope!; open_scope! }
90
+ ;
91
+
92
+ end_if_tag
93
+ : STMT_OPEN ENDIF STMT_CLOSE { result = close_scope! }
94
+ | STMT_OPEN ENDUNLESS STMT_CLOSE { result = close_scope! }
95
+ ;
96
+
97
+ if_block
98
+ : if_tag end_if_tag { result = IfNode.new(val[0], val[1]) }
99
+ | if_tag document end_if_tag { result = IfNode.new(val[0], val[2]) }
100
+ | if_tag else_tag document end_if_tag { result = IfNode.new(val[0], val[1], val[3]) }
101
+ | if_tag document else_tag end_if_tag { result = IfNode.new(val[0], val[2], val[3]) }
102
+ | if_tag document else_tag document end_if_tag { result = IfNode.new(val[0], val[2], val[4]) }
103
+ ;
104
+
105
+ for_tag
106
+ : STMT_OPEN FOR IDENTIFIER IN filtered_expression STMT_CLOSE { open_scope!; result = [val[2].value, val[4]] }
107
+ ;
108
+
109
+ end_for_tag
110
+ : STMT_OPEN ENDFOR STMT_CLOSE { result = close_scope! }
111
+ ;
112
+
113
+ /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
114
+ for_block
115
+ : for_tag end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[1]) }
116
+ | for_tag document end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[2]) }
117
+ ;
118
+
119
+ block_tag
120
+ : STMT_OPEN BLOCK IDENTIFIER STMT_CLOSE { result = open_block_scope!(val[2].value) }
121
+ ;
122
+
123
+ end_block_tag
124
+ : STMT_OPEN ENDBLOCK STMT_CLOSE { result = close_block_scope! }
125
+ ;
126
+
127
+ /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
128
+ block_block
129
+ : block_tag end_block_tag { result = BlockNode.new(val[0], val[1]) }
130
+ | block_tag document end_block_tag { result = BlockNode.new(val[0], val[2]) }
131
+ ;
132
+
133
+ generic_block_tag
134
+ : STMT_OPEN IDENTIFIER STMT_CLOSE { open_scope!; result = [val[1].value, []] }
135
+ | STMT_OPEN IDENTIFIER parameter_list STMT_CLOSE { open_scope!; result = [val[1].value, val[2]] }
136
+ ;
137
+
138
+ end_generic_block_tag
139
+ : STMT_OPEN END STMT_CLOSE { result = close_scope! }
140
+ ;
141
+
142
+ generic_block
143
+ : generic_block_tag document end_generic_block_tag { result = GenericBlockNode.new(val[0].first, val[2], val[0].last) }
144
+ ;
145
+
146
+ extends_statement
147
+ : STMT_OPEN EXTENDS STRING STMT_CLOSE { result = val[2].value }
148
+ | STMT_OPEN EXTENDS IDENTIFIER STMT_CLOSE { result = VariableNode.new(val[2].value) }
149
+ ;
150
+
151
+ document_component
152
+ : TEXT_BLOCK { result = TextNode.new(val[0].value) }
153
+ | inject_statement
154
+ | if_block
155
+ | for_block
156
+ | generic_block
157
+ | block_block
158
+ ;
159
+
160
+ document
161
+ : document_component { push val[0] }
162
+ | document document_component { push val[1] }
163
+ | extends_statement { document.extends = val[0] }
164
+ | document extends_statement { document.extends = val[1] }
165
+ ;
166
+
167
+ ---- header ----
168
+ # racc_parser.rb : generated by racc
169
+
170
+ ---- inner ----
@@ -0,0 +1,926 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) George Ogata
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ class C::Parser
25
+ # shift/reduce conflict on "if (c) if (c) ; else ; else ;"
26
+ expect 1
27
+ rule
28
+
29
+ # A.2.4 External definitions
30
+
31
+ # Returns TranslationUnit
32
+ translation_unit
33
+ : external_declaration {result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])}
34
+ | translation_unit external_declaration {result = val[0]; result.entities << val[1]}
35
+
36
+ # Returns Declaration|FunctionDef
37
+ external_declaration
38
+ : function_definition {result = val[0]}
39
+ | declaration {result = val[0]}
40
+
41
+ # Returns FunctionDef
42
+ function_definition
43
+ : declaration_specifiers declarator declaration_list compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], val[2], val[3])}
44
+ | declaration_specifiers declarator compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])}
45
+
46
+ # Returns [Declaration]
47
+ declaration_list
48
+ : declaration {result = [val[0]]}
49
+ | declaration_list declaration {result = val[0] << val[1]}
50
+
51
+ # A.2.3 Statements
52
+
53
+ # Returns Statement
54
+ statement
55
+ : labeled_statement {result = val[0]}
56
+ | compound_statement {result = val[0]}
57
+ | expression_statement {result = val[0]}
58
+ | selection_statement {result = val[0]}
59
+ | iteration_statement {result = val[0]}
60
+ | jump_statement {result = val[0]}
61
+
62
+ # Returns Statement
63
+ labeled_statement
64
+ : identifier COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]}
65
+ | CASE constant_expression COLON statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]}
66
+ | DEFAULT COLON statement {val[2].labels.unshift(Default .new_at(val[0].pos )); result = val[2]}
67
+ # type names can also be used as labels
68
+ | typedef_name COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]}
69
+
70
+ # Returns Block
71
+ compound_statement
72
+ : LBRACE block_item_list RBRACE {result = Block.new_at(val[0].pos, val[1])}
73
+ | LBRACE RBRACE {result = Block.new_at(val[0].pos )}
74
+
75
+ # Returns NodeChain[Declaration|Statement]
76
+ block_item_list
77
+ : block_item {result = NodeChain[val[0]]}
78
+ | block_item_list block_item {result = val[0] << val[1]}
79
+
80
+ # Returns Declaration|Statement
81
+ block_item
82
+ : declaration {result = val[0]}
83
+ | statement {result = val[0]}
84
+
85
+ # Returns ExpressionStatement
86
+ expression_statement
87
+ : expression SEMICOLON {result = ExpressionStatement.new_at(val[0].pos, val[0])}
88
+ | SEMICOLON {result = ExpressionStatement.new_at(val[0].pos )}
89
+
90
+ # Returns Statement
91
+ selection_statement
92
+ : IF LPAREN expression RPAREN statement {result = If .new_at(val[0].pos, val[2], val[4] )}
93
+ | IF LPAREN expression RPAREN statement ELSE statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])}
94
+ | SWITCH LPAREN expression RPAREN statement {result = Switch.new_at(val[0].pos, val[2], val[4] )}
95
+
96
+ # Returns Statement
97
+ iteration_statement
98
+ : WHILE LPAREN expression RPAREN statement {result = While.new_at(val[0].pos, val[2], val[4] )}
99
+ | DO statement WHILE LPAREN expression RPAREN SEMICOLON {result = While.new_at(val[0].pos, val[4], val[1], :do => true )}
100
+ | FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])}
101
+ | FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])}
102
+ | FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])}
103
+ | FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[6])}
104
+ | FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])}
105
+ | FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], nil , val[6])}
106
+ | FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , nil , val[4], val[6])}
107
+ | FOR LPAREN SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , nil , nil , val[5])}
108
+ | FOR LPAREN declaration expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])}
109
+ | FOR LPAREN declaration expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])}
110
+ | FOR LPAREN declaration SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])}
111
+ | FOR LPAREN declaration SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])}
112
+
113
+ # Returns Statement
114
+ jump_statement
115
+ : GOTO identifier SEMICOLON {result = Goto .new_at(val[0].pos, val[1].val)}
116
+ | CONTINUE SEMICOLON {result = Continue.new_at(val[0].pos )}
117
+ | BREAK SEMICOLON {result = Break .new_at(val[0].pos )}
118
+ | RETURN expression SEMICOLON {result = Return .new_at(val[0].pos, val[1] )}
119
+ | RETURN SEMICOLON {result = Return .new_at(val[0].pos )}
120
+ # type names can also be used as labels
121
+ | GOTO typedef_name SEMICOLON {result = Goto .new_at(val[0].pos, val[1].name)}
122
+
123
+ # A.2.2 Declarations
124
+
125
+ # Returns Declaration
126
+ declaration
127
+ : declaration_specifiers init_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
128
+ | declaration_specifiers SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
129
+
130
+ # Returns {Pos, [Symbol]}
131
+ declaration_specifiers
132
+ : storage_class_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
133
+ | storage_class_specifier {result = [val[0][0], [val[0][1]]]}
134
+ | type_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
135
+ | type_specifier {result = [val[0][0], [val[0][1]]]}
136
+ | type_qualifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
137
+ | type_qualifier {result = [val[0][0], [val[0][1]]]}
138
+ | function_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
139
+ | function_specifier {result = [val[0][0], [val[0][1]]]}
140
+
141
+ # Returns NodeArray[Declarator]
142
+ init_declarator_list
143
+ : init_declarator {result = NodeArray[val[0]]}
144
+ | init_declarator_list COMMA init_declarator {result = val[0] << val[2]}
145
+
146
+ # Returns Declarator
147
+ init_declarator
148
+ : declarator {result = val[0]}
149
+ | declarator EQ initializer {val[0].init = val[2]; result = val[0]}
150
+
151
+ # Returns [Pos, Symbol]
152
+ storage_class_specifier
153
+ : TYPEDEF {result = [val[0].pos, :typedef ]}
154
+ | EXTERN {result = [val[0].pos, :extern ]}
155
+ | STATIC {result = [val[0].pos, :static ]}
156
+ | AUTO {result = [val[0].pos, :auto ]}
157
+ | REGISTER {result = [val[0].pos, :register]}
158
+
159
+ # Returns [Pos, Type|Symbol]
160
+ type_specifier
161
+ : VOID {result = [val[0].pos, :void ]}
162
+ | CHAR {result = [val[0].pos, :char ]}
163
+ | SHORT {result = [val[0].pos, :short ]}
164
+ | INT {result = [val[0].pos, :int ]}
165
+ | LONG {result = [val[0].pos, :long ]}
166
+ | FLOAT {result = [val[0].pos, :float ]}
167
+ | DOUBLE {result = [val[0].pos, :double ]}
168
+ | SIGNED {result = [val[0].pos, :signed ]}
169
+ | UNSIGNED {result = [val[0].pos, :unsigned ]}
170
+ | BOOL {result = [val[0].pos, :_Bool ]}
171
+ | COMPLEX {result = [val[0].pos, :_Complex ]}
172
+ | IMAGINARY {result = [val[0].pos, :_Imaginary]}
173
+ | struct_or_union_specifier {result = [val[0].pos, val[0] ]}
174
+ | enum_specifier {result = [val[0].pos, val[0] ]}
175
+ | typedef_name {result = [val[0].pos, val[0] ]}
176
+
177
+ # Returns Struct|Union
178
+ struct_or_union_specifier
179
+ : struct_or_union identifier LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].val, val[3])}
180
+ | struct_or_union LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], nil , val[2])}
181
+ | struct_or_union identifier {result = val[0][1].new_at(val[0][0], val[1].val, nil )}
182
+ # type names can also be used as struct identifiers
183
+ | struct_or_union typedef_name LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].name, val[3])}
184
+ | struct_or_union typedef_name {result = val[0][1].new_at(val[0][0], val[1].name, nil )}
185
+
186
+ # Returns [Pos, Class]
187
+ struct_or_union
188
+ : STRUCT {result = [val[0].pos, Struct]}
189
+ | UNION {result = [val[0].pos, Union ]}
190
+
191
+ # Returns NodeArray[Declaration]
192
+ struct_declaration_list
193
+ : struct_declaration {result = NodeArray[val[0]]}
194
+ | struct_declaration_list struct_declaration {val[0] << val[1]; result = val[0]}
195
+
196
+ # Returns Declaration
197
+ struct_declaration
198
+ : specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
199
+
200
+ # Returns {Pos, [Symbol]}
201
+ specifier_qualifier_list
202
+ : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
203
+ | type_specifier {result = [val[0][0], [val[0][1]]]}
204
+ | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
205
+ | type_qualifier {result = [val[0][0], [val[0][1]]]}
206
+
207
+ # Returns NodeArray[Declarator]
208
+ struct_declarator_list
209
+ : struct_declarator {result = NodeArray[val[0]]}
210
+ | struct_declarator_list COMMA struct_declarator {result = val[0] << val[2]}
211
+
212
+ # Returns Declarator
213
+ struct_declarator
214
+ : declarator {result = val[0]}
215
+ | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]}
216
+ | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
217
+
218
+ # Returns Enum
219
+ enum_specifier
220
+ : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
221
+ | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
222
+ | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
223
+ | ENUM LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
224
+ | ENUM identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )}
225
+ # type names can also be used as enum names
226
+ | ENUM typedef_name LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
227
+ | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
228
+ | ENUM typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )}
229
+
230
+ # Returns NodeArray[Enumerator]
231
+ enumerator_list
232
+ : enumerator {result = NodeArray[val[0]]}
233
+ | enumerator_list COMMA enumerator {result = val[0] << val[2]}
234
+
235
+ # Returns Enumerator
236
+ enumerator
237
+ : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )}
238
+ | enumeration_constant EQ constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])}
239
+
240
+ # Returns [Pos, Symbol]
241
+ type_qualifier
242
+ : CONST {result = [val[0].pos, :const ]}
243
+ | RESTRICT {result = [val[0].pos, :restrict]}
244
+ | VOLATILE {result = [val[0].pos, :volatile]}
245
+
246
+ # Returns [Pos, Symbol]
247
+ function_specifier
248
+ : INLINE {result = [val[0].pos, :inline]}
249
+
250
+ # Returns Declarator
251
+ declarator
252
+ : pointer direct_declarator {result = add_decl_type(val[1], val[0])}
253
+ | direct_declarator {result = val[0]}
254
+
255
+ # Returns Declarator
256
+ direct_declarator
257
+ : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)}
258
+ | LPAREN declarator RPAREN {result = val[1]}
259
+ | direct_declarator LBRACKET type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
260
+ | direct_declarator LBRACKET type_qualifier_list RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
261
+ | direct_declarator LBRACKET assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))}
262
+ | direct_declarator LBRACKET RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))}
263
+ | direct_declarator LBRACKET STATIC type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
264
+ | direct_declarator LBRACKET STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
265
+ | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
266
+ | direct_declarator LBRACKET type_qualifier_list MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
267
+ | direct_declarator LBRACKET MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
268
+ | direct_declarator LPAREN parameter_type_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, param_list(*val[2]), :var_args => val[2][1]))}
269
+ | direct_declarator LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
270
+ | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
271
+
272
+ # Returns Pointer
273
+ pointer
274
+ : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
275
+ | MUL {result = Pointer.new_at(val[0].pos) }
276
+ | MUL type_qualifier_list pointer {p = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]); val[2].direct_type = p; result = val[2]}
277
+ | MUL pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]}
278
+
279
+ # Returns {Pos, [Symbol]}
280
+ type_qualifier_list
281
+ : type_qualifier {result = [val[0][0], [val[0][1]]]}
282
+ | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]}
283
+
284
+ # Returns [NodeArray[Parameter], var_args?]
285
+ parameter_type_list
286
+ : parameter_list {result = [val[0], false]}
287
+ | parameter_list COMMA ELLIPSIS {result = [val[0], true ]}
288
+
289
+ # Returns NodeArray[Parameter]
290
+ parameter_list
291
+ : parameter_declaration {result = NodeArray[val[0]]}
292
+ | parameter_list COMMA parameter_declaration {result = val[0] << val[2]}
293
+
294
+ # Returns Parameter
295
+ parameter_declaration
296
+ : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach
297
+ result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)}
298
+ | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )}
299
+ | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )}
300
+
301
+ # Returns NodeArray[Parameter]
302
+ identifier_list
303
+ : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]}
304
+ | identifier_list COMMA identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)}
305
+
306
+ # Returns Type
307
+ type_name
308
+ : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]}
309
+ | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) }
310
+
311
+ # Returns Type
312
+ abstract_declarator
313
+ : pointer {result = val[0]}
314
+ | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]}
315
+ | direct_abstract_declarator {result = val[0]}
316
+
317
+ # Returns Type
318
+ direct_abstract_declarator
319
+ : LPAREN abstract_declarator RPAREN {result = val[1]}
320
+ | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
321
+ | direct_abstract_declarator LBRACKET RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]}
322
+ | LBRACKET assignment_expression RBRACKET {result = Array.new_at(val[0].pos, nil, val[1])}
323
+ | LBRACKET RBRACKET {result = Array.new_at(val[0].pos )}
324
+ | direct_abstract_declarator LBRACKET MUL RBRACKET {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO
325
+ | LBRACKET MUL RBRACKET {result = Array.new_at(val[0].pos)} # TODO
326
+ | direct_abstract_declarator LPAREN parameter_type_list RPAREN {val[0].direct_type = Function.new_at(val[0].pos, nil, param_list(*val[2]), val[2][1]); result = val[0]}
327
+ | direct_abstract_declarator LPAREN RPAREN {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]}
328
+ | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
329
+ | LPAREN RPAREN {result = Function.new_at(val[0].pos )}
330
+
331
+ # Returns CustomType
332
+ typedef_name
333
+ #: identifier -- insufficient since we must distinguish between type
334
+ # names and var names (otherwise we have a conflict)
335
+ : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)}
336
+
337
+ # Returns Expression
338
+ initializer
339
+ : assignment_expression {result = val[0]}
340
+ | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
341
+ | LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
342
+
343
+ # Returns NodeArray[MemberInit]
344
+ initializer_list
345
+ : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]}
346
+ | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]}
347
+ | initializer_list COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
348
+ | initializer_list COMMA initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])}
349
+
350
+ # Returns {Pos, NodeArray[Expression|Token]}
351
+ designation
352
+ : designator_list EQ {result = val[0]}
353
+
354
+ # Returns {Pos, NodeArray[Expression|Token]}
355
+ designator_list
356
+ : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]}
357
+ | designator_list designator {result = val[0]; val[0][1] << val[1][1]}
358
+
359
+ # Returns {Pos, Expression|Member}
360
+ designator
361
+ : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
362
+ | DOT identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]}
363
+
364
+ # A.2.1 Expressions
365
+
366
+ # Returns Expression
367
+ primary_expression
368
+ : identifier {result = Variable.new_at(val[0].pos, val[0].val)}
369
+ | constant {result = val[0]}
370
+ | string_literal {result = val[0]}
371
+ # GCC EXTENSION: allow a compound statement in parentheses as an expression
372
+ | LPAREN expression RPAREN {result = val[1]}
373
+ | LPAREN compound_statement RPAREN {block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected"
374
+ result = BlockExpression.new(val[1]); result.pos = val[0].pos}
375
+
376
+ # Returns Expression
377
+ postfix_expression
378
+ : primary_expression {result = val[0]}
379
+ | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])}
380
+ | postfix_expression LPAREN argument_expression_list RPAREN {result = Call .new_at(val[0].pos, val[0], val[2] )}
381
+ | postfix_expression LPAREN RPAREN {result = Call .new_at(val[0].pos, val[0], NodeArray[])}
382
+ | postfix_expression DOT identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))}
383
+ | postfix_expression ARROW identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))}
384
+ | postfix_expression INC {result = PostInc .new_at(val[0].pos, val[0] )}
385
+ | postfix_expression DEC {result = PostDec .new_at(val[0].pos, val[0] )}
386
+ | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
387
+ | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
388
+
389
+ # Returns [Expression|Type]
390
+ argument_expression_list
391
+ : argument_expression {result = NodeArray[val[0]]}
392
+ | argument_expression_list COMMA argument_expression {result = val[0] << val[2]}
393
+
394
+ # Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1])
395
+ argument_expression
396
+ : assignment_expression {result = val[0]}
397
+ | type_name {result = val[0]}
398
+
399
+ # Returns Expression
400
+ unary_expression
401
+ : postfix_expression {result = val[0]}
402
+ | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
403
+ | DEC unary_expression {result = PreDec.new_at(val[0].pos, val[1])}
404
+ | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
405
+ | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
406
+ | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
407
+
408
+ # Returns [Class, Pos]
409
+ unary_operator
410
+ : AND {result = [Address , val[0].pos]}
411
+ | MUL {result = [Dereference, val[0].pos]}
412
+ | ADD {result = [Positive , val[0].pos]}
413
+ | SUB {result = [Negative , val[0].pos]}
414
+ | NOT {result = [BitNot , val[0].pos]}
415
+ | BANG {result = [Not , val[0].pos]}
416
+
417
+ # Returns Expression
418
+ cast_expression
419
+ : unary_expression {result = val[0]}
420
+ | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
421
+
422
+ # Returns Expression
423
+ multiplicative_expression
424
+ : cast_expression {result = val[0]}
425
+ | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
426
+ | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
427
+ | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
428
+
429
+ # Returns Expression
430
+ additive_expression
431
+ : multiplicative_expression {result = val[0]}
432
+ | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
433
+ | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
434
+
435
+ # Returns Expression
436
+ shift_expression
437
+ : additive_expression {result = val[0]}
438
+ | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
439
+ | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
440
+
441
+ # Returns Expression
442
+ relational_expression
443
+ : shift_expression {result = val[0]}
444
+ | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
445
+ | relational_expression GT shift_expression {result = More.new_at(val[0].pos, val[0], val[2])}
446
+ | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
447
+ | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
448
+
449
+ # Returns Expression
450
+ equality_expression
451
+ : relational_expression {result = val[0]}
452
+ | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
453
+ | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
454
+
455
+ # Returns Expression
456
+ and_expression
457
+ : equality_expression {result = val[0]}
458
+ | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
459
+
460
+ # Returns Expression
461
+ exclusive_or_expression
462
+ : and_expression {result = val[0]}
463
+ | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
464
+
465
+ # Returns Expression
466
+ inclusive_or_expression
467
+ : exclusive_or_expression {result = val[0]}
468
+ | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
469
+
470
+ # Returns Expression
471
+ logical_and_expression
472
+ : inclusive_or_expression {result = val[0]}
473
+ | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
474
+
475
+ # Returns Expression
476
+ logical_or_expression
477
+ : logical_and_expression {result = val[0]}
478
+ | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
479
+
480
+ # Returns Expression
481
+ conditional_expression
482
+ : logical_or_expression {result = val[0]}
483
+ | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
484
+
485
+ # Returns Expression
486
+ assignment_expression
487
+ : conditional_expression {result = val[0]}
488
+ | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
489
+
490
+ # Returns Class
491
+ assignment_operator
492
+ : EQ {result = Assign}
493
+ | MULEQ {result = MultiplyAssign}
494
+ | DIVEQ {result = DivideAssign}
495
+ | MODEQ {result = ModAssign}
496
+ | ADDEQ {result = AddAssign}
497
+ | SUBEQ {result = SubtractAssign}
498
+ | LSHIFTEQ {result = ShiftLeftAssign}
499
+ | RSHIFTEQ {result = ShiftRightAssign}
500
+ | ANDEQ {result = BitAndAssign}
501
+ | XOREQ {result = BitXorAssign}
502
+ | OREQ {result = BitOrAssign}
503
+
504
+ # Returns Expression
505
+ expression
506
+ : assignment_expression {result = val[0]}
507
+ | expression COMMA assignment_expression {
508
+ if val[0].is_a? Comma
509
+ if val[2].is_a? Comma
510
+ val[0].exprs.push(*val[2].exprs)
511
+ else
512
+ val[0].exprs << val[2]
513
+ end
514
+ result = val[0]
515
+ else
516
+ if val[2].is_a? Comma
517
+ val[2].exprs.unshift(val[0])
518
+ val[2].pos = val[0].pos
519
+ result = val[2]
520
+ else
521
+ result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
522
+ end
523
+ end
524
+ }
525
+
526
+ # Returns Expression
527
+ constant_expression
528
+ : conditional_expression {result = val[0]}
529
+
530
+ # A.1.1 -- Lexical elements
531
+ #
532
+ # token
533
+ # : keyword (raw string)
534
+ # | identifier expanded below
535
+ # | constant expanded below
536
+ # | string_literal expanded below
537
+ # | punctuator (raw string)
538
+ #
539
+ # preprocessing-token (skip)
540
+
541
+ # Returns Token
542
+ identifier
543
+ : ID {result = val[0]}
544
+
545
+ # Returns Literal
546
+ constant
547
+ : ICON {result = val[0].val; result.pos = val[0].pos}
548
+ | FCON {result = val[0].val; result.pos = val[0].pos}
549
+ #| enumeration_constant -- these are parsed as identifiers at all
550
+ # places the `constant' nonterminal appears
551
+ | CCON {result = val[0].val; result.pos = val[0].pos}
552
+
553
+ # Returns Token
554
+ enumeration_constant
555
+ : ID {result = val[0]}
556
+
557
+ # Returns StringLiteral
558
+ # Also handles string literal concatenation (6.4.5.4)
559
+ string_literal
560
+ : string_literal SCON {val[0].val << val[1].val.val; result = val[0]}
561
+ | SCON { result = val[0].val; result.pos = val[0].pos }
562
+
563
+ ---- inner
564
+ # A.1.9 -- Preprocessing numbers -- skip
565
+ # A.1.8 -- Header names -- skip
566
+
567
+ # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
568
+ # we don't do preprocessing
569
+ @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
570
+ @@digraphs = %r'<[:%]|[:%]>'
571
+
572
+ # A.1.6 -- String Literals -- simple for us because we don't decode
573
+ # the string (and indeed accept some illegal strings)
574
+ @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
575
+
576
+ # A.1.5 -- Constants
577
+ @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
578
+ @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
579
+
580
+ @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
581
+ @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
582
+ @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
583
+ @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
584
+ # (note that as with string-literals, we accept some illegal
585
+ # character-constants)
586
+
587
+ # A.1.4 -- Universal character names -- skip
588
+
589
+ # A.1.3 -- Identifiers -- skip, since an identifier is lexically
590
+ # identical to an enumeration constant
591
+
592
+ # A.1.2 Keywords
593
+ keywords = %w'auto break case char const continue default do
594
+ double else enum extern float for goto if inline int long register
595
+ restrict return short signed sizeof static struct switch typedef union
596
+ unsigned void volatile while _Bool _Complex _Imaginary'
597
+ @@keywords = %r"#{keywords.join('|')}"
598
+
599
+ def initialize
600
+ @type_names = ::Set.new
601
+
602
+ @warning_proc = lambda{}
603
+ @pos = C::Node::Pos.new(nil, 1, 0)
604
+ end
605
+ def initialize_copy(x)
606
+ @pos = x.pos.dup
607
+ @type_names = x.type_names.dup
608
+ end
609
+ attr_accessor :pos, :type_names
610
+
611
+ def parse(str)
612
+ if str.respond_to? :read
613
+ str = str.read
614
+ end
615
+ @str = str
616
+ begin
617
+ prepare_lexer(str)
618
+ return do_parse
619
+ rescue ParseError => e
620
+ e.set_backtrace(caller)
621
+ raise
622
+ end
623
+ end
624
+
625
+ #
626
+ # Error handler, as used by racc.
627
+ #
628
+ def on_error(error_token_id, error_value, value_stack)
629
+ if error_value == '$'
630
+ parse_error @pos, "unexpected EOF"
631
+ else
632
+ parse_error(error_value.pos,
633
+ "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
634
+ end
635
+ end
636
+
637
+ def self.feature(name)
638
+ attr_writer "#{name}_enabled"
639
+ class_eval <<-EOS
640
+ def enable_#{name}
641
+ @#{name}_enabled = true
642
+ end
643
+ def #{name}_enabled?
644
+ @#{name}_enabled
645
+ end
646
+ EOS
647
+ end
648
+ private_class_method :feature
649
+
650
+ #
651
+ # Allow blocks in parentheses as expressions, as per the gcc
652
+ # extension. [http://rubyurl.com/iB7]
653
+ #
654
+ feature :block_expressions
655
+
656
+ private # ---------------------------------------------------------
657
+
658
+ class Token
659
+ attr_accessor :pos, :val
660
+ def initialize(pos, val)
661
+ @pos = pos
662
+ @val = val
663
+ end
664
+ end
665
+ def eat(str)
666
+ lines = str.split(/\r\n|[\r\n]/, -1)
667
+ if lines.length == 1
668
+ @pos.col_num += lines[0].length
669
+ else
670
+ @pos.line_num += lines.length - 1
671
+ @pos.col_num = lines[-1].length
672
+ end
673
+ end
674
+
675
+ #
676
+ # Make a Declaration from the given specs and declarators.
677
+ #
678
+ def make_declaration(pos, specs, declarators)
679
+ specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
680
+ decl = Declaration.new_at(pos, nil, declarators)
681
+
682
+ # set storage class
683
+ storage_classes = specs.find_all do |x|
684
+ [:typedef, :extern, :static, :auto, :register].include? x
685
+ end
686
+ # 6.7.1p2: at most, one storage-class specifier may be given in
687
+ # the declaration specifiers in a declaration
688
+ storage_classes.length <= 1 or
689
+ begin
690
+ if declarators.length == 0
691
+ for_name = ''
692
+ else
693
+ for_name = "for `#{declarators[0].name}'"
694
+ end
695
+ parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
696
+ end
697
+ decl.storage = storage_classes[0]
698
+
699
+ # set type (specifiers, qualifiers)
700
+ decl.type = make_direct_type(pos, specs)
701
+
702
+ # set function specifiers
703
+ decl.inline = specs.include?(:inline)
704
+
705
+ # look for new type names
706
+ if decl.typedef?
707
+ decl.declarators.each do |d|
708
+ if d.name
709
+ @type_names << d.name
710
+ end
711
+ end
712
+ end
713
+
714
+ return decl
715
+ end
716
+
717
+ def make_function_def(pos, specs, func_declarator, decl_list, defn)
718
+ add_decl_type(func_declarator, make_direct_type(pos, specs))
719
+
720
+ # get types from decl_list if necessary
721
+ function = func_declarator.indirect_type
722
+ function.is_a? Function or
723
+ parse_error pos, "non function type for function `#{func_declarator.name}'"
724
+ params = function.params
725
+ if decl_list
726
+ params.all?{|p| p.type.nil?} or
727
+ parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
728
+ decl_list.each do |declaration|
729
+ declaration.declarators.each do |declarator|
730
+ param = params.find{|p| p.name == declarator.name} or
731
+ parse_error pos, "no parameter named #{declarator.name}"
732
+ if declarator.indirect_type
733
+ param.type = declarator.indirect_type
734
+ param.type.direct_type = declaration.type.dup
735
+ else
736
+ param.type = declaration.type.dup
737
+ end
738
+ end
739
+ end
740
+ params.all?{|p| p.type} or
741
+ begin
742
+ s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
743
+ parse_error pos, "types missing for parameters #{s}"
744
+ end
745
+ end
746
+
747
+ fd = FunctionDef.new_at(pos,
748
+ function.detach,
749
+ func_declarator.name,
750
+ defn,
751
+ :no_prototype => !decl_list.nil?)
752
+
753
+ # set storage class
754
+ # 6.9.1p4: only extern or static allowed
755
+ specs.each do |s|
756
+ [:typedef, :auto, :register].include?(s) and
757
+ "`#{s}' illegal for function"
758
+ end
759
+ storage_classes = specs.find_all do |s|
760
+ s == :extern || s == :static
761
+ end
762
+ # 6.7.1p2: at most, one storage-class specifier may be given in
763
+ # the declaration specifiers in a declaration
764
+ storage_classes.length <= 1 or
765
+ "multiple or duplicate storage classes given for `#{func_declarator.name}'"
766
+ fd.storage = storage_classes[0] if storage_classes[0]
767
+
768
+ # set function specifiers
769
+ # 6.7.4p5 'inline' can be repeated
770
+ fd.inline = specs.include?(:inline)
771
+
772
+ return fd
773
+ end
774
+
775
+ #
776
+ # Make a direct type from the list of type specifiers and type
777
+ # qualifiers.
778
+ #
779
+ def make_direct_type(pos, specs)
780
+ specs_order = [:signed, :unsigned, :short, :long, :double, :void,
781
+ :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
782
+
783
+ type_specs = specs.find_all do |x|
784
+ specs_order.include?(x) || !x.is_a?(Symbol)
785
+ end
786
+ type_specs.sort! do |a, b|
787
+ (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
788
+ end
789
+
790
+ # set type specifiers
791
+ # 6.7.2p2: the specifier list should be one of these
792
+ type =
793
+ case type_specs
794
+ when [:void]
795
+ Void.new
796
+ when [:char]
797
+ Char.new
798
+ when [:signed, :char]
799
+ Char.new :signed => true
800
+ when [:unsigned, :char]
801
+ Char.new :signed => false
802
+ when [:short], [:signed, :short], [:short, :int],
803
+ [:signed, :short, :int]
804
+ Int.new :longness => -1
805
+ when [:unsigned, :short], [:unsigned, :short, :int]
806
+ Int.new :unsigned => true, :longness => -1
807
+ when [:int], [:signed], [:signed, :int]
808
+ Int.new
809
+ when [:unsigned], [:unsigned, :int]
810
+ Int.new :unsigned => true
811
+ when [:long], [:signed, :long], [:long, :int],
812
+ [:signed, :long, :int]
813
+ Int.new :longness => 1
814
+ when [:unsigned, :long], [:unsigned, :long, :int]
815
+ Int.new :longness => 1, :unsigned => true
816
+ when [:long, :long], [:signed, :long, :long],
817
+ [:long, :long, :int], [:signed, :long, :long, :int]
818
+ Int.new :longness => 2
819
+ when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
820
+ Int.new :longness => 2, :unsigned => true
821
+ when [:float]
822
+ Float.new
823
+ when [:double]
824
+ Float.new :longness => 1
825
+ when [:long, :double]
826
+ Float.new :longness => 2
827
+ when [:_Bool]
828
+ Bool.new
829
+ when [:float, :_Complex]
830
+ Complex.new
831
+ when [:double, :_Complex]
832
+ Complex.new :longness => 1
833
+ when [:long, :double, :_Complex]
834
+ Complex.new :longness => 2
835
+ when [:float, :_Imaginary]
836
+ Imaginary.new
837
+ when [:double, :_Imaginary]
838
+ Imaginary.new :longness => 1
839
+ when [:long, :double, :_Imaginary]
840
+ Imaginary.new :longness => 2
841
+ else
842
+ if type_specs.length == 1 &&
843
+ [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
844
+ type_specs[0]
845
+ else
846
+ if type_specs == []
847
+ parse_error pos, "no type specifiers given"
848
+ else
849
+ parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
850
+ end
851
+ end
852
+ end
853
+ type.pos ||= pos
854
+
855
+ # set type qualifiers
856
+ # 6.7.3p4: type qualifiers can be repeated
857
+ type.const = specs.any?{|x| x.equal? :const }
858
+ type.restrict = specs.any?{|x| x.equal? :restrict}
859
+ type.volatile = specs.any?{|x| x.equal? :volatile}
860
+
861
+ return type
862
+ end
863
+
864
+ def make_parameter(pos, specs, indirect_type, name)
865
+ type = indirect_type
866
+ if type
867
+ type.direct_type = make_direct_type(pos, specs)
868
+ else
869
+ type = make_direct_type(pos, specs)
870
+ end
871
+ [:typedef, :extern, :static, :auto, :inline].each do |sym|
872
+ specs.include? sym and
873
+ parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
874
+ end
875
+ return Parameter.new_at(pos, type, name,
876
+ :register => specs.include?(:register))
877
+ end
878
+
879
+ def add_type_quals(type, quals)
880
+ type.const = quals.include?(:const )
881
+ type.restrict = quals.include?(:restrict)
882
+ type.volatile = quals.include?(:volatile)
883
+ return type
884
+ end
885
+
886
+ #
887
+ # Add te given type as the "most direct" type to the given
888
+ # declarator. Return the declarator.
889
+ #
890
+ def add_decl_type(declarator, type)
891
+ if declarator.indirect_type
892
+ declarator.indirect_type.direct_type = type
893
+ else
894
+ declarator.indirect_type = type
895
+ end
896
+ return declarator
897
+ end
898
+
899
+ def param_list(params, var_args)
900
+ if params.length == 1 &&
901
+ params[0].type.is_a?(Void) &&
902
+ params[0].name.nil?
903
+ return NodeArray[]
904
+ elsif params.empty?
905
+ return nil
906
+ else
907
+ return params
908
+ end
909
+ end
910
+
911
+ def parse_error(pos, str)
912
+ raise ParseError, "#{pos}: #{str}"
913
+ end
914
+
915
+ ---- header
916
+
917
+ require 'set'
918
+
919
+ # Error classes
920
+ module C
921
+ class ParseError < StandardError; end
922
+ end
923
+
924
+ # Local variables:
925
+ # mode: ruby
926
+ # end: