#include "小流冲.cpp"
#include "去重名.cpp"
枚 项类型{单符,规名,多符,关键字,是节点,或号,左括,左中,冒号,标识};
枚 点类型{一点,可无,加点,乘点};
构 节点;
构 项{
    项类型 a;串 b;符 c;节点*d;
    显 项(节点*e){d=e;a=是节点;}
    项(串&g,项类型 e){b=g;a=e;}
    项(符 d,项类型 e){a=e;c=d;}
    
    显 项(符 d){
        c=d;
        猜(d){
        若'(':a=左括;中;若'[':a=左中;中;
        若'|':a=或号;中;若':':a=冒号;中;
        }
    }
    串 型串(){
        静 向量<串>啊{"单符","规名","多符","关键字","是节点","或号","左括","左中","冒号","标识"};
        整 i=静转<整>(a);中 啊[i];
    }
    串 表示();
    极 为记(){
        猜(a){
        若 左括:若 左中:若 或号:若 冒号:中 真;
        }
        中 假;
    }
};
构 节点{
    向量<项>列;点类型 d;极 为或=0;
    串 表示(){
        整 j=列.大小();串流 s;符 k;
        静 符 a{'('},b{')'},c{'['},m{']'},e{'|'};
        如(d==一点);异 如(d==加点||d==乘点)s<<a;
        异 s<<c;
        如(为或)k=e;异 k=' ';
        对(整 i=0;i<j-1;i++){
            项&p=列[i];s<<p.表示()<<k;
        }
        s<<列.后().表示();
        如(d==一点);异 如(d==可无)s<<m;
        异{s<<b;如(d==加点)s<<'+';异 s<<'*';}
        中 s.小串();
    }
};
串 项::表示(){
    静 符 m{'\''},n{'\"'};串 h;
    猜(a){
    若 单符:符压(h,m,c,m);断;
    若 关键字:符压(h,n,b,n);断;
    若 多符:符压(h,m,b,m);断;
    若 规名:中 b;
    若 是节点:中 d->表示();
    }
    中 h;
}
类 解析规{
    向量<节点*>们;向量<项>层;
    串 b;符 c,d;项类型 a;向量<串>则;
    向量<极>呀;去重名 去;
    空 打印层(){
        静 动 f=[&](项&t){中 t.型串();};
        打印(串连(层,f,' '));
    }
    空 解析中(){
        静 入无序集 键{"非规名.txt"};b=取中();
        如(键.有(b))a=关键字;异 a=规名;
        压(层,项{b,a});压(则,b);
    }
    空 解单引(){
        右();c=看();
        如(可中符(c)){
            a=关键字;b=取中();右();
            压(层,项{b,a});中;
        }
        右();d=看();右();
        如(d!='\''){
            a=多符;未(2);b=取到('\'');右();
            压(层,项{b,a});中;
        }
        压(层,项{c,单符});
    }
    空 归约(向量<项>&列,点类型 e,极 有或,整 j){
        动*k=新 节点{列,e,有或};压(们,k);
        
        
        从几清理(层,j);压(层,项{k});
        
        
    }
    空 解析或号(){
        
        呀.后()=1;
        静 动 f=[&](项&t){中 t.为记();};
        整 j=逆找(f,层)+1;如(j==层.大小()-1)中;
        
        向量<项>列;子向量(层,j,列);
        归约(列,一点,0,j);
    }
    空 解析括号(){
        
        
        a=冒号;向量<项>列;
        如(c==')')a=左括;异 如(c==']')a=左中;
        极 有=呀.后();如(有)解析或号();
        静 动 g=[&](项&t){中 t.a==a;};
        静 动 f=[&](项&t){中 t.a!=或号;};
        整 j=逆找(g,层);过滤(f,层,j+1,列);
        点类型 e;如(c==']')e=可无;异 e=一点;
        归约(列,e,有,j);呀.出后();
    }
    
    空 解析个(){
        
        点类型 e;如(c=='+')e=加点;异 e=乘点;
        项&t=层.后();如(t.a==是节点){t.d->d=e;中;}
        向量<项>列;压(列,t);整 k=层.大小()-1;
        归约(列,e,0,k);
    }
    空 解析尾(){
        
        如(层.大小()==2&&层.后().a==是节点)中;
        解析括号();
    }
    空 解析一(){
        串 d=取中();d=去.取名(d);压(啊,d);
        
        当(1){
            如(入.尾)断;c=看();
            如(可中符(c)){解析中();下;}
            异 如(c=='\n'){
                
                右();c=看();
                如(c==' ')下;
                异 如(c=='\n'){入.跳过符(c);断;}
                异 断;
            }
            猜(c){
            若' ':右();断;若'\'':解单引();断;
            若'(':若'[':若':'://:算个括号
                压(呀,0);压(层,项{c});右();断;
            若')':若']':解析括号();右();断;
            若'+':若'*':解析个();右();断;
            若'|':解析或号();压(层,项{c});右();断;
            默认:
                输出<<c;打印("奇怪!\n");右();
            }
        }
        解析尾();
        压(规,d,们.后());清理(层);
    }
    空 求未知(){
        向量<串>啊;不在映(则,规,啊);
        串 b{"非规名.txt"};转文件(啊,b);
    }
公:
    无序映<串,节点*>规;向量<串>啊;
    ~解析规(){清理针(们);}
    显 解析规(串&名){入.切换(名);解析();}
    空 看看(){
        对(动&p:啊){
            输出<<p<<':';动 t=规.查找(p);
            输出<<t->第二->表示()<<行尾;
        }
    }
    空 解析(){
        当(1){
            如(入.尾)断;c=看();
            如(可中符(c))解析一();
            异{
                打印("错误,必须中文开头");
                输出<<c;右();
            }
        }
        看看();
    }
};
空 主(){
    串 名{"规则.txt"};解析规 a{名};
}