#pragma once #include #include #include #include #include #include #include namespace ztl{ struct Code{ const std::string _str; std::optional getStr(size_t n)const{return idx+n>=_str.size()?std::nullopt:std::optional{_str[idx+n]};}; size_t idx=0; std::optional now()const{return getStr(0);} std::optional first()const{return getStr(1);} std::optional second()const{return getStr(2);} std::optional third()const{return getStr(3);} void consume(){ if(idx==_str.size())[[unlikely]]{ throw std::logic_error("the Code cannot to be consume!"); } idx++; } bool isEnd(){ return idx==_str.size(); } }; template concept Numeric = std::integral || std::floating_point; template class INodeData{ public: T data; virtual~INodeData()=default; }; class Node{ public: virtual~Node()=default; }; template class NumberNode:public Node,public INodeData{ public: NumberNode(T&t):data(t){ } T data; virtual~NumberNode()=default; }; template bool isItsType(const Code&code)=delete; bool inline isIntChar(const char c)noexcept{ return '0'<=c&&c<='9'; } template<> bool inline isItsType>(const Code&code){ if(isIntChar(code.now().value())){ if(code.now().value()=='0'){ if(isIntChar(code.first().value())){ return false; }else{ return true; } }else{ return true; } }else{ return false; } } template inline T parse(Code&code)=delete; template<> inline NumberNode parse(Code&code){ int v=0; while(code.now().has_value()&&isIntChar(code.now().value())){ v=v*10+(code.now().value()-'0'); code.consume(); } return NumberNode(v); } class Parser{ Code code; public: Parser(const std::string &code):code({._str=code}){ } void advance(){ while(!code.isEnd()){ if(code.now().value()==';'){ return; } if(code.now().value()==' '){ code.consume(); }else if(isItsType>(code)){ std::cout<>(code).data<<'\n'; }else[[unlikely]]{ throw std::logic_error("cannot parse the code"); } } } }; }