LiCode(Alpha26.5.25)
2026-05-25 21:10:34
发布于:香港
#include<algorithm>
#include<cctype>
#include<fstream>
#include<iostream>
#include<limits>
#include<sstream>
#include<string>
#include<string_view>
#include<vector>
static constexpr const char* key_words[]={
"let","input","print","Null","println",
"print.flush","print.buffer=open","print.buffer=close"
};
static constexpr size_t kw_cnt=sizeof(key_words)/sizeof(const char*);
bool ostream_need_buffer=true;
enum ctypes: char{Int,Float,String,Null,Error,KeyWord};
struct variable{
std::string name{};
std::string data{};
ctypes type=Null;
};
static std::vector<variable> memory;
std::string trim(std::string_view str_v) noexcept{
std::string_view::iterator start=str_v.begin();
std::string_view::iterator end=str_v.end();
while(start!=end&&std::isspace(static_cast<int>(*start))) start++;
do{end--;}while(std::distance(start,end)>0&&std::isspace(static_cast<int>(*end)));
return std::string(start,end+1);
}
bool vname_check(std::string_view name) noexcept{
if(name.empty()) return false;
std::string_view::size_type len=name.size();
if(std::isdigit(static_cast<int>(name.front()))) return false;
for(std::string_view::size_type i=0;i<len;i++){
char chr=name[i];
if(std::isalnum(static_cast<int>(chr))||chr=='_') continue;
return false;
}
for(std::size_t i=0;i<kw_cnt;i++){
if(name==key_words[i]) return false;
}
std::vector<variable>::size_type size=memory.size();
for(std::vector<variable>::size_type i=0;i<size;i++){
if(name==memory[i].name) return false;
}
return true;
}
variable opt_sval(std::string_view str_v) noexcept{
if(str_v=="input") return variable{{},"input",KeyWord};
if(str_v=="Null") return variable{{},{},Null};
if(str_v.empty()) return variable{{},{},Null};
const std::string_view::size_type len=str_v.size();
if(len==1){
char chr=str_v.front();
if(chr=='.') return variable{{},"0.000000",Float};
if(std::isdigit(static_cast<int>(chr))) return variable{{},std::string(str_v),Int};
return variable{"","",Error};
}
if(len>=2){
char front=str_v.front(),back=str_v.back();
if((front=='\"'&&back=='\"')||(front=='\''&&back=='\'')){
std::string result{};
for(std::string_view::size_type i=1;i<len-1;i++){
char chr=str_v[i];
if(chr=='\''){
if(front=='\'') return variable{{},{},Error};
result.push_back('\'');
}
else if(chr=='\"'){
if(front=='\"') return variable{{},{},Error};
result.push_back('\"');
}
else if(chr=='\\'){
if(i==len-1) return variable{{},{},Error};
switch(str_v[++i]){
case 'a':
result.push_back('\a');
break;
case 'b':
result.push_back('\b');
break;
case 'f':
result.push_back('\f');
break;
case 'n':
result.push_back('\n');
break;
case 'r':
result.push_back('\r');
break;
case 't':
result.push_back('\t');
break;
case 'v':
result.push_back('\v');
break;
case '\\':
result.push_back('\\');
break;
case '\'':
result.push_back('\'');
break;
case '\"':
result.push_back('\"');
break;
case '0':
result.push_back('\0');
break;
default:
result.push_back(chr);
result.push_back(str_v[i]);
break;
}
}
else result.push_back(chr);
}
return variable{{},result,String};
}
else{
std::string_view::const_iterator cbegin=str_v.cbegin(),cend=str_v.cend();
bool isneg=false;
for(;cbegin!=cend;cbegin++){
if(*cbegin=='+') continue;
if(*cbegin=='-') isneg^=true;
else break;
}
if(cbegin==cend) return variable{{},{},Error};
variable result{{},isneg?"-":std::string{},Int};
std::string_view::size_type dotpos=str_v.find('.');
std::string::size_type len;
std::string intpart=std::string(trim(str_v.substr(cbegin-str_v.cbegin(),dotpos)));
len=intpart.size();
if(len==0) result.data.push_back('0');
else{
for(std::string::size_type i=0;i<len;i++){
char chr=intpart[i];
if(!std::isdigit(static_cast<int>(chr)))
return variable{{},{},Error};
result.data.push_back(chr);
}
}
if(dotpos!=std::string_view::npos){
result.type=Float;
result.data.push_back('.');
std::string floatpart=std::string(trim(str_v.substr(dotpos+1)));
len=floatpart.size();
if(len==0) result.data.append("000000");
for(std::string::size_type i=0;i<6;i++){
char chr=floatpart[i];
if(!std::isdigit(static_cast<int>(chr)))
return variable{{},{},Error};
result.data.push_back(chr);
}
if(len<6){
std::string_view::size_type pad=6-len;
result.data.append(pad,'0');
}
}
return result;
}
}
return variable{};
}
std::vector<variable>::size_type find_v(std::string_view name) noexcept{
std::vector<variable>::iterator it=
std::find_if(memory.begin(),memory.end(),[&name](const variable& var){return var.name==name;});
if(it!=memory.end()) return static_cast<std::vector<variable>::size_type>(std::distance(memory.begin(),it));
else return std::numeric_limits<std::vector<variable>::size_type>::max();
}
enum exec_flag: char{emptyln,goodres,vnameno,valueno};
exec_flag execln(std::string_view str_v) noexcept{
std::string line=trim(str_v);
if(line.empty()||line.front()=='#') return emptyln;
std::istringstream stringin(line);
std::string word;
stringin>>word;
if(word=="let"){
std::getline(stringin,word);
std::string::size_type eq=word.find('=');
std::string name=trim(word.substr(0,eq));
if(!vname_check(name)) return vnameno;
if(eq!=std::string::npos){
std::string value=trim(word.substr(eq+1));
variable opt_value=opt_sval(value);
if(opt_value.type==Error) return valueno;
opt_value.name=name;
memory.push_back(opt_value);
if(opt_value.type==KeyWord){
memory.back().data.clear();
if(opt_value.data=="input"){
while(true){
std::istream::int_type chr=std::cin.get();
if(chr==' '||chr=='\r'||chr=='\n'||chr=='\t'||chr==EOF) break;
memory.back().data.push_back(static_cast<char>(chr));
}
if(memory.back().data.empty()) memory.back().type=Null;
else memory.back().type=String;
}
}
}
else memory.push_back(variable{{},{},Null});
}
else if(word=="input"){
while(std::getline(stringin,word,',')){
std::vector<variable>::size_type index=find_v(word);
if(index!=std::numeric_limits<std::vector<variable>::size_type>::max()){
while(true){
std::istream::int_type chr=std::cin.get();
if(chr==' '||chr=='\r'||chr=='\n'||chr=='\t'||chr==EOF) break;
memory[index].data.push_back(static_cast<char>(chr));
}
if(memory[index].data.empty()) memory.back().type=Null;
else memory[index].type=String;
}
else return vnameno;
}
if(!word.empty()){
std::vector<variable>::size_type index=find_v(word);
if(index!=std::numeric_limits<std::vector<variable>::size_type>::max()){
while(true){
std::istream::int_type chr=std::cin.get();
if(chr==' '||chr=='\r'||chr=='\n'||chr=='\t'||chr==EOF) break;
memory[index].data.push_back(static_cast<char>(chr));
}
if(memory[index].data.empty()) memory.back().type=Null;
else memory[index].type=String;
}
else return vnameno;
}
}
else if(word=="print"){
while(std::getline(stringin,word,',')){
word=trim(word);
if(word=="print.flush") std::cout.flush();
else if(word=="print.buffer=open") ostream_need_buffer=true;
else if(word=="print.buffer=close") ostream_need_buffer=false;
else{
std::vector<variable>::size_type index=find_v(word);
if(index!=std::numeric_limits<std::vector<variable>::size_type>::max()){
if(ostream_need_buffer) std::cout<<memory[index].data;
else std::cerr<<memory[index].data;
}
else return vnameno;
}
}
}
else if(word=="println"){
while(std::getline(stringin,word,',')){
word=trim(word);
if(word=="print.flush") std::cout.flush();
else if(word=="print.buffer=open") ostream_need_buffer=true;
else if(word=="print.buffer=close") ostream_need_buffer=false;
else{
std::vector<variable>::size_type index=find_v(word);
if(index!=std::numeric_limits<std::vector<variable>::size_type>::max()){
if(ostream_need_buffer) std::cout<<memory[index].data;
else std::cerr<<memory[index].data;
}
else return vnameno;
}
}
std::cout.put('\n').flush();
}
return goodres;
}
int main(){
std::ifstream fin("LiCode.txt");
if(!fin.is_open()){
std::cerr<<"Cannot open 'LiCode.txt!'";
return 404;
}
std::string line;
std::uint64_t lnum=0;
while(std::getline(fin,line)){
lnum++;
exec_flag exec_result=execln(line);
switch(exec_result){
case emptyln:
continue;
case goodres:
continue;
case vnameno:
std::cerr<<"LiCode System Error: variable name is not good! Error line: "<<lnum;
break;
case valueno:
std::cerr<<"LiCode System Error: variable value is not a correct value! Error line: "<<lnum;
break;
default:
std::cerr<<"LiCode System Error: 404 error! Error line: "<<lnum;
}
fin.close();
abort();
}
fin.close();
}
明天公布语法(C++17以上)
全部评论 2
?
昨天 来自 浙江
0写一条评论
昨天 来自 上海
0


























有帮助,赞一个