siahsd/pidl/expr.yp
Wilco Baan Hofman ad758df90b Add pidl. Add preliminary work on SecIP.
Please note that the Alphatronics implementation does not follow the Vebon specification.
An extra padding byte had to be added to the idl..
2012-08-01 03:30:50 +02:00

202 lines
3.7 KiB
Text

# expr.yp
# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
# Published under the GNU GPL
#
%left '->'
%right '!' '~'
%left '*' '/' '%'
%left '+' '-'
%left '<<' '>>'
%left '>' '<'
%left '==' '!='
%left '&'
%left '|'
%left '&&'
%left '||'
%left '?' ':'
%left NEG DEREF ADDROF INV
%left '.'
%%
exp:
NUM
|
TEXT { "\"$_[1]\"" }
|
func
|
var
|
'~' exp %prec INV { "~$_[2]" }
|
exp '+' exp { "$_[1] + $_[3]" }
|
exp '-' exp { "$_[1] - $_[3]" }
|
exp '*' exp { "$_[1] * $_[3]" }
|
exp '%' exp { "$_[1] % $_[3]" }
|
exp '<' exp { "$_[1] < $_[3]" }
|
exp '>' exp { "$_[1] > $_[3]" }
|
exp '|' exp { "$_[1] | $_[3]" }
|
exp '==' exp { "$_[1] == $_[3]" }
|
exp '<=' exp { "$_[1] <= $_[3]" }
|
exp '=>' exp { "$_[1] => $_[3]" }
|
exp '<<' exp { "$_[1] << $_[3]" }
|
exp '>>' exp { "$_[1] >> $_[3]" }
|
exp '!=' exp { "$_[1] != $_[3]" }
|
exp '||' exp { "$_[1] || $_[3]" }
|
exp '&&' exp { "$_[1] && $_[3]" }
|
exp '&' exp { "$_[1] & $_[3]" }
|
exp '?' exp ':' exp { "$_[1]?$_[3]:$_[5]" }
|
'~' exp { "~$_[1]" }
|
'!' exp { "not $_[1]" }
|
exp '/' exp { "$_[1] / $_[3]" }
|
'-' exp %prec NEG { "-$_[2]" }
|
'&' exp %prec ADDROF { "&$_[2]" }
|
exp '^' exp { "$_[1]^$_[3]" }
|
'(' exp ')' { "($_[2])" }
;
possible_pointer:
VAR { $_[0]->_Lookup($_[1]) }
|
'*' possible_pointer %prec DEREF { $_[0]->_Dereference($_[2]); "*$_[2]" }
;
var:
possible_pointer { $_[0]->_Use($_[1]) }
|
var '.' VAR { $_[0]->_Use("$_[1].$_[3]") }
|
'(' var ')' { "($_[2])" }
|
var '->' VAR { $_[0]->_Use("*$_[1]"); $_[1]."->".$_[3] }
;
func:
VAR '(' opt_args ')' { "$_[1]($_[3])" }
;
opt_args:
#empty
{ "" }
|
args
;
exp_or_possible_pointer:
exp
|
possible_pointer
;
args:
exp_or_possible_pointer
|
exp_or_possible_pointer ',' args { "$_[1], $_[3]" }
;
%%
package Parse::Pidl::Expr;
sub _Lexer {
my($parser)=shift;
$parser->YYData->{INPUT}=~s/^[ \t]//;
for ($parser->YYData->{INPUT}) {
if (s/^(0x[0-9A-Fa-f]+)//) {
$parser->YYData->{LAST_TOKEN} = $1;
return('NUM',$1);
}
if (s/^([0-9]+(?:\.[0-9]+)?)//) {
$parser->YYData->{LAST_TOKEN} = $1;
return('NUM',$1);
}
if (s/^([A-Za-z_][A-Za-z0-9_]*)//) {
$parser->YYData->{LAST_TOKEN} = $1;
return('VAR',$1);
}
if (s/^\"(.*?)\"//) {
$parser->YYData->{LAST_TOKEN} = $1;
return('TEXT',$1);
}
if (s/^(==|!=|<=|>=|->|\|\||<<|>>|&&)//s) {
$parser->YYData->{LAST_TOKEN} = $1;
return($1,$1);
}
if (s/^(.)//s) {
$parser->YYData->{LAST_TOKEN} = $1;
return($1,$1);
}
}
}
sub _Use($$)
{
my ($self, $x) = @_;
if (defined($self->YYData->{USE})) {
return $self->YYData->{USE}->($x);
}
return $x;
}
sub _Lookup($$)
{
my ($self, $x) = @_;
return $self->YYData->{LOOKUP}->($x);
}
sub _Dereference($$)
{
my ($self, $x) = @_;
if (defined($self->YYData->{DEREFERENCE})) {
$self->YYData->{DEREFERENCE}->($x);
}
}
sub _Error($)
{
my ($self) = @_;
if (defined($self->YYData->{LAST_TOKEN})) {
$self->YYData->{ERROR}->("Parse error in `".$self->YYData->{FULL_INPUT}."' near `". $self->YYData->{LAST_TOKEN} . "'");
} else {
$self->YYData->{ERROR}->("Parse error in `".$self->YYData->{FULL_INPUT}."'");
}
}
sub Run {
my($self, $data, $error, $lookup, $deref, $use) = @_;
$self->YYData->{FULL_INPUT} = $data;
$self->YYData->{INPUT} = $data;
$self->YYData->{LOOKUP} = $lookup;
$self->YYData->{DEREFERENCE} = $deref;
$self->YYData->{ERROR} = $error;
$self->YYData->{USE} = $use;
return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error);
}