UVA12422 (Kengdie) Mua (II) - Expression Evaluator 题解

题目传送门

闲话

蒟蒻的第一篇黑题题解!

连着花了 \(12\) 个小时才做出来,打代码 \(6\) 小时,调试 \(6\) 小时。

一开始怎么编也编不过,直到看到了 tiger 大神的题解才豁然开朗。

思路

本题主要是输出函数或运算式子的结果,最重要的就是判断优先级。

tiger 大神提出了表达式树法和递归下降法两种,蒟蒻的我不会表达式树法,于是就用递归下降法来做。

这里判断优先级的方法与 tiger 大神一样,在递归中多传一个参数来表示式子中的最小运算符优先级,每次到最后递归时将这个参数加一,直到加到参数最大——这里是 ^ 的优先级最大时再分类运算即可。

本题中的 table 是一种类似 C++ 的 map 的结构,我们就可以开一个 map 来存储它。

当然在输入时我们也需要像 UVA12421 那样把名称、保留字、数字、字符等都分割开以便后续计算。

在处理函数时,需要找到配对的括号,还是比较容易实现的。

还要注意几点:

  1. 多测要清空!

  2. 类型名和函数名不要打错!因为这个我调了至少 \(2\) 小时。

  3. 小数要保留到 \(14\) 位。

  4. 小心动态数组下标越界。

代码

