update
This commit is contained in:
parent
12ee3ed0ef
commit
bb86bb93c8
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
/build
|
/build
|
||||||
|
/.cache
|
||||||
|
/.vscode
|
2
include/Lexer.hpp
Normal file
2
include/Lexer.hpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
|
@ -1,114 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <concepts>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <iostream>
|
|
||||||
#include <optional>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <concepts>
|
|
||||||
|
|
||||||
namespace ztl{
|
|
||||||
struct Code{
|
|
||||||
const std::string _str;
|
|
||||||
std::optional<char> getStr(size_t n)const{return idx+n>=_str.size()?std::nullopt:std::optional<char>{_str[idx+n]};};
|
|
||||||
size_t idx=0;
|
|
||||||
std::optional<char> now()const{return getStr(0);}
|
|
||||||
std::optional<char> first()const{return getStr(1);}
|
|
||||||
std::optional<char> second()const{return getStr(2);}
|
|
||||||
std::optional<char> 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<class T>
|
|
||||||
concept Numeric = std::integral<T> || std::floating_point<T>;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
class INodeData{
|
|
||||||
public:
|
|
||||||
T data;
|
|
||||||
virtual~INodeData()=default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Node{
|
|
||||||
public:
|
|
||||||
virtual~Node()=default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<Numeric T>
|
|
||||||
class NumberNode:public Node,public INodeData<T>{
|
|
||||||
public:
|
|
||||||
NumberNode(T&t):data(t){
|
|
||||||
|
|
||||||
}
|
|
||||||
T data;
|
|
||||||
virtual~NumberNode()=default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool isItsType(const Code&code)=delete;
|
|
||||||
|
|
||||||
bool inline isIntChar(const char c)noexcept{
|
|
||||||
return '0'<=c&&c<='9';
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
bool inline isItsType<NumberNode<int>>(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<class T>
|
|
||||||
inline T parse(Code&code)=delete;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline NumberNode<int> 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<int>(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<NumberNode<int>>(code)){
|
|
||||||
std::cout<<parse<NumberNode<int>>(code).data<<'\n';
|
|
||||||
}else[[unlikely]]{
|
|
||||||
throw std::logic_error("cannot parse the code");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,8 +1,5 @@
|
|||||||
#include <string>
|
#include "Lexer.hpp"
|
||||||
#include <Parser.hpp>
|
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
std::string s = "1 2 3 ; ; ; ;";
|
|
||||||
ztl::Parser parser(s);
|
|
||||||
parser.advance();
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user