我为极地功能编写了一个工具。它列出了输入范围内的值:
0 Grad: (0 RAD|1 RES) 20 Grad: (0.349065850398866 RAD|1.3639702342662 RES) 40 Grad: (0.698131700797732 RAD|1.83909963117728 RES) 60 Grad: (1.0471975511966 RAD|2.73205080756888 RES) 80 Grad: (1.39626340159546 RAD|6.67128181961771 RES) 100 Grad: (1.74532925199433 RAD|4.67128181961771 RES) 120 Grad: (2.0943951023932 RAD|0.732050807568878 RES) 140 Grad: (2.44346095279206 RAD|0.16090036882272 RES) 160 Grad: (2.79252680319093 RAD|0.636029765733797 RES) 180 Grad: (3.14159265358979 RAD|1 RES)
它基于功能
abs(1 + tan($_[0]));
如何从UserInput(Perl语法)解析这样的函数并将其分配给变量?
我想避免更改Perl脚本;使函数动态而不是静态。
欢迎并感谢阅读。
编辑: 对不起quadrupelpost ....
感谢您的帮助,但以下代码段提供了错误的值:
print("Eingabe: Funktion (phi = $t); PERL syntax!: > ");
$iFunktion = <STDIN>;
chop($iFunktion);
print("Eingabe: Grad Start: > ");
$iGradStart = <STDIN>;
chop($iGradStart);
print("Eingabe: Grad End: > ");
$iGradEnd = <STDIN>;
chop($iGradEnd);
print("Eingabe: Schrittweite: > ");
$iSchrittweite = <STDIN>;
chop($iSchrittweite);
print("\nBerechne Funktion von $iGradStart bis $iGradEnd Grad mit einer Schrittweite von $iSchrittweite\n");
for ($i = $iGradStart; $i < $iGradEnd; $i = $i + $iSchrittweite)
{
$flRad = °2rad($i);
#$flResult = &Compute($flRad);
$t = $i;
$flResult = eval($iFunktion);
print("$i Grad: ($flRad RAD|$flResult RES) \n");
}
输入为abs(1 + tan($ t));
(其他信息,后续合并)
print("Eingabe: Grad Start: > ");
$iGradStart = <STDIN>;
chop($iGradStart);
print("Eingabe: Grad End: > ");
$iGradEnd = <STDIN>;
chop($iGradEnd);
print("Eingabe: Schrittweite: > ");
$iSchrittweite = <STDIN>; chop($iSchrittweite);
print("\nfrom $iGradStart to $iGradEnd Grad with $iSchrittweite\n");
for ($i = $iGradStart; $i <= $iGradEnd; $i = $i + $iSchrittweite)
{
$flRad = °2rad($i);
$flResult = &Compute($flRad);
print("$i Grad: ($flRad RAD|$flResult RES) \n");
}
sub Compute { return abs(1 + tan($_[0])); }
答案 0 :(得分:4)
您应该查看eval
statement。它允许您将字符串计算为Perl代码。
例如,此代码:
print "Function? ";
chomp($function = <STDIN>);
for ($i = 0;$i < 10;$i++) {
print $i,"->",eval($function),"\n";
}
给出这个:
Function? $i * $i
0->0
1->1
2->4
3->9
4->16
5->25
6->36
7->49
8->64
9->81
当您将用户输入作为代码运行时,如果除了使用之外的其他人正在使用您的脚本,您将需要做一些事情来清理用户输入。您可能还想进行替换,以便用户可以输入x
而不是$i
等。如果您想从eval
抓取错误,请检查$@
变量
答案 1 :(得分:1)
根据你的其他内容,我想我会跳过解析的想法并让用户创建一个Perl库或子类。它们将代码包装在子例程名称中,并告诉脚本库和子名称。您也可以将它与适当的配置文件或命令行选项结合使用。
答案 2 :(得分:0)
Math::Expression::Evaluator 几乎做你想要的,除了没有abs()
并且无法添加用户功能(回调)。我花了大约五分钟来添加一些初步的支持,思想。
#!/usr/bin/perl
use strict;
use warnings;
use Math::Trig;
use Math::Expression::Evaluator;
my $expr = join ' ', @ARGV;
die "No expression provided" unless $expr;
my $m = Math::Expression::Evaluator->new;
# NOT in the distribution
$m->add_user_function('abs', sub { abs($_[0]) });
my $func = $m->parse($expr);
die "Cannot parse" unless $func;
for my $i (0 .. 10){
my $rads = deg2rad($i);
my $res = $func->val({x => $_});
print("$i Grad: ($rads RAD|$res RES) \n");
}