:开始::函数:formget_file:模式:FormGet[formout_String]:参数:{formout}:ArgumentTypes:{手动}:返回类型:手动:结束::开始::函数:formget_exec:模式:FormGet[formcmd_String,formprogram_String]:参数:{formcmd,formprogram}:ArgumentTypes:{手动}:返回类型:手动:结束::Evaluate:_FormGet:=(消息[FormGet::syntax];中止[]):开始::函数:formgetdebug:模式:FormGetDebug[debug_Integer,logfile_:“”]:参数:{debug,logfile}:ArgumentTypes:{Integer,手动}:返回类型:手动:结束::Evaluate:FormGet::syntax=“语法错误。”:Evaluate:FormGet::nofile=“无法打开``。”:Evaluate:FormGet::nooutput=“FORM没有输出。”:Evaluate:FormGet::formerror=“`1`”:Evaluate:FormGet::usage=“FormGet[formoutputfile]从formoutputpile读取FORM输出。\nFormGet[formcmd,formprogram]在formprogram上运行formcmd并读取输出。”/******************************************************************表格获取.tm[上次修改时间:4月19日8日,Thomas Hahn]此程序提供Mathematica函数FormGet,它读取将FORM文件输出到Mathematica。(FORM是一个计算机代数高能物理中常用的系统。)FORM的输出格式与Mathematica的略有不同InputForm和while转换(例如,将圆括号转换为方形括号表示函数)在大多数情况下都很容易使用任何像样的模式匹配语言,如perl或awk,都会让人感到痛苦为每个可能想要读取的FORM文件编写此程序。此外,FormGet保留了FORM输出的结构,如果使用括号命令将分组为常见因素。编译:键入“mcc-O-O FormGet FormGet.tm”,然后如果需要,复制可执行文件FormGet到一些方便的位置,如/usr/local/bin。用法:在Mathematica中安装软件包:安装[“FormGet”]。读取现有的FORM输出文件:FormGet[“formoutputfile”]。从FORM管道读取输出:FormGet[“/path/to/FORM”,“formprogram”]。输出:由FORM写出的表达式expr=a+b+c;在Mathematica中以“expr->a+b+c”的形式出现。如果有几个表达式则返回此类规则的列表。带括号的零件返回到函数“Br”中。虚单位(FORM中的“i_”)转换为Mathematica的i,并且所有下划线都被“$”字符替换,以生成表达式Mathematica可以接受。带方括号的标识符作为字符串返回,即不是直接评估。例如,FORM表达式[a+b]+c变为Mathematica中的“a+b”+c。FormGet通常应避开源代码列表和统计信息信息。但是,如果出现问题,请尝试关闭带有“#-”的源列表和/或带有“nwrite statistics”的统计信息在表格中。限制:在FORM中,可以有非交互功能,其产品是也使用普通的“*”运算符编写。因此,如果转让给Mathematica使用FormGet时,此类产品的订单很可能被摧毁。解决这个问题的一种方法是FormGetNC[file_]:=块[{Times=Times},FormGet[file]]NCFunctions=a|b|c|d(*非交互性的函数*)次数[n_]:=次数[n]/;FreeQ[{n},NC函数]次数[n_]:=非交换乘法[n]******************************************************************/#包括“mathlink.h”#包括#包括#包括#包括#包括#包括#包括#包括#包括typedef结构rhs{struct rhs*next;char-expr[2048];}RHS;typedef结构表达式{struct-expr*next;右侧*右侧;整数nrhs;字符lhs[128];}EXPR;typedef常量int cint;typedef char*string;typedef MLCONST char*cstring;静态int调试=0;静态文件*stddeb;/******************************************************************/静态内联void MLMessage(MLINK mlp,cstring标记,cstring-arg){MLPutFunction(mlp,“评估包”,1);MLPutFunction(mlp,“消息”,(arg)?2 : 1);MLPutFunction(mlp,“消息名称”,2);MLPutSymbol(mlp,“FormGet”);MLPutString(mlp,tag);if(arg)MLPutString(mlp,arg);MLEndPacket(mlp);while(MLNextPacket(mlp)!=返回包)ML新数据包(mlp);ML新数据包(mlp);/*丢弃返回的Null*/}/******************************************************************/静态内联void MLFail(MLINK mlp,cstring标记,cstring-arg){MLMessage(mlp、tag、arg);MLPutSymbol(mlp,“$Failed”);MLEndPacket(mlp);}/******************************************************************/静态内联void MLPutTerm(MLINK mlp,cstring s){MLPutFunction(mlp,“ToExpression”,1);MLPutString(mlp,s);}/******************************************************************/静态void SendExpr(EXPR*EXPR,cint nexpr){EXPR*ep,*epnext;右侧*rp,*rpnext;如果(nexpr==0)MLMessage(stdlink,“nooutput”,NULL);MLPutFunction(stdlink,“列表”,nexpr);对于(ep=expr;(epnext=ep->next);ep=下一步){MLPutFunction(stdlink,“规则”,2);MLPutFunction(stdlink,“ToExpression”,1);MLPutString(stdlink,ep->lhs);if(调试&2)fprintf(stderr,“lhs=|%s|\nrhs%d部分”,ep->lhs,ep->nrhs);MLPutFunction(stdlink,“ToExpression”,1);如果(ep->nrhs>1)MLPutFunction(stdlink,“StringJoin”,ep->n rhs);对于(rp=ep->rhs;rp;rp=rpnext){MLPutString(stdlink,rp->expr);if(debug&4)fprintf(stderr,“expr=|%s|\n”,rp->expr);rpnext=rp->next;自由(rp);}自由(ep);}游离(ep);MLEndPacket(stdlink);}/******************************************************************/静态void FormGet(FILE*文件){字符*s,*d,*x,last;字符br[64],*brpos;int nexpr=-1,inexpr=0,b=0,动词=0,n,nx;int justbr;字符行[512],errmsg[512]、*errend=errmsg;EXPR*cur,*EXPR,**nextexpr=&EXPR;右侧**下一个;下一个表达式:++下一步;*nextexpr=cur=malloc(sizeof(EXPR));nextexpr=&cur->next;*nextexpr=空;nextrhs=&cur->rhs;*nextrhs=空;cur->nrhs=0;d=cur->lhs;n=尺寸(cur->lhs);nx=justbr=0;brpos=空;last=“+”;下一行:做{if(fgets(line,sizeof line,file)==NULL){fclose(文件);if(errend==errmsg)SendExpr(expr,nexpr);其他{错误结束[-1]=0;/*放弃最后一个\n*/MLFail(stdlink,“formerror”,errmsg);}回报;}if(debug&1)fputs(行,标准错误);如果(*line=='\n')继续;if((s=strstr(行,“-->”))||(s=strstr(行,“==>”))||(s=strstr(行,“===”)){strncpy(errend,s+4,errmsg+sizeof(errmsg)-errend);errend+=strlen(错误);继续;}}while(errend>errmsg);如果(不确定==0){int tok=0,动词=0;字符*eq;if(/**line!=''||*/((eq=strchr(行,'='))==NULL)||strchr(eq+1,'='))转到下一行;for(s=行;s<等式;++s)switch(*s|动词){案例“”:tok |=2*(tok&1);断裂;案例“[”:案例“]”+256:动词^=256;/*落空*/违约:如果(tok==3)转到下一行;tok |=1;}}#定义ASSOCIATIVE字符串(“+-*/^,([”,last)如果(justbr)nx=4,x=“”,brpos=d;justbr=0;for(s=线;*s;++s){char c=*s;如果(c<=“”)继续;开关(c |动词){大小写“;”:不确定=0;if(brpos&&justbr==0){成员(brpos,“+Br[”,4);*d++=“]”;}*d=0;转到nextexpr;案例“=”:不确定=1;n=0;*d=0;last=“+”;继续;大小写“(”:if(关联){如果(b){br[b++]=“)”;断裂;}nx=2,x=“Br”;}c=“[”,br[b++]=“]”|(nx<<6);断裂;案例“)”:案例“]”:如果(b>0)c=br[--b];justbr |=c>>7;c=0x7f;断裂;案例“[”:if(ASSOCIATIVE)谓词=256,c='\“';否则br[b++]=']';断裂;案例“]”+256:动词=0;c=“\”;断裂;案例“_”:c=“$”;断裂;案例“?”:大小写“\\”:继续;}如果(n<=nx+2){RHS*RHS=*nextrhs=malloc(sizeof(RHS));nexttrhs=&rhs->next;*nextrhs=空;*d=0;d=rhs->expr;n=尺寸(rhs->expr)-1;++cur->nrhs;}如果(nx){成员(d,x,nx);d+=nx;n-=nx;nx=0;}*d++=最后=c;--n;}转到下一行;}/******************************************************************/静态void formget_file(void){c管柱成型;中的文件*;断言(MLGetString(stdlink,&formout));in=fopen(formout,“r”);如果(in)FormGet(in);else MLFail(stdlink,“nofile”,formout);MLReleaseString(stdlink,formout);}/******************************************************************/静态void formget_exec(void){中的文件*;int fd[2],状态;pid_t pid;cstring formcmd,formprogram;c字符串argv[16],*argp=argv;字符串p0,p;断言(MLGetString(stdlink,&formcmd)&&MLGetString(stdlink和formprogram)&&(p=p0=strdup(公式cmd));do*argp++=字符串(&p,“|”);while(p);argp[0]=表单程序;argp[1]=空;信号(SIGCHLD、SIG_IGN);断言(管道(fd)!=-1&&(pid=fork())!=-1 );如果(pid==0){usleep(500);关闭(fd[0]);dup2(fd[1],1);dup2(fd[1],2);关闭(fd[1]);退出(execvp((char*)argv[0],(char**)argv));}关闭(fd[1]);in=fdopen(fd[0],“r”);如果(in)FormGet(in);否则MLFail(stdlink,“nofile”,argv[0]);kill(pid,SIGKILL);等待(&status);游离(p0);MLReleaseString(stdlink,formprogram);MLReleaseString(stdlink,formcmd);}/******************************************************************/静态void formgetdebug(cint deb){cstring日志文件;断言(MLGetString(stdlink,&logfile));调试=deb;stddeb=标准错误;if(*日志文件){stddeb=fopen(日志文件,“w”);if(stddeb==空){MLFail(stdlink,“noopen”,日志文件);调试=0;回报;}setbuf(stddeb,空);}MLPutSymbol(stdlink,“True”);MLEndPacket(stdlink);}/******************************************************************/int main(int argc,char**argv){整数fd;/*确保管道不会与0、1、2重叠*/do fd=打开(“/dev/null”,O_WRONLY);而(fd<=2);闭合(fd);return MLMain(argc,argv);}