version 1.14, 2005/06/09 02:35:55
|
version 1.18, 2009/02/13 17:20:23
|
Line 1
|
Line 1
|
|
# $Id$ |
|
|
## Last modification: 8/3/00 by akp |
## Last modification: 8/3/00 by akp |
## Originally written by Daniel Martin, Dept of Math, John Hopkins |
## Originally written by Daniel Martin, Dept of Math, John Hopkins |
Line 39 $close{'('} = ')';
|
Line 39 $close{'('} = ')';
|
|
|
my $binoper3 = '(?:\\^|\\*\\*)'; |
my $binoper3 = '(?:\\^|\\*\\*)'; |
my $binoper2 = '[/*_,]'; |
my $binoper2 = '[/*_,]'; |
my $binoper1 = '(?:<>|<=|>=|[-+=><%!])'; |
my $binoper1 = '(?:[-+%!])'; |
|
my $binoper0 = '(?:<>|<=|>=|[=><])'; |
my $openparen = '[{(\\[]'; |
my $openparen = '[{(\\[]'; |
my $closeparen = '[})\\]]'; |
my $closeparen = '[})\\]]'; |
my $varname = '[A-Za-z](?:_[0-9]+)?'; |
my $varname = '[A-Za-z](?:_[0-9]+)?'; |
Line 64 my $trigfname = '(?:(?:a(?:rc)?)?(?:sin|
|
Line 65 my $trigfname = '(?:(?:a(?:rc)?)?(?:sin|
|
my $otherfunc = '(?:exp|abs|logten|log|ln|sqrt|sgn|step|fact|int|lim|fun[a-zA-Z])'; |
my $otherfunc = '(?:exp|abs|logten|log|ln|sqrt|sgn|step|fact|int|lim|fun[a-zA-Z])'; |
my $funcname = '(?:' . $otherfunc . '|' . $trigfname . ')'; |
my $funcname = '(?:' . $otherfunc . '|' . $trigfname . ')'; |
|
|
my $tokenregexp = "(?:($binoper3)|($binoper2)|($binoper1)|($openparen)|" . |
my $tokenregexp = "(?:($binoper3)|($binoper2)|($binoper1)|($binoper0)|($openparen)|" . |
"($closeparen)|($funcname)|($specialvalue)|($varname)|" . |
"($closeparen)|($funcname)|($specialvalue)|($varname)|" . |
"($numberE)|($number))"; |
"($numberE)|($number))"; |
|
|
Line 77 sub nexttoken {
|
Line 78 sub nexttoken {
|
if (defined($1)) {return ['binop3', $1];} |
if (defined($1)) {return ['binop3', $1];} |
if (defined($2)) {return ['binop2', $2];} |
if (defined($2)) {return ['binop2', $2];} |
if (defined($3)) {return ['binop1', $3];} |
if (defined($3)) {return ['binop1', $3];} |
if (defined($4)) {return ['openp', $4];} |
if (defined($4)) {return ['binop0', $4];} |
if (defined($5)) {return ['closep', $5];} |
if (defined($5)) {return ['openp', $5];} |
if (defined($6)) {return ['func1', $6];} |
if (defined($6)) {return ['closep', $6];} |
if (defined($7)) {return ['special', $7];} |
if (defined($7)) {return ['func1', $7];} |
if (defined($8)) {return ['varname', $8];} |
if (defined($8)) {return ['special', $8];} |
if (defined($9)) {return ['numberE', $9];} |
if (defined($9)) {return ['varname', $9];} |
if (defined($10)) {return ['number', $10];} |
if (defined($10)) {return ['numberE',$10];} |
|
if (defined($11)) {return ['number', $11];} |
} |
} |
else { |
else { |
push @{$self->{posarray}}, [$p1, undef]; |
push @{$self->{posarray}}, [$p1, undef]; |
Line 118 sub parse {
|
Line 120 sub parse {
|
local $_; |
local $_; |
while ($currenttok) { |
while ($currenttok) { |
$_ = $currenttok->[0]; |
$_ = $currenttok->[0]; |
/binop1/ && do { |
/binop[01]/ && do { |
# check if we have a binary or unary operation here. |
# check if we have a binary or unary operation here. |
if (defined(${$currentref})) { |
if (defined(${$currentref})) { |
# binary - walk up the tree until we hit an open paren or the top |
# binary - walk up the tree until we hit an open paren or the top |
Line 126 sub parse {
|
Line 128 sub parse {
|
$currentref = pop @backtrace; |
$currentref = pop @backtrace; |
} |
} |
my $index = ((${$currentref}->[0] eq 'top')?1:3); |
my $index = ((${$currentref}->[0] eq 'top')?1:3); |
${$currentref}->[$index] = ['binop1', $currenttok->[1], |
${$currentref}->[$index] = [$currenttok->[0], $currenttok->[1], |
${$currentref}->[$index], undef]; |
${$currentref}->[$index], undef]; |
push @backtrace, $currentref; |
push @backtrace, $currentref; |
push @backtrace, \${$currentref}->[$index]; |
push @backtrace, \${$currentref}->[$index]; |
$currentref = \${$currentref}->[$index]->[3]; |
$currentref = \${$currentref}->[$index]->[3]; |
} else { |
} elsif (/binop1/) { |
# unary |
# unary |
${$currentref} = ['unop1', $currenttok->[1], undef]; |
${$currentref} = ['unop1', $currenttok->[1], undef]; |
push @backtrace, $currentref; |
push @backtrace, $currentref; |
$currentref = \${$currentref}->[2]; |
$currentref = \${$currentref}->[2]; |
|
} else { |
|
my ($mark) = pop(@{$self->{posarray}}); |
|
my $position = 1+$mark->[0]; |
|
return $self->error("Didn't expect " . $currenttok->[1] . |
|
" at position $position" , $mark); |
} |
} |
}; |
}; |
/binop2/ && do { |
/binop2/ && do { |
Line 482 sub tostring {
|
Line 489 sub tostring {
|
# print STDERR Data::Dumper->Dump([@_]); |
# print STDERR Data::Dumper->Dump([@_]); |
my($self) = shift; |
my($self) = shift; |
my($type, @args) = @$self; |
my($type, @args) = @$self; |
|
|
local $_; |
local $_; |
$_ = $type; |
$_ = $type; |
/binop1/ && do { |
/binop[01]/ && do { |
my ($p1, $p2) = ('',''); |
my ($p1, $p2) = ('',''); |
if ($args[2]->[0] eq 'binop1') {($p1,$p2)=qw{ ( ) };} |
if ($args[2]->[0] eq 'binop1') {($p1,$p2)=qw{ ( ) };} |
return ($args[1]->tostring() . $args[0] . $p1 . |
return ($args[1]->tostring() . $args[0] . $p1 . |
Line 518 sub tostring {
|
Line 526 sub tostring {
|
}; |
}; |
/special|varname|numberE?/ && return $args[0]; |
/special|varname|numberE?/ && return $args[0]; |
/closep/ && do { |
/closep/ && do { |
my(%close) = %AlgParser::close; |
|
|
|
|
|
|
|
return ($args[0] . $args[1]->tostring() . $close{$args[0]}); |
return ($args[0] . $args[1]->tostring() . $close{$args[0]}); |
}; |
}; |
Line 529 sub tostring {
|
Line 534 sub tostring {
|
sub tolatex { |
sub tolatex { |
my($self) = shift; |
my($self) = shift; |
my($type, @args) = @$self; |
my($type, @args) = @$self; |
|
|
local $_; |
local $_; |
$_ = $type; |
$_ = $type; |
/binop1/ && do { |
/binop[01]/ && do { |
my ($p1, $p2) = ('',''); |
my ($p1, $p2) = ('',''); |
if ($args[2]->[0] eq 'binop1') {($p1,$p2)=qw{ \left( \right) };} |
if ($args[2]->[0] eq 'binop1') {($p1,$p2)=qw{ \left( \right) };} |
my $cmd=$args[0]; |
my $cmd=$args[0]; |
Line 551 sub tolatex {
|
Line 557 sub tolatex {
|
if ($args[0] eq '/'){ |
if ($args[0] eq '/'){ |
return('\frac{'.$lop.'}{'.$rop.'}'); |
return('\frac{'.$lop.'}{'.$rop.'}'); |
} |
} |
elsif ($args[0] eq '*'){ |
my $op = $args[0]; |
return($lop. '\cdot ' .$rop); |
if ($args[0] eq '*'){ |
|
$op = '\cdot '; |
} |
} |
else{ |
$lop = '\left('.$lop.'\right)' if ($args[1]->[0] =~ /binop1|numberE/); |
$lop = '\left('.$lop.'\right)' if ($args[1]->[0] =~ /binop1|numberE/); |
$rop = '\left('.$rop.'\right)' if ($args[2]->[0] =~ /binop[12]|numberE|unop1/); |
$rop = '\left('.$rop.'\right)' if ($args[2]->[0] =~ /binop[12]|numberE|unop1/); |
if ($args[0] =~ /implicit/) { |
if ($args[0] =~ /implicit/) { |
$op = ($lop =~ m/[.0-9]$/ && $rop =~ m/^[-+.0-9]/) ? '\cdot ' : ' '; |
$args[0] = ($lop =~ m/[.0-9]$/ && $rop =~ m/^[-+.0-9]/) ? '\cdot ' : ' '; |
|
} |
|
return ($lop.$args[0].$rop); |
|
} |
} |
|
return ($lop.$op.$rop); |
|
|
}; |
}; |
/binop3/ && do { |
/binop3/ && do { |
my ($p1, $p2, $p3, $p4)=('','','',''); |
my ($p1, $p2, $p3, $p4)=('','','',''); |
Line 626 sub tolatex {
|
Line 632 sub tolatex {
|
/closep/ && do { |
/closep/ && do { |
my($backslash) = ''; |
my($backslash) = ''; |
if ($args[0] eq '{') {$backslash = '\\';} |
if ($args[0] eq '{') {$backslash = '\\';} |
#This is for editors to match: } |
#This is for editors to match: } |
return ('\left' . $backslash . $args[0] . $args[1]->tolatex() . |
return ('\left' . $backslash . $args[0] . $args[1]->tolatex() . |
'\right' . $backslash . $close{$args[0]}); |
'\right' . $backslash . $close{$args[0]}); |
}; |
}; |