version 1.11, 2005/02/25 06:31:00
|
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 547 sub tolatex {
|
Line 553 sub tolatex {
|
return ($args[0] . $p1 . $args[1]->tolatex() . $p2); |
return ($args[0] . $p1 . $args[1]->tolatex() . $p2); |
}; |
}; |
/binop2/ && do { |
/binop2/ && do { |
my ($p1, $p2, $p3, $p4) = ('','','',''); |
my ($lop,$rop) = ($args[1]->tolatex,$args[2]->tolatex); |
if ($args[0] =~ /implicit/) { |
|
if ( (($args[1]->head eq qq(number)) && |
|
($args[2]->head eq qq(number))) || |
|
(($args[1]->head eq qq(binop2)) && |
|
($args[1]->[2]->head eq qq(number))) ) { |
|
$args[0] = '\\,'; |
|
} else { |
|
$args[0] = ' '; |
|
} |
|
} |
|
if ($args[1]->[0] =~ /binop1|numberE/) |
|
{($p1,$p2)=qw{ \left( \right) };} |
|
# if ($args[2]->[0] =~ /binop[12]|numberE/) |
|
if ($args[2]->[0] =~ /binop[12]|numberE|unop1/) |
|
{($p3,$p4)=qw{ \left( \right) };} |
|
if ($args[0] eq '/'){ |
if ($args[0] eq '/'){ |
# return('\frac{' . $p1 . $args[1]->tolatex() . $p2 . '}'. |
return('\frac{'.$lop.'}{'.$rop.'}'); |
# '{' . $p3 . $args[2]->tolatex() . $p4 . '}' ); |
|
return('\frac{' . $args[1]->tolatex() . '}'. |
|
'{' . $args[2]->tolatex() . '}' ); |
|
} |
} |
elsif ($args[0] eq '*'){ |
my $op = $args[0]; |
return($args[1]->tolatex() . '\cdot ' . $args[2]->tolatex() ); |
if ($args[0] eq '*'){ |
|
$op = '\cdot '; |
} |
} |
else{ |
$lop = '\left('.$lop.'\right)' if ($args[1]->[0] =~ /binop1|numberE/); |
return ($p1 . $args[1]->tolatex() . $p2 . $args[0] . $p3 . |
$rop = '\left('.$rop.'\right)' if ($args[2]->[0] =~ /binop[12]|numberE|unop1/); |
$args[2]->tolatex() . $p4); |
if ($args[0] =~ /implicit/) { |
|
$op = ($lop =~ m/[.0-9]$/ && $rop =~ m/^[-+.0-9]/) ? '\cdot ' : ' '; |
} |
} |
|
return ($lop.$op.$rop); |
|
|
}; |
}; |
/binop3/ && do { |
/binop3/ && do { |
my ($p1, $p2, $p3, $p4)=('','','',''); |
my ($p1, $p2, $p3, $p4)=('','','',''); |
Line 588 sub tolatex {
|
Line 580 sub tolatex {
|
}; |
}; |
/func1/ && do { |
/func1/ && do { |
my($p1,$p2); |
my($p1,$p2); |
if($args[0] eq "sqrt"){($p1,$p2)=qw{ \left{ \right} };} |
if($args[0] eq "sqrt"){($p1,$p2)=('{','}');} |
else {($p1,$p2)=qw{ \left( \right) };} |
else {($p1,$p2)=qw{ \left( \right) };} |
|
|
# |
# |
Line 606 sub tolatex {
|
Line 598 sub tolatex {
|
return ('\log_{10}'. $p1 . $args[1]->tolatex() . $p2); |
return ('\log_{10}'. $p1 . $args[1]->tolatex() . $p2); |
} |
} |
elsif (defined($2)) { |
elsif (defined($2)) { |
return ('\\' . $2.$3 .'^{-1}'. $p1 . $args[1]->tolatex() . $p2); |
if (defined($3) && ($2 eq 'sec' || $2 eq 'csc' || $2 eq 'cot')) { |
|
return ('\mathrm{' . $2.$3 .'}^{-1}'. $p1 . $args[1]->tolatex() . $p2); |
|
} else { |
|
return ('\\' . $2.$3 .'^{-1}'. $p1 . $args[1]->tolatex() . $p2); |
|
} |
} |
} |
elsif (defined($4)) { |
elsif (defined($4)) { |
return ('|' . $args[1]->tolatex() . '|'); |
return ('|' . $args[1]->tolatex() . '|'); |
Line 616 sub tolatex {
|
Line 612 sub tolatex {
|
} |
} |
} |
} |
else { |
else { |
return ('\\' . $args[0] . $p1 . $args[1]->tolatex() . $p2); |
if ($args[0] =~/(sec|csc|cot)h/) { |
|
return ('\mathrm{' . $args[0] . '}' . $p1 . $args[1]->tolatex() . $p2); |
|
} else { |
|
return ('\\' . $args[0] . $p1 . $args[1]->tolatex() . $p2); |
|
} |
} |
} |
}; |
}; |
/special/ && do { |
/special/ && do { |
Line 632 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]}); |
}; |
}; |