mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
re-wrote pidl to use Parse::Yapp instead of Parse::RecDescent, This
makes pidl about 3x faster, and also gives us much better error
reporting and a more standard grammer definition that will be much
easier to code in lex/yacc if we want to do so at a later
date. (Parse::Yapp uses essentially the same grammer file as lex/yacc)
It also means we no longer need Parse::RecDescent, which should make
pidl much more portable.
(This used to be commit 4bbaffeb44
)
This commit is contained in:
parent
e10859fd0a
commit
55d2c54e03
@ -1,5 +1,5 @@
|
||||
idl.pm: idl.gram
|
||||
perl -Ilib -MParse::RecDescent - idl.gram idl
|
||||
idl.pm: idl.yp
|
||||
yapp idl.yp
|
||||
|
||||
clean:
|
||||
rm -f idl.pm
|
||||
|
307
source4/build/pidl/idl.yp
Normal file
307
source4/build/pidl/idl.yp
Normal file
@ -0,0 +1,307 @@
|
||||
########################
|
||||
# IDL Parse::Yapp parser
|
||||
# Copyright (C) Andrew Tridgell <tridge@samba.org>
|
||||
# released under the GNU GPL version 2 or later
|
||||
|
||||
|
||||
|
||||
################
|
||||
# grammer
|
||||
%%
|
||||
idl: idl_interface
|
||||
| idl idl_interface { util::FlattenArray([$_[1],$_[2]]) }
|
||||
;
|
||||
|
||||
idl_interface: module_header interface { [ $_[1], $_[2] ] }
|
||||
;
|
||||
|
||||
module_header: '[' module_params ']'
|
||||
{{
|
||||
"TYPE" => "MODULEHEADER",
|
||||
"PROPERTIES" => util::FlattenHash($_[2])
|
||||
}}
|
||||
;
|
||||
|
||||
module_params:
|
||||
#empty
|
||||
| module_param { [ $_[1] ] }
|
||||
| module_params ',' module_param { push(@{$_[1]}, $_[3]); $_[1] }
|
||||
;
|
||||
|
||||
module_param: identifier '(' listtext ')'
|
||||
{ { "$_[1]" => "$_[3]" } }
|
||||
;
|
||||
|
||||
interface: 'interface' identifier '{' definitions '}'
|
||||
{{
|
||||
"TYPE" => "INTERFACE",
|
||||
"NAME" => $_[2],
|
||||
"DATA" => $_[4]
|
||||
}}
|
||||
;
|
||||
|
||||
definitions:
|
||||
definition { [ $_[1] ] }
|
||||
| definitions definition { push(@{$_[1]}, $_[2]); $_[1] }
|
||||
;
|
||||
|
||||
|
||||
definition: function | const | typedef
|
||||
;
|
||||
|
||||
const: 'const' identifier identifier '=' anytext ';'
|
||||
{{
|
||||
"TYPE" => "CONST",
|
||||
"DTYPE" => $_[2],
|
||||
"NAME" => $_[3],
|
||||
"VALUE" => $_[5]
|
||||
}}
|
||||
;
|
||||
|
||||
|
||||
function: property_list type identifier '(' element_list2 ')' ';'
|
||||
{{
|
||||
"TYPE" => "FUNCTION",
|
||||
"NAME" => $_[3],
|
||||
"RETURN_TYPE" => $_[2],
|
||||
"PROPERTIES" => $_[1],
|
||||
"DATA" => $_[5]
|
||||
}}
|
||||
;
|
||||
|
||||
typedef: 'typedef' type identifier array_len ';'
|
||||
{{
|
||||
"TYPE" => "TYPEDEF",
|
||||
"NAME" => $_[3],
|
||||
"DATA" => $_[2],
|
||||
"ARRAY_LEN" => $_[4]
|
||||
}}
|
||||
;
|
||||
|
||||
type: struct | union | enum | identifier
|
||||
| void { "void" }
|
||||
;
|
||||
|
||||
|
||||
enum: 'enum' '{' enum_elements '}'
|
||||
{{
|
||||
"TYPE" => "ENUM",
|
||||
"ELEMENTS" => $_[3]
|
||||
}}
|
||||
;
|
||||
|
||||
enum_elements:
|
||||
enum_element { [ $_[1] ] }
|
||||
| enum_elements ',' enum_element { push(@{$_[1]}, $_[3]); $_[1] }
|
||||
;
|
||||
|
||||
enum_element: identifier
|
||||
| identifier '=' anytext { "$_[1]$_[2]$_[3]" }
|
||||
;
|
||||
|
||||
struct: property_list 'struct' '{' element_list1 '}'
|
||||
{{
|
||||
"TYPE" => "STRUCT",
|
||||
"PROPERTIES" => $_[1],
|
||||
"ELEMENTS" => $_[4]
|
||||
}}
|
||||
;
|
||||
|
||||
union: property_list 'union' '{' union_elements '}'
|
||||
{{
|
||||
"TYPE" => "UNION",
|
||||
"PROPERTIES" => $_[1],
|
||||
"DATA" => $_[4]
|
||||
}}
|
||||
;
|
||||
|
||||
union_elements:
|
||||
union_element { [ $_[1] ] }
|
||||
| union_elements union_element { push(@{$_[1]}, $_[2]); $_[1] }
|
||||
;
|
||||
|
||||
union_element:
|
||||
'[' 'case' '(' anytext ')' ']' base_element ';'
|
||||
{{
|
||||
"TYPE" => "UNION_ELEMENT",
|
||||
"CASE" => $_[4],
|
||||
"DATA" => $_[7]
|
||||
}}
|
||||
| '[' 'case' '(' anytext ')' ']' ';'
|
||||
{{
|
||||
"TYPE" => "EMPTY",
|
||||
"CASE" => $_[4],
|
||||
}}
|
||||
| '[' 'default' ']' base_element ';'
|
||||
{{
|
||||
"TYPE" => "UNION_ELEMENT",
|
||||
"CASE" => "default",
|
||||
"DATA" => $_[4]
|
||||
}}
|
||||
| '[' 'default' ']' ';'
|
||||
{{
|
||||
"TYPE" => "EMPTY",
|
||||
"CASE" => "default",
|
||||
}}
|
||||
;
|
||||
|
||||
base_element: property_list type pointers identifier array_len
|
||||
{{
|
||||
"NAME" => $_[4],
|
||||
"TYPE" => $_[2],
|
||||
"PROPERTIES" => $_[1],
|
||||
"POINTERS" => $_[3],
|
||||
"ARRAY_LEN" => $_[5]
|
||||
}}
|
||||
;
|
||||
|
||||
|
||||
pointers:
|
||||
#empty
|
||||
{ 0 }
|
||||
| pointers '*' { $_[1]+1 }
|
||||
;
|
||||
|
||||
|
||||
|
||||
element_list1:
|
||||
#empty
|
||||
| base_element ';' { [ $_[1] ] }
|
||||
| element_list1 base_element ';' { push(@{$_[1]}, $_[2]); $_[1] }
|
||||
;
|
||||
|
||||
element_list2:
|
||||
#empty
|
||||
| 'void'
|
||||
| base_element { [ $_[1] ] }
|
||||
| element_list2 ',' base_element { push(@{$_[1]}, $_[3]); $_[1] }
|
||||
;
|
||||
|
||||
array_len:
|
||||
#empty
|
||||
| '[' ']' { "*" }
|
||||
| '[' '*' ']' { "*" }
|
||||
| '[' anytext ']' { "$_[2]" }
|
||||
;
|
||||
|
||||
|
||||
property_list:
|
||||
#empty
|
||||
| '[' properties ']' { $_[2] }
|
||||
| property_list '[' properties ']' { util::FlattenArray([$_[1],$_[3]]); }
|
||||
;
|
||||
|
||||
properties: property { [ $_[1] ] }
|
||||
| properties ',' property { push(@{$_[1]}, $_[3]); $_[1] }
|
||||
;
|
||||
|
||||
property: identifier
|
||||
| identifier '(' anytext ')' {{ "$_[1]" => "$_[3]" }}
|
||||
;
|
||||
|
||||
listtext:
|
||||
anytext
|
||||
| listtext ',' anytext { "$_[1] $_[3]" }
|
||||
;
|
||||
|
||||
anytext: #empty
|
||||
{ "" }
|
||||
| identifier | constant | text
|
||||
| anytext '-' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '.' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '*' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '>' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '|' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '&' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '/' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '+' anytext { "$_[1]$_[2]$_[3]" }
|
||||
| anytext '(' anytext ')' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
|
||||
;
|
||||
|
||||
identifier: IDENTIFIER
|
||||
;
|
||||
|
||||
constant: CONSTANT
|
||||
;
|
||||
|
||||
text: TEXT { "\"$_[1]\"" }
|
||||
;
|
||||
|
||||
|
||||
#####################################
|
||||
# start code
|
||||
%%
|
||||
|
||||
use util;
|
||||
|
||||
sub _Error {
|
||||
if (exists $_[0]->YYData->{ERRMSG}) {
|
||||
print $_[0]->YYData->{ERRMSG};
|
||||
delete $_[0]->YYData->{ERRMSG};
|
||||
return;
|
||||
};
|
||||
my $line = $_[0]->YYData->{LINE};
|
||||
my $last_token = $_[0]->YYData->{LAST_TOKEN};
|
||||
my $file = $_[0]->YYData->{INPUT_FILENAME};
|
||||
|
||||
print "Syntax error at $file:$line near '$last_token'\n";
|
||||
}
|
||||
|
||||
sub _Lexer {
|
||||
my($parser)=shift;
|
||||
|
||||
$parser->YYData->{INPUT}
|
||||
or return('',undef);
|
||||
|
||||
again:
|
||||
$parser->YYData->{INPUT} =~ s/^[ \t]*//;
|
||||
|
||||
for ($parser->YYData->{INPUT}) {
|
||||
if (s/^\# (\d+) \"(.*?)\"( \d+|)//) {
|
||||
$parser->YYData->{LINE} = $1;
|
||||
$parser->YYData->{INPUT_FILENAME} = $2;
|
||||
goto again;
|
||||
}
|
||||
if (s/^(\n)//) {
|
||||
$parser->YYData->{LINE}++;
|
||||
goto again;
|
||||
}
|
||||
if (s/^\"(.*?)\"//) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return('TEXT',$1);
|
||||
}
|
||||
if (s/^(\d+)(\W|$)/$2/) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return('CONSTANT',$1);
|
||||
}
|
||||
if (s/^([\w_]+)//) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
if ($1 =~
|
||||
/^(interface|const|typedef|union
|
||||
|struct|enum|void|case|default)$/x) {
|
||||
return $1;
|
||||
}
|
||||
return('IDENTIFIER',$1);
|
||||
}
|
||||
if (s/^(.)//s) {
|
||||
$parser->YYData->{LAST_TOKEN} = $1;
|
||||
return($1,$1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_idl($$)
|
||||
{
|
||||
my $self = shift;
|
||||
my $filename = shift;
|
||||
|
||||
my $saved_delim = $/;
|
||||
undef $/;
|
||||
my $data = `cpp $filename`;
|
||||
$/ = $saved_delim;
|
||||
|
||||
$self->YYData->{INPUT} = $data;
|
||||
$self->YYData->{LINE} = 0;
|
||||
$self->YYData->{LAST_TOKEN} = "NONE";
|
||||
return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +0,0 @@
|
||||
Many thanks to Damian Conway for his excellent Parse::Recdescent
|
||||
package. I have included a copy of it here to prevent problems with
|
||||
differing versions and pidl. The original package is distributed with
|
||||
the following copyright:
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
Copyright (c) 1997-2000, Damian Conway. All Rights Reserved.
|
||||
This module is free software. It may be used, redistributed
|
||||
and/or modified under the terms of the Perl Artistic License
|
||||
(see http://www.perl.com/perl/misc/Artistic.html)
|
@ -31,23 +31,14 @@ my($opt_eparser) = 0;
|
||||
my($opt_keep) = 0;
|
||||
my($opt_output);
|
||||
|
||||
my $idl_parser = new idl;
|
||||
|
||||
#####################################################################
|
||||
# parse an IDL file returning a structure containing all the data
|
||||
sub IdlParse($)
|
||||
{
|
||||
# this autoaction allows us to handle simple nodes without an action
|
||||
# $::RD_TRACE = 1;
|
||||
$::RD_AUTOACTION = q {
|
||||
$#item==1 && ref($item[1]) eq "" ?
|
||||
$item[1] :
|
||||
"XX_" . $item[0] . "_XX[$#item]" };
|
||||
my($filename) = shift;
|
||||
my($parser) = idl->new;
|
||||
my($saved_sep) = $/;
|
||||
|
||||
undef $/;
|
||||
my($idl) = $parser->idl(`cpp $filename | grep -v '^#'`);
|
||||
$/ = $saved_sep;
|
||||
my $filename = shift;
|
||||
my $idl = $idl_parser->parse_idl($filename);
|
||||
util::CleanData($idl);
|
||||
return $idl;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
[ uuid(12345778-1234-abcd-ef00-0123456789ab),
|
||||
version(0.0),
|
||||
endpoints(lsarpc lsass),
|
||||
endpoints(lsarpc,lsass),
|
||||
pointer_default(unique)
|
||||
] interface lsarpc
|
||||
{
|
||||
@ -449,7 +449,7 @@
|
||||
|
||||
|
||||
[
|
||||
uuid(3919286a-b10c-11d0-9ba8-00c04fd92ef5)
|
||||
uuid(3919286a-b10c-11d0-9ba8-00c04fd92ef5),
|
||||
version(0.0),
|
||||
endpoints(lsarpc,lsass),
|
||||
pointer_default(unique)
|
||||
@ -459,6 +459,6 @@ interface lsads
|
||||
|
||||
/*****************/
|
||||
/* Function 0x00 */
|
||||
lsads_Unknown0();
|
||||
void lsads_Unknown0();
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
[
|
||||
uuid(8fb6d884-2388-11d0-8c35-00c04fda2795),
|
||||
endpoints(srvsvc atsvc browser keysvc wkssvc),
|
||||
endpoints(srvsvc,atsvc,browser,keysvc,wkssvc),
|
||||
version(4.1)
|
||||
]
|
||||
interface w32time
|
||||
|
Loading…
Reference in New Issue
Block a user