#include<bits/stdc++.h>
#define MAX 100005
using namespace std;
string RESERVED[25]={"and","break","do","else","elseif","end","false","for","function","if","in","local","nil","not","or","repeat","return","then","true","until","while"};
string FUNCTION[35]={"tonumber","tostring","print","string","rep","sub","table","concat","sort","math","abs","floor","ceil","sqrt","exp","log","log10","pi","rad","deg","acos","asin","atan","atan2","cos","sin","tan","max","min"};
string str,ans;
int cnt,len,j,pm[MAX],tot;
bool pd;
struct Operator{
    string Name,val;
    bool operator == (const Operator & A)const{
        return A.Name ==Name && A.val==val;
    }
};
string changestring(double x){
    string tmp;
    char ch[MAX]={};
    memset(ch,0,sizeof(ch));
    sprintf(ch,"%.14g",x);
    tmp=ch;
    return tmp;
}
string dealstring(string tmp){
    string ANS="";
    for(int i=1;i<tmp.length();i++){
        if(!tmp[i+1])break;
        if(tmp[i]!='\\')ANS+=tmp[i];
        else{
            i++;
            if(tmp[i]=='\"')ANS+='\"';
            if(tmp[i]=='\'')ANS+='\'';
            if(tmp[i]=='\\')ANS+='\\';
            if(tmp[i]=='n')ANS+='\n';
        }
    }
    return ANS;
}
struct Memory{
    string Name,mstr;
    double mnum;
    int mloc;
    map<Memory,int> mp;
    bool operator < (const Memory & A)const{
        if(Name!=A.Name)return Name<A.Name;
        if(mstr!=A.mstr)return mstr<A.mstr;
        if(mnum!=A.mnum)return mnum<A.mnum;
        if(mloc!=A.mloc)return mloc<A.mloc;
        return mp<A.mp;
    }
};
vector<Operator> opt;
vector<Memory> vm;
stack<int> st;
map<string,int> Store;
bool checknum(int x){
    char ch=str[x];
    if(ch>='0'&&ch<='9'||ch=='e'||ch>='A'&&ch<='F'||ch>='a'&&ch<='f')return 1;
    if(ch=='-'||ch=='+')if(str[x-1]=='e')return 1;else return 0;
    if(ch=='.'&&!pd){pd=1;return 1;}
    return 0;
}
bool checkstring(int x,char tmp){
    char ch1=str[x],ch2=str[x-1];
    if(tmp!=ch1)return 1;
    else{if(ch2=='\\')return 1;else return 0;}
    return 0;
}
int checksymbol(int x){
    char ch1=str[x],ch2=str[x+1];
    if(ch1=='.'&&ch2=='.'&&str[x+2]=='.')return 3;
    if(ch1=='.'&&ch2=='.'||ch1=='='&&ch2=='='||ch1=='>'&&ch2=='='||ch1=='<'&&ch2=='='||ch1=='~'&&ch2=='=')return 2;
    /*+ - * / % ^ # == >= <= > < ~= ( ) { } [ ] ; : , . .. ... =*/
    if(ch1=='.'||ch1==','||ch1==':'||ch1==';'||ch1=='='||ch1=='+'||ch1=='-'||ch1=='*'||ch1=='/'||ch1=='%'||ch1=='^'||ch1=='#'||ch1=='<'||ch1=='>'||ch1=='('||ch1==')'||ch1=='{'||ch1=='}'||ch1=='['||ch1==']')return 1;
    return 0;
}
int Priority(string tmp){
    if(tmp=="or")return 1;
    if(tmp=="and")return 2;
    if(tmp==">"||tmp=="<"||tmp==">="||tmp=="<="|tmp=="~="||tmp=="==")return 3;
    if(tmp=="..")return 4;
    if(tmp=="+" || tmp=="-")return 5;
    if(tmp=="*"|| tmp=="/"||tmp=="%")return 6;
    if(tmp=="not"||tmp=="#")return 7;
    if(tmp=="^")return 8;
    if(tmp=="=")return 0;
    return -1;
}
bool checkname(int x){
    char ch=str[x];
    if(ch>='0'&&ch<='9'||ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'||ch=='_')return 1;
    return 0;
}
bool checkreserved(string s){
    for(int i=0;i<21;i++)if(s==RESERVED[i])return 1;
    return 0;
}
bool checkmemory(int l,int r){
    if(l==r||(l==r-1&&opt[l].val=="{"))return 1;l++;
    while(l<=r&&(opt[l].val=="["||opt[l].val=="."))if(opt[l].val==".")l+=2;else l=pm[l]+1;
    if(l==r+1)return 1;
    return 0;
}
bool checkfunction(string s){
    for(int i=0;i<29;i++)if(s==FUNCTION[i])return 1;
    return 0;
}
bool checknumber(string s){
    if(s[0]=='+'||s[0]=='-')s=s.substr(1);
    if(s[0]=='0'&&(s[1]=='x'||s[1]=='X')){
        for(int i=2;i<s.length();i++)if(!(s[i]>='0'&&s[i]<='9'||s[i]>='A'&&s[i]<='F'||s[i]>='a'&&s[i]<='f'))return 0;
        return 1;
    }
    bool pd1=0,pd2=0;
    for(int i=0;i<s.length();i++){
        if(s[i]>='0'&&s[i]<='9')continue;
        else if(s[i]=='.'){
            if(!pd1&&(i!=0||s[i+1]>='0'&&s[i+1]<='9'))pd1=1;
            else return 0;
        }else if(!pd2||s[i]=='e'||s[i]=='E'){
            pd2=1;
            if(s[i+1]=='+'||s[i+1]=='-')i++;
            pd1=1;
        }else return 0;
    }
    return 1;
}
double Table(Memory tmp){
    double tmpi=1.0;
    while(1){
        Memory cl={"number","",tmpi,0};cl.mp.clear();
        if(!tmp.mp[cl])break;
        tmpi++;
    }
    return tmpi-1;
}
double changedou(string tmp){
    double tmpd=0,dou=0.1;
    bool pd=0;
    if(tmp[0]=='+')return changedou(tmp.substr(1));
    else if(tmp[0]=='-') return -1*changedou(tmp.substr(1));
    for(int i=0;i<tmp.length();i++){
        if(tmp[i]=='.')pd=1;
        else if(tmp[i]=='e'||tmp[i]=='E'){
            int PoN=1,ANS=0;
            if(tmp[++i]=='-')PoN=-1;
            i++;
            while(tmp[i]>='0'&&tmp[i]>='9')ANS=ANS*10+tmp[i]-'0',i++;
            ANS*=PoN;
            tmpd*=pow(10,ANS);
            return tmpd;
        }else if(pd)tmpd+=dou*(tmp[i]-'0')*1.0,dou/=10;
        else tmpd=tmpd*10+(tmp[i]-'0')*1.0;
    }
    return tmpd;
}
double changehex(string tmp){
    double tmpd=0;
    for(int i=0;i<tmp.length();i++){
        if(tmp[i]>='a'&&tmp[i]<='f')tmpd=tmpd*16+tmp[i]-'a'+10;
        else if(tmp[i]>='A'&&tmp[i]<='F')tmpd=tmpd*16+tmp[i]-'A'+10;
        else tmpd=tmpd*16+tmp[i]-'0';
    }
    return tmpd;
}
double changenum(string tmp){
    if(tmp[0]=='0'&&(tmp[1]=='x'||tmp[1]=='X'))return changehex(tmp.substr(2));
    return changedou(tmp);
}
string STRING(Memory tmp){
    if(tmp.Name=="string")return tmp.mstr;
    else if(tmp.Name=="number")return changestring(tmp.mnum);
    else if(tmp.Name=="boolean")return tmp.mnum?"true":"false";
    else return tmp.Name;
}
Memory VAR(Memory tmp){
    if(tmp.Name!="var")return tmp;
    return vm[tmp.mloc];
}
Memory dealsymbol(Operator op,Memory m1,Memory m2){
    if(op.val=="")return m2;
    if(op.val!="=") m1=VAR(m1);
    m2=VAR(m2);
    if(op.val=="or"){
        Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
        if(m1.mnum!=0.0||m2.mnum!=0.0)cl.mnum=1;else cl.mnum=0;
        return cl;
    }else if(op.val=="and"){
        Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
        if(m1.mnum!=0.0&&m2.mnum!=0.0)cl.mnum=1;else cl.mnum=0;
        return cl;
    }else if(op.val=="not"){
        Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
        if(m2.mnum==0.0)cl.mnum=1;else cl.mnum=0;
        return cl;
    }else if(op.val=="<"){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum<m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr<m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val==">"){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum>m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr>m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val=="<="){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum<=m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr<=m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val==">="){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum>=m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr>=m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val=="=="){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum==m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr==m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val=="~="){
        if(m1.Name=="boolean"||m1.Name=="number"){
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mnum!=m2.mnum)cl.mnum=1;else cl.mnum=0;
            return cl;
        }else{
            Memory cl;cl.Name="boolean",cl.mstr="";cl.mloc=0;cl.mp.clear();
            if(m1.mstr!=m2.mstr)cl.mnum=1;else cl.mnum=0;
            return cl;
        }
    }else if(op.val==".."){
        Memory cl;cl.Name="string",cl.mstr=m1.mstr+m2.mstr,cl.mnum=0,cl.mloc=0;cl.mp.clear();
        return cl;
    }else if(op.val=="+"){
        Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m1.mnum+m2.mnum,cl.mloc=0;cl.mp.clear();
        return cl;
    }else if(op.val=="-"){
        if(m1.Name=="nil"){
            Memory cl;cl.Name="number",cl.mstr="",cl.mnum=-m2.mnum,cl.mloc=0;cl.mp.clear();
            return cl;
        }else{
            Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m1.mnum-m2.mnum,cl.mloc=0;cl.mp.clear();
            return cl;
        }
    }else if(op.val=="*"){
        Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m1.mnum*m2.mnum,cl.mloc=0;cl.mp.clear();
        return cl;
    }else if(op.val=="/"){
        Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m1.mnum/m2.mnum,cl.mloc=0;cl.mp.clear();
        return cl;
    }else if(op.val=="%"){
        Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m1.mnum-floor(m1.mnum/m2.mnum)*m2.mnum,cl.mloc=0;
        cl.mp.clear();
        return cl;
    }else if(op.val=="#"){
        if(m2.Name=="string"){
            Memory cl;cl.Name="number",cl.mstr="",cl.mnum=m2.mstr.size(),cl.mloc=0,cl.mp.clear();
            return cl;
        }else{
            Memory cl;cl.Name="number",cl.mstr="",cl.mnum=Table(m2),cl.mloc=0,cl.mp.clear();
            return cl;
        }
    }else if(op.val=="^"){
        Memory cl;cl.Name="number",cl.mstr="",cl.mnum=pow(m1.mnum,m2.mnum),cl.mloc=0,cl.mp.clear();
        return cl;
    }else if(op.val=="="){
        if(m1.Name=="var")vm[m1.mloc]=VAR(m2);
        return m1;
    }
    Memory cl;cl.Name="nil",cl.mstr="",cl.mnum=0,cl.mloc=0,cl.mp.clear();
    return cl;
}
Memory dealfunction(string type,vector<Memory> v){
    if(type!="table.sort")v[0]=VAR(v[0]);
    for(int i=1;i<v.size();i++)v[i]=VAR(v[i]);
    if(type=="tonumber"){
        if(v[0].Name=="string"&&checknumber(v[0].mstr)){
            Memory cl={"string","",changenum(v[0].mstr),0};cl.mp.clear();
            return cl;
        }else if(v[0].Name=="number")return v[0];
        else{
            Memory cl={"nil","",0,0};cl.mp.clear();
            return cl;
        }
    }else if(type=="tostring"){
        Memory cl;cl.Name="string",cl.mstr=STRING(v[0]),cl.mnum=0,cl.mloc=0;
        return cl;
    }else if(type=="print"){
        Memory output=VAR(v[0]);
        if(output.Name=="string")cout<<output.mstr<<'\n';
        else if(output.Name=="number")printf("%.14g\n",output.mnum);
        else if(output.Name=="boolean")if(output.mnum)cout<<"true\n";else cout<<"false\n";
        else cout<<output.Name<<'\n';
        Memory cl;cl.Name="nil",cl.mstr="",cl.mnum=0,cl.mloc=0,cl.mp.clear();
    return cl;
    }else if(type=="string.sub"){
        if(v[1].mnum<=0)v[1].mnum+=v[0].mstr.size()+1;
        else if(v.size()==2){
            Memory cl={"number","",1.0*v[0].mstr.size(),0};cl.mp.clear();
            v.push_back(cl);
        }else if(v[2].mnum<=0)v[2].mnum+=v[0].mstr.size()+1;
        else if(v[2].mnum-v[1].mnum+1>0){
            Memory cl={"string",v[0].mstr.substr(v[1].mnum-1,v[2].mnum-v[1].mnum+1),0,0};cl.mp.clear();
            return cl;
        }
        Memory cl={"string","",0,0};cl.mp.clear();
        return cl;
    }else if(type=="string.rep"){
        string tmp="";
        for(int i=0;i<v[1].mnum;i++)tmp+=v[0].mstr;
        Memory cl={"string",tmp,0,0};cl.mp.clear();
        return cl;
    }else if(type=="table.concat"){
        int tmp=Table(v[0]);
        if(!tmp){
            Memory cl={"string","",0,0};cl.mp.clear();
            return cl;
        }
        Memory cl={"number","",1,0};cl.mp.clear();
        string ANS=vm[v[0].mp[cl]].mstr;
        for(int i=2;i<=tmp;i++){
            if(v.size()>1)ANS+=v[1].mstr;
            Memory cl={"number","",1.0*i,0};cl.mp.clear();
            ANS+=vm[v[0].mp[cl]].mstr;
        }
        Memory Cl={"string",ANS,0,0};Cl.mp.clear();
        return Cl;
    }else if(type=="table.sort"){
        if(v.size()>1){
            Memory cl={"nil","",0,0};cl.mp.clear();
            return cl;
        }
        int tmp=Table(VAR(v[0]));
        vector<Memory> Sort;Sort.clear();
        for(int i=1;i<=tmp;i++){
            Memory cl={"number","",1.0*i,0};cl.mp.clear();
            Sort.push_back(vm[VAR(v[0]).mp[cl]]);
        }
        sort(Sort.begin(),Sort.end());
        for(int i=1;i<=tmp;i++){
            Memory cl={"number","",1.0*i,0};cl.mp.clear();
            vm[vm[v[0].mloc].mp[cl]]=Sort[i-1];
        }
        Memory cl={"nil","",0,0};cl.mp.clear();
        return cl;
    }
    if(type=="math.abs"){
        Memory cl={"number","",abs(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.floor"){
        Memory cl={"number","",floor(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.ceil"){
        Memory cl={"number","",ceil(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.sqrt"){
        Memory cl={"number","",sqrt(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.exp"){
        Memory cl={"number","",exp(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.log"){
        Memory cl={"number","",log(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.log10"){
        Memory cl={"number","",log10(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.rad"){
        Memory cl={"number","",v[0].mnum/(45/atan(1.0)),0};cl.mp.clear();
        return cl;
    }else if(type=="math.deg"){
        Memory cl={"number","",v[0].mnum*(45/atan(1.0)),0};cl.mp.clear();
        return cl;
    }else if(type=="math.acos"){
        Memory cl={"number","",acos(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.atan"){
        Memory cl={"number","",atan(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.asin"){
        Memory cl={"number","",asin(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.sin"){
        Memory cl={"number","",sin(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.cos"){
        Memory cl={"number","",cos(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.tan"){
        Memory cl={"number","",tan(v[0].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.atan2"){
        Memory cl={"number","",atan2(v[0].mnum,v[1].mnum),0};cl.mp.clear();
        return cl;
    }else if(type=="math.max"){
        if(v[0].Name=="string"){
            if(v[0].mstr>v[1].mstr){
                Memory cl={"string",v[0].mstr,0,0};cl.mp.clear();
                return cl;
            }
            Memory cl={"string",v[1].mstr,0,0};cl.mp.clear();
            return cl;
        }else if(v[0].mnum>v[1].mnum){
            Memory cl={"number","",v[0].mnum,0};cl.mp.clear();
            return cl;
        }
        Memory cl={"number","",v[1].mnum,0};cl.mp.clear();
        return cl;
    }else if(type=="math.min"){
        if(v[0].Name=="string"){
            if(v[0].mstr<v[1].mstr){
                Memory cl={"string",v[0].mstr,0,0};cl.mp.clear();
                return cl;
            }
            Memory cl={"string",v[1].mstr,0,0};cl.mp.clear();
            return cl;
        }else if(v[0].mnum<v[1].mnum){
            Memory cl={"number","",v[0].mnum,0};cl.mp.clear();
            return cl;
        }
        Memory cl={"number","",v[1].mnum,0};cl.mp.clear();
        return cl;
    }
    Memory cl={"nil","",0,0};cl.mp.clear();
    return cl;
}
Memory DEALT(int l,int r,int k){
    if(l>r){
        Memory cl={"nil","",0};cl.mp.clear();
        return cl;
    }
    while(opt[l]==Operator{"SYMBOL","("}&&opt[r]==Operator{"SYMBOL",")"})l++,r--,k=0;
    Operator tmpo=Operator{"EOL",""};/*tmpo.Name="EOL",tmpo.val="";*/
    Memory CL={"nil","",0};CL.mp.clear();
    Memory tmpm=CL;/*tmpm.Name="nil";tmpm.mstr="";tmpm.mnum=0;*/
    tmpm.mp.clear();
    if(checkmemory(l,r)){
        if(l==r){
            if(opt[l].val=="true"){
                Memory cl={"boolean","",1,0};cl.mp.clear();
                return cl;
            }
            if(opt[l].val=="false"){
                Memory cl={"boolean","",0,0};cl.mp.clear();
                return cl;
            }
            if(opt[l].Name=="STRING"){
                Memory cl;cl.Name="string";
                cl.mstr=dealstring(opt[l].val);cl.mnum=0;cl.mloc=0;cl.mp.clear();
                return cl;
            }
            if(opt[l].Name=="NUMBER"){
                Memory cl={"number","",changenum(opt[l].val),0};cl.mp.clear();
                return cl;
            }
            if(checkfunction(opt[l].val)){
                Memory cl={"function",opt[l].val,0,0};cl.mp.clear();
                return cl;
            }
        }
        if(checkfunction(opt[l].val)){
            Memory cl={"function",opt[l].val+'.'+opt[l+2].val,0,0};cl.mp.clear();
            return cl;
        }
        if(l==r-1){
            Memory cl={"table","",0,0};cl.mp.clear();
            return cl;
        }
        if(opt[l].Name=="NAME"){
            int aper=Store[opt[l].val];
            if(!aper){
                tot++;
                Memory cl={"nil","",0,0};cl.mp.clear();
                vm.push_back(cl);
                aper=tot;
                Store[opt[l].val]=aper;
            }
            l++;
            while(l<=r){
                if(opt[l].val=="["){
                    int matchs=pm[l];
                    Memory mem=DEALT(l+1,matchs-1,0);
                    int id=vm[aper].mp[VAR(mem)];
                    if(!id){
                        tot++;
                        Memory cl={"nil","",0,0};cl.mp.clear();
                        vm.push_back(cl);
                        id=tot;
                        vm[aper].mp[VAR(mem)]=id;
                    }
                    aper=id;
                    l=matchs+1;
                }else{
                    Memory cl={"string",opt[l+1].val,0,0};cl.mp.clear();
                    int id=vm[aper].mp[cl];
                    if(!id){
                        tot++;
                        Memory cl={"nil","",0,0};cl.mp.clear();
                        vm.push_back(cl);
                        id=tot;
                        Store[opt[l+1].val]=id;
                    }
                    aper=id;
                    l+=2;
                }
            }
            Memory cl={"var","",0,aper};cl.mp.clear();
            return cl;
        }
    }
    if(k==8){
        vector<pair<int,int> >vp;vp.clear();
        int First=l;
        for(int i=l;i<=r;i++)if(opt[i].val=="^")vp.push_back({First,i-1}),First=i+1;
        vp.push_back({First,r});
        int vplen=vp.size();
        tmpm=DEALT(vp[vplen-1].first,vp[vplen-1].second,9);
        vplen--;
        while(vplen)tmpm=dealsymbol(Operator{"SYMBOL","^"},DEALT(vp[vplen-1].first,vp[vplen-1].second,9),tmpm),vplen--;
        return tmpm;
    }
    for(int i=l;i<=r;i++){
        if(opt[i].val=="("||opt[i].val=="["){i=pm[i];continue;}
        else if(opt[i].Name=="NAME"&&k==9){
            if(checkfunction(opt[i].val)||vm[Store[opt[i].val]].Name=="function"){
                vector<Memory> par;string ftype;
                if(vm[Store[opt[i].val]].Name=="function")ftype=vm[Store[opt[i].val]].mstr;
                else{
                    ftype=opt[i].val;
                    if(opt[i+1].val==".")ftype+=('.'+opt[i+2].val),i+=2;
                }
                par.clear();int j;
                for(j=i+2,i=i+2;opt[j].val!=")";i=j+1,j=i){
                    while(opt[j].val!=","&&opt[j].val!=")"){j++;if(opt[j].val=="(")j=pm[j]+1;}
                    par.push_back(DEALT(i,j-1,0));
                    if(opt[j].val!=",")j--;
                }
                return dealfunction(ftype,par);
            }
        }else if(opt[i].Name=="SYMBOL"&&Priority(opt[i].val)==k){
            Memory tmp=DEALT(l,i-1,k+1);
            l=i+1;
            tmpm=dealsymbol(tmpo,tmpm,tmp);
            tmpo=opt[i];
        }
    }
    return dealsymbol(tmpo,tmpm,DEALT(l,r,k+1));
}
void init(){
    tot=0;
    vm.clear();
    Memory cl={"nil","",0,0};cl.mp.clear();
    vm.push_back(cl);
    Store.clear();
    ans="";
}
int main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
    init();
    while(getline(cin,str)){
        len=str.length();
        if(!len)init();
        for(int i=0;i<len;i++){
            if(str[i]==' ')continue;
            else if(str[i]=='-'&&str[i+1]=='-')break;
            else if(str[i]>='0'&&str[i]<='9'||str[i]=='.'&&str[i+1]>='0'&&str[i+1]<='9'){
                pd=0;
                if(str[i]=='.')ans+=str[i],i++,pd=1;
                if(str[i]=='0'&&(str[i+1]=='X'||str[i+1]=='x'))ans+=str[i],ans+=str[i+1],i+=2,pd=1;
                while(checknum(i))ans+=str[i],i++;i--;
                opt.push_back(Operator{"NUMBER",ans});
                ans="";
            }else if(str[i]=='\''||str[i]=='\"'){
                ans+=str[i];
                char tmp=str[i];i++;
                while(i<str.length()&&checkstring(i,tmp))ans+=str[i],i++;
                ans+=str[i];
                opt.push_back(Operator{"STRING",ans});
                ans="";
            }else if(checksymbol(i)){
                int tmp=checksymbol(i);
                for(int j=0;j<tmp;j++)ans+=str[i+j];
                i+=tmp,i--;
                opt.push_back(Operator{"SYMBOL",ans});
                ans="";
            }else if(str[i]>='a'&&str[i]<='z'||str[i]>='A'&&str[i]<='Z'){
                while(checkname(i))ans+=str[i],i++;i--;
                if(checkreserved(ans)){
                    if(ans=="and"||ans=="or"||ans=="not")opt.push_back(Operator{"SYMBOL",ans});
                    else if(ans=="true"||ans=="false")opt.push_back(Operator{"NUMBER",ans});
                    else opt.push_back(Operator{"RESERVED",ans});
                }else{
                    opt.push_back(Operator{"NAME",ans});
                }
                ans="";
            }
        }
        int optlen=opt.size();
        for(int i=0;i<optlen;i++){
            if(opt[i]==Operator{"SYMBOL","("}||opt[i]==Operator{"SYMBOL","["}||opt[i]==Operator{"SYMBOL","{"})st.push(i);
            if(opt[i]==Operator{"SYMBOL",")"}||opt[i]==Operator{"SYMBOL","]"}||opt[i]==Operator{"SYMBOL","}"})pm[st.top()]=i,st.pop();
        }
        for(int i=0;i<optlen;i++){
            if(opt[i].val=="math"&&opt[i+1].val=="."&&opt[i+2].val=="pi"){
                opt[i]=Operator{"NUMBER",changestring(acos(-1.0))};
                opt[i+1]=Operator{"SYMBOL","*"};
                opt[i+2]=Operator{"NUMBER","1"};
            }
        }
        DEALT(0,optlen-1,0);
        opt.clear();
    }
    return 0;
}
posted @ 2024-02-25 12:31  GyrthCurunír  阅读(11)  评论(0编辑  收藏  举报