racc 1.4.14 → 1.4.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) 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/info.rb +2 -2
  7. data/test/assets/bibtex.y +141 -0
  8. data/test/assets/cadenza.y +170 -0
  9. data/test/assets/cast.y +926 -0
  10. data/test/assets/csspool.y +729 -0
  11. data/test/assets/edtf.y +583 -0
  12. data/test/assets/huia.y +318 -0
  13. data/test/assets/journey.y +47 -0
  14. data/test/assets/liquor.y +313 -0
  15. data/test/assets/machete.y +423 -0
  16. data/test/assets/macruby.y +2197 -0
  17. data/test/assets/mediacloth.y +599 -0
  18. data/test/assets/mof.y +649 -0
  19. data/test/assets/namae.y +302 -0
  20. data/test/assets/nasl.y +626 -0
  21. data/test/assets/nokogiri-css.y +255 -0
  22. data/test/assets/opal.y +1807 -0
  23. data/test/assets/php_serialization.y +98 -0
  24. data/test/assets/rdblockparser.y +576 -0
  25. data/test/assets/rdinlineparser.y +561 -0
  26. data/test/assets/riml.y +665 -0
  27. data/test/assets/ruby18.y +1943 -0
  28. data/test/assets/ruby19.y +2174 -0
  29. data/test/assets/ruby20.y +2350 -0
  30. data/test/assets/ruby21.y +2359 -0
  31. data/test/assets/ruby22.y +2381 -0
  32. data/test/assets/tp_plus.y +622 -0
  33. data/test/assets/twowaysql.y +278 -0
  34. data/test/helper.rb +31 -15
  35. data/test/regress/bibtex +474 -0
  36. data/test/regress/cadenza +796 -0
  37. data/test/regress/cast +3425 -0
  38. data/test/regress/csspool +2318 -0
  39. data/test/regress/edtf +1794 -0
  40. data/test/regress/huia +1392 -0
  41. data/test/regress/journey +222 -0
  42. data/test/regress/liquor +885 -0
  43. data/test/regress/machete +833 -0
  44. data/test/regress/mediacloth +1463 -0
  45. data/test/regress/mof +1368 -0
  46. data/test/regress/namae +634 -0
  47. data/test/regress/nasl +2058 -0
  48. data/test/regress/nokogiri-css +836 -0
  49. data/test/regress/opal +6429 -0
  50. data/test/regress/php_serialization +336 -0
  51. data/test/regress/rdblockparser +1061 -0
  52. data/test/regress/rdinlineparser +1243 -0
  53. data/test/regress/riml +3297 -0
  54. data/test/regress/ruby18 +6351 -0
  55. data/test/regress/ruby22 +7456 -0
  56. data/test/regress/tp_plus +1933 -0
  57. data/test/regress/twowaysql +556 -0
  58. data/test/test_racc_command.rb +177 -0
  59. metadata +75 -20
@@ -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: