上篇解析语法规则源码.

#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{};
}//解析括号,如果就是个`冒号 是节点`,最好就完了.不用再加个归纳->解析尾时.试语句搞错了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值