#include "小流冲.cpp"
#include "去重名.cpp"
//标识为不为`规名`的关键字
枚 项类型{单符,规名,多符,关键字,是节点,或号,左括,左中,冒号,标识};
枚 点类型{一点,可无,加点,乘点};
//默认为串点,一个个串起来的,开头都是中文的规名
//可无,如后面有+*,再改,一点.只出现一次,默认
构 节点;
构 项{
项类型 a;串 b;符 c;节点*d;
显 项(节点*e){d=e;a=是节点;}
项(串&g,项类型 e){b=g;a=e;}
项(符 d,项类型 e){a=e;c=d;}
//上面,是真正的符'c'
显 项(符 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.小串();
}//字母覆盖了,d与m
};//并连为或,串连为---且
//项与节点的关系很怪异.
串 项::表示(){
静 符 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'
a=多符;未(2);b=取到('\'');右();
压(层,项{b,a});中;
}//还有中文关键词
压(层,项{c,单符});
}
空 归约(向量<项>&列,点类型 e,极 有或,整 j){
动*k=新 节点{列,e,有或};压(们,k);
//打印("大小",层.大小(),j);
//输出<<"归约前:";打印层();
从几清理(层,j);压(层,项{k});
//输出<<"归约后:";打印层();
//打印("节点表示:",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个
//整 k=层.大小()-2;打印层();
如(层.大小()==2&&层.后().a==是节点)中;
解析括号();//打印("节点",层.后().表示());
}
空 解析一(){
串 d=取中();d=去.取名(d);压(啊,d);
//打印("=========",d);
当(1){
如(入.尾)断;c=看();
如(可中符(c)){解析中();下;}
异 如(c=='\n'){//为 d就可以(断 当);
//打印("啊");
右();c=看();
如(c==' ')下;
异 如(c=='\n'){入.跳过符(c);断;}
异 断;
}//不是空格就算退出规则了
猜(c){
若' ':右();断;若'\'':解单引();断;
若'(':若'[':若':'://:算个括号
压(呀,0);压(层,项{c});右();断;
若')':若']':解析括号();右();断;
若'+':若'*':解析个();右();断;
若'|':解析或号();压(层,项{c});右();断;
默认:
输出<<c;打印("奇怪!\n");右();
}//最后不要右();
}//还有`名`等标识符
解析尾();
压(规,d,们.后());清理(层);
}
空 求未知(){//未知标识
向量<串>啊;不在映(则,规,啊);
串 b{"非规名.txt"};转文件(啊,b);
}//已求出来了,就不用再求了.
公:
无序映<串,节点*>规;向量<串>啊;//顺序规名
~解析规(){清理针(们);}
显 解析规(串&名){入.切换(名);解析();}
空 看看(){//列举规则
对(动&p:啊){
输出<<p<<':';动 t=规.查找(p);
输出<<t->第二->表示()<<行尾;
}
}
空 解析(){
当(1){
如(入.尾)断;c=看();
如(可中符(c))解析一();
异{
打印("错误,必须中文开头");
输出<<c;右();
}
}
看看();
}
};
//a|b|...|e=>a
//(a或并串)(*|+)=>
//[]=>吧.一堆项=>项节点
空 主(){//串 名
串 名{"规则.txt"};解析规 a{名};
}//解析括号,如果就是个`冒号 是节点`,最好就完了.不用再加个归纳->解析尾时.试语句搞错了.
09-10
1389

08-11
311

08-11
291

08-11
993


2508C++,读写文件
08-11
268

08-11
384

08-11
294

08-01
159

07-31
269

07-30
1005

07-30
329

07-29
338

07-28
908


2507C++,折叠函数
07-28
324

07-27
673

07-27
256

07-27
965

07-25
1020

07-25
757

07-25
197
