1 ########################
2 # IDL Parse::Yapp parser
3 # Copyright (C) Andrew Tridgell <tridge@samba.org>
4 # released under the GNU GPL version 2 or later
8 # the precedence actually doesn't matter at all for this grammer, but
9 # by providing a precedence we reduce the number of conflicts
11 %left '-' '+' '&' '|' '*' '>' '.' '/' '(' ')' '[' ',' ';'
19 | idl interface { push(@{$_[1]}, $_[2]); $_[1] }
20 | idl coclass { push(@{$_[1]}, $_[2]); $_[1] }
23 coclass: property_list 'coclass' identifier '{' interface_names '}' optional_semicolon
26 "PROPERTIES" => $_[1],
29 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
30 "LINE" => $_[0]->YYData->{LINE},
36 | interface_names 'interface' identifier ';' { push(@{$_[1]}, $_[2]); $_[1] }
39 interface: property_list 'interface' identifier base_interface '{' definitions '}' optional_semicolon
41 "TYPE" => "INTERFACE",
42 "PROPERTIES" => $_[1],
46 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
47 "LINE" => $_[0]->YYData->{LINE},
53 | ':' identifier { $_[2] }
57 definition { [ $_[1] ] }
58 | definitions definition { push(@{$_[1]}, $_[2]); $_[1] }
62 definition: function | const | typedef | declare
65 const: 'const' identifier identifier '=' anytext ';'
71 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
72 "LINE" => $_[0]->YYData->{LINE},
74 | 'const' identifier identifier array_len '=' anytext ';'
81 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
82 "LINE" => $_[0]->YYData->{LINE},
87 function: property_list type identifier '(' element_list2 ')' ';'
91 "RETURN_TYPE" => $_[2],
92 "PROPERTIES" => $_[1],
94 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
95 "LINE" => $_[0]->YYData->{LINE},
99 declare: 'declare' property_list decl_type identifier';'
102 "PROPERTIES" => $_[2],
105 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
106 "LINE" => $_[0]->YYData->{LINE},
110 decl_type: decl_enum | decl_bitmap
119 decl_bitmap: 'bitmap'
125 typedef: 'typedef' property_list type identifier array_len ';'
128 "PROPERTIES" => $_[2],
131 "ARRAY_LEN" => $_[5],
132 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
133 "LINE" => $_[0]->YYData->{LINE},
137 type: struct | union | enum | bitmap | identifier
142 enum: 'enum' '{' enum_elements '}'
150 enum_element { [ $_[1] ] }
151 | enum_elements ',' enum_element { push(@{$_[1]}, $_[3]); $_[1] }
154 enum_element: identifier
155 | identifier '=' anytext { "$_[1]$_[2]$_[3]" }
158 bitmap: 'bitmap' '{' bitmap_elements '}'
166 bitmap_element { [ $_[1] ] }
167 | bitmap_elements ',' bitmap_element { push(@{$_[1]}, $_[3]); $_[1] }
170 bitmap_element: identifier '=' anytext { "$_[1] ( $_[3] )" }
173 struct: 'struct' '{' element_list1 '}'
180 empty_element: property_list ';'
184 "PROPERTIES" => $_[1],
187 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
188 "LINE" => $_[0]->YYData->{LINE},
192 base_or_empty: base_element ';' | empty_element;
194 optional_base_element:
195 property_list base_or_empty { $_[2]->{PROPERTIES} = util::FlattenHash([$_[1],$_[2]->{PROPERTIES}]); $_[2] }
200 | union_elements optional_base_element { push(@{$_[1]}, $_[2]); $_[1] }
203 union: 'union' '{' union_elements '}'
210 base_element: property_list type pointers identifier array_len
214 "PROPERTIES" => $_[1],
216 "ARRAY_LEN" => $_[5],
217 "FILE" => $_[0]->YYData->{INPUT_FILENAME},
218 "LINE" => $_[0]->YYData->{LINE},
226 | pointers '*' { $_[1]+1 }
231 | element_list1 base_element ';' { push(@{$_[1]}, $_[2]); $_[1] }
237 | base_element { [ $_[1] ] }
238 | element_list2 ',' base_element { push(@{$_[1]}, $_[3]); $_[1] }
243 | '[' ']' array_len { push(@{$_[3]}, "*"); $_[3] }
244 | '[' anytext ']' array_len { push(@{$_[4]}, "$_[2]"); $_[4] }
250 | property_list '[' properties ']' { util::FlattenHash([$_[1],$_[3]]); }
253 properties: property { $_[1] }
254 | properties ',' property { util::FlattenHash([$_[1], $_[3]]); }
257 property: identifier {{ "$_[1]" => "1" }}
258 | identifier '(' listtext ')' {{ "$_[1]" => "$_[3]" }}
263 | listtext ',' anytext { "$_[1] $_[3]" }
268 | commalisttext ',' anytext { "$_[1],$_[3]" }
273 | identifier | constant | text
274 | anytext '-' anytext { "$_[1]$_[2]$_[3]" }
275 | anytext '.' anytext { "$_[1]$_[2]$_[3]" }
276 | anytext '*' anytext { "$_[1]$_[2]$_[3]" }
277 | anytext '>' anytext { "$_[1]$_[2]$_[3]" }
278 | anytext '<' anytext { "$_[1]$_[2]$_[3]" }
279 | anytext '|' anytext { "$_[1]$_[2]$_[3]" }
280 | anytext '&' anytext { "$_[1]$_[2]$_[3]" }
281 | anytext '/' anytext { "$_[1]$_[2]$_[3]" }
282 | anytext '+' anytext { "$_[1]$_[2]$_[3]" }
283 | anytext '~' anytext { "$_[1]$_[2]$_[3]" }
284 | anytext '(' commalisttext ')' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
285 | anytext '{' commalisttext '}' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
288 identifier: IDENTIFIER
294 text: TEXT { "\"$_[1]\"" }
303 #####################################
310 if (exists $_[0]->YYData->{ERRMSG}) {
311 print $_[0]->YYData->{ERRMSG};
312 delete $_[0]->YYData->{ERRMSG};
315 my $line = $_[0]->YYData->{LINE};
316 my $last_token = $_[0]->YYData->{LAST_TOKEN};
317 my $file = $_[0]->YYData->{INPUT_FILENAME};
319 print "$file:$line: Syntax error near '$last_token'\n";
326 $parser->YYData->{INPUT}
330 $parser->YYData->{INPUT} =~ s/^[ \t]*//;
332 for ($parser->YYData->{INPUT}) {
334 if (s/^\# (\d+) \"(.*?)\"( \d+|)//) {
335 $parser->YYData->{LINE} = $1-1;
336 $parser->YYData->{INPUT_FILENAME} = $2;
339 if (s/^\#line (\d+) \"(.*?)\"( \d+|)//) {
340 $parser->YYData->{LINE} = $1-1;
341 $parser->YYData->{INPUT_FILENAME} = $2;
349 $parser->YYData->{LINE}++;
352 if (s/^\"(.*?)\"//) {
353 $parser->YYData->{LAST_TOKEN} = $1;
356 if (s/^(\d+)(\W|$)/$2/) {
357 $parser->YYData->{LAST_TOKEN} = $1;
358 return('CONSTANT',$1);
361 $parser->YYData->{LAST_TOKEN} = $1;
363 /^(coclass|interface|const|typedef|declare|union
364 |struct|enum|bitmap|void)$/x) {
367 return('IDENTIFIER',$1);
370 $parser->YYData->{LAST_TOKEN} = $1;
379 my $filename = shift;
381 my $saved_delim = $/;
384 if (! defined $cpp) {
387 my $data = `$cpp -xc $filename`;
390 $self->YYData->{INPUT} = $data;
391 $self->YYData->{LINE} = 0;
392 $self->YYData->{LAST_TOKEN} = "NONE";
394 my $idl = $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
396 return util::CleanData($idl